开源项目(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 测试及 ...
随机推荐
- char[],char *,string之间转换
char []与char *之间转换 char []转char *:直接进行赋值即可 // char[] 转char *char str[] = "lala";char *str1 ...
- Flask-SQLAlchemy 与 SQL Alchemy 的区别、联系
目录 一.SQL Alchemy 1. SQL Alchemy 基本操作 1.1 连接数据库 1.2 声明映射(建立数据库表的模型) 1.3 创建映射类的实例 1.4 创建会话 1.5 单表的增删改查 ...
- Tomcat 中的 Session 和 Cookie
HTTP 是一种无状态通信协议,每个请求之间相互独立,服务器不能识别曾经来过的请求.而对于 Web 应用,它的活动都是依赖某个状态的,比如用户登录,此时使用 HTTP 就需要它在一次登录请求后,有为后 ...
- c#结束练习题
1.输入一个秒数,输出对应的小时.分钟.秒. 例:输入“4000“(秒),输出“1小时6分40秒”. 2.计算1-1/2+1/3-1/4+...-1/100的值. 3.写一个函数,对一个一维数组排序. ...
- 象棋中“车”的攻击范围_C#
如题: var a = new String[8,8]; int h, l; Console.WriteLine("输入车所在的行(0-7):"); h = int.Parse(C ...
- Linux(Ubuntu)通过nfs挂载远程硬盘
需求 现有两台Linux Server,需要把Linux01 下的8T硬盘挂在到 Linux02 下:Linux01 硬盘: Linux02 硬盘: 挂载原理 通过 nfs-server 将Linux ...
- 504 Gateway Time-out ( Nginx + PHP ) 解决小计
问题 最近有个项目,运算量比较大,服务器经常报 504 Gateway Time-out 解决方案 fastcgi_connect_timeout 默认值是 60 第一次尝试修改为 120 ,仍然报5 ...
- .net core web api 默认的模型验证
转载自 https://www.codercto.com/a/45938.html
- pandas-19 DataFrame读取写入文件的方法
pandas-19 DataFrame读取写入文件的方法 DataFrame有非常丰富的IO方法,比如DataFrame读写csv文件excel文件等等,操作很简单.下面在代码中标记出来一些常用的读写 ...
- EnumSet详细讲解
https://blog.csdn.net/tugangkai/article/details/89631886 之前介绍的Set接口的实现类HashSet/TreeSet,它们内部都是用对应的Has ...