计算机视觉探索之路(二)——图像拼接

一、基本原理

1.特征点匹配(基于特征)

(1)什么样的点是特征点

那些最容易识别的像素点(角点),比如纹理丰富的物体边缘点等。

1)opencv棋盘格角点检测原理总结

findCHESSBOARDcorners 是opencv提供的一种找棋盘格角点的方法,可用来参考

由此我设想,带有棋盘格的图像有没有可能更容易拼接

(2)检测特征点

1)定位

标识图像上在图像转换(例如平移(移位),缩放(大小增加/减小)和旋转)下稳定的点。定位器找到这些点的x,y坐标。ORB检测器使用的定位器称为FAST

2)描述

该描述符对点的外观进行编码,以便我们可以区分一个特征点。在特征点评估的描述符只是一个数字数组。理想情况下,两个图像中的相同物理点应具有相同的描述符。ORB使用功能描述符的修改版本,称为BRISK。

例如,为实现人脸识别系统,我们首先需要一个人脸检测器,该检测器输出一个人脸所在的矩形的坐标。检测器不知道或不在乎该人是谁。它唯一的工作就是找到一张脸。系统的第二部分是识别算法。原始图像被裁剪为检测到的脸部矩形,并将此裁剪后的图像馈送到最终识别人的脸部识别算法。特征检测器的定位器的作用类似于面部检测器。它定位有趣的点,但不处理该点的身份。描述符描述了点周围的区域,因此可以在其他图像中再次对其进行识别。

仅当我们知道两个图像中的相应特征时,才能计算出两个图像的单应性。因此,使用匹配算法来查找一个图像中的哪些特征与另一图像中的特征匹配。为此,将一个图像中每个特征的描述符与第二个图像中每个特征的描述符进行比较,以找到良好的匹配。

(3)如何匹配到一起

单应性

在这里插入图片描述
观察着三张图的封面中反光,3由1通过单应性变换而来,通过12算单应性,再用单应性把1转化成3

描述子

对于检测出的角点,用一些数学上的特征对其进行描述,如梯度直方图,局部随机二值特征等。检测子和描述子的常用提取方法有:

sift,harris,surf(基于sift改进,速度约是sift3倍),fast,agast,brisk,freak,brisk,brief/orb 等。

surf
取一幅图像中的一个SIFT关键点,并找出其与另一幅图像中欧式距离最近的前两个关键点,在这两个关键点中,如果最近的距离除以次近的距离得到的比率ratio少于某个阈值T,则接受这一对匹配点。
ratio=0. 4:对于准确度要求高的匹配;
ratio=0. 6:对于匹配点数目要求比较多的匹配;
ratio=0. 5:一般情况下
SURF


ORB
OrB

匹配

通过各个角点的描述子来判断它们在两张图像中的对应关系

surf
SURF
OrB
ORB

ORB速度明显快于SURF,但是提取的特征点也远少于SURF,图像特征是图像拼接质量的关键,在进行图像拼接时,需要在速度与质量之间进行取舍。
在这里插入图片描述
对比三幅渐入渐出融合的效果图,其羽化锐度只是一个加权系数,对融合速度并不会造成影响。对两幅原始图像中进行实验,三个羽化锐度参数所对应的融合速度在0.33S~0.36S之间,而其融合效果相差十分明显,羽化锐度越大,线性加权平均效果越好,拼接缝越不明显,图像重合区域的过度看起来更加的自然。实际运用中,通过改变加权系数,找到合适的值,来调整图像重叠区域的平滑过渡,使重叠区域看起来更加自然

3)如何消除一些错误的匹配

消噪:去除错误匹配的外点,保留正确的匹配点。常用方法有KDTREE,BBF,Ransac,GTM等。

2.拼接(图像拼接)

单应性

平移(MOTION_TRANSLATION):可以将第一张图像移位(平移) (x,y)以获得第二张图像。我们仅需要估计两个参数x和y。
欧几里得(MOTION_EUCLIDEAN):第一个图像是第二个图像的旋转和移位版本。因此,存在三个参数-x,y和angle。您会在图4中注意到,当正方形进行欧几里德变换时,大小不变,平行线保持平行,变换后直角保持不变。
仿射(MOTION_AFFINE):仿射变换是旋转,平移(shift),缩放和剪切的组合。该变换具有六个参数。当正方形进行仿射变换时,平行线保持平行,但以直角相交的线不再保持正交。
单应性(MOTION_HOMOGRAPHY):上述所有变换都是2D变换。它们不考虑3D效果。另一方面,单应变换可以解决一些3D效果(但不是全部)。此转换有8个参数。使用同形法转换后的正方形可以更改为任何四边形。
opencv提供的stitch拼接

opencv提供的stitch拼接

#include <iostream>
#include <fstream>
 #include <opencv2/core/core.hpp>
 #include "opencv2/highgui/highgui.hpp"
 #include "opencv2/stitching.hpp"
 #include<Windows.h>

 using namespace std;
 using namespace cv;

 bool try_use_gpu = false;
 vector<Mat> imgs;
string result_name = "result.jpg";

 int main()
 {
	     Mat img1 = imread("images\\L_8.jpg");
	     Mat img2 = imread("images\\L_9.jpg");
		// Mat img3 = imread("images\\18.jpg");
	     imgs.push_back(img1);
	     imgs.push_back(img2);
		// imgs.push_back(img3);
	     Mat pano;
	     Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
	     Stitcher::Status status = stitcher.stitch(imgs, pano);
	     if (status != Stitcher::OK)
		     {
		         cout << "Can't stitch images, error code = " << status << endl;
		         return -1;
		     }
	     namedWindow(result_name);
	     imshow(result_name, pano);
	     imwrite(result_name, pano);
	     waitKey();
	     return 0;
	 }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
理论上,维图像只有行与列两个维度。然而当我们将多张图像拼接在一起时,就可以将它们表示为三维图像,其中第三个维度表示图像的数量。 MATLAB提供了多种方式来将图像拼接成三维,最常见的方法是使用cat、permute和reshape函数。具体来说,使用cat函数可以将多张维图像按照指定的维度拼接在一起,例如将三张RGB图像拼接成一个3D数组: ``` im1 = imread('image1.jpg'); im2 = imread('image2.jpg'); im3 = imread('image3.jpg'); im_array = cat(4,im1,im2,im3); ``` 上述代码中,将im1、im2和im3分别代表的三张RGB图像按照第4个维度拼接在一起,得到一个4D数组im_array。 使用permute函数可以改变矩阵的维度,例如将维图像升维成三维: ``` im = imread('image.jpg'); im_array = permute(im,[1 2 3]); ``` 上述代码中,将im的行、列和通道分别对应的维度为1、2和3,然后使用permute函数将这三个维度改变成1、2和3,得到一个三维图像im_array。 使用reshape函数可以将图像数组的维度改变为指定的形状,例如将一个$n\times m\times k$的三维数组重塑成$nk\times m$的维数组: ``` im_array = rand([100 100 3]); % 生成一个100x100x3的随机数组 im_reshaped = reshape(im_array,[300 100]); ``` 上述代码中,将一个$100\times 100\times 3$的随机数组重塑为$300\times 100$的维数组im_reshaped。 总之,MATLAB提供了多种方式来在维图像上添加第三个维度,进而将多幅图像拼接成三维的图像数组。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值