【OpenCV】透视变换应用——实现鸟瞰图与贴图
透视变换是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】透视变换应用——实现鸟瞰图与贴图相关推荐
- 详解 OpenCV 透视变换原理 及 实例
OpenCV提供了两种图片变换的方式:仿射变换和透视变换,两者的区别很容易区分, 前者是将矩形的图片变成平行四边形 后者是将图片变成梯形 这两种变换虽然都有各自的应用场景,但在实际的图片变换中由于透视 ...
- 使用OpenCV透视变换技术实现坐标变换实践
1. 概述 1.1. 需求 在局部空间(无GPS定位)视频监控过程中,把视频识别到物体位置,投射到空间平面坐标系中,获取物体在局部空间的平面坐标. 1.2. 解决方案 使用图像透视变换技术. 1.3. ...
- OpenCV 透视变换 图像拼接
A:OpenCV 透视变换 一:OpenCV透视变换的概念 仿射变换(affine transform)与透视变换(perspective transform)在图像还原.图像局部变化处理方面有重要意 ...
- python使用openCV把原始彩色图像转化为灰度图、使用矩阵索引的方式对数据数据进行剪裁(image cropping)
python使用openCV把原始彩色图像转化为灰度图.使用矩阵索引的方式对数据数据进行剪裁(image cropping) 目录
- Python使用openCV把原始彩色图像转化为灰度图、使用OpenCV把图像二值化(仅仅包含黑色和白色的简化版本)、基于自适应阈值预处理(adaptive thresholding)方法
Python使用openCV把原始彩色图像转化为灰度图.使用OpenCV把图像二值化(仅仅包含黑色和白色的简化版本).基于自适应阈值预处理(adaptive thresholding)方法 目录
- OpenCV透视变换应用于图像的实例(附完整代码)
OpenCV透视变换应用于图像的实例 OpenCV透视变换应用于图像的实例 OpenCV透视变换应用于图像的实例 #include "opencv2/imgproc.hpp" #i ...
- OpenCV透视变换应用于图像的实例(附完整源代码)
OpenCV透视变换应用于图像的实例 透视变换应用于图像的实例完整源代码 透视变换应用于图像的实例完整源代码 #include "opencv2/imgproc.hpp" #inc ...
- 使用opencv将16位深度图转灰度图
使用opencv将16位深度图转灰度图,默认深度图每个像素以uint16_t来保存. #include <string> #include "opencv2/core/core. ...
- OpenCV透视变换——将斜方向的图片转成正方向鸟瞰图
目录 一.获取需要变换的图像中一个区域的四个点位置 二.利用getPerspectiveTransform函数获取透视转换矩阵 三.利用warpPerspective函数获取处理好的鸟瞰图像 标记四个 ...
最新文章
- [css] 你了解css3的currentColor吗?举例说明它的作用是什么?
- foundApp宣传展示页企业网站模板
- 无法显示隐藏文件的解决方法
- 虚拟机下挂载CentOS 镜像并配置yum本地镜像源
- (零)ubuntu下制作最小deb包
- oracle-00028,Oracle 10g錯誤:「ORA-00028:您的會話已被終止」
- python图像转字符画_Python实现图片转字符画的示例
- Mybatis动态sql及性能优化-3
- mysql某建表语句
- ARM 与 STM32 的关系
- Slices in Python
- matlab处理各种数据、文件
- (十二):为什么需要一个新的ORM框架
- 大学生活快要结束了,才想要珍惜~~~
- [NPUCTF2020]ReadlezPHP(反序列化)
- OGRE渲染引擎之地形、天空和雾
- 非科班转行的2018秋招算法工程师面经:面试实录+人生经验
- 别让虚拟化成为“永恒之蓝”的下一个攻击目标
- 数据分析--可视化matplotlib
- GO111MODULE 环境变量
热门文章
- 滴滴开源3周年,都发布过哪些项目?
- 高通平台usb充电检测
- 1+X 网络安全运营平台与管理 sql注入实验报告
- apk私钥_Android创建私钥并为APK文件签名
- html 小三角折叠菜单,html+css+js下拉列表小三角
- 同轴电缆75欧什么意思?这是高频电磁传播的概念是特性阻抗,不同于直流电路的电阻阻值。下文指出:同轴电缆的特征阻抗只与外导体的内径和内导体的外径有关,和电缆长度无关。测试原理TDR,史密斯,谐振法
- 乾元通多链路通信设备保障高铁网络稳定
- linux复制文件夹排除文件,【linux】复制文件夹中文件,排除部分文件
- 【漫事杂谈007】哈利波特电影一共有几部
- “低代码”将干掉70%的软件开发工作