开源项目(7)Opencv日常之Homography
参考教程 https://blog.csdn.net/liuphahaha/article/details/50719275
什么是Homography
在图1中有两张书的平面图,两张图分别有四个相对位置相同的点,Homography就是一个变换(3*3矩阵),将一张图中的点映射到另一张图中对应的点
如何得到一个Homography
要得到两张图片的H,就必须至少知道4个相同对应位置的点,opencv中可以利用findHomography正确得到
- //pts_src和pts_dst是源图像和目标图像中的点矢量。它们是vector <Point2f>类型。我们需要至少4个对应点。
- Mat h = findHomography(pts_src, pts_dst);
- //计算出的单应性可用于将源图像扭曲到目标。 im_src和im_dst属于Mat类型。大小是im_dst的大小(宽度,高度)。
- warpPerspective(im_src, im_dst, h, size);
OpenCV C++ Homography的一个简单例子:
- #include "opencv2/opencv.hpp"
- using namespace cv;
- using namespace std;
- int main( int argc, char** argv)
- {
- // Read source image.
- Mat im_src = imread("book2.jpg");
- // Four corners of the book in source image
- vector<Point2f> pts_src;
- pts_src.push_back(Point2f(141, 131));
- pts_src.push_back(Point2f(480, 159));
- pts_src.push_back(Point2f(493, 630));
- pts_src.push_back(Point2f(64, 601));
- // Read destination image.
- Mat im_dst = imread("book1.jpg");
- // Four corners of the book in destination image.
- vector<Point2f> pts_dst;
- pts_dst.push_back(Point2f(318, 256));
- pts_dst.push_back(Point2f(534, 372));
- pts_dst.push_back(Point2f(316, 670));
- pts_dst.push_back(Point2f(73, 473));
- // Calculate Homography
- Mat h = findHomography(pts_src, pts_dst);
- // Output image
- Mat im_out;
- // Warp source image to destination based on homography
- warpPerspective(im_src, im_out, h, im_dst.size());
- // Display images
- imshow("Source Image", im_src);
- imshow("Destination Image", im_dst);
- imshow("Warped Source Image", im_out);
- waitKey(0);
- }
Homography应用:图像矫正
假设你有一张如下所示的图片
你想点击图中书的四个顶点,然后得到正放的书:
该如何做?
利用Homography可以做到这点。
1.首先获取书本四个顶点的坐标 pts_src
2.然后我们需要知道书本的宽高比,此书的宽高比是3/4,所以可使输出图像的size 为300*400,就可设其四个点的坐标为(0,0),(299,0),(299,399),(0,399)保存在pts_dst中
3.通过pts_src和pts_dst 获取homography
4.对原图应用homography 得到输出
- #include <opencv2/opencv.hpp>
- using namespace cv;
- using namespace std;
- struct userdata{
- Mat im;
- vector<Point2f> points;
- };
- void mouseHandler(int event, int x, int y, int flags, void* data_ptr)
- {
- if ( event == EVENT_LBUTTONDOWN )
- {
- userdata *data = ((userdata *) data_ptr);
- circle(data->im, Point(x,y),3,Scalar(0,0,255), 5, CV_AA);
- imshow("Image", data->im);
- if (data->points.size() < 4)
- {
- data->points.push_back(Point2f(x,y));
- }
- }
- }
- void main()
- {
- // Read source image.
- Mat im_src = imread("book1.jpg");
- // Destination image. The aspect ratio of the book is 3/4
- Size size(300,400);
- Mat im_dst = Mat::zeros(size,CV_8UC3);
- // Create a vector of destination points.
- vector<Point2f> pts_dst;
- pts_dst.push_back(Point2f(0,0));
- pts_dst.push_back(Point2f(size.width - 1, 0));
- pts_dst.push_back(Point2f(size.width - 1, size.height -1));
- pts_dst.push_back(Point2f(0, size.height - 1 ));
- // Set data for mouse event
- Mat im_temp = im_src.clone();
- userdata data;
- data.im = im_temp;
- cout << "Click on the four corners of the book -- top left first and" << endl
- << "bottom left last -- and then hit ENTER" << endl;
- // Show image and wait for 4 clicks.
- imshow("Image", im_temp);
- // Set the callback function for any mouse event
- setMouseCallback("Image", mouseHandler, &data);
- waitKey(0);
- // Calculate the homography
- Mat h = findHomography(data.points, pts_dst);
- // Warp source image to destination
- warpPerspective(im_src, im_dst, h, size);
- // Show image
- imshow("Image", im_dst);
- waitKey(0);
- }
Homography应用:虚拟广告牌
在足球或者棒球体育直播中,经常可以看到球场旁边有虚拟广告,并且还会根据地区,国家的不同播放不同的广告,这是如何做到的?
看完此篇博客,你应该就能知道如何实现了。原理跟前一个差不多,这里直接上代码
- #include <opencv2/opencv.hpp>
- using namespace cv;
- using namespace std;
- struct userdata{
- Mat im;
- vector<Point2f> points;
- };
- void mouseHandler(int event, int x, int y, int flags, void* data_ptr)
- {
- if ( event == EVENT_LBUTTONDOWN )
- {
- userdata *data = ((userdata *) data_ptr);
- circle(data->im, Point(x,y),3,Scalar(0,255,255), 5, CV_AA);
- imshow("Image", data->im);
- if (data->points.size() < 4)
- {
- data->points.push_back(Point2f(x,y));
- }
- }
- }
- int main( int argc, char** argv)
- {
- // Read in the image.
- Mat im_src = imread("first-image.jpg");
- Size size = im_src.size();
- // Create a vector of points.
- vector<Point2f> pts_src;
- pts_src.push_back(Point2f(0,0));
- pts_src.push_back(Point2f(size.width - 1, 0));
- pts_src.push_back(Point2f(size.width - 1, size.height -1));
- pts_src.push_back(Point2f(0, size.height - 1 ));
- // Destination image
- Mat im_dst = imread("times-square.jpg");
- // Set data for mouse handler
- Mat im_temp = im_dst.clone();
- userdata data;
- data.im = im_temp;
- //show the image
- imshow("Image", im_temp);
- cout << "Click on four corners of a billboard and then press ENTER" << endl;
- //set the callback function for any mouse event
- setMouseCallback("Image", mouseHandler, &data);
- waitKey(0);
- // Calculate Homography between source and destination points
- Mat h = findHomography(pts_src, data.points);
- // Warp source image
- warpPerspective(im_src, im_temp, h, im_temp.size());
- // Extract four points from mouse data
- Point pts_dst[4];
- for( int i = 0; i < 4; i++)
- {
- pts_dst[i] = data.points[i];
- }
- // Black out polygonal area in destination image.
- fillConvexPoly(im_dst, pts_dst, 4, Scalar(0), CV_AA);
- // Add warped source image to destination image.
- im_dst = im_dst + im_temp;
- // Display image.
- imshow("Image", im_dst);
- waitKey(0);
- return 0;
- }
结果
开源项目(7)Opencv日常之Homography的更多相关文章
- C#.NET开源项目、机器学习、Power BI
[总目录]本博客博文总目录-实时更新 阅读目录 1.开源Math.NET基础数学类库使用系列 2.C#操作Excel组件Spire.XLS文章目录 3.彩票数据资料库文章 4.数据挖掘与机器学习相 ...
- 转:基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】
文章来自于:http://blog.renren.com/share/246648717/8171467499 基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴 ...
- .Net 开源项目资源大全
伯乐在线已在 GitHub 上发起「DotNet 资源大全中文版」的整理.欢迎扩散.欢迎加入. https://github.com/jobbole/awesome-dotnet-cn (注:下面用 ...
- Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)
下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITableVie ...
- GitHub上史上最全的Android开源项目分类汇总 (转)
GitHub上史上最全的Android开源项目分类汇总 标签: github android 开源 | 发表时间:2014-11-23 23:00 | 作者:u013149325 分享到: 出处:ht ...
- iOS及Mac开源项目和学习资料【超级全面】
UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITable ...
- iOS开发--iOS及Mac开源项目和学习资料
文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...
- iOS、mac开源项目及库汇总
原文地址:http://blog.csdn.net/qq_26359763/article/details/51076499 iOS每日一记------------之 中级完美大整理 iOS.m ...
- iOS、mac开源项目及库(感谢原作者的分享)
目录 模糊效果 富文本 表相关 HUD与Toast 其他UI 其他动画 网络测试 网络聊天 Model 数据库 PDF 摄像照相视频音频处理 消息相关 消息推送服务器端 版本新API的Demo 测试及 ...
随机推荐
- golang面对对象
- LaTeX 小试牛刀
跟大家分享一下正式第一次使用 LaTex 的经验,之前数学建模的时候一直想用,但没有找到合适的软件.前段时间,实验室老师让我帮忙套个 IEEE ACCESS 的模板. 尝试过 TexPad,的确 UI ...
- C#简单构架之EF进行读写分离+多数据库Mysql/SqlServer
http://www.php361.com/index.php?c=index&a=view&id=3857 不建议用,太重的框架EF,仅仅参考一下别人的思路就好. [导读]最近因为项 ...
- 整理:WPF中Binding的几种写法
原文:整理:WPF中Binding的几种写法 目的:整理WPF中Bind的写法 <!--绑定到DataContext--> <Button Content="{Bindin ...
- MethodInvoker委托,跨线程访问
Invoke(new MethodInvoker(delegate { textBox1.Enabled = true; })); 上面是简单缩写,也可以写成 private void btnOK_C ...
- Google Chrome 浏览器JS无法更新解决办法
JS无法更新原因: 浏览器为了加载快,默认是按照自定规则更新缓存,非实时更新. 我们在开发的时候,JS变动很快,需要即时让浏览器加载最新文件,也就是禁用浏览器缓存 (1)使用F12进入开发者模式,找到 ...
- jwt认证生成后的token如何传回后端并解析的详解
jwt认证生成后的token后端解析 一.首先前端发送token token所在的位置headers {'authorization':token的值',Content-Type':applicati ...
- python基础06--文件操作
1.1 文件操作 1.只读(r,rb) rb以bytes方式读文件 只写(w,wb) 追加(a,ab) r+ 读写 w+ 写读 a+ 追加写读 以什么编码方式储存的文件,就用什么编码方式打开 ...
- 【开发笔记】-MySQL数据库5.7+版本,编码格式设置
原因 昨天不小心把数据库搞崩了,重装了5.7.27版本得mysql数据库,在安装过程中并没有设置数据库默认编码格式等操作.在把项目启动后,jpa自动创建表结构,会把数据库,表,字段的编码自动设置为IS ...
- vue与webpack开发环境搭建:从无到有
一个vue从无到有的搭建过程. 一.不论是webpack还是vue,最初的第一步就是安装node.js.它是基石. 从官网下载你需要的安装包:官网下载链接:http://nodejs.cn/downl ...