如何将中空形状检测为一个物体而不是两个物体?
How to detect a hollowed shape as one object instead of two?
一个空心的形状,以下面的情况为例,被检测为2个物体,外三角形(可以看作只是一个轮廓)以某种方式被检测为2个物体,如第二张图所示(2外部黑色三角形内部和外部的绿色轮廓)。
第一张图片:
第二张图片(我的代码的结果):
预期结果:
我的代码:
import os
import cv2
import numpy as np
file_name = os.path.join(os.path.dirname(__file__),'hollowtri.png')
assert os.path.exists(file_name)
a = cv2.imread(file_name)
#Convert image to gray image
imgGray = cv2.cvtColor(a,cv2.COLOR_BGR2GRAY)
#Doing threshold on the image
_,thresh = cv2.threshold(imgGray,100,255,cv2.THRESH_BINARY_INV)
#Finding objects
contours,_ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
#Print the result based on the contours found
num = 0
for contour in contours:
cv2.drawContours(a,contours,num,(0,255,0),2)
num+=1
cv2.imshow("Thresh", thresh)
cv2.imshow("Triangle", a)
cv2.waitKey(0)
我不想用cv2.RETR_EXTERNAL
因为我要检测内实心三角形,请问有解决办法吗?我希望外三角形仅被检测为 1 个对象。
注:只有涂黑的形状才是关注对象。所以结果应该只包含 2 个对象,但是在图像 2 中,外三角形在内部和外部用绿色勾勒了两次,我的目标是只勾勒一次,因为空心三角形只有 1 个对象,而不是 2 个。
要解决您的问题,选择 flag
很重要。我们正在处理一个轮廓位于另一个轮廓内的情况。我们可以在寻找轮廓 cv2.findContours()
时使用 RETR_CCOMP
标志。并分析层级输出。
简介
在下面的二进制图像中,我们有一个 object,但是在寻找轮廓时,我们最终得到 2 个(意味着 2 个不同的 objects)。
- 等高线 1(以红色指出)是 object 的外边界 - 这是 parent,值为
-1
- 等高线 2(以绿色指出)是 object 的内边界 - 这是 child,值为
0
我们只想找到每个不同 object 的外边界。在上图中,那将只是轮廓 1。
代码:
img = cv2.imread(r'C:\Users4316\Desktop\Stack\tri.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
th = cv2.threshold(gray,100,255,cv2.THRESH_BINARY_INV)[1]
# using cv2.RETR_CCOMP flag
contours,hierarchy = cv2.findContours(th,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)
# initializing an index list
contour_index_list = []
# draw every contour whose 4th column in hierarch array is -1
for index in range(0, len(contours)):
if (hierarchy[:,index][0][3] == -1):
contour_index_list.append(index)
cv2.drawContours(img, [contours[index]], 0, (0, 255, 0), 3)
结果:
详情:
观察hierarchy
变量给出一个数组,每行分配给每个轮廓:
array([[[ 1, -1, -1, -1],
[-1, 0, 2, -1],
[-1, -1, -1, 1]]], dtype=int32)
According to the documentation,第4列表示parent-child关系。
如果值为:
- -1 轮廓是 parent
- 0 轮廓是 child
一个空心的形状,以下面的情况为例,被检测为2个物体,外三角形(可以看作只是一个轮廓)以某种方式被检测为2个物体,如第二张图所示(2外部黑色三角形内部和外部的绿色轮廓)。
第一张图片:
第二张图片(我的代码的结果):
预期结果:
我的代码:
import os
import cv2
import numpy as np
file_name = os.path.join(os.path.dirname(__file__),'hollowtri.png')
assert os.path.exists(file_name)
a = cv2.imread(file_name)
#Convert image to gray image
imgGray = cv2.cvtColor(a,cv2.COLOR_BGR2GRAY)
#Doing threshold on the image
_,thresh = cv2.threshold(imgGray,100,255,cv2.THRESH_BINARY_INV)
#Finding objects
contours,_ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
#Print the result based on the contours found
num = 0
for contour in contours:
cv2.drawContours(a,contours,num,(0,255,0),2)
num+=1
cv2.imshow("Thresh", thresh)
cv2.imshow("Triangle", a)
cv2.waitKey(0)
我不想用cv2.RETR_EXTERNAL
因为我要检测内实心三角形,请问有解决办法吗?我希望外三角形仅被检测为 1 个对象。
注:只有涂黑的形状才是关注对象。所以结果应该只包含 2 个对象,但是在图像 2 中,外三角形在内部和外部用绿色勾勒了两次,我的目标是只勾勒一次,因为空心三角形只有 1 个对象,而不是 2 个。
要解决您的问题,选择 flag
很重要。我们正在处理一个轮廓位于另一个轮廓内的情况。我们可以在寻找轮廓 cv2.findContours()
时使用 RETR_CCOMP
标志。并分析层级输出。
简介
在下面的二进制图像中,我们有一个 object,但是在寻找轮廓时,我们最终得到 2 个(意味着 2 个不同的 objects)。
- 等高线 1(以红色指出)是 object 的外边界 - 这是 parent,值为
-1
- 等高线 2(以绿色指出)是 object 的内边界 - 这是 child,值为
0
我们只想找到每个不同 object 的外边界。在上图中,那将只是轮廓 1。
代码:
img = cv2.imread(r'C:\Users4316\Desktop\Stack\tri.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
th = cv2.threshold(gray,100,255,cv2.THRESH_BINARY_INV)[1]
# using cv2.RETR_CCOMP flag
contours,hierarchy = cv2.findContours(th,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)
# initializing an index list
contour_index_list = []
# draw every contour whose 4th column in hierarch array is -1
for index in range(0, len(contours)):
if (hierarchy[:,index][0][3] == -1):
contour_index_list.append(index)
cv2.drawContours(img, [contours[index]], 0, (0, 255, 0), 3)
结果:
详情:
观察hierarchy
变量给出一个数组,每行分配给每个轮廓:
array([[[ 1, -1, -1, -1],
[-1, 0, 2, -1],
[-1, -1, -1, 1]]], dtype=int32)
According to the documentation,第4列表示parent-child关系。 如果值为:
- -1 轮廓是 parent
- 0 轮廓是 child