open-cv实现图像矫正

加载必要的包和读取图像路径。

# 利用透视变换对纸张进行矫形
import cv2
import numpy as np
import math

im = cv2.imread('../img_data/paper.jpg')
cv2.imshow('im', im)

显示原始图像:

# 灰度化
im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.imshow('im_gray', im_gray)

灰度化图像并显示:

canny边沿提取图像的轮廓

im_canny = cv2.Canny(im_gray,
                     70, 300, 3)
cv2.imshow('im_canny', im_canny)

canny轮廓如下所示:
open-cv实现图像矫正_第1张图片
取出canny边沿提取的边沿点的数据,并将不同的轮廓按照面积排序,找出四边形的轮廓,并储存起来。

# 在canny边沿提取的结果之上进行轮廓的检测
cnts, hie = cv2.findContours(
    im_canny,
    cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_NONE
)

# 对轮廓按照面积排序(倒)
docCnt = None
if len(cnts) > 0:
    cnts = sorted(cnts,
                  key=cv2.contourArea,  # 根据该函数计算的结果排序
                  reverse=True
                  )
    # 对排序后的轮廓执行多边形拟合
    for c in cnts:
        peri = cv2.arcLength(c, True)  # 计算周长
        # 多边形拟合
        approx = cv2.approxPolyDP(c, 0.02 * peri, True)
        if len(approx) == 4:  # 四边形
            docCnt = approx
            break
print(docCnt)  # 打印纸张的轮廓

在原图上标记纸张轮廓的四个顶点,并显示出来

points = []
for peaks in docCnt:
    peak = peaks[0]
    # 在角点绘制小圆圈
    cv2.circle(im, tuple(peak), 10, (0, 0, 255), 2)
    points.append(peak)

cv2.imshow('im_point', im)

纸张的四个角点标记图如下所示:

计算纸张原本的高度和宽度,并将斜着的图片透视变换到竖直方向的矩阵。

# 计算纸张的高度 宽度
dw = points[1][0] - points[0][0]
dh = points[1][1] - points[0][1]
h = int(math.sqrt(dw ** 2 + dh ** 2))

dw = points[2][0] - points[1][0]
dh = points[2][1] - points[1][1]
w = int(math.sqrt(dw ** 2 + dh ** 2))

src = np.float32(
    [[points[0], points[1], points[2], points[3]]]  # 原顶点
)
dst = np.float32([[0, 0], [0, h], [w, h], [w, 0]])

# 生成透视变换矩阵
m = cv2.getPerspectiveTransform(src, dst)
result = cv2.warpPerspective(im_gray, m, (w, h))  # 透视变换
cv2.imshow('result', result)

cv2.waitKey()
cv2.destroyAllWindows()

将矫正后的图片显示出来:
open-cv实现图像矫正_第2张图片

你可能感兴趣的:(python,python,opencv,计算机视觉)