3

Using python - OpenCV I have succeeded to read the following image, detect the rectangles , crop them and save every rectangle as an image.

Main Image

and this is a sample of the rectangles that I have succeeded to crop and save as an image. (So there will be 12 of them)

Rectanle Image

Then working on every rectangle image, in order to isolate the circle and create a new image for every circle - which I have succeeded to do too using cv2.HoughCircles.

The output of the image A contains the circle looks like :

Image contains circle and more

Now: what I need to do is to remove everything outside of the green circle and convert everything outside the green circle to black, then get B(only the green circle):

Isolated Image Circle

The question is: How to get B from A.

I take code from OpenCV : Remove background of an image, but it is not work for the image A as excepted, while output such a image instead:


This is the code taken from OpenCV : Remove background of an image.

circle_path_test = 'D:\rec.png'

img  = cv2.imread(circle_path_test)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

## (2) Threshold
th, threshed = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV|cv2.THRESH_OTSU)

## (3) Find the min-area contour
_, cnts, _ = cv2.findContours(threshed, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key=cv2.contourArea)
for cnt in cnts:
    if cv2.contourArea(cnt) > 100:
        break

## (4) Create mask and do bitwise-op
mask = np.zeros(img.shape[:2],np.uint8)
cv2.drawContours(mask, [cnt],-1, 255, -1)
dst = cv2.bitwise_and(img, img, mask=mask)

## Save it
# cv2.imshow("dst.png", dst);cv2.waitKey()       
#rec_img_name_without_extension ,img_ext = os.path.splitext(circle_path_test)                
cv2.imwrite(os.path.join(os.getcwd(), 'dst_circle_gray - Copy.png') , dst) 
Kinght 金
  • 17,681
  • 4
  • 60
  • 74
  • Make this clear: Is there any other circle except at the center? Will other region be green or similar with the center circle? – Kinght 金 Jan 22 '18 at 15:08
  • There is no other circles except the one in the center. Yes .some of the other regions outside the circle can be green or similar to the color inside the circle. –  Jan 22 '18 at 15:28
  • Ok, I'll update. – Kinght 金 Jan 22 '18 at 15:33

1 Answers1

5

I answered the similar question @ OpenCV : Remove background of an image . It works successful for the image you posted in the question.


It fails on the below image. Because, the code is for only two circle detected, or when the inner circle is the the first sorted contour greater than 100.

To make it work, you should make it meet the condition. You can do something to rule out the non-circle ones, the non-center ones, the too-small or too-big ones. Such as:

enter image description here


A sample code:

#!/usr/bin/python3
# 2018.01.20 20:58:12 CST
# 2018.01.20 21:24:29 CST
# 2018.01.22 23:30:22 CST

import cv2
import numpy as np

## (1) Read
img = cv2.imread("img04.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

## (2) Threshold
th, threshed = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV|cv2.THRESH_OTSU)

## (3) Find the first contour that greate than 100, locate in centeral region
## Adjust the parameter when necessary
cnts = cv2.findContours(threshed, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2]
cnts = sorted(cnts, key=cv2.contourArea)
H,W = img.shape[:2]
for cnt in cnts:
    x,y,w,h = cv2.boundingRect(cnt)
    if cv2.contourArea(cnt) > 100 and (0.7 < w/h < 1.3) and (W/4 < x + w//2 < W*3/4) and (H/4 < y + h//2 < H*3/4):
        break

## (4) Create mask and do bitwise-op
mask = np.zeros(img.shape[:2],np.uint8)
cv2.drawContours(mask, [cnt],-1, 255, -1)
dst = cv2.bitwise_and(img, img, mask=mask)

## Display it
cv2.imwrite("dst.png", dst)
cv2.imshow("dst.png", dst)
cv2.waitKey()

The result:

enter image description here

Kinght 金
  • 17,681
  • 4
  • 60
  • 74
  • Thank you so much. You are the best . It works perfectly :-) Thank you again. –  Jan 22 '18 at 16:01
  • Let me check how I can accept the answer. I am new to this website... Hope I have the reputation for that –  Jan 22 '18 at 18:03