OpenCV 从零学习 · 第 20 讲:透视变换与文档矫正
函数:cv2.getPerspectiveTransform / cv2.warpPerspective | 难度:★★★☆☆
手机斜着拍一张文档,纸是梯形。透视变换能把"梯形"重新映射成"正矩形"——这正是扫描类 App(如扫描全能王)的核心一步。它把前面学的边缘、轮廓、几何变换串成一个完整小项目,作为本系列的收官。
一、核心两步
# src_pts: 原图中四个角(顺序对应);dst_pts: 目标矩形四角
M = cv2.getPerspectiveTransform(src_pts, dst_pts) # 3x3 变换矩阵
warped = cv2.warpPerspective(img, M, (width, height))
| 参数 | 含义 |
src_pts | 原图 4 个角点,float32、顺序一致 |
dst_pts | 目标矩形 4 角,如 (0,0)(w,0)(w,h)(0,h) |
(width,height) | 输出尺寸,(宽,高) |
二、完整文档矫正流程
import cv2, numpy as np
img = cv2.imread('doc.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150)
# 找最大四边形的四个顶点(简化:用轮廓近似,进阶可换更稳方法)
# 假设已得到四个角点,顺序:左上、右上、右下、左下
pts = np.array([[x1,y1],[x2,y2],[x3,y3],[x4,y4]], dtype=np.float32)
w, h = 500, 700
dst = np.array([[0,0],[w,0],[w,h],[0,h]], dtype=np.float32)
M = cv2.getPerspectiveTransform(pts, dst)
warped = cv2.warpPerspective(img, M, (w, h))
场景 A · 拍歪的文档/名片/白板扶正
找出纸张四角 → 透视变换 → 得到正面平视图。再接第 6 讲阈值化做二值化,就是一套"手机拍纸→扫描件"流水线。
找出纸张四角 → 透视变换 → 得到正面平视图。再接第 6 讲阈值化做二值化,就是一套"手机拍纸→扫描件"流水线。
场景 B · 车牌 / 路牌矫正
倾斜拍摄的车牌,透视变换摆正后再做 OCR/识别,识别率显著提升。
倾斜拍摄的车牌,透视变换摆正后再做 OCR/识别,识别率显著提升。
⚠ 新手必踩坑
src_pts和dst_pts必须都是 float32,且顺序一一对应(左上对左上、右上对右上…),顺序错乱会把图扭成麻花。- src 要 4 个点,少一个多一个都会报错;常见错误是用了 3 个点(那是仿射,不是透视)。
- 四角怎么来?实战靠"边缘→找轮廓→approxPolyDP 取四边形"(第 8 讲),不是手标点;手点只适合 demo。
- 输出尺寸 (宽,高) 按目标矩形给,别和原图 shape 混淆。
本讲要点
getPerspectiveTransform拿 3×3 矩阵,warpPerspective执行变换。- 四点必须 float32、顺序对应;4 点(非 3 点)才是透视。
- 是"扫描类 App"核心步骤,串起了边缘/轮廓/几何变换。
