原理:目标物体的轮廓实质是指一系列像素点构成,这些点构成了一个有序的点集。我们可以通过findContours函数将二值图像的边缘像素点分成多个轮廓,从而逐个提取目标外部轮廓,内部轮廓有待研究。
Python:
import cv2 as cv
import numpy as np
if __name__=="__main__":
img=cv.imread("D:/testimage/number.jpg")
#img1=cv.imread("D:/testimage/sample.jpg")
#灰度化+高斯滤波
gray_dst = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
blur_dst=cv.GaussianBlur(gray_dst,(3,3),0)
#OTSU阈值分割
ret,otsu_dst=cv.threshold(blur_dst,0,255,cv.THRESH_OTSU)
cv.imshow("s", otsu_dst)
#Canny算子提取边缘轮廓
canny_dst=cv.Canny(otsu_dst,10,250)
cv.imshow("s", canny_dst)
#寻找二值图像轮廓点
edge_points,h=cv.findContours(canny_dst,cv.RETR_EXTERNAL,
cv.CHAIN_APPROX_SIMPLE)
contours=edge_points
#轮廓的数量
k=len(edge_points)
src=np.zeros(gray_dst.shape,np.uint8)
for i in range(k):
#画出轮廓
cv.drawContours(src,contours,i,250,2)
#最小外包圆
circle=cv.minEnclosingCircle(contours[i])
cv.circle(img,(int(circle[0][0]),int(circle[0][1])),int(circle[1]),(0,255,0),2)
#绘制多边形
approxCurve=cv.approxPolyDP(contours[i],0.3,True)
t=approxCurve.shape[0]
for i in range(t-1):
cv.line(img,(approxCurve[i,0,0],approxCurve[i,0,1]),
(approxCurve[i+1,0,0],approxCurve[i+1,0,1]),(255,0,0),2)
cv.line(img, (approxCurve[t-1, 0, 0], approxCurve[t-1, 0, 1]),
(approxCurve[0, 0, 0], approxCurve[0, 0, 1]),(255,0,0),2)
cv.imshow("1",src)
cv.imshow("2",img)
cv.imwrite("D:/testimage/result-1.jpg", src)
cv.imwrite("D:/testimage/result-2.jpg", img)
cv.waitKey(0)
cv.destroyAllWindows()