基于Python 和 OpenCV 画出多边形,以及判断某个点是不是在多边形内。
函数定义:cv2.pointPolygonTest(contour, pt, measureDist)
函数功能:找到图像里的点和轮廓之间的最短距离. 它返回的距离当点在轮廓外的时候是负值,当点在轮廓内是正值,如果在轮廓上是0。
其中,contour 为轮廓多边形;pt 为坐标点;measureDist, 若为True,是找带符号的距离;若为False,会找点是否在内,外,或轮廓上(相应返回+1, -1, 0)。
测试用例:
- import cv2
-
- mask = cv2.imread(r"mask.jpg", 0)
- mask[mask > 100] = 255
- mask[mask != 255] = 0
-
- cnts, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
- print("mask info:", mask.shape, len(cnts))
-
- pt0 = (131, 104) # 外点, 红色
- pt1 = (166, 157) # 轮廓上的点
- pt2 = (260, 170) # 内点
- img = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
- img = cv2.circle(img, pt0, 2, (0, 0, 255), 2) # 红色
- img = cv2.circle(img, pt1, 2, (0, 255, 0), 2) # 绿色
- img = cv2.circle(img, pt2, 2, (255, 0, 0), 2) # 蓝色
-
- dst0 = cv2.pointPolygonTest(cnts[0], pt0, 1)
- dst1 = cv2.pointPolygonTest(cnts[0], pt1, 1)
- dst2 = cv2.pointPolygonTest(cnts[0], pt2, 1)
- print("dst:", dst0, dst1, dst2)
- cv2.imwrite(r"ret.jpg", img)
测试结果:
dst: -58.52 2.82 44.28
图像:

函数定义:img = cv2.polylines(img, pts, isClosed, color, thickness, lineType, shift)
其中:
pts 是多边形定点构成的矩阵,将传入的点一次连接。
isClosed - 表示绘制的多边形是否闭合. 如闭合(True),则每个曲线的最后一个顶点到第一个顶点是连接的,若不闭合(False),则多边形就不闭合。
示例代码:
- import cv2
- import numpy as np
-
- # 纯白图像
- img = np.zeros((500, 500, 3), np.uint8)
- img[:] = [255, 255, 255]
-
- # 四个顶点坐标
- pts = np.array([[100, 100], [200, 20], [370, 6], [450, 200]], np.int32)
- # 顶点个数:4,矩阵变成4*1*2维
- pts = pts.reshape((-1, 1, 2)) # (4,1,2)
- cv2.polylines(img, [pts], isClosed=True, color=(0, 0, 255), thickness=3)
- cv2.imwrite(r"a.jpg", img)
结果:

- # 四个顶点坐标
- pts = np.array([[100, 100], [200, 20], [370, 6], [450, 200]], np.int32)
-
- # 顶点个数:4,矩阵变成4*1*2维
- pts = pts.reshape((-1, 1, 2)) # (4,1,2)
-
- # 画多边形
- img = cv2.polylines(img, [pts], isClosed=True, color=(0, 0, 255), thickness=3)
-
- # 测试点与多边形的距离
- dist = cv2.pointPolygonTest(pts, (307, 100), True)
扩展阅读:
1、opencv python 轮廓/凸缺陷/PointPolygonTest/形状匹配
opencv python 轮廓/凸缺陷/PointPolygonTest/形状匹配 - SegmentFault 思否
形状匹配:
OpenCV附带了一个函数cv2.matchShapes(),它使我们能够比较两个形状或两个轮廓,并返回一个显示相似性的度量。 结果越低,匹配就越好.它是根据hu-moment值计算的。
ret = cv2.matchShapes(cnt1,cnt2,1,0.0)
2、比好好的opencv专栏