检查两个轮廓是否相交?
我收到了2个轮廓(cont1
和cont2
)cv2.findContours()
。我怎么知道它们是否相交?我不需要坐标,我只需要一个布尔值True
或False
。
我尝试了不同的方式,并且已经尝试与
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'>
-
一旦有了的两个轮廓
cv2.findContours()
,就可以使用按位AND
运算来检测相交。具体来说,我们可以使用np.logical_and()
。想法是为每个轮廓创建两个单独的图像,然后AND
对它们使用逻辑运算。具有正值(1
或True
)的任何点都将是交点。因此,由于您只想获取是否存在相交的布尔值,因此我们可以检查相交的图像以查看是否存在单个正值。本质上,如果整个数组都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
存在。我们将获得一个True
或1
轮廓相交的地方,False
或0
它们不相交的地方。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)