赞
踩
一.什么是透视变换
透视变换就是透视变换(Perspective Transformation)是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。简单的来说就是把一张斜着看的二维图形变为俯瞰的二维图像,透视变换再计算机视觉中相当常用,因为计算机采集的图形并非规整的图像,比如再使用自动倒车,赛道识别等方面都需要使用透视变换来改变计算机所采集的的信息,比如:
二.代码演示:
目标是把这张图片:
变为:
首先是打开图片
- frame = imread("test3.jpg", 1);
- frame1 = frame.clone();
这里先定义两张一样的图片,一张用于用户输入,一张用于数据处理
然后调整一下图片的大小,这里我测试了一下,把图片都变成正方形可以使变换的更加准确
- Size a = frame.size();
- resize(frame, frame, Size(max(a.height,a.width), max(a.height ,a.width)));
- 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函数如下:
- int num_point = 0, out_size = 0;
- void On_mouse(int event, int x, int y, int flags, void*) {
- if (event == EVENT_LBUTTONDOWN) {
- in_point[num_point] = Point(x, y);
- cout << x << ' ' << y << endl;
- circle(frame1, in_point[num_point], 6, Scalar(0, 255, 0), -1);
- imshow("test", frame1);
- num_point++;
- }
- }
然后我们把输入的四个点的坐标存在in_point这个数组里
最后我们使用getPerspectiveTransform和warpPerspective函数进行透视变换:
- temp = getPerspectiveTransform(in_point, out_point);
- warpPerspective(frame, result, temp, frame.size());
这里注意我们输入点的顺序是:左上,右上,左下,右下。
完整代码:
- #include<opencv2/opencv.hpp>
- #include<iostream>
- using namespace std;
- using namespace cv;
- Mat frame,frame1;
- Point2f in_point[4];
- Point2f out_point[4];
- int num_point = 0, out_size = 0;
- void On_mouse(int event, int x, int y, int flags, void*) {
- if (event == EVENT_LBUTTONDOWN) {
- in_point[num_point] = Point(x, y);
- cout << x << ' ' << y << endl;
- circle(frame1, in_point[num_point], 6, Scalar(0, 255, 0), -1);
- imshow("test", frame1);
- num_point++;
- }
- }
- int main(){
- cout << "请依次点击需要变换的四边形的左上角,右上角,左下角,右下角" << endl;
- cout << "点选取好后单击Enter" << endl;
- frame = imread("test3.jpg", 1); //test3.jpg是我自己在这个目录下的文件,也可以替换为图片的绝对路径,但是要注意使用双斜杠
- frame1 = frame.clone();
- Size a = frame.size();
- resize(frame, frame, Size(max(a.height,a.width), max(a.height ,a.width)));
- resize(frame1, frame1, Size(max(a.height, a.width), max(a.height, a.width)));
- imshow("test", frame);
- setMouseCallback("test", On_mouse, 0);
- while (1) {
- if (waitKey(10) == 13) {
- out_size = std::max(in_point[1].x - in_point[0].x, in_point[3].x - in_point[2].x);
- out_point[0] = Point2f(0.0, 0.0);
- out_point[1] = Point2f(out_size * 1.0, 0.0);
- out_point[2] = Point2f(0.0, out_size * 1.0);
- out_point[3] = Point2f(out_size * 1.0, out_size * 1.0);
- Mat temp, result;
- temp = getPerspectiveTransform(in_point, out_point);
- warpPerspective(frame, result, temp, frame.size());
- imshow("result", result);
- cout << "转换完成" << endl;
- waitKey(0);
- }
- }
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。