检查两个轮廓是否相交?

发布于 2021-01-29 14:56:01

我收到了2个轮廓(cont1cont2cv2.findContours()。我怎么知道它们是否相交?我不需要坐标,我只需要一个布尔值TrueFalse

我尝试了不同的方式,并且已经尝试与

if ((cont1 & cont2).area() > 0):

…但是得到的错误是数组没有方法“ Area()”

...
cont1array = cv2.findContours(binary1, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[0]
cont2array = cv2.findContours(binary2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[0]
...

for cont1 in cont1array:
  for cont2 in cont2array:
    print("cont1")
    print(cont1)
    print(type(cont1))
    print("cont2")
    print(cont2)
    print(type(cont2))
>   if cont1 and cont2 intersect: #i dont know how check intersect
      print("yes they intersect")
    else:
      print("no they do not intersect")

# cont1
# [[172 302]
#  [261 301]
#  [262 390]
#  [173 391]]
# <class 'numpy.ndarray'>
# cont2
# [[  0   0]
#  [  0 699]
#  [499 699]
#  [499   0]]
# <class 'numpy.ndarray'>
关注者
0
被浏览
171
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    一旦有了的两个轮廓cv2.findContours(),就可以使用按位AND运算来检测相交。具体来说,我们可以使用np.logical_and()。想法是为每个轮廓创建两个单独的图像,然后AND对它们使用逻辑运算。具有正值(1True)的任何点都将是交点。因此,由于您只想获取是否存在相交的布尔值,因此我们可以检查相交的图像以查看是否存在单个正值。本质上,如果整个数组都False存在,则轮廓之间就没有交集。但是,如果只有一个True,则轮廓会接触并因此相交。

    def contourIntersect(original_image, contour1, contour2):
        # Two separate contours trying to check intersection on
        contours = [contour1, contour2]
    
        # Create image filled with zeros the same size of original image
        blank = np.zeros(original_image.shape[0:2])
    
        # Copy each contour into its own image and fill it with '1'
        image1 = cv2.drawContours(blank.copy(), contours, 0, 1)
        image2 = cv2.drawContours(blank.copy(), contours, 1, 1)
    
        # Use the logical AND operation on the two images
        # Since the two images had bitwise and applied to it,
        # there should be a '1' or 'True' where there was intersection
        # and a '0' or 'False' where it didnt intersect
        intersection = np.logical_and(image1, image2)
    
        # Check if there was a '1' in the intersection
        return intersection.any()
    

    原始图片

    在此处输入图片说明

    检测到轮廓

    在此处输入图片说明

    现在,我们将两个检测到的轮廓传递给函数,并获得此交集数组:

    [[False False False ... False False False]
     [False False False ... False False False]
     [False False False ... False False False]
     ...
     [False False False ... False False False]
     [False False False ... False False False]
     [False False False ... False False False]]
    

    我们检查intersection数组以查看是否True存在。我们将获得一个True1轮廓相交的地方,False0它们不相交的地方。

    return intersection.any()
    

    这样我们得到

    完整代码

    import cv2
    import numpy as np
    
    def contourIntersect(original_image, contour1, contour2):
        # Two separate contours trying to check intersection on
        contours = [contour1, contour2]
    
        # Create image filled with zeros the same size of original image
        blank = np.zeros(original_image.shape[0:2])
    
        # Copy each contour into its own image and fill it with '1'
        image1 = cv2.drawContours(blank.copy(), contours, 0, 1)
        image2 = cv2.drawContours(blank.copy(), contours, 1, 1)
    
        # Use the logical AND operation on the two images
        # Since the two images had bitwise AND applied to it,
        # there should be a '1' or 'True' where there was intersection
        # and a '0' or 'False' where it didnt intersect
        intersection = np.logical_and(image1, image2)
    
        # Check if there was a '1' in the intersection array
        return intersection.any()
    
    original_image = cv2.imread("base.png")
    image = original_image.copy()
    
    cv2.imshow("original", image)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    cv2.imshow("gray", gray)
    blurred = cv2.GaussianBlur(gray, (5,5), 0)
    cv2.imshow("blur", blurred)
    threshold = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]
    cv2.imshow("thresh", threshold)
    
    contours = cv2.findContours(threshold.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # Depending on OpenCV version, number of arguments return by cv.findContours 
    # is either 2 or 3
    contours = contours[1] if len(contours) == 3 else contours[0]
    
    contour_list = []
    for c in contours:
        contour_list.append(c)
        cv2.drawContours(image, [c], 0, (0,255,0), 2)
    
    print(contourIntersect(original_image, contour_list[0], contour_list[1]))
    cv2.imshow("contour", image)
    cv2.waitKey(0)
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看