Using python - OpenCV I have succeeded to read the following image, detect the rectangles , crop them and save every rectangle as an image.
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:
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: