图像校正—透视变换

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.youkuaiyun.com/dcrmg/article/details/52475777


透视变换通过投影的方式,把当前图像映射到另外一个平面,就像电影院里的交代放映机,如果幕布或者胶带其中任意一个与放映机发出的光纤不是垂直90度角的,那么投影到幕布上的图像就会发生畸变。这种畸变就是透视畸变的一种。


透视变换对畸变图像的校正需要取得畸变图像的一组4个点的坐标,和目标图像的一组4个点的坐标,通过两组坐标点可以计算出透视变换的变换矩阵,之后对整个原始图像执行变换矩阵的变换,就可以实现图像校正。


以下一幅图像中的书由于拍摄时摄像头视角的原因,导致一定程度的畸变:



可以看到距离摄像头越近的点,看起来越大,越远的点看起来越小。对这幅图像透视校正的目的就是要纠正这种形变,得到书的正视角矩形图像,校正效果相当于是从书的正上方视角拍摄的。

例程用Opencv中的warpPerspective方法实现:


  1. #include "core/core.hpp"
  2. #include "highgui/highgui.hpp"
  3. #include "imgproc/imgproc.hpp"
  4. using namespace cv;
  5. void onMouse(int event,int x,int y,int flags,void *utsc);
  6. Point2f srcTri[4],dstTri[4];
  7. int clickTimes=0; //在图像上单击次数
  8. Mat image;
  9. Mat imageWarp;
  10. int main(int argc,char *argv[])
  11. {
  12. image=imread(argv[1]);
  13. imshow("Source Image",image);
  14. setMouseCallback("Source Image",onMouse);
  15. waitKey();
  16. return 0;
  17. }
  18. void onMouse(int event,int x,int y,int flags,void *utsc)
  19. {
  20. if(event==CV_EVENT_LBUTTONUP) //响应鼠标左键抬起事件
  21. {
  22. circle(image,Point(x,y),2.5,Scalar(0,0,255),2.5); //标记选中点
  23. imshow("Source Image",image);
  24. srcTri[clickTimes].x=x;
  25. srcTri[clickTimes].y=y;
  26. clickTimes++;
  27. }
  28. if(clickTimes==4)
  29. {
  30. dstTri[0].x=0;
  31. dstTri[0].y=0;
  32. dstTri[1].x=image.rows-1;
  33. dstTri[1].y=0;
  34. dstTri[2].x=0;
  35. dstTri[2].y=image.cols-161;
  36. dstTri[3].x=image.rows-1;
  37. dstTri[3].y=image.cols-161;
  38. Mat transform=Mat::zeros(3,3,CV_32FC1); //透视变换矩阵
  39. transform=getPerspectiveTransform(srcTri,dstTri); //获取透视变换矩阵
  40. warpPerspective(image,imageWarp,transform,Size(image.rows,image.cols-160)); //透视变换
  41. imshow("After WarpPerspecttive",imageWarp);
  42. }
  43. }


通过鼠标左键单击原始图像书的4个角点,透射到另外一个视平面的4个矩形的角点上,实现畸变校正。

每次点击在原图上画出红色的原点标示出点位:




透视校正效果:




由于拍摄视角倾斜角度比较大,并且转换后的图像有高度方向上的拉伸,所以图像对比度有所下降。


### 使用 OpenCV 实现图像透视变换校正 为了实现图像透视变换校正,在 .NET 环境下可以利用 `OpenCvSharp` 这一工具,它是对 OpenCV 原生库的一个封装[^1]。对于具体的编程语言环境而言,这里以 C# 为例来展示如何操作。 #### 准备工作 确保已经安装了 `OpenCvSharp4` 和 `OpenCvSharp4.runtime.win` NuGet 包以便于在项目中调用相应的 API 接口函数。 #### 加载图片并定义源点和目标点坐标 ```csharp using Cv = OpenCvSharp; // ... string imagePath = "path_to_image"; var srcImage = Cv.Cv2.ImRead(imagePath); Point2f[] sourcePoints = new Point2f[] { new Point2f(x1, y1), // 左上角 new Point2f(x2, y2), // 右上角 new Point2f(x3, y3), // 右下角 new Point2f(x4, y4) // 左下角 }; Point2f[] destinationPoints = new Point2f[] { new Point2f(0, 0), new Point2f(width - 1, 0), new Point2f(width - 1, height - 1), new Point2f(0, height - 1) }; ``` 上述代码片段展示了加载一张待处理的图片以及指定用于计算透视矩阵所需的四个对应关系的点集,即原始图上的四边形顶点位置及其映射到的新矩形区域内的相应位置[^4]。 #### 计算透视变换矩阵与执行转换 ```csharp Mat transformationMatrix = Cv.Cv2.GetPerspectiveTransform(sourcePoints, destinationPoints); Size outputSize = new Size(width, height); // 定义输出尺寸 Mat dstImage = new Mat(); Cv.Cv2.WarpPerspective(srcImage, dstImage, transformationMatrix, outputSize); // 显示结果 Cv.Cv2.ImShow("Original Image", srcImage); Cv.Cv2.ImShow("Warped Image", dstImage); Cv.Cv2.WaitKey(0); Cv.Cv2.DestroyAllWindows(); ``` 此部分实现了基于给定参数求解透视投影变换矩阵,并应用该矩阵完成实际的空间变换过程;最后通过窗口形式呈现前后对比效果[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值