OpenCV Python 轮廓
【目标】
凸性缺陷查找点与多边形的关系不同形状的匹配【代码】
左图中红色点为凸性检测的缺陷点,即凹点
右图为了验证点与多边形关系而做的图,也是官网要求做的练习。
import cv2 import numpy as np img = cv2.imread('star.png', 0)colorimg = cv2.imread('star.png', 1)convexHullImg = colorimg.copy()ret, thresh = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY)# 寻找轮廓contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)cnt = contours[0]# 凸包hull = cv2.convexHull(cnt, returnPoints=False)defects = cv2.convexityDefects(cnt, hull)# 画出缺陷凹点for i in range(defects.shape[0]):startptidx, endptidx, farptidx, dis = defects[i, 0]startpt = tuple(cnt[startptidx][0])endpt = tuple(cnt[endptidx][0])farpt = tuple(cnt[farptidx][0]) cv2.line(convexHullImg, startpt, endpt, (0, 255, 255))cv2.circle(convexHullImg, farpt, 3, (0, 0, 255), 3)# 根据点在图像中和轮廓中的位置,画出颜色图polygonTestImg = colorimg.copy()# cv2.circle(polygonTestImg, (280, 180), 3, (0, 0, 255), 3)dist = cv2.pointPolygonTest(cnt, (50, 50), True)h, w, _ = polygonTestImg.shape# 在轮廓上,为白色bluevalue = 255redvalue = 255for j in range(h):for i in range(w):dist = cv2.pointPolygonTest(cnt, (i, j), True)if dist > 127:dist = 127if dist < -127:dist = -127if dist > 0:colorshow = (255 - dist * 2, 255 - dist * 2, 0)elif dist < 0:colorshow = (0, 255 + dist * 2, 255 + dist * 2)elif dist == 0:colorshow = (255, 255, 255)cv2.circle(polygonTestImg, (i, j), 2, colorshow, 2)cv2.imshow('convexHullImg', convexHullImg)cv2.imshow('polygonTestImg', polygonTestImg)cv2.waitKey(0)cv2.destroyAllWindows()
# 测试形状匹配import cv2import numpy as np img1 = cv2.imread('star.png', 0)img2 = cv2.imread('box.png', 0)img3 = cv2.imread('testfit.png', 0)ret1, thresh1 = cv2.threshold(img1, 127, 255, cv2.THRESH_BINARY)ret2, thresh2 = cv2.threshold(img2, 127, 255, cv2.THRESH_BINARY)ret3, thresh3 = cv2.threshold(img3, 127, 255, cv2.THRESH_BINARY)con1, hir1 = cv2.findContours(thresh1, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)con2, hir2 = cv2.findContours(thresh2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)con3, hir3 = cv2.findContours(thresh3, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)cnt1 = con1[0]cnt2 = con2[0]cnt3 = con3[0]ret12 = cv2.matchShapes(cnt1, cnt2, cv2.CONTOURS_MATCH_I2, 0.0) ret13 = cv2.matchShapes(cnt1, cnt3, cv2.CONTOURS_MATCH_I2, 0.0)ret23 = cv2.matchShapes(cnt2, cnt3, cv2.CONTOURS_MATCH_I2, 0.0)print(ret12, ret13, ret23)cv2.imshow('img1', img1)cv2.imshow('img2', img2)cv2.imshow('img3', img3)cv2.waitKey(0)cv2.destroyAllWindows()
输出结果如下:
0.05888818307213595 0.2987404256696341 1.6190198650037022
【接口】
convexityDefectsvoid cv::convexityDefects(InputArray contour,InputArray convexhull,OutputArray convexityDefects );
cv2.convexityDefects(contour, convexhull[, convexityDefects]) ->convexityDefects
pointPolygonTest计算查找一个轮廓的凸性缺陷
contour: 输入的轮廓convexhull: 轮廓的凸包,用
convexHull
convexityDefects: 凸性缺陷输出向量, 每个缺陷是 4个整型元素的 vector。
double cv::pointPolygonTest(InputArray contour,Point2f pt,bool measureDist );
cv2.pointPolygonTest(contour, pt, measureDist) ->retval
matchShapes判断一个点是否在轮廓内或边缘上,计算其距离;正数在内部,负数在外部;
如果
measureDist=false
则返回1, -1, 0
contour: 输入的轮廓pt: 测试点measureDist: 如果为真,则计算距离,否则不用计算,只判断是否在内部还是外部;
double cv::matchShapes(InputArray contour1,InputArray contour2,int method,double parameter );
cv2.matchShapes(contour1, contour2, method, parameter) ->retval
ShapeMatchModes比较两个形状
contour1: 第一个轮廓contour2: 第二个轮廓method: 比较的方法 见下ShapeMatchModesparameter: 方法的特殊参数(暂时不支持)
【OpenCV-Python】教程:3-9 轮廓(1)开始
【OpenCV-Python】教程:3-9 轮廓(2)轮廓特征
【OpenCV-Python】教程:3-9 轮廓(3)轮廓属性
【参考】
OpenCV官方文档如果觉得《【OpenCV-Python】教程:3-9 轮廓(4)更多函数》对你有帮助,请点赞、收藏,并留下你的观点哦!