『7x24小时有问必答』
传送带上的工件是斜的、快递单被拍成梯形、仪表盘在广角镜下桶形畸变——直接送进 OCR 或模板匹配,识别率会掉一大截。读完本文掌握 resize、仿射变换、旋转与透视矫正的用法。

---

一、为什么需要几何变换

摄像头很难正对目标。PCB 在传送带上可能倾斜 15 度,文档扫描时被拍成梯形,广角镜头下桶形畸变让直线变弯。如果直接把这些图送进检测算法,坐标系是歪的,ROI 区域对不上,后面所有测量都会带偏。几何变换的目标就是把图像恢复到标准视角,让后续算法在统一的坐标系里工作。
几何变换解决的是图像坐标系不统一的问题,是检测和识别的前置步骤。

---

二、几何变换的本质

所有几何变换都是像素重采样:原图每个像素坐标  (x, y)  经过变换矩阵映射到新位置  (x', y'),再用插值补齐缺失像素。
缩放:改变输出尺寸,配合插值控制平滑度。放大用  INTER_CUBIC,缩小用  INTER_AREA
仿射变换:保持直线平行性,能做平移、旋转、缩放、剪切,用 2×3 矩阵描述
透视变换:能处理梯形、斜拍等不平行情况,用 4 组对应点求解 3×3 单应矩阵
缩放和仿射用 2×3 矩阵,透视用 3×3 矩阵,两者本质都是坐标映射加插值。

---

三、核心接口

接口名称
核心功能
关键参数
工业推荐取值
cv2.resize
缩放图像
dsize
,  interpolation
放大用  INTER_CUBIC,缩小用  INTER_AREA
cv2.warpAffine
仿射变换
M
,  dsize
2×3 矩阵,dsize  等于输出尺寸
cv2.getRotationMatrix2D
生成旋转矩阵
center
,  angle,  scale
中心取图像中点,scale=0.8~1.0
cv2.getPerspectiveTransform
求透视矩阵
4 组对应点
源点按顺序对应目标点
cv2.warpPerspective
透视变换
M
,  dsize
输出尺寸等于目标矩形宽高
cv2.resize  缩放图像,dsize  是  (宽, 高)  不是  (高, 宽)。cv2.getRotationMatrix2D  生成旋转矩阵,angle  为正表示逆时针。cv2.getPerspectiveTransform  从 4 组源点和目标点计算 3×3 透视矩阵,工业上最常用的是在图像上标出目标区域的四个角点然后拉成矩形。
import  cv2

import  numpy  as  np

import  os

def  main():

      out_dir =  "output/opencv_series"

      os.makedirs(out_dir, exist_ok=True)

       # 构造一张 400x400 的梯形图:模拟斜拍文档

      img = np.ones((400,  400,  3), dtype=np.uint8) *  255

      pts = np.array([[80,  60], [320,  50], [340,  350], [60,  340]], np.int32)

      cv2.fillPoly(img, [pts], (200,  200,  200))

      cv2.polylines(img, [pts],  True, (0,  0,  0),  2)

      cv2.imwrite(os.path.join(out_dir,  "trapezoid_src.png"), img)

       # 缩放

      resized = cv2.resize(img, (200,  200), interpolation=cv2.INTER_AREA)

       # 旋转 15 度

      h, w = img.shape[:2]

      M_rot = cv2.getRotationMatrix2D((w //  2, h //  2),  15,  0.9)

      rotated = cv2.warpAffine(img, M_rot, (w, h),

                                            borderMode=cv2.BORDER_CONSTANT,

                                            borderValue=(255,  255,  255))

       # 透视矫正:把梯形区域拉成 300x300 矩形

      src_pts = np.float32([[80,  60], [320,  50], [340,  350], [60,  340]])

      dst_pts = np.float32([[0,  0], [300,  0], [300,  300], [0,  300]])

      M_persp = cv2.getPerspectiveTransform(src_pts, dst_pts)

      corrected = cv2.warpPerspective(img, M_persp, (300,  300))

      cv2.imwrite(os.path.join(out_dir,  "resized.png"), resized)

      cv2.imwrite(os.path.join(out_dir,  "rotated.png"), rotated)

      cv2.imwrite(os.path.join(out_dir,  "corrected.png"), corrected)

       print("几何变换完成,结果保存在", out_dir)

if  __name__ ==  "__main__":

      main()

resize/warpAffine 处理平移旋转缩放,warpPerspective 处理梯形畸变。

---

四、效果验证与场景选型

运行后得到三张结果图:resized.png  尺寸 200×200;rotated.png  逆时针旋转 15 度加白边填充;corrected.png  把梯形恢复为 300×300 矩形。
选型建议:
只统一分辨率 → resize,注意缩小用  INTER_AREA
只旋转平移 → warpAffine + getRotationMatrix2D
斜拍梯形畸变 → 必须用 warpPerspective
有桶形畸变 → 先  cv2.undistort  做相机标定校正,再做透视矫正
Jetson 嵌入式 → 用  cv2.cuda.warpPerspective  加速,参数与 CPU 版一致
按畸变类型选变换方法,旋转矫正优先于透视矫正。

---

五、常见问题

坑
现象
解法
resize 尺寸写反
输出图被压扁
dsize
  是  (宽, 高)
旋转后黑边过多
四角大面积黑色
调小 scale 或扩大输出尺寸
透视矩阵顺序错
矫正后严重扭曲
保证 src_pts 与 dst_pts 一一对应
插值选错
缩小图出现摩尔纹
缩小用  INTER_AREA
角点坐标精度不够
结果有锯齿
用  np.float32  传入角点
透视变换的 4 组角点顺序是头号踩坑点,错一个结果就全歪。

---

六、总结

几何变换是工业视觉对齐的核心手段。按畸变类型分层处理:先标定去畸变,再透视矫正,最后旋转缩放对齐到标准模板。在产线上,通常把角点检测、矩阵计算、warp 三步封装成一个函数,输入原始图和模板尺寸,直接输出矫正后的 ROI。
分层处理是工业几何变换的最佳实践——先标定,再透视,最后仿射。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码