Find number of close loops in Binary Edge Image

孤者浪人 提交于 2021-02-11 15:57:41

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!