当前位置:   article > 正文

使用opencv对图像进行透视变换_opencv透视变换

opencv透视变换

一.什么是透视变换

透视变换就是透视变换(Perspective Transformation)是指利用透视中心像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。简单的来说就是把一张斜着看的二维图形变为俯瞰的二维图像,透视变换再计算机视觉中相当常用,因为计算机采集的图形并非规整的图像,比如再使用自动倒车,赛道识别等方面都需要使用透视变换来改变计算机所采集的的信息,比如:

二.代码演示: 

目标是把这张图片:

变为:

 

 首先是打开图片

  1. frame = imread("test3.jpg", 1);
  2. frame1 = frame.clone();

这里先定义两张一样的图片,一张用于用户输入,一张用于数据处理

然后调整一下图片的大小,这里我测试了一下,把图片都变成正方形可以使变换的更加准确

  1. Size a = frame.size();
  2. resize(frame, frame, Size(max(a.height,a.width), max(a.height ,a.width)));
  3. resize(frame1, frame1, Size(max(a.height, a.width), max(a.height, a.width)));

然后使确定矩形的四个点,这里我们让用户自己再图片上进行点击,我们可以使用openCV自带的函数setmousecallback,用法如下:

这里共有三个参数:

第一个:窗口名称

第二个:鼠标的响应函数和回调函数

第三个:回调函数的参数

我们在第二个参数中写一个返回值void的函数On_mouse,其中识别鼠标按下的回调的参数是:EVENT_LBUTTONDOWN

	setMouseCallback("test", On_mouse, 0);

然后我们期望用户点击后在用户点击的地方显示一个点,我们可以使用circle函数,所以On_mouse函数如下:

  1. int num_point = 0, out_size = 0;
  2. void On_mouse(int event, int x, int y, int flags, void*) {
  3. if (event == EVENT_LBUTTONDOWN) {
  4. in_point[num_point] = Point(x, y);
  5. cout << x << ' ' << y << endl;
  6. circle(frame1, in_point[num_point], 6, Scalar(0, 255, 0), -1);
  7. imshow("test", frame1);
  8. num_point++;
  9. }
  10. }

然后我们把输入的四个点的坐标存在in_point这个数组里

最后我们使用getPerspectiveTransform和warpPerspective函数进行透视变换:

  1. temp = getPerspectiveTransform(in_point, out_point);
  2. warpPerspective(frame, result, temp, frame.size());

这里注意我们输入点的顺序是:左上,右上,左下,右下。

完整代码:

  1. #include<opencv2/opencv.hpp>
  2. #include<iostream>
  3. using namespace std;
  4. using namespace cv;
  5. Mat frame,frame1;
  6. Point2f in_point[4];
  7. Point2f out_point[4];
  8. int num_point = 0, out_size = 0;
  9. void On_mouse(int event, int x, int y, int flags, void*) {
  10. if (event == EVENT_LBUTTONDOWN) {
  11. in_point[num_point] = Point(x, y);
  12. cout << x << ' ' << y << endl;
  13. circle(frame1, in_point[num_point], 6, Scalar(0, 255, 0), -1);
  14. imshow("test", frame1);
  15. num_point++;
  16. }
  17. }
  18. int main(){
  19. cout << "请依次点击需要变换的四边形的左上角,右上角,左下角,右下角" << endl;
  20. cout << "点选取好后单击Enter" << endl;
  21. frame = imread("test3.jpg", 1); //test3.jpg是我自己在这个目录下的文件,也可以替换为图片的绝对路径,但是要注意使用双斜杠
  22. frame1 = frame.clone();
  23. Size a = frame.size();
  24. resize(frame, frame, Size(max(a.height,a.width), max(a.height ,a.width)));
  25. resize(frame1, frame1, Size(max(a.height, a.width), max(a.height, a.width)));
  26. imshow("test", frame);
  27. setMouseCallback("test", On_mouse, 0);
  28. while (1) {
  29. if (waitKey(10) == 13) {
  30. out_size = std::max(in_point[1].x - in_point[0].x, in_point[3].x - in_point[2].x);
  31. out_point[0] = Point2f(0.0, 0.0);
  32. out_point[1] = Point2f(out_size * 1.0, 0.0);
  33. out_point[2] = Point2f(0.0, out_size * 1.0);
  34. out_point[3] = Point2f(out_size * 1.0, out_size * 1.0);
  35. Mat temp, result;
  36. temp = getPerspectiveTransform(in_point, out_point);
  37. warpPerspective(frame, result, temp, frame.size());
  38. imshow("result", result);
  39. cout << "转换完成" << endl;
  40. waitKey(0);
  41. }
  42. }
  43. return 0;
  44. }

 


 

 

 

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

闽ICP备14008679号