问题
I have a binary image with the number of close loops and free curves like shown in image..
My approach so far- (python code):
- Skeletonize the image to get edge of 1 pixel
- Use label/bwlabel to get individual curve/edge
- Applied DFS to get the edge which is not close
- Apply DFS to get close edge..but not working correctly..
Expected output -
Number of close loops =6, the sum of the pixels along the loop or all (x,y) points along the edge of the close curve as highlighted in RED
Expected Output-
回答1:
You already have a binary image: simply use findContours() to get the inner contours.
Bare in mind you want use cv2.RETR_CCOMP as the Countour Retrieval Mode to easily access the holes:
retrieves all of the contours and organizes them into a two-level hierarchy. At the top level, there are external boundaries of the components. At the second level, there are boundaries of the holes. If there is another contour inside a hole of a connected component, it is still put at the top level.
It should be a matter of simply getting the length of countours on the second level (holes)
回答2:
Here is one way to do that in Python/OpenCV.
- Read the input as grayscale
- Threshold to binary
- Get the contours and hierarchy
- Loop over the contours and corresponding hierarchy and discard contours with no parent (the external ones) and save and count the contours with no children (the innermost ones)
- Draw the contours on the input
- Save the results
Input:
import cv2
import numpy as np
# read image as grayscale
img = cv2.imread('loops.png', cv2.IMREAD_GRAYSCALE)
hh, ww = img.shape
# blacken right columns that are white
img[0:hh, ww-3:ww] = 0
# threshold
thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY)[1]
# get contours
contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
hierarchy = contours[1] if len(contours) == 2 else contours[2]
contours = contours[0] if len(contours) == 2 else contours[1]
# get the actual inner list of hierarchy descriptions
hierarchy = hierarchy[0]
# count inner contours
count = 0
result = img.copy()
result = cv2.merge([result,result,result])
for component in zip(contours, hierarchy):
cntr = component[0]
hier = component[1]
# discard outermost no parent contours and keep innermost no child contours
# hier = indices for next, previous, child, parent
# no parent or no child indicated by negative values
if (hier[3] > -1) & (hier[2] < 0):
count = count + 1
cv2.drawContours(result, [cntr], 0, (0,0,255), 2)
# print count
print("count:",count)
# save result
cv2.imwrite("loops_result.png",result)
# show result
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Resulting contours:
Count:
count: 6
来源:https://stackoverflow.com/questions/62120690/find-number-of-close-loops-in-binary-edge-image