為了方便講解,我們先來創建一個多邊形做演示
第一步:創建圖像,並繪制一個六邊形。代碼和生成圖像如下:
# 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深度學習】獲取更多學習資訊
長按或者掃描下面二維碼即可關注