Homography 笔记(附 OpenCV 代码)

27 篇文章 0 订阅
本文介绍了Homography的概念,它是用于同一平面上图像对齐的3x3变换矩阵。通过 Homography,可以将一张图像上的点映射到另一张图像上对应点,实现图像对齐和全景拼接。文章还展示了如何使用OpenCV计算和应用Homography,包括在虚拟广告牌场景中的应用示例。
摘要由CSDN通过智能技术生成


翻译自 https://www.learnopencv.com/homography-examples-using-opencv-python-c/ 。
依个人口味略作修改,侵权删。

据圣经神话的记载,巴别塔(The Tower of Babel)是人类的第一个工程灾难。这个项目具备了所有的条件,但是仍然失败了。因为上帝混淆了人类的语言,从而使得他们无法再有效的沟通协作,进而导致了通天塔的崩溃和人类的混乱。

在我看来,像 Homography 这样的术语在时刻提醒我们,我们仍在为语言构成的沟通鸿沟而挣扎。Homography 就是一个很简单的概念却起了一个很唬人的名字。

什么是 Homography?

考虑 同一个平面(比如书皮)的两张图片,红点表示同一个物理坐标点在两张图片上的各自位置。在 CV 术语中,我们称之为对应点。

Corresponding points

Homography 就是将一张图像上的点映射到另一张图像上对应点的3x3变换矩阵.
A Homography is a transformation ( a 3×3 matrix ) that maps the points in one image to the corresponding points in the other image.

因为 Homography 是一个 3x3 的 矩阵,所以我们可以把它写成

Homography

对于图中的一对儿对应点,位于图一的 (x1, y1) 和 位于图二的 (x2, y2). H 把二者映射关系建立起来

H

使用 Homography 进行图像对齐(Image Alignment)

对于所有的对应点,只要它们都位于同一个物理平面上,上述 Homography 就是成立的。换句话说,就是可以把图一中书皮上的所有点都映射到图二的书皮上,也就是看起来,图一中的书皮和图二中的书皮对齐了!如下图:

Image Alignment

那么对于不在此平面上的点呢?这时再应用 Homography 就无法再对齐到对应点了。比如 上图中的 桌面,地面,橱柜面。对于这种图像中有多个平面的情况,我们就需要针对每一个平面使用其对应的Homography了。

全景拼接:Homography 的一个重要应用

在前面的例子中,我们知道,如果已知 两个图像的 Homography,那么我们可以把一张图像 warp 到 另外一张图像内去。但是,这里有一个很严重的bug:两张图像必须包含同一个平面,并且仅有这个平面上的点是准确对齐的。事实上,可以证明,如果你用相机拍摄一张任意风景的照片(不仅仅是一个平面)然后旋转相机再任意拍摄一张,这两张照片可以用一个 Homography 联系起来! 刚才拍摄的两张任意3D场景的图片可以用 Homography 联系起来,而两张图像会有一些共同的区域,这些区域又可以用来对齐和拼接,bingo,这样你就可以得到这两张图像的全景拼接图了。当然,这还是很粗糙的全景拼接,还需要很多精细的细节操作,但是基本原理是这样的,用Homography 把共同的部分对齐,然后巧妙的拼接,从而看不到拼缝。全景拼接,大功告成。

如何计算 Homography?

对于 H 矩阵,一般设 H22 为 1, 所以 H 有 8 个未知参数。至少需要8 个等式才能求解。而一组对应点可以提供 2 个等式,所以,至少需要 4 组对应点(任意三点不共线)来求得 H。 如果有更多组对应点,效果更佳。 OpenCV 可以鲁棒地计算出一个最好地拟合所有对应点的 Homography。通常,图像间的这些对应点通过 SIFT 或者 SURF 这样算法进行自动特征提取和匹配。当然,对于简单的demo,手动选取对应点就足够了。

OpenCV C++

//pts_src : 源图像点坐标
//pts_dst : 结果图像坐标
// 数据类型都是 vector<Point2f>.
// 需要至少4组对应点.
Mat h = findHomography(pts_src, pts_dst);

//im_src : 源图像
// im_dst : 结果图像
// h: 上一步计算得到的 Homography
// size : im_dst 的 大小(宽度,高度)
// 将 im_src 通过 h warp 到 im_dst 上去
warpPerspective(im_src, im_dst, h, size);

// warp points, not full image
vector<Point2f> dstPoints, srcPoints;
srcPoints.push_back(Point2f(1,1));
cv::perspectiveTransform(srcPoints,dstPoints,warpMatrix);

下面是一个例子

#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 应用

虚拟广告牌

在很多直播体育赛事中,广告是动态插入到直播视频流中去的,从而根据观众的个人喜好,地域习俗等展示个性化的广告。

以下是第一张上传到互联网的图片

[外链图片转存失败(img-A1fUf1PJ-1568973089922)(https://www.learnopencv.com/wp-content/uploads/2016/01/first-image.jpg)]

下图是 时代广场的 图片

[外链图片转存失败(img-Hgmsqxvc-1568973089922)(https://www.learnopencv.com/wp-content/uploads/2016/01/times-square-768x512.jpg)]

好了,我们想把 第一张图嵌入到 时代广场的 广告屏上去,4 步搞定

  1. 选择时代广场上广告屏的 4 个顶点,作为 pts_dst
  2. 选取欲嵌入的图像的 4 个顶点,假设图像尺寸 W x H, 那么 四个顶点就是 (0,0), (0, W-1), (H - 1, 0), (H - 1, W - 1)
  3. 使用 pts_dst 和 pts_src 计算 Homography
  4. 对 源图像应用计算得到的 Homography 从而 混合到 目标图像上。得到下图

[外链图片转存失败(img-av2EKXBw-1568973089922)(https://www.learnopencv.com/wp-content/uploads/2016/01/virtual-billboard-768x512.jpg)]

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值