ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

opencv19:轮廓凸包,距离与匹配

2021-10-28 16:58:34  阅读:354  来源: 互联网

标签:cnt 匹配 img cv2 opencv19 凸包 图像 False 轮廓


目标

在本章中,将学习

  • 凸起缺陷检测
  • 寻找点到多边形的最短距离
  • 匹配不同的形状

理论和代码

凸性缺陷(Convexity Defects)

上一节学习了如何寻找轮廓, 凸包上的任何偏差都可以被认为是有凸性缺陷。
OpenCV中有一个函数来寻找凸包,cv2.convexityDefects()

hull = cv2.convexHull(cnt, returnPoints = False)
defects = cv2.convexityDefects(cnt, hull)

注意
必须在发现凸包时,传递returnPoints= False, 返回的是cnt中点的下标,如果是True时候,返回的是点的坐标。

cv2.convexityDefects返回一个数组,其中每行包含这些值[起点、终点、最远点、到最远点的近似距离]。可以用图像把它形象化。画一条连接起点和终点的线,然后在最远处画一个圆。记住,返回的前三个值是cnt的索引。必须从cnt中获取这些值。

import cv2
import numpy as np
img = cv2.imread('star.png')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(img_gray, 127, 255,0)
contours,hierarchy = cv2.findContours(thresh,2,1)
cnt = contours[0]
hull = cv2.convexHull(cnt, returnPoints=False)
defects = cv2.convexityDefects(cnt, hull)
for i in range(defects.shape[0]):
    s,e,f,d = defects[i,0]
    start = tuple(cnt[s][0])
    end = tuple(cnt[e][0])
    far = tuple(cnt[f][0])
    cv2.line(img,start,end,[0,255,0],2)
    cv2.circle(img,far,5,[0,0,255],-1)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

在这里插入图片描述

点到多边形测试

cv2.pointPolygonTest函数找出图像中一点到轮廓线的最短距离。它返回的是符号距离距离(signed distance),点在轮廓线外时为负,点在轮廓线内时为正,点在轮廓线上时为零。

可以检查点(50,50)如下:

dist = cv2.pointPolygonTest(cnt,(50,50),True)
# -38.8329756778952

在函数中,第三个参数是measureDist。如果它是True,它会找到有符号的距离。如果为False,则查找该点是在轮廓线内部还是外部(分别返回 1、-1和0)

注意
如果不想知道具体距离,请确保第三个参数为False,因为计算距离是一个耗时的过程, 设置为False可使速度提高2-3倍。

形状匹配

OpenCV附带一个函数cv2.matchShapes(),该函数能够比较两个形状或两个轮廓,并返回一个显示相似性的度量结果越低,匹配越好。它是根据矩值(hu-moment)计算出来的。不同的测量方法在文档中有解释。

# 形状匹配
import cv2
import numpy as np

img1 = cv2.imread('star.png', 0)
img2 = cv2.imread('star2.png', 0)
img3 = cv2.imread('approx.png', 0)
ret, thresh = cv2.threshold(img1, 127, 250, 0)
ret2, thresh2 = cv2.threshold(img2, 127, 250, 0)
ret3, thresh3 = cv2.threshold(img3, 127, 250, 0)

contours1, hierarchy1 = cv2.findContours(thresh, 2, 1)
cnt1 = contours1[0]

contours2, hierarchy2 = cv2.findContours(thresh2, 2, 1)
cnt2 = contours2[0]

contours3, hierarchy3 = cv2.findContours(thresh3, 2, 1)
cnt3 = contours3[0]

ret1 = cv2.matchShapes(cnt1, cnt2, 1, 0.0)
print(ret1)   # 0.0101502123705427

ret2 = cv2.matchShapes(cnt2, cnt3, 1, 0.0)
print(ret2)   # 0.9202466744178138

尝试过匹配下面给出的不同形状的形状:
在这里插入图片描述

得到以下结果:

  • 匹配的图像A与本身= 0.0
  • 匹配图像A与图像B =0.0101502123705427
  • 匹配图像A与图像C = 0.9202466744178138
    可以看到,即使是图像旋转也不会对其匹配度产生比较大的影响

说明
Hu Moments(或者相反Hu moment invariants)是一种使用不变的图像转换的中央矩计算的一组7个数字。前6个moments被证明是不变的变换,缩放和旋转和反转。第7个moment表示符号变化。
在这里插入图片描述

附加资源

标签:cnt,匹配,img,cv2,opencv19,凸包,图像,False,轮廓
来源: https://blog.csdn.net/uncle_ll/article/details/121014433

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有