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

OpenCVSharp:透视变换

概述

透视变换是一种计算机视觉技术,它可以将图像从一个视角转换到另一个视角,通过计算3×3的变换矩阵来实现图像中任意四边形区域到另一个四边形区域的映射。这种变换能够校正图像中的透视畸变,例如将倾斜拍摄的文档"拉直"为正面视图,或者从不同角度观察同一平面物体时的视角转换,广泛应用于文档扫描、建筑摄影校正、图像拼接和增强现实等领域。

效果:

实践

首先按照顺序点击四个点获取这四个点的坐标并在图像上绘制出来:

public void HandleMouseClick(OpenCvSharp.Point position, double actualWidth, double actualHeight) { if (_originalMat == null) return; // 计算缩放比例 // Image控件通常是Uniform Stretch,所以我们需要计算实际显示的图像区域 double imageWidth = _originalMat.Width; double imageHeight = _originalMat.Height; double scaleX = actualWidth / imageWidth; double scaleY = actualHeight / imageHeight; double scale = Math.Min(scaleX, scaleY); // 计算图像在控件中的偏移(居中显示时) double offsetX = (actualWidth - imageWidth * scale) / 2; double offsetY = (actualHeight - imageHeight * scale) / 2; // 转换坐标到图像坐标系 double imgX = (position.X - offsetX) / scale; double imgY = (position.Y - offsetY) / scale; // 检查点击是否在图像范围内 if (imgX >= 0 && imgX < imageWidth && imgY >= 0 && imgY < imageHeight) { AddPoint((float)imgX, (float)imgY); } } private void AddPoint(float x, float y) { if (_points.Count >= 4) return; _points.Add(new Point2f(x, y)); // 在临时Mat上绘制点 Cv2.Circle(_tempMat, (int)x, (int)y, 5, Scalar.Red, -1); // 更新显示图像以显示新绘制的点 DisplayImage = ConvertMatToBitmapImage(_tempMat); if (_points.Count == 4) { PerformPerspectiveTransform(); } }

然后执行透视变换:

private void PerformPerspectiveTransform() { Point2f[] srcPoints = _points.ToArray(); Point2f[] dstPoints = new Point2f[] { new Point2f(0, 0), new Point2f(0, 480), new Point2f(640, 480), new Point2f(640, 0), }; try { usingvar matrix = Cv2.GetPerspectiveTransform(srcPoints, dstPoints); usingvar dst = new Mat(new Size(640, 480), MatType.CV_8UC3); Cv2.WarpPerspective(_originalMat, dst, matrix, dst.Size()); ResultImage = ConvertMatToBitmapImage(dst); } catch (Exception ex) { MessageBox.Show($"变换失败: {ex.Message}"); } }

这个过程主要用到了Cv2.GetPerspectiveTransform与Cv2.WarpPerspective函数,我们只需搞懂这两个函数怎么用就知道怎么使用透视变换了。

先查看Cv2.GetPerspectiveTransform的函数签名:

public static Mat GetPerspectiveTransform(IEnumerable<Point2f> src, IEnumerable<Point2f> dst)

这个函数根据四对对应点计算透视变换矩阵,将源图像中的四边形区域映射到目标图像中的四边形区域。

参数名

类型

说明

src

IEnumerable<Point2f>

源图像中四边形顶点的坐标集合(4个点)

dst

IEnumerable<Point2f>

目标图像中对应四边形顶点的坐标集合(4个点)

现在查看WarpPerspective的函数签名:

public static void WarpPerspective( InputArray src, OutputArray dst, InputArray m, Size dsize, InterpolationFlags flags = InterpolationFlags.Linear, BorderTypes borderMode = BorderTypes.Constant, Scalar? borderValue = null)

这个函数将透视变换应用到输入图像上,根据给定的3×3变换矩阵将图像从一个视角转换到另一个视角。

参数名

类型

说明

src

InputArray

输入图像

dst

OutputArray

输出图像,具有dsize指定的尺寸和与src相同的类型

m

InputArray

3×3透视变换矩阵

dsize

Size

输出图像的尺寸

flags

InterpolationFlags

插值方法组合(INTER_LINEAR或INTER_NEAREST)和可选标志WARP_INVERSE_MAP(设置M为逆变换)

borderMode

BorderTypes

像素外推方法(BORDER_CONSTANT或BORDER_REPLICATE)

borderValue

Scalar?

常数边界时使用的值,默认为0

这样就可以实现透视变换了。

http://www.jsqmd.com/news/125719/

相关文章:

  • 基于Java+大数据+SSM基于Hadoop的健康饮食推荐系统(源码+LW+调试文档+讲解等)/健康饮食建议系统/健康膳食推荐平台/健康饮食指导系统/营养饮食推荐系统
  • GeoJSON.io 免费在线地理编辑器:零基础快速上手终极教程
  • 抖音无水印下载神器:3分钟学会保存高清视频的终极方法
  • LangFlow情感分析仪表盘构建教程
  • 【重磅开源】让 Claude/GitHub Copilot 秒变你的 M365 私人助理!
  • 基于Java+大数据+SSM基于Hadoop的宁波旅游推荐周边商城实现与设计(源码+LW+调试文档+讲解等)/宁波旅游攻略/宁波旅游景点/宁波周边游/宁波商城推荐/宁波购物商城/旅游推荐系统
  • GeoJSON.io 地理数据编辑工具:从零基础到精通的完整操作指南
  • vue3+el-upload+多张图片(20MB左右)+图片压缩上传到后端+可限制条数+懒加载
  • 利用Wireshark深入理解ModbusTCP报文格式说明
  • 突破屏幕限制:Topit窗口置顶工具重新定义macOS多任务体验
  • Mac窗口管理终极利器:Topit让多任务处理效率翻倍 [特殊字符]
  • 终极Mac窗口置顶指南:如何用Topit告别多任务切换烦恼
  • 嵌入式图像转换工具终极使用指南
  • 123
  • Yolov8模型,使用pt跑正常,使用yaml跑得到的P、R、mAP等值均为0的问题
  • KeilC51与MDK同时安装后的License管理建议
  • Topit窗口置顶神器:告别多任务窗口混乱的终极方案
  • ESP32开发红外遥控家电中枢:新手教程(含代码)
  • 全球成膜助剂供应商有哪些?聚焦2025年全球成膜助剂供应商TOP榜单盘点 - 品牌2026
  • 如何快速掌握image2cpp:图像转字节数组的终极指南
  • yolo项目数据集路径缓存
  • 终极效率神器:5步掌握现代自动化工具的完整指南
  • macOS窗口管理终极方案:3步打造你的专属工作空间
  • Topit窗口置顶工具:重新定义macOS多任务工作流的终极解决方案
  • 第63天(中等题 数据结构)
  • 敏捷第22讲:自动化部署——每天手工打包浪费一小时?是时候搭建自动化流水线了
  • 复杂糖脂:细胞识别与信号传导的关键介质 CAS号: 851608-39-4
  • LangFlow单元测试生成器提升开发效率
  • 聚焦江西过碳酸钠生产厂名单盘点:环保助剂领域的中坚力量 - 品牌2026
  • C#排名第一?别吵!这才是.NET开发者的底气