为了方便讲解,我们先来创建一个多边形做演示
第一步:创建图像,并绘制一个六边形。代码和生成图像如下:
# Create an image r = 100 src = np.zeros((4*r, 4*r), dtype=np.uint8) # Create a sequence of points to make a contour vert = [None]*6 vert[0] = (3*r//2, int(1.34*r)) vert[1] = (1*r, 2*r) vert[2] = (3*r//2, int(2.866*r)) vert[3] = (5*r//2, int(2.866*r)) vert[4] = (3*r, 2*r) vert[5] = (5*r//2, int(1.34*r)) # Draw it in src for i in range(6): cv.line(src, vert[i], vert[(i+1)%6], ( 255 ), 3) cv.imshow("src", src)
第二步:查找轮廓,计算图像上的点到轮廓的距离
# Get the contours _, contours, _ = cv.findContours(src, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) # Calculate the distances to the contour raw_dist = np.empty(src.shape, dtype=np.float32) for i in range(src.shape[0]): for j in range(src.shape[1]): raw_dist[i,j] = cv.pointPolygonTest(contours[1], (j,i), True)
注意cv.RETR_TREE查找轮廓后轮廓是从外到内的排列顺序,那么contours[1]就是六边形的内边轮廓
第三步:获取轮廓内部距离轮廓最远的点(作为内切圆圆心)和最小距离(作为内切圆半径),绘制内切圆
# 获取最大值即内接圆半径,中心点坐标 minVal, maxVal, _, maxDistPt = cv.minMaxLoc(raw_dist) minVal = abs(minVal) maxVal = abs(maxVal) result = cv.cvtColor(src,cv.COLOR_GRAY2BGR) cv.circle(result,maxDistPt, np.int(maxVal),(0,255,0), 2, cv.LINE_8, 0) cv.imshow('result', result)
最终效果:
当然,如果你还想获取外接圆,直接调用函数cv2.minEnclosingCircle(即可),下面是代码演示和效果:
# contours[0]对应最外层轮廓
center,radius = cv.minEnclosingCircle(contours[0])
cv.circle(result,(int(center[0]),int(center[1])),int(radius),(0,0,255),2)
完整代码:
import cv2 as cv import numpy as np # Create an image r = 100 src = np.zeros((4*r, 4*r), dtype=np.uint8) # Create a sequence of points to make a contour vert = [None]*6 vert[0] = (3*r//2, int(1.34*r)) vert[1] = (1*r, 2*r) vert[2] = (3*r//2, int(2.866*r)) vert[3] = (5*r//2, int(2.866*r)) vert[4] = (3*r, 2*r) vert[5] = (5*r//2, int(1.34*r)) # Draw it in src for i in range(6): cv.line(src, vert[i], vert[(i+1)%6], ( 255 ), 3) cv.imshow("src", src) # Get the contours _, contours, _ = cv.findContours(src, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) # Calculate the distances to the contour raw_dist = np.empty(src.shape, dtype=np.float32) for i in range(src.shape[0]): for j in range(src.shape[1]): raw_dist[i,j] = cv.pointPolygonTest(contours[1], (j,i), True) # 获取最大值即内接圆半径,中心点坐标 minVal, maxVal, _, maxDistPt = cv.minMaxLoc(raw_dist) minVal = abs(minVal) maxVal = abs(maxVal) result = cv.cvtColor(src,cv.COLOR_GRAY2BGR) center,radius = cv.minEnclosingCircle(contours[0]) cv.circle(result,(int(center[0]),int(center[1])),int(radius),(0,0,255),2) cv.circle(result,maxDistPt, np.int(maxVal),(0,255,0), 2, cv.LINE_8, 0) cv.imshow('result', result) cv.waitKey(0) cv.destroyAllWindows()
关注【OpenCV与AI深度学习】获取更多学习资讯
长按或者扫描下面二维码即可关注