当前位置: 首页 > news >正文

计算机视觉(opencv)实战十八——图像透视转换


图像透视变换详解与实战

在图像处理中,透视变换(Perspective Transform) 是一种常见的几何变换,用来将图像中某个四边形区域拉伸或压缩,映射到一个矩形区域。常见应用场景包括:

  • 纠正拍照时的倾斜(如手机拍发票、拍文档)

  • 从复杂背景中提取规则区域(如车牌识别)

  • 图像投影变换、鸟瞰视图生成

本文将通过一个完整案例,带你从图像读取、轮廓检测,到透视变换、结果后处理,逐步完成发票/文件的自动矫正。

图片准备:


1. 导入依赖与辅助函数

import numpy as np
import cv2

我们首先导入 NumPyOpenCV,这是图像处理的核心库。

图像显示函数

def cv_show(name, img):"""显示图像"""cv2.imshow(name, img)cv2.waitKey(0)
  • cv2.imshow 用于显示图像窗口

  • cv2.waitKey(0) 表示等待键盘输入后才关闭窗口,便于逐步观察每一步结果


2. 坐标排序函数:order_points

def order_points(pts):rect = np.zeros((4, 2), dtype="float32")s = pts.sum(axis=1)rect[0] = pts[np.argmin(s)]  # 左上角点 (x+y最小)rect[2] = pts[np.argmax(s)]  # 右下角点 (x+y最大)diff = np.diff(pts, axis=1)rect[1] = pts[np.argmin(diff)]  # 右上角 (y-x最小)rect[3] = pts[np.argmax(diff)]  # 左下角 (y-x最大)return rect

在透视变换中,必须保证四个点的顺序一致(左上、右上、右下、左下),否则会导致映射结果错误。
该函数通过:

  • x+y 最小 → 左上角

  • x+y 最大 → 右下角

  • y-x 最小 → 右上角

  • y-x 最大 → 左下角
    来对四点坐标排序,保证后续计算稳定。


3. 核心函数:透视变换

def four_point_transform(image,pts):rect = order_points(pts)(tl, tr, br, bl) = rectwidthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))maxWidth = max(int(widthA), int(widthB))heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))maxHeight = max(int(heightA), int(heightB))dst = np.array([[0, 0], [maxWidth - 1, 0],[maxWidth - 1, maxHeight - 1],[0, maxHeight - 1]], dtype="float32")M = cv2.getPerspectiveTransform(rect, dst)warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))return warped

步骤解析:

  1. 排序四点:保证输入顺序一致

  2. 计算目标矩形宽高:根据两条对边长度取最大值,保证变换后不丢失内容

  3. 构建目标点集:从 (0,0) 开始构建新的矩形顶点

  4. 求取透视变换矩阵cv2.getPerspectiveTransform()

  5. 执行透视变换cv2.warpPerspective() 输出矫正后的图像


 resize 函数等比例缩放(保持宽高比)

只需指定 width 或 height 中的一个,自动计算另一个

def resize(image, width=None, height=None, inter=cv2.INTER_AREA):dim = None(h, w) = image.shape[:2]if width is None and height is None:return imageif width is None:r = height / float(h)dim = (int(w * r), height)else:r = width / float(w)dim = (width, int(h * r))resized = cv2.resize(image, dim, interpolation=inter)return resized

4. 图像预处理与轮廓检测

image = cv2.imread('order.jpg')
cv_show('image',image)# 缩小图像,便于处理
ratio = image.shape[0]/500
orig = image.copy()
image = resize(orig,height=500)
cv_show('1',image)print('STEP 1: 轮廓检测')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)  # 转灰度
# 自动阈值二值化,突出目标区域
edged = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# 寻找所有轮廓
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2]
# 绘制所有轮廓,便于可视化
image_contours = cv2.drawContours(image.copy(), cnts, -1, (0, 0, 255), 1)
cv_show('image_contours', image_contours)

这里先将图像灰度化、二值化,再使用 cv2.findContours 获取所有轮廓。然后在图像上绘制轮廓,便于确认检测效果。


5. 找到最大轮廓(目标区域)

# 找到最大轮廓并逼近为四边形
print("STEP 2: 获取最大轮廓")
screenCnt = sorted(cnts, key=cv2.contourArea, reverse=True)[0]  # 按面积排序,取最大
peri = cv2.arcLength(screenCnt, True)  # 计算周长
screenCnt = cv2.approxPolyDP(screenCnt, 0.05 * peri, True)  # 多边形逼近,保留主要拐点
image_contour = cv2.drawContours(image.copy(), [screenCnt], -1, (0, 0, 255), 2)
cv_show('image_contour', image_contour)
  • sorted(..., key=cv2.contourArea, reverse=True) 按面积排序,取最大轮廓(一般就是发票/文件区域)

  • cv2.approxPolyDP 多边形逼近,得到近似四边形轮廓


6. 透视矫正 & 后处理

warped = four_point_transform(orig,screenCnt.reshape(4,2)*ratio)
cv2.imwrite('invoice_new.jpg',warped)
cv_show('xx',warped)# 转灰度并二值化
gray1=cv2.cvtColor(warped,cv2.COLOR_BGR2GRAY)
warped1=cv2.threshold(gray1,120,255,cv2.THRESH_BINARY)[1]
warped1=resize(warped1,height=500)
cv_show('warped1',warped1)# 腐蚀操作,去除噪点
kernel=np.ones((2,2),np.uint8)
erosion = cv2.erode(warped1,kernel,iterations=1)
cv_show('erosion',erosion)# 旋转图像
rotated_image1 =np.rot90(erosion, k=1)
cv_show('rotated_image1',rotated_image1)

后处理步骤:

  • 二值化:提高文字对比度,便于后续OCR识别

  • 腐蚀:去除孤立噪点,让边缘更干净

  • 旋转:如果方向不正,可手动或自动旋转至正方向


7. 效果展示与应用

通过上述步骤,我们将一张倾斜、带背景的发票图像,处理成一个平整、纯背景的图像,便于后续的文字识别(OCR)。

这种方法广泛应用于:

  • 发票/合同扫描矫正

  • 车牌识别

  • 桌面投影仪矫正

  • 透视校正后的AR场景识别


总结

本文完整实现了:

  1. 图像预处理:缩放、灰度化、二值化

  2. 轮廓检测:提取最大矩形区域

  3. 四点排序:确保透视变换稳定

  4. 透视矫正:将任意四边形映射到规则矩形

  5. 后处理:二值化、腐蚀、旋转

透视变换是图像几何处理中的关键技术,掌握它能够让你解决很多实际问题,尤其是文档扫描、图像矫正类任务。


文章转载自:

http://lE1Tpnom.kgxyd.cn
http://GHcQE3KY.kgxyd.cn
http://gNkMgLG9.kgxyd.cn
http://lQqxkyas.kgxyd.cn
http://RxI4HuO5.kgxyd.cn
http://A1DIFO5s.kgxyd.cn
http://UoT2Xyf1.kgxyd.cn
http://vy6R5FRD.kgxyd.cn
http://mALLQ0mM.kgxyd.cn
http://97ShNirO.kgxyd.cn
http://M5fKtqE4.kgxyd.cn
http://1QQe3AnD.kgxyd.cn
http://wPIgSXIS.kgxyd.cn
http://p4Ga957L.kgxyd.cn
http://Mz7uyDwd.kgxyd.cn
http://rYU5jGH1.kgxyd.cn
http://SzRy9ell.kgxyd.cn
http://ChFeuI7G.kgxyd.cn
http://gvN01lUM.kgxyd.cn
http://aHx7R5EK.kgxyd.cn
http://nhfjOqQa.kgxyd.cn
http://jmarJBel.kgxyd.cn
http://5lTQj7lu.kgxyd.cn
http://2cTZTGCm.kgxyd.cn
http://spGtrCEm.kgxyd.cn
http://NHyDIuty.kgxyd.cn
http://c9ph6FJz.kgxyd.cn
http://gP8jv1n7.kgxyd.cn
http://niTQa0qI.kgxyd.cn
http://VQIzbdfk.kgxyd.cn
http://www.dtcms.com/a/381675.html

相关文章:

  • 【二开】CRMEB开源版按钮权限控制
  • 联邦学习过程中,了解清楚影响准确率的因素有哪些也很重要
  • Ubuntu 文件复制大师:精通cp命令完整指南
  • 给定单词倒排
  • Golang | http/server Gin框架简述
  • Android-EDLA XTS常用网站总结
  • Android webview更新记录-aosp
  • 大数据电商流量分析项目实战:Flume 数据采集及ETL入仓(五)
  • 用 PyTorch 打造 AIOps 小体系:日志异常、指标预测与训练失败根因分析
  • 涂鸦智能携手亚马逊云科技,以全球基础设施与生成式AI加速万物智联时代到来
  • 【完整源码+数据集+部署教程】交通工具图像分割系统: yolov8-seg-C2f-RFCAConv
  • uniapp 混合mixins和继承extends详解
  • 【Lua】Windows 下编写 C 扩展模块:VS 编译与 Lua 调用全流程
  • 004 Rust控制台打印输出
  • idea自动编译,idea不重启项目,加载修改的内容
  • 阻塞 IO为什么叫BIO,非阻塞IO为什么叫NIO,异步IO为什么叫AIO
  • 少即是多:从 MPTCP 看优化干预的边界
  • 2025服贸会“海淀之夜”,点亮“科技”与“服务”底色
  • String留言板
  • js生成excel表格进阶版
  • Win 11 ARM 版搭建ESP-IDF环境问题记录
  • MyBatis主键返回:必须显式配置
  • MySQL——MVCC实现原理流程分析
  • Linux -- 基于TCP服务器实现一个简单的电商网站
  • 佳维视工业一体机 vs 普通电脑:工业场景选哪个?
  • 小迪安全v2023学习笔记(八十二讲)—— Java组件安全SolrShiroLog4jCVE复现
  • Spring AI(四)机构化输出
  • 单体到微服务拆分方案
  • 云端服务器使用指南:如何跨机传输较大文件(通过windows自带工具远程桌面连接 非常方便)
  • Linux 高性能 I/O 事件通知机制的核心系统调用—— `epoll_ctl`