Python - OpenCV - Cropping images and isolating specific objects
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:
Admin
Updated on June 06, 2022Comments
-
Admin almost 2 years
Using python - OpenCV I have succeeded to read the following image, detect the rectangles , crop them and save every rectangle as an 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)
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 :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):The question is: How to get
B
fromA
.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)