# 图像校正示例
import cv2
import numpy as np
im = cv2.imread("../dataset/data/paper.jpg")
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.imshow('im', im)
# 模糊第三个0 ,拿去翻译Gaussian kernel standard deviation in X direction.
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 膨胀
dilate = cv2.dilate(blurred, cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))) # 根据函数返回kernel
# 检测边沿
edged = cv2.Canny(dilate, # 原始图像
30, 120, # 滞后阈值、模糊度
3) # 孔径大小
# cv2.imshow("edged", edged)
# 轮廓检测
# 进行轮廓处理的时候,我们要给的图像是灰度二值化
cnts = cv2.findContours(edged.copy(),
cv2.RETR_EXTERNAL, # 只检测外轮廓
cv2.CHAIN_APPROX_SIMPLE) # 只保留该方向的终点坐标
docCnt = None
# 绘制轮廓
im_cnt = cv2.drawContours(im, # 绘制图像
cnts, # 轮廓点列表
-1, # 绘制全部轮廓
(0, 0, 255), # 轮廓颜色:红色
2) # 轮廓粗细
cv2.imshow("im_cnt", im_cnt)
# 计算轮廓面积,并排序
if len(cnts) > 0:
cnts = sorted(cnts, # 数据
key=cv2.contourArea, # 排序依据,根据contourArea函数结果排序,根据轮廓的面积进行排序
reverse=True)#倒叙排列
for c in cnts:
peri = cv2.arcLength(c, True) # 计算轮廓周长,计算封闭轮廓的周长
approx = cv2.approxPolyDP(c, 0.02 * peri, True) # 轮廓多边形拟合
# 轮廓为4个点表示找到纸张
if len(approx) == 4:
docCnt = approx
break
print(docCnt)
# 用圆圈标记处角点
points = []
for peak in docCnt:
peak = peak[0]
# 绘制圆
cv2.circle(im, # 绘制图像
tuple(peak), 10, # 圆心、半径
(0, 0, 255), 2) # 颜色、粗细
points.append(peak) # 添加到列表
print(points)#坐标分别是左上,左下,右下,右上
cv2.imshow("im_point", im)
# 校正
src = np.float32([points[0], points[1], points[2], points[3]]) # 原来逆时针方向四个点
dst = np.float32([[0, 0], [0, 488], [337, 488], [337, 0]]) # 对应变换后逆时针方向四个点
m = cv2.getPerspectiveTransform(src, dst) # 生成透视变换矩阵
result = cv2.warpPerspective(gray.copy(), m, (337, 488)) # 透视变换
cv2.imshow("result", result) # 显示透视变换结果
#下面的是使用勾股定理进行图像矫正,以这个为重点,上面的数据是定死的
# h = int(math.sqrt((points[1][0]-points[0][0])**2+(points[1][1]-points[0][1])**2))
# w = int(math.sqrt((points[2][0]-points[1][0])**2+(points[2][1]-points[1][1])**2))
# w = int(math.sqrt((points[3][1] - points[0][1]) ** 2 + (points[3][0] - points[0][0]) ** 2))
# print("w:",w,"h:",h)#h和w我们可以自己找,并不是说局限于上面我找的
# dst = np.float32([[0,0],[0,h],[w,h],[w,0]])
# 生成透视变换矩阵
# m = cv2.getPerspectiveTransform(src,dst)
# 执行透视变换,返回变换后的图像
# result = cv2.warpPerspective(gray.copy(),m,(w,h))
# cv2.imshow("result",result)
cv2.waitKey()
cv2.destroyAllWindows()
函数cv2.approxPolyDP()用来构造指定精度的逼近多边形曲线。该函数的语法格式为:
approxCurve = cv2.approxPolyDP(curve,epsilon,closed)
“”"
参数:
curve: 轮廓
epsilon: 精度,原始轮廓的边界点与逼近多边形边界之间的最大距离
closed: 布尔类型,该值为True时,逼近多边形是封闭的;否则,逼近多边形是不封闭的
返回值:
approxCurve: 逼近多边形的点集
“”"