正如@Silencer 所建议的,我使用他在此处发布的代码在我的图像中的数字周围绘制轮廓。在某些时候,使用数字就像0,6,8,9
我看到它们的内部轮廓(圆圈)也被填充了。我怎样才能防止这种情况?是否为 cv2.drawContours() 设置最小/最大动作区域,以便我可以排除内部区域?
我试图通过cv2.RETR_EXTERNAL
,但使用这个参数只考虑整个外部区域。
代码是这样的(再次感谢 Silencer。几个月来一直在寻找这个..):
import numpy as np
import cv2
im = cv2.imread('imgs\\2.png')
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
#contours.sort(key=lambda x: int(x.split('.')[0]))
for i, cnts in enumerate(contours):
## this contour is a 3D numpy array
cnt = contours[i]
res = cv2.drawContours(im, [cnt], 0, (255, 0, 0), 1)
cv2.imwrite("contours.png", res)
'''
## Method 1: crop the region
x,y,w,h = cv2.boundingRect(cnt)
croped = res[y:y+h, x:x+w]
cv2.imwrite("cnts\\croped{}.png".format(i), croped)
'''
## Method 2: draw on blank
# get the 0-indexed coords
offset = cnt.min(axis=0)
cnt = cnt - cnt.min(axis=0)
max_xy = cnt.max(axis=0) + 1
w, h = max_xy[0][0], max_xy[0][1]
# draw on blank
canvas = np.ones((h, w, 3), np.uint8) * 255
cv2.drawContours(canvas, [cnt], -1, (0, 0, 0), -1)
#if h > 15 and w < 60:
cv2.imwrite("cnts\\canvas{}.png".format(i), canvas)
我正在处理的主要图像..
谢谢
更新
我在下面实现了 Fiver 答案,结果如下:
import cv2
import numpy as np
img = cv2.imread('img.png')
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
img_v = img_hsv[:, :, 2]
ret, thresh = cv2.threshold(~img_v, 127, 255, 0)
image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for i, c in enumerate(contours):
tmp_img = np.zeros(img_v.shape, dtype=np.uint8)
res = cv2.drawContours(tmp_img, [c], -1, 255, cv2.FILLED)
tmp_img = np.bitwise_and(tmp_img, ~img_v)
ret, inverted = cv2.threshold(tmp_img, 127, 255, cv2.THRESH_BINARY_INV)
cnt = contours[i]
x, y, w, h = cv2.boundingRect(cnt)
cropped = inverted[y:y + h, x:x + w]
cv2.imwrite("roi{}.png".format(i), cropped)