开源项目(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 测试及 ...
随机推荐
- 第二节:EF Core的常规“增删改”及状态的变化
一. 整体说明 1. 本节用到的表 2. 状态说明补充 ①.Detached: 游离的状态,与数据库没有什么交涉,比如新new一个实体,状态就是Detached. ②.Added: 增加的状态. ③. ...
- Java | Spring Boot Swagger2 集成REST ful API 生成接口文档
Spring Boot Swagger2 集成REST ful API 生成接口文档 原文 简介 由于Spring Boot 的特性,用来开发 REST ful 变得非常容易,并且结合 Swagg ...
- ES7.3.0配置邮件告警
情况说明: 三台es组成集群,一台kibana,版本均为7.3.0 es版本要求是白金版,基础版的不行,不过可以试用30天的白金版 步骤:先说我自己走通的流程,然后介绍官方说明 1.因为我这边使用的是 ...
- Scala 系列(十一)—— 模式匹配
一.模式匹配 Scala 支持模式匹配机制,可以代替 swith 语句.执行类型检查.以及支持析构表达式等. 1.1 更好的swith Scala 不支持 swith,可以使用模式匹配 match.. ...
- 如何在ASP.NET Core Web API中使用Mini Profiler
原文如何在ASP.NET Core Web API中使用Mini Profiler 由Anuraj发表于2019年11月25日星期一阅读时间:1分钟 ASPNETCoreMiniProfiler 这篇 ...
- jq动画插件,自制基于vue的圆形时钟
首先附上jq插件库,里面的东西太炫了,建议学前端的可以看看学习下:http://www.jq22.com/ 里面有个“超个性动画版本的个人简历”,通过屏幕上不断打印内容,改变相应样式来实现动画简历,我 ...
- rsync 排除指定目录
背景 将Server1上的数据同步到Server2: Server1目录结构: /us_data/yahoo └── qlib ├── calendars ├── dataset_cache ├── ...
- react 使用的小建议
使用pureRender,setState和Immutable.js来操作state Immutable 中文意思不可变. 不能直接修改state的值,要用setState 和Immutable re ...
- kbmmw 中的Boyer-Moore算法
kbmmw 5.10 版本中实现了一个非常好用的字符串搜索算法,即Boyer-Moore算法. 在用于查找子字符串的算法当中,BM(Boyer-Moore)算法是目前被认为最高效的字符串搜索算法, 它 ...
- postgresql源代码结构
转载学习: 德哥培训! 源码下载: https://www.postgresql.org/ftp/source/ 1.postgressql源码目录结构 2.src目录结构