检查两个轮廓是否相交? [英] Check if two contours intersect?

查看:147
本文介绍了检查两个轮廓是否相交?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 2 个从 cv2.findContours() 接收到的轮廓(cont1cont2).我怎么知道它们是否相交?我不需要坐标,我只需要一个布尔值 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]...对于 cont1array 中的 cont1:对于 cont2array 中的 cont2:打印(cont1")打印(续 1)打印(类型(cont1))打印(cont2")打印(续 2)打印(类型(cont2))>如果 cont1 和 cont2 相交:#我不知道如何检查相交打印(是的,它们相交")别的:打印(不,他们不相交")# 续 1# [[172 302]# [261 301]# [262 390]# [173 391]]# <class 'numpy.ndarray'># cont2# [[ 0 0]# [0699]# [499 699]# [499 0]]# <class 'numpy.ndarray'>

解决方案

一旦你有了 cv2.findContours() 的两个轮廓,你就可以使用按位 AND检测交叉点的操作.具体来说,我们可以使用

检测到的轮廓

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

[[假假假...假假假][假假假...假假假][假假假...假假假]...[假假假...假假假][假假假...假假假][假假假...假假假]]

我们检查 intersection 数组以查看 True 是否存在.我们将在轮廓相交的地方获得 True1,在轮廓相交的地方获得 False0.>

返回intersection.any()

这样我们就得到了

<块引用>

错误

完整代码

导入 cv2将 numpy 导入为 np定义轮廓相交(原始图像,轮廓1,轮廓2):# 两个单独的轮廓试图检查交点轮廓 = [轮廓 1,轮廓 2]# 创建与原始图像大小相同的填充零的图像空白 = np.zeros(original_image.shape[0:2])# 将每个轮廓复制到自己的图像中并用1"填充image1 = cv2.drawContours(blank.copy(), 轮廓, 0, 1)image2 = cv2.drawContours(blank.copy(), 轮廓, 1, 1)# 对两幅图像使用逻辑与运算# 由于这两个图像已按位 AND 应用于它,# 应该有一个'1'或'True'的地方有交集# 和一个'0'或'False',它没有相交交集 = np.logical_and(image1, image2)# 检查交集数组中是否有'1'返回intersection.any()original_image = cv2.imread("base.png")图像 = original_image.copy()cv2.imshow(原始",图像)灰色 = cv2.cvtColor(图像,cv2.COLOR_BGR2GRAY)cv2.imshow(灰色",灰色)模糊 = cv2.GaussianBlur(gray, (5,5), 0)cv2.imshow(模糊",模糊)阈值 = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]cv2.imshow(阈值",阈值)轮廓 = cv2.findContours(threshold.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 根据 OpenCV 版本,cv.findContours 返回的参数数量# 是 2 或 3轮廓 = 轮廓 [1] 如果 len(轮廓) == 3 否则轮廓 [0]轮廓列表 = []对于轮廓中的 c:contour_list.append(c)cv2.drawContours(image, [c], 0, (0,255,0), 2)打印(轮廓相交(原始图像,轮廓列表[0],轮廓列表[1]))cv2.imshow(轮廓",图像)cv2.waitKey(0)

I have 2 contours (cont1 and cont2) received from cv2.findContours(). How do I know if they intersect or not? I don't need coordinates, I only need a boolean True or False.

I have attempted different ways and already tried to do a check with

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

... but got the error that the array has no method "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'>

解决方案

Once you have the two contours from cv2.findContours(), you can use a bitwise AND operation to detect intersection. Specifically, we can use np.logical_and(). The idea is to create two separate images for each contour and then use the logical AND operation on them. Any points that have a positive value (1 or True) will be points of intersection. So since you're only looking to obtain a boolean value of whether there is intersection, we can check the intersected image to see if there is a single positive value. Essentially, if the entire array is False then there was no intersection between the contours. But if there is a single True, then the contours touched and thus intersect.

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()

Example

Original Image

Detected Contour

We now pass the two detected contours to the function and obtain this intersection array:

[[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]]

We check the intersection array to see if True exists. We will obtain a True or 1 where the contours intersect and False or 0 where they do not.

return intersection.any()

Thus we obtain

False

Full code

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)

这篇关于检查两个轮廓是否相交?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆