Python OpenCV4获取轮廓最大内切圆和外接圆

为了方便讲解,我们先来创建一个多边形做演示

第一步:创建图像,并绘制一个六边形。代码和生成图像如下:

# 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深度学习】获取更多学习资讯

长按或者扫描下面二维码即可关注

 

posted @ 2019-11-18 15:17  Color_Spcae  阅读(8099)  评论(0编辑  收藏  举报