开源项目(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 测试及 ...
随机推荐
- .NET下使用HTTP请求的正确姿势
来源:Lewis.Zou cnblogs.com/modestmt/p/7724821.html 一.前言 去年9月份的时候我看到过外国朋友关于.NET Framework下HttpClient缺陷的 ...
- FusionInsight大数据开发---Spark应用开发
Spark应用开发 要求: 了解Spark基本原理 搭建Spark开发环境 开发Spark应用程序 调试运行Spark应用程序 YARN资源调度,可以和Hadoop集群无缝对接 Spark适用场景大多 ...
- excel查找定位操作(for lutai)
产成品出库的单价要根据订单号和存货编码引用产成品入库的单价 方法一:使用Index 和Match =INDEX(产成品入库!I2:P13 ,IF( ) ,7) 方法二:使用vlookup ,首先 ...
- springmvc集成shiro后,session、request是否发生变化
1. 疑问 我们在项目中使用了spring mvc作为MVC框架,shiro作为权限控制框架,在使用过程中慢慢地产生了下面几个疑惑,本篇文章将会带着疑问慢慢地解析shiro源码,从而解开心里面的那点小 ...
- LP线性规划求解 之 单纯形 算法
LP线性规划求解 之 单纯形 算法 认识-单纯形 核心: 顶点旋转 随机找到一个初始的基本可行解 不断沿着可行域旋转(pivot) 重复2,直到结果不能改进为止 案例-过程 以上篇的case2的松弛型 ...
- NumPy 之 面向数组编程
import numpy as np Using NumPy arrays enables you to express many kinds of data processing tasks as ...
- mongodb 通过嵌入文档中的字段排序
mongodb中的全部数据: db.testInfo.find({}) .sort({_id:-1}) .limit(100) 查询结果: /* 1 createdAt:2019/10/11 下午5: ...
- python的with语法的深入理解
如果你有一些对象(比如一个文件.网络连接或锁),需要支持 with 语句,下面介绍两种定义方法. 方法(1): 首先介绍下with 工作原理 (1)紧跟with后面的语句被求值后,返回对象的“__en ...
- Prometheus(五):Prometheus+Alertmanager 配置企业微信报警
此处默认已安装Prometheus服务,服务地址:192.168.56.200 一.设置企业微信 1.1.企业微信注册(已有企业微信账号请跳过) 企业微信注册地址:https://work.weix ...
- linux设备驱动程序--gpio控制
gpio驱动程序 上一章节linux设备驱动程序--创建设备节点章节主要介绍了linux字符设备驱动程序的框架,从这一章节开始我们讲解各种外设的控制,包括gpio,i2c,dma等等,既然是外设,那就 ...