我用opencv的minAreaRect检测轮廓后,结果如下,第一张图是原图,第二张是检测出来的最小矩形图,第三张是画在空板上的,一共检测出来三个矩形,我要怎么分辨出来那个是内框图,哪个是外框图,哪位老大给讲解下
opencv的cv2.findContours()这个函数的cv2.RETR_TREE方法提供了轮廓间的层级关系,4.0版本以上的有两个返回值:
contours, hierarchy=cv2.findContours(gray,minThresh,255,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
前面一个contours就是所有找到的轮廓,重点在于后面这个hierachy
根据区域做差的面积判断也是可以的.
情况一:大小区域没有包含关系,做差后大区域面积不变.
情况二:大区域非完全包含小区域,做差后大区域面积大于做差前大区域面积与小区域面积之差.
情况三:大区域完全包含小区域,做差后大区域面积等于做差前大区域面积与小区域面积之差.
用QPainterPath的contains方法
Contours Hierarchy https://docs.opencv.org/3.4/d9/d8b/tutorial_py_contours_hierarchy.html
昨天发的博客正好讲这个内容。
通过 hierarchy 可以根据轮廓的层次结构筛选最外层/内层轮廓:
OpenCV 提供函数 cv.findContours() 从二值图像中寻找轮廓,函数 cv2.drawContours() 绘制轮廓。
返回值 hierarchy 表示轮廓的层次结构和拓扑信息,是一个形如 (1,k,4) 的 Numpy 数组。hierarchy[0][i] 表示第 i 个轮廓的层次结构,是包含 4个值的数组 [Next, Previous, First Child, Parent],分别代表第 i 个轮廓的同层的后一个轮廓、同层的前一个轮廓、第一个子轮廓、父轮廓的编号。
注意7:对实际图像进行轮廓查找时,得到的轮廓数量很多,包括大量的噪声和细微的目标。轮廓的层次结构有助于筛选轮廓,例如只关注最外层轮廓时可以使用 hierarchy[0][i][3]=-1 (没有父轮廓,即为最外层轮廓)。
参考例程:
# 12.2 绘制轮廓
img = cv2.imread("../images/pattern1.png", flags=1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图像
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_OTSU+cv2.THRESH_BINARY_INV)
# 寻找二值化图中的轮廓
binary, contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # OpenCV3
# contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # OpenCV4~
# 绘制最内层轮廓, hierarchy[0][i][3]=-1 表示没有父轮廓,即为最外层轮廓
contourEx = img.copy() # OpenCV3.2 之前的早期版本,查找轮廓函数会修改原始图像
for i in range(len(contours)): # 绘制第 i 个轮廓
if hierarchy[0][i][3]==-1: # 最外层轮廓
x, y, w, h = cv2.boundingRect(contours[i]) # 外接矩形
text = "{}({},{})".format(i, x, y)
contourEx = cv2.drawContours(contourEx, contours, i, (205, 0, 0), thickness=-1) # 第 i 个轮廓,内部填充
参考资料:
https://youcans.blog.csdn.net/article/details/124997148
https://youcans.blog.csdn.net/article/details/124997075
如果已知白色轮廓一直是最大的一个的话,可以将检测到的矩形轮廓吗面积按照大小进行排列,最大的那一个一定是白色轮廓,不过这个方法仅仅局限于白色框是最大或者最小的那一个的情况。