透视变换是3D转换,透视变换的本质是将图像投影到一个新的视平面;

据此,我们可以使用透视变化来实现鸟瞰图和图形贴图的效果;

一、鸟瞰图

实现前:

实现效果:

1.准备一个空的mat对象 用于保存转换后的图

    Mat image=imread("road.jpg");imshow("image",image);Mat result=Mat::zeros(500,600,CV_8UC1);//存储转换后的图像坐标 按顺时针 左上、右上、右下、左下(可自己定顺序)vector<Point2f> obj;obj.push_back(Point2f(0,0));obj.push_back(Point2f(600,0));obj.push_back(Point2f(600,500));obj.push_back(Point2f(0,500));

2.在原图窗口里做鼠标操作,通过setMouseCallback鼠标回调函数,获取原图四个坐标

在原图中点击四个点获取四个坐标,顺序与上述1中设置的坐标对应,如果1中是顺时针,按选择坐标时也应该按顺时针操作,并且按照左上、右上、右下、左下顺序;

    //2.在原图窗口里做鼠标操作,通过鼠标回调函数,获取原图四个坐标struct imagedata data;data.img=image;//将原图传入setMouseCallback("image",mouseHundle,&data);//鼠标回调函数waitKey(0);//键盘输入 向下执行//点击按键之后结束鼠标操作,得到原图四个坐标和转换后的坐标
//用到的结构体和鼠标处理函数
struct imagedata
{Mat img;vector<Point2f>points;//该points是test1原图需要做转换的坐标//在test2中是原图转换后的坐标
};void mouseHundle(int event,int x,int y,int flag,void *arg)
{struct imagedata* ind=(struct imagedata *)arg;if(event==EVENT_LBUTTONDOWN)//鼠标左键按下{//画圆circle(ind->img,Point(x,y),3,Scalar(0,0,255),3,CV_AA);imshow("image",ind->img);//test1鸟瞰图显示原图带圆点//imshow("dst",ind->img);//test2贴图显示city图带圆点if(ind->points.size()<4){ind->points.push_back(Point2f(x,y));//转换的坐标只需要收集四个}}
}

3.开始计算坐标映射矩阵

Mat res=findHomography(data.points,obj,CV_RANSAC);

4.进行透视转换

将原图转变为效果图进行显示

warpPerspective(image,result,res,result.size());
imshow("result",result);
waitKey(0);

二、贴图

city图实现前: 

贴图实现后:

左边大屏幕更改

贴图与鸟瞰图有些不同,鸟瞰图是将一张原图,通过选择四个点转换成鸟瞰图;

转换后的坐标固定的,转换前的4个坐标由鼠标选择;

而贴图的话,是将原图通过选择的点进行转换,再贴到city图中;

转换前的坐标固定的,就是普通的图片,转换后的坐标由鼠标选择;

1.准备原图要贴上去的图,即1.jpg

     Mat image1=imread("1.jpg");//原图Mat image2=imread("city.jpg");//city图Mat dst=image2.clone();//克隆一份城市图//1.准备原图要贴上去的图,即1.jpg//Mat result=Mat::zeros(image1.rows,image1.cols,CV_8UC1);//存储转换前的图像坐标vector<Point2f> obj;obj.push_back(Point2f(0,0));obj.push_back(Point2f(image1.cols,0));obj.push_back(Point2f(image1.cols,image1.rows));obj.push_back(Point2f(0,image1.rows));imshow("dst",image2);

2.在city窗口里做鼠标操作,通过鼠标回调函数,获取转换后的四个坐标

    struct imagedata data;data.img=dst;//将city图传入setMouseCallback("dst",mouseHundle,&data);//鼠标回调函数waitKey(0);

3.开始计算坐标映射矩阵

//点击按键之后结束鼠标操作,得到原图四个坐标和转换后的坐标Mat res=findHomography(obj,data.points,CV_RANSAC);

4.透视转换

warpPerspective(image1,dst,res,dst.size());imshow("image1",dst);

做到这一步,将原图变成这样子

5. 获取四个坐标,将city图中选择的位置填充成黑色,防止两个图片颜色冲突

最后通过image2+=dst把图片贴到city图上,这样就完成了

    Point pts[4];for(int i=0;i<4;i++){pts[i]=data.points[i];}//在city图中选择的位置填充成黑色,防止两图颜色冲突fillConvexPoly(image2,pts,4,Scalar(0),CV_AA);image2+=dst;//把图片贴到city图上imshow("final",image2);waitKey(0);

完整源码

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace  cv;struct imagedata
{Mat img;vector<Point2f>points;//该points是test1原图需要做转换的坐标//在test2中是原图转换后的坐标
};void mouseHundle(int event,int x,int y,int flag,void *arg)
{struct imagedata* ind=(struct imagedata *)arg;if(event==EVENT_LBUTTONDOWN)//鼠标左键按下{//画圆circle(ind->img,Point(x,y),3,Scalar(0,0,255),3,CV_AA);//imshow("image",ind->img);//test1显示原图带圆点imshow("dst",ind->img);//test2显示city图带圆点if(ind->points.size()<4){ind->points.push_back(Point2f(x,y));//转换的坐标只需要收集四个}}
}void test1()
{Mat image=imread("road.jpg");imshow("image",image);//1.准备空的mat对象  用于保存转换后的图Mat result=Mat::zeros(500,600,CV_8UC1);//存储转换后的图像坐标 按顺时针 左上、右上、右下、做下(可自己定顺序)vector<Point2f> obj;obj.push_back(Point2f(0,0));obj.push_back(Point2f(600,0));obj.push_back(Point2f(600,500));obj.push_back(Point2f(0,500));//2.在原图窗口里做鼠标操作,通过鼠标回调函数,获取原图四个坐标struct imagedata data;data.img=image;//将原图传入setMouseCallback("image",mouseHundle,&data);//鼠标回调函数waitKey(0);//点击按键之后结束鼠标操作,得到原图四个坐标和转换后的坐标//3.开始计算坐标映射矩阵Mat res=findHomography(data.points,obj,CV_RANSAC);//4.透视转换warpPerspective(image,result,res,result.size());imshow("result",result);waitKey(0);
}
void test2()
{Mat image1=imread("1.jpg");Mat image2=imread("city.jpg");Mat dst=image2.clone();//克隆一份城市图//1.准备原图要贴上去的图,即1.jpg//Mat result=Mat::zeros(image1.rows,image1.cols,CV_8UC1);//存储转换前的图像坐标vector<Point2f> obj;obj.push_back(Point2f(0,0));obj.push_back(Point2f(image1.cols,0));obj.push_back(Point2f(image1.cols,image1.rows));obj.push_back(Point2f(0,image1.rows));imshow("dst",image2);//2.在city窗口里做鼠标操作,通过鼠标回调函数,获取需要四个坐标struct imagedata data;data.img=dst;//将city图传入setMouseCallback("dst",mouseHundle,&data);//鼠标回调函数waitKey(0);//点击按键之后结束鼠标操作,得到原图四个坐标和转换后的坐标//3.开始计算坐标映射矩阵Mat res=findHomography(obj,data.points,CV_RANSAC);//4.透视转换warpPerspective(image1,dst,res,dst.size());imshow("image1",dst);Point pts[4];for(int i=0;i<4;i++){pts[i]=data.points[i];}//在city图中选择的位置填充成黑色,防止两图颜色冲突fillConvexPoly(image2,pts,4,Scalar(0),CV_AA);image2+=dst;//把图片贴到city图上imshow("final",image2);waitKey(0);
}int main()
{//test1();test2();return 0;
}

感谢观看!!!!

以上就是全部内容,如果对您有帮助,欢迎点赞评论,或者发现有哪里写错的,欢迎指正!

【OpenCV】透视变换应用——实现鸟瞰图与贴图相关推荐

  1. 详解 OpenCV 透视变换原理 及 实例

    OpenCV提供了两种图片变换的方式:仿射变换和透视变换,两者的区别很容易区分, 前者是将矩形的图片变成平行四边形 后者是将图片变成梯形 这两种变换虽然都有各自的应用场景,但在实际的图片变换中由于透视 ...

  2. 使用OpenCV透视变换技术实现坐标变换实践

    1. 概述 1.1. 需求 在局部空间(无GPS定位)视频监控过程中,把视频识别到物体位置,投射到空间平面坐标系中,获取物体在局部空间的平面坐标. 1.2. 解决方案 使用图像透视变换技术. 1.3. ...

  3. OpenCV 透视变换 图像拼接

    A:OpenCV 透视变换 一:OpenCV透视变换的概念 仿射变换(affine transform)与透视变换(perspective transform)在图像还原.图像局部变化处理方面有重要意 ...

  4. python使用openCV把原始彩色图像转化为灰度图、使用矩阵索引的方式对数据数据进行剪裁(image cropping)

    python使用openCV把原始彩色图像转化为灰度图.使用矩阵索引的方式对数据数据进行剪裁(image cropping) 目录

  5. Python使用openCV把原始彩色图像转化为灰度图、使用OpenCV把图像二值化(仅仅包含黑色和白色的简化版本)、基于自适应阈值预处理(adaptive thresholding)方法

    Python使用openCV把原始彩色图像转化为灰度图.使用OpenCV把图像二值化(仅仅包含黑色和白色的简化版本).基于自适应阈值预处理(adaptive thresholding)方法 目录

  6. OpenCV透视变换应用于图像的实例(附完整代码)

    OpenCV透视变换应用于图像的实例 OpenCV透视变换应用于图像的实例 OpenCV透视变换应用于图像的实例 #include "opencv2/imgproc.hpp" #i ...

  7. OpenCV透视变换应用于图像的实例(附完整源代码)

    OpenCV透视变换应用于图像的实例 透视变换应用于图像的实例完整源代码 透视变换应用于图像的实例完整源代码 #include "opencv2/imgproc.hpp" #inc ...

  8. 使用opencv将16位深度图转灰度图

    使用opencv将16位深度图转灰度图,默认深度图每个像素以uint16_t来保存. #include <string> #include "opencv2/core/core. ...

  9. OpenCV透视变换——将斜方向的图片转成正方向鸟瞰图

    目录 一.获取需要变换的图像中一个区域的四个点位置 二.利用getPerspectiveTransform函数获取透视转换矩阵 三.利用warpPerspective函数获取处理好的鸟瞰图像 标记四个 ...

最新文章

  1. [css] 你了解css3的currentColor吗?举例说明它的作用是什么?
  2. foundApp宣传展示页企业网站模板
  3. 无法显示隐藏文件的解决方法
  4. 虚拟机下挂载CentOS 镜像并配置yum本地镜像源
  5. (零)ubuntu下制作最小deb包
  6. oracle-00028,Oracle 10g錯誤:「ORA-00028:您的會話已被終止」
  7. python图像转字符画_Python实现图片转字符画的示例
  8. Mybatis动态sql及性能优化-3
  9. mysql某建表语句
  10. ARM 与 STM32 的关系
  11. Slices in Python
  12. matlab处理各种数据、文件
  13. (十二):为什么需要一个新的ORM框架
  14. 大学生活快要结束了,才想要珍惜~~~
  15. [NPUCTF2020]ReadlezPHP(反序列化)
  16. OGRE渲染引擎之地形、天空和雾
  17. 非科班转行的2018秋招算法工程师面经:面试实录+人生经验
  18. 别让虚拟化成为“永恒之蓝”的下一个攻击目标
  19. 数据分析--可视化matplotlib
  20. GO111MODULE 环境变量

热门文章

  1. 滴滴开源3周年,都发布过哪些项目?
  2. 高通平台usb充电检测
  3. 1+X 网络安全运营平台与管理 sql注入实验报告
  4. apk私钥_Android创建私钥并为APK文件签名
  5. html 小三角折叠菜单,html+css+js下拉列表小三角
  6. 同轴电缆75欧什么意思?这是高频电磁传播的概念是特性阻抗,不同于直流电路的电阻阻值。下文指出:同轴电缆的特征阻抗只与外导体的内径和内导体的外径有关,和电缆长度无关。测试原理TDR,史密斯,谐振法
  7. 乾元通多链路通信设备保障高铁网络稳定
  8. linux复制文件夹排除文件,【linux】复制文件夹中文件,排除部分文件
  9. 【漫事杂谈007】哈利波特电影一共有几部
  10. “低代码”将干掉70%的软件开发工作