参考教程 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. Springboot Actuator之十一:actuator PublicMetrics

    前言接下来的几篇文章我们来分析一下spring-boot-actuator 中在org.springframework.boot.actuate.metrics中的代码,如图: 这里的代码不仅多,而且 ...

  2. jboss/wildfly安全域的密码加密和解密

    加密: java_path=$(source /opt/wildfly/bin/.Beta1.jar:/opt/wildfly/modules/system/layers/base/org/jboss ...

  3. 揭秘丨7分钟看懂华为云鲲鹏Redis背后的自研技术【华为云技术分享】

    2019年5月,华为云发布全球首个基于自研ARM架构的分布式缓存鲲鹏Redis,搭载华为LibOS+华为编译器+安全容器引擎三项黑科技,在保证Redis强劲高性能外,还降低客户30%的使用成本,真正实 ...

  4. java中System.err.print和System.out.print区别

    System.err.print    是报错专用输输出,有颜色标记,所有err打印的都在顶行输出 System.out.print   是标准输出,白底黑字 package iobuffer; pu ...

  5. C# 练习题 利用条件运算符的嵌套来完成分数等级划分

    题目:利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示.1.程序分析:(a>b)?a:b这是条件运算符的基本例子. cla ...

  6. C#读写设置修改调整UVC摄像头画面-对比度

    有时,我们需要在C#代码中对摄像头的对比度进行读和写,并立即生效.如何实现呢? 建立基于SharpCamera的项目 首先,请根据之前的一篇博文 点击这里 中的说明,建立基于SharpCamera的摄 ...

  7. Java自学-类和对象 this

    Java 中的 this this 这个关键字,相当于普通话里的"我" 小明说 "我吃了" 这个时候,"我" 代表小明 小红说 " ...

  8. Java自学-面向对象 类和对象

    Java中的类和对象 引入面向对象的基本概念 假设,我们要设计一个LOL这样的游戏,使用面向对象的思想来设计,应该怎么做? 步骤 1 : 设计英雄这个类 LOL有很多英雄,比如盲僧,团战可以输,提莫必 ...

  9. npm换源成淘宝镜像

    由于node下载第三方依赖包是从国外服务器下载,虽然没有被墙,但是下载的速度是非常的缓慢且有可能会出现异常. 所以为了提高效率,我们还是把npm的镜像源替换成淘宝的镜像源.有几种方式供我们选择 使用c ...

  10. Java 之 异常基础

    一.异常概念 异常:指的是程序在执行过程中,出现的非正常的情况,最终会导致 JVM 的非正常停止. 在 Java 等面向对象的编程语言中,异常本身就是一个类,产生异常就是创建异常对象并抛出了一个异常对 ...