单应性变换(Homography)的学习与理解

1,单应性矩阵、本质矩阵

内容源于:

Homography Examples using OpenCV ( Python / C ++ )

What is Homography ?

Consider two images of a plane (top of the book) shown in Figure 1. The red dot represents the same physical point in the two images. In computer vision jargon we call these corresponding points. Figure 1. shows four corresponding points in four different colors — red, green, yellow and orange. 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 exampleFigure 1 : Two images of a 3D plane ( top of the book ) are related by a Homography

Now since a homography is a 3×3 matrix we can write it as

  \[ H = \left[ \begin{array}{ccc} h_{00} & h_{01} & h_{02} \\ h_{10} & h_{11} & h_{12} \\ h_{20} & h_{21} & h_{22} \end{array} \right] \]

Let us consider the first set of corresponding points — (x_1,y_1) in the first image and (x_2,y_2)} in the second image. Then, the Homography H maps them in the following way

  \[ \left[ \begin{array}{c} x_1 \\ y_1 \\ 1 \end{array} \right] &= H \left[ \begin{array}{c} x_2 \\ y_2 \\ 1 \end{array} \right] &= \left[ \begin{array}{ccc} h_{00} & h_{01} & h_{02} \\ h_{10} & h_{11} & h_{12} \\ h_{20} & h_{21} & h_{22} \end{array} \right] \left[ \begin{array}{c} x_2 \\ y_2 \\ 1 \end{array} \right] \]

Image Alignment Using Homography

The above equation is true for ALL sets of corresponding points as long as they lie on the same plane in the real world. In other words you can apply the homography to the first image and the book in the first image will get aligned with the book in the second image! See Figure 2.

Image Alignment using HomographyFigure 2 : One image of a 3D plane can be aligned with another image of the same plane using Homography

But what about points that are not on the plane ? Well, they will NOT be aligned by a homography as you can see in Figure 2. But wait, what if there are two planes in the image ? Well, then you have two homographies — one for each plane.

Panorama : An Application of Homography

In the previous section, we learned that if a homography between two images is known, we can warp one image onto the other. However, there was one big caveat. The images had to contain a plane ( the top of a book ), and only the planar part was aligned properly. It turns out that if you take a picture of any scene ( not just a plane ) and then take a second picture by rotating the camera, the two images are related by a homography! In other words you can mount your camera on a tripod and take a picture. Next, pan it about the vertical axis and take another picture. The two images you just took of a completely arbitrary 3D scene are related by a homography. The two images will share some common regions that can be aligned and stitched and bingo you have a panorama of two images. Is it really that easy ? Nope! (sorry to disappoint) A lot more goes into creating a good panorama, but the basic principle is to align using a homography and stitch intelligently so that you do not see the seams. Creating panoramas will definitely be part of a future post.

How to calculate a Homography ?

To calculate a homography between two images, you need to know at least 4 point correspondences between the two images. If you have more than 4 corresponding points, it is even better. OpenCV will robustly estimate a homography that best fits all corresponding points. Usually, these point correspondences are found automatically by matching features like SIFT or SURF between the images, but in this post we are simply going to click the points by hand.

Let’s look at the usage first.

C++

1
2
3
4
5
6
7
8
9
10
// pts_src and pts_dst are vectors of points in source
// and destination images. They are of type vector<Point2f>.
// We need at least 4 corresponding points.
 
Mat h = findHomography(pts_src, pts_dst);
 
// The calculated homography can be used to warp
// the source image to destination. im_src and im_dst are
// of type Mat. Size is the size (width,height) of im_dst.
warpPerspective(im_src, im_dst, h, size);

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'''
pts_src and pts_dst are numpy arrays of points
in source and destination images. We need at least
4 corresponding points.
'''
h, status = cv2.findHomography(pts_src, pts_dst)
 
'''
The calculated homography can be used to warp
the source image to destination. Size is the
size (width,height) of im_dst
'''
 
im_dst = cv2.warpPerspective(im_src, h, size)

Let us look at a more complete example in both C++ and Python.

OpenCV C++ Homography Example

Images in Figure 2. can be generated using the following C++ code. The code below shows how to take four corresponding points in two images and warp image onto the other.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#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);
}

OpenCV Python Homography Example

Images in Figure 2. can also be generated using the following Python code. The code below shows how to take four corresponding points in two images and warp image onto the other.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/env python
 
import cv2
import numpy as np
 
if __name__ = = '__main__' :
 
     # Read source image.
     im_src = cv2.imread( 'book2.jpg' )
     # Four corners of the book in source image
     pts_src = np.array([[ 141 , 131 ], [ 480 , 159 ], [ 493 , 630 ],[ 64 , 601 ]])
 
 
     # Read destination image.
     im_dst = cv2.imread( 'book1.jpg' )
     # Four corners of the book in destination image.
     pts_dst = np.array([[ 318 , 256 ],[ 534 , 372 ],[ 316 , 670 ],[ 73 , 473 ]])
 
     # Calculate Homography
     h, status = cv2.findHomography(pts_src, pts_dst)
     
     # Warp source image to destination based on homography
     im_out = cv2.warpPerspective(im_src, h, (im_dst.shape[ 1 ],im_dst.shape[ 0 ]))
     
     # Display images
     cv2.imshow( "Source Image" , im_src)
     cv2.imshow( "Destination Image" , im_dst)
     cv2.imshow( "Warped Source Image" , im_out)
 
     cv2.waitKey( 0 )
  • 7
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值