2番目のステップで、これらの輪郭を輪郭検出に使用したいと仮定すると、より簡単な解決策があります。膨張を使用すると、白い領域が拡大され、ギャップが閉じます。
import cv2
import numpy as np
image = cv2.imread('lineswithgaps.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# apply dilation on src image
kernel = np.ones((3,3),np.uint8)
dilated_img = cv2.dilate(gray, kernel, iterations = 2)
cv2.imshow("filled gaps for contour detection", dilated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
欠点として、エッジが厚くなりますが、高精度を必要としない場合、これは問題にならない可能性があります...輪郭を今すぐ検出したい場合は、切り取った最初のコードに次の行を追加するだけです:
canvas = dilated_img.copy() # Canvas for plotting contours on
canvas = cv2.cvtColor(canvas, cv2.COLOR_GRAY2RGB) # create 3 channel image so we can plot contours in color
contours, hierarchy = cv2.findContours(dilated_img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
# loop through the contours and check through their hierarchy, if they are inner contours
# more here: https://docs.opencv.org/master/d9/d8b/tutorial_py_contours_hierarchy.html
for i,cont in enumerate(contours):
# look for hierarchy[i][3]!=-1, ie hole boundaries
if ( hierarchy[0][i][3] != -1 ):
#cv2.drawContours(canvas, cont, -1, (0, 180, 0), 1) # plot inner contours GREEN
cv2.fillPoly(canvas, pts =[cont], color=(0, 180, 0)) # fill inner contours GREEN
else:
cv2.drawContours(canvas, cont, -1, (255, 0, 0), 1) # plot all others BLUE, for completeness
cv2.imshow("Contours detected", canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()