效果
第一步,进行轮廓提取,将图片转化为灰度图,然后进行高斯模糊,模糊后提取轮廓,然后进行膨胀收缩使轮廓更加的清晰
def getContours(img):
img = cv2.resize(img, (0, 0), None, 0.5, 0.5)
imgG = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imgBlur = cv2.GaussianBlur(imgG,(5,5),1)
imgCanny = cv2.Canny(imgBlur,100,100)
kernel = np.ones((5,5))
imgDial = cv2.dilate(imgCanny,kernel,iterations=3)
imgThre = cv2.erode(imgDial,kernel,iterations=2)
cv2.imshow('img',img)
cv2.imshow('res',imgCanny)
cv2.imshow('res2',imgThre)
getContours(img)
cv2.waitKey(0)
第二步,找出最大轮廓
用到的函数
cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]]) → image, contours, hierarchy
image-寻找轮廓的图像;
mode-轮廓的检索模式:cv2.RETR_EXTERNAL表示只检测外轮廓
method cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
contourArea()函数的作用:主要用于计算图像轮廓的面积。
arcLength()函数的作用:主要是计算图像轮廓的周长
approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed)
主要功能是把一个连续光滑曲线折线化,对图像轮廓点进行多边形拟合
InputArray curve:一般是由图像的轮廓点组成的点集
OutputArray approxCurve:表示输出的多边形点集
double epsilon:主要表示输出的精度,就是另个轮廓点之间最大距离数,5,6,7,,
bool closed:表示输出的多边形是否封闭
boundingRect函数
函数作用:计算轮廓的垂直边界最小矩形,矩形是与图像上下边界平行的
contours, hiearchy = cv2.findContours(imgThre,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
finalCountours = []
for i in contours:
area = cv2.contourArea(i)
if area> minArea:
# 计算轮廓的周长,true表示轮廓为封闭
peri = cv2.arcLength(i,True)
#进行轮廓的多边拟合
appprox = cv2.approxPolyDP(i,0.02*peri,True)
bbox = cv2.boundingRect(appprox)
if filter > 0 :
if(len(appprox))==filter:
finalCountours.append([len(appprox),area,appprox,bbox,i])
else:
finalCountours.append([len(appprox), area, appprox, bbox, i])
# 对第二个数值面积进行排序,为升序,找出轮廓的最大值
finalCountours = sorted(finalCountours, key=lambda x: x[1], reverse=True)
for con in finalCountours:
cv2.drawContours(img, con[4], -1, (0, 0, 255), 3)
最大轮廓外表
第三步,得出的轮廓四角的顺序可能发生变化,因此需要将四角的坐标固定为矩形一种固定的顺序
这个函数为重新排序函数,无论给什么顺序的四角坐标,都能整理好!
def reorder(myPoints):
#print(myPoints.shape)
# zeros_like 输出为形状和x一致的矩阵,其元素全部为0
myPointsNew = np.zeros_like(myPoints)
myPoints = myPoints.reshape((4,2))
add = myPoints.sum(1)
myPointsNew[0] = myPoints[np.argmin(add)]
myPointsNew[3] = myPoints[np.argmax(add)]
diff = np.diff(myPoints,axis=