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深度學習】獲取更多學習資訊

長按或者掃描下面二維碼即可關注

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM