当前位置:   article > 正文

透视变换原理以及C++/opencv实现

透视变换原理

部分转载自知乎透视变换 - 知乎 (zhihu.com)

1.什么是透视变换

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

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

2.透视变换的数学原理

透视变换(Perspective Transformation)的本质是将图像投影到一个新的视平面,其通用变换公式如下:

 

 

也就是说:给定透视变换对应的四对像素点坐标,即可求得透视变换矩阵;反之,给定透视变换矩阵,即可对图像或像素点坐标完成透视变换

3.透视变换的代码实现(C++/OpenCv)

OpenCV提供了warpPerspective( )函数来实现图片的透视变换,只需要输入梯形四个顶点的坐标和目标画布四个角的坐标,即可自动完成转换。核心代码只有两行:首先读取两个坐标数组,计算变换矩阵;然后根据变换矩阵对原图进行透视变换,并输出到目标画布。

cv2.getPerspectiveTransform(src, dst) → retval
  • src:源图像中待测矩形的四点坐标
  • sdt:目标图像中矩形的四点坐标

原图像的四个坐标顺序应与目标图像中的四个坐标一 一随影,若都是顺时针则都是顺时针,若都是 Z 字型,则都是 Z 字型。

返回由源图像中矩形到目标图像矩形变换的矩阵,得到矩阵得有用才行啊,所以引出下面这个函数

cv2.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst
  • src:输入图像
  • M:变换矩阵
  • dsize:目标图像shape
  • flags:插值方式,interpolation方法INTER_LINEAR或INTER_NEAREST
  • borderMode:边界补偿方式,BORDER_CONSTANT or BORDER_REPLICATE
  • borderValue:边界补偿大小,常值,默认为0
  1. #include <opencv2/imgcodecs.hpp>
  2. #include <opencv2/highgui.hpp>
  3. #include <opencv2/imgproc.hpp>
  4. #include <iostream>
  5. using namespace cv;
  6. using namespace std;
  7. int main()
  8. {
  9. Mat srcImage = imread("C:\\Users\\LY\\Desktop\\FringeImage_2022-11-19-20-46\\2.bmp");//"C:\Users\LY\Desktop\FringeImage_2022-11-19-20-46\1.bmp"
  10. // 目标图像
  11. Mat dstImage;
  12. // 取原图四个顶点up
  13. //Point2f AffinePointsSrc[4] = { Point2f(729.4169,577.4854), Point2f(1341.8,608.1793),Point2f(724.1677,1108.8), Point2f(1340.7,1101.7) };
  14. //down
  15. Point2f AffinePointsSrc[4] = { Point2f(661.3996,770.9839), Point2f(1290.1,790.8698),Point2f(662.8568, 1311.7), Point2f(1285.3, 1290.6) };
  16. //up
  17. //Point2f AffinePointsDst[4] = { Point2f(923.902,612.663), Point2f(1567.42,635.797),Point2f(931.644,1188.41), Point2f(1571.4,1162.16) };
  18. //down
  19. Point2f AffinePointsDst[4] = { Point2f(923.435,609.981), Point2f(1567.35,632.982),Point2f(932.406,1185.72), Point2f(1571.48,1159.49) };
  20. // 求出透视变换矩阵
  21. Mat TransImage = getPerspectiveTransform(AffinePointsSrc, AffinePointsDst);
  22. warpPerspective(srcImage, dstImage, TransImage, Size(srcImage.cols, srcImage.rows), INTER_CUBIC);
  23. // 目标图像上的四个点上标记圆形
  24. for (int i = 0; i < 4; i++)
  25. {
  26. circle(dstImage, AffinePointsDst[i], 2, Scalar(0, 0, 255), 2);
  27. }
  28. imshow("src", srcImage);
  29. imshow("dst", dstImage);
  30. imwrite("C:\\Users\\LY\\Desktop\\dst_down2.bmp",dstImage);
  31. waitKey();
  32. }



 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/153470
推荐阅读
相关标签
  

闽ICP备14008679号