参考教程 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的更多相关文章

  1. C#.NET开源项目、机器学习、Power BI

    [总目录]本博客博文总目录-实时更新   阅读目录 1.开源Math.NET基础数学类库使用系列 2.C#操作Excel组件Spire.XLS文章目录 3.彩票数据资料库文章 4.数据挖掘与机器学习相 ...

  2. 转:基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】

    文章来自于:http://blog.renren.com/share/246648717/8171467499 基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴 ...

  3. .Net 开源项目资源大全

    伯乐在线已在 GitHub 上发起「DotNet 资源大全中文版」的整理.欢迎扩散.欢迎加入. https://github.com/jobbole/awesome-dotnet-cn (注:下面用 ...

  4. Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)

    下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITableVie ...

  5. GitHub上史上最全的Android开源项目分类汇总 (转)

    GitHub上史上最全的Android开源项目分类汇总 标签: github android 开源 | 发表时间:2014-11-23 23:00 | 作者:u013149325 分享到: 出处:ht ...

  6. iOS及Mac开源项目和学习资料【超级全面】

    UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITable ...

  7. iOS开发--iOS及Mac开源项目和学习资料

    文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...

  8. iOS、mac开源项目及库汇总

    原文地址:http://blog.csdn.net/qq_26359763/article/details/51076499    iOS每日一记------------之 中级完美大整理 iOS.m ...

  9. iOS、mac开源项目及库(感谢原作者的分享)

    目录 模糊效果 富文本 表相关 HUD与Toast 其他UI 其他动画 网络测试 网络聊天 Model 数据库 PDF 摄像照相视频音频处理 消息相关 消息推送服务器端 版本新API的Demo 测试及 ...

随机推荐

  1. 第二节:EF Core的常规“增删改”及状态的变化

    一. 整体说明 1. 本节用到的表 2. 状态说明补充 ①.Detached: 游离的状态,与数据库没有什么交涉,比如新new一个实体,状态就是Detached. ②.Added: 增加的状态. ③. ...

  2. Java | Spring Boot Swagger2 集成REST ful API 生成接口文档

      Spring Boot Swagger2 集成REST ful API 生成接口文档 原文 简介 由于Spring Boot 的特性,用来开发 REST ful 变得非常容易,并且结合 Swagg ...

  3. ES7.3.0配置邮件告警

    情况说明: 三台es组成集群,一台kibana,版本均为7.3.0 es版本要求是白金版,基础版的不行,不过可以试用30天的白金版 步骤:先说我自己走通的流程,然后介绍官方说明 1.因为我这边使用的是 ...

  4. Scala 系列(十一)—— 模式匹配

    一.模式匹配 Scala 支持模式匹配机制,可以代替 swith 语句.执行类型检查.以及支持析构表达式等. 1.1 更好的swith Scala 不支持 swith,可以使用模式匹配 match.. ...

  5. 如何在ASP.NET Core Web API中使用Mini Profiler

    原文如何在ASP.NET Core Web API中使用Mini Profiler 由Anuraj发表于2019年11月25日星期一阅读时间:1分钟 ASPNETCoreMiniProfiler 这篇 ...

  6. jq动画插件,自制基于vue的圆形时钟

    首先附上jq插件库,里面的东西太炫了,建议学前端的可以看看学习下:http://www.jq22.com/ 里面有个“超个性动画版本的个人简历”,通过屏幕上不断打印内容,改变相应样式来实现动画简历,我 ...

  7. rsync 排除指定目录

    背景 将Server1上的数据同步到Server2: Server1目录结构: /us_data/yahoo └── qlib ├── calendars ├── dataset_cache ├── ...

  8. react 使用的小建议

    使用pureRender,setState和Immutable.js来操作state Immutable 中文意思不可变. 不能直接修改state的值,要用setState 和Immutable re ...

  9. kbmmw 中的Boyer-Moore算法

    kbmmw 5.10 版本中实现了一个非常好用的字符串搜索算法,即Boyer-Moore算法. 在用于查找子字符串的算法当中,BM(Boyer-Moore)算法是目前被认为最高效的字符串搜索算法, 它 ...

  10. postgresql源代码结构

    转载学习: 德哥培训! 源码下载: https://www.postgresql.org/ftp/source/ 1.postgressql源码目录结构 2.src目录结构