OpenCV-C++实现单应性矩阵的求解

15 篇文章 1 订阅

1. 单应性矩阵的理解

1.1 图像层面

        单应性矩阵H(Homography)约束了同一3D空间点在两个像素平面的2D齐次坐标。

\left[ \begin{matrix} {u_{a}} \\ {v_{a}} \\ w \\\end{matrix} \right]=\left[ \begin{matrix} {H_{1}} & {H_{2}} & {H_{3}} \\ {H_{4}} & {H_{5}} & {H_{6}} \\ {H_{7}} & {H_{8}} & {H_{9}} \\\end{matrix} \right]\left[ \begin{matrix}{u_{b}} \\{v_{b}} \\ 1 \\ \end{matrix} \right]\displaystyle

        单应性矩阵H具有8个自由度,已知A和B两张图像上的四对点,即可列出八个方程来求解出单应性矩阵H

1.2 三维层面

        单应性矩阵H(Homography)可以理解为描述物体在世界坐标系和像素坐标系之间的位置映射关系。 

https://img-blog.csdn.net/20131204205302359

        以棋盘格相对位姿估计为例,世界坐标系定在棋盘格上,即z=0。因此世界坐标系和像素坐标系之间的关系如下:

\left[ \begin{matrix} u \\ v \\ 1 \\\end{matrix} \right]=sK\left[ \begin{matrix} R & T \\ \end{matrix} \right]\left[ \begin{matrix} x \\ y \\ z \\ 1 \\\end{matrix} \right]=sK\left[ \begin{matrix} {r_{1}} & {r_{2}} & {r_{3}} & T \\\end{matrix} \right]\left[ \begin{matrix} x \\ y \\ 0 \\ 1 \\\end{matrix} \right]=sK\left[ \begin{matrix} {r_{1}} & {r_{2}} & T \\\end{matrix} \right]\left[ \begin{matrix} x \\ y \\ 1 \\\end{matrix} \right]

        因此,H=sK\left[ \begin{matrix} {r_{1}} & {r_{2}} & T \\\end{matrix} \right]即为成像平面与标定板平面之间的单应性矩阵。其中,K为相机内参矩阵,s是任意尺度的比例(目的是使得单应性定义到该尺度比例)。

2. 单应性矩阵的自由度及求解思路

        首先抛出结论:单应性矩阵具有8个自由度,需要4对点求解。

        首先,我们假设两张图像中的对应点对齐次坐标为(x',y',1)和(x,y,1),则有:

\left[ \begin{matrix} {x'} \\ {y'} \\ 1 \\\end{matrix} \right]=\left[ \begin{matrix} {h_{11}} & {h_{12}} & {h_{13}} \\ {h_{21}} & {h_{22}} & {h_{23}} \\ {h_{31}} & {h_{32}} & {h_{33}} \\\end{matrix} \right]\left[ \begin{matrix} x \\ y \\ 1 \\\end{matrix} \right]

        矩阵展开后有3个等式,将第3个等式代入前两个等式中可得:

{x}'=\frac{​{​{h}_{11}}x+{​{h}_{12}}y+{​{h}_{13}}}{​{​{h}_{31}}x+{​{h}_{32}}y+{​{h}_{33}}}

{y}'=\frac{​{​{h}_{21}}x+{​{h}_{22}}y+{​{h}_{23}}}{​{​{h}_{31}}x+{​{h}_{32}}y+{​{h}_{33}}}

        也就是说,一个点对对应两个等式。

        由于这里使用的是齐次坐标系,也就是说可以进行任意尺度的缩放。比如我们把{h_{ij}}乘以任意一个非零常数k并不改变等式结果,所以实际上单应矩阵\mathbf{\mathit{H}}只有8个自由度。8自由度下H计算过程有两种方法。

第一种方法:直接设置{h_{33}}=1

第二种方法:将H添加约束条件,将H矩阵模变为1 

        接下来由四个对应点的像素列出8个方程,根据最优化的方法(此处略)可以求解出结果。

3. 求解单应性矩阵及对图像进行单应性变换的方法

3.1 获得输入与输出图像

        首先随意拍摄一张图片(3072×4096),命名为src.jpg:

src.jpg

        目的是要将书本校正,因此先使用图像处理软件(如全能扫描王,华为自带相册等)获得校正后的图像(2070×2500),命名为dst.jpg:

dst.jpg

3.2 四对点像素坐标的获取

        使用Photoshop已经预先获取了src.jpg中书本四个角对应的像素点:

左上:(889,1032)

右上:(2471,1079)

左下:(276,2868)

右下:(2829,2979)

注意:x轴方向是水平向右,y轴方向是水平向下,坐标原点是图像左上角第一个像素点。

        另外,也可使用图像分隔等方法检测目标物体的四个特征点。由于不是本篇文章的重点,这里不作详细说明。

        dst.jpg中四个角对应的像素点即图像四个角的像素坐标:

左上:(0,0)

右上:(2069,0)

左下:(0,2499)

右下:(2069,2499)

3.3 C++实现

        主要函数:findHomography与warpPerspective

        C++实现代码如下:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

Mat myResize(Mat &srcImag, double width_ratio, double height_ratio);

int main()
{
	Mat im_src,im_dst,im_out,H;
	im_src=imread("../src.jpg");
	im_dst=imread("../dst.jpg");
	Size size=im_dst.size();
	//根据源图片和目标图片相对于的四对点(左上,右上,左下,右下)来计算单应性矩阵
	vector<Point2f> pts_src{Point2f(889,1032),Point2f(2471,1079),Point2f(276,2868),Point2f(2829,2979)};
	vector<Point2f> pts_dst{Point2f(0,0),Point2f(2069,0),Point2f(0,2499),Point2f(2069,2499)};
	//计算单应性矩阵H
	H = findHomography(pts_src,pts_dst);
	cout<< H << endl;
	//根据计算出来的单应性矩阵H,对图像进行透视变换
	warpPerspective(im_src, im_out, H, size);
	//将输出图片按0.3的比例缩小
	im_out=myResize(im_out, 0.3, 0.3);
	imshow("result", im_out);
	
	waitKey();
	destroyAllWindows();
	return 0;
}

//调整图片大小
Mat myResize(Mat &srcImag, double width_ratio, double height_ratio)
{
	Mat src=srcImag;
	float scaleW = width_ratio;
    float scaleH = height_ratio;
    int width = int(src.cols * scaleW);
    int height = int(src.rows * scaleH);
	resize(src, src, Size(width, height));
	return src;
}

3.4 结果展示 

        计算出的单应性矩阵如下:

        对src.jpg进行单应性变换的结果如下:

im_out

        结果与dst.jpg基本一致,由此证明过程无误。

  • 2
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Quentin_HIT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值