赞
踩
目录
现在我们有不同角度照的两张图
我们最后要拼成这个样子
在拼接过程中会有部分信息缺失,比如右下角的花,如果我们使用两张宽与高本就相同的图片效果会好一些,我们的手机中拍摄长图与文章中的方法类似
项目中一共有两个代码,一个为主代码ImageStiching,另一个为调用代码Stitcher
首先导入Sticher文件中的Stithcer类,然后导入cv2,之后读取两张图片
由于我两张图片的尺寸不一样,我们在这里要修改一下尺寸,最后使两张图片等宽,等高
实例化Sticher,然后使用stitcher的stitch方法
最终将结果展示出来
首先导入库,然后定义类,之后向类中添加函数,一共有五个函数
显示函数,测试时方便就在这先定义了
我们下面按照运行的流程走一遍
这个是主函数的接口,我们从这开始看,我们先看参数
之后我们读入图像
对应主函数的
我们可以发现这里实际上是吧这两张图的变量名称交换了,下面我们的imageA是右侧的图,我们下面对右侧图进行变化,左侧图不变
之后我们使用了定义的detectAndDescribe()方法
参数为image,我们上面依次放入了imageA与imageB,导入后我们对图像进行灰度处理
然后我们使用SIFT算法
此时我们获得了关键点与特征,特征就是每个点对应的向量前面的SIFT课程中有提到
然后我们将关键点转换为float32的形式,之后返回关键点与特征这个元组
我们现在对应下面这个图来看,kspA是right图的关键点,kpsB是left这张图的关键点
此时我们回到主函数发现调用了matchKeyPoints()这个方法,输入的参数有刚刚获取的两个图的关键点与特征,还有匹配置信率ratio与RANSAC的拒绝阈值
首先我们创建蛮力匹配器,然后进行蛮力匹配
然后我们创建空列表matches用于存放置信高的匹配内容
之后我们进行筛选,我们对所有的匹配进行遍历,两个判定条件
筛选过后我们这次并不是直接添加m的所有内容,而是只添加匹配的关键点索引
也就是说上面这个图中左边的是queryIdx,右边的是trainIdx,但是我们在最开始读图像的时候是交换了图像的左右位置的,也就是说此时的queryIdx是实际上right这个图的关键点,trainIdx是left这个图的关键点
trainIdx与queryIdx都是整形数据,我们打印出来看一下
由于是遍历所有的匹配,会出现很多组结果,我们在这只显示一组的结果
之后我们进入下一组判定,如果我们的匹配数量大于4,那么可以继续运行否则就return None,return None就代表左右这两张图片不像,所以就不用完成拼接了
4这个值是在 14.特征匹配 提到的单应性矩阵,这个单应性矩阵需要四组匹配才能进行计算
在处理下面之前我们先整理一下
所以kpsA对应queryIdx(也就是matches的1号元素),kpsB对应trainIdx(也就是matches的0号元素)
如果判定大于4我们可以继续进行,首先我们提取出关键点,这个时候我们使用到了上面提出来的索引,元组内的1号元素是左侧图像的索引,我们提取出来
然后将点转换为np.float32格式
ptsB同理,提取的右侧图像的关键点
之后使用我们的单应性矩阵,我们通过单应性矩阵对右侧的图进行变化
findHomograhy的参数为
返回值有两个左边的矩阵为H,右边的矩阵为status,status表示关键点是否匹配的状态,有0与1两个值
我们看一下H与states
states有很多个值,我们只截取了头部与尾部的部分,它表示我们关键点是否匹配的状态,如果是1则代表两个关键点匹配上了,如果是0则代表关键点没有匹配上
返回匹配与H,status两个矩阵的元组
此时再回到我们的stitch()
如果刚刚进行的matchKeyPoints返回值为None则不能进行拼接
把元组M的三个元素提取出来
warpPerspective是下面这样图的操作,我们在 11.提取图像内容区域 中介绍过,参数为原图像的尺寸,变化矩阵,变换后图像的尺寸
现在的result是我们变换后的结果,我们看一下
之后我们把imageB(left图像)贴到result的左侧,我们看一下结果
现在两张图片已经贴合上了,但是图像的上侧我们发现有部分黑边,这个时候我们要给它裁掉,这也表示了两张图拼接会有部分的信息损失
裁掉了5个像素点,这个根据图片的实际情况来,有的可能不需要裁,裁掉之后我们合成的图像是这样的
现在回到我们的stitcher,我们走到了这里,如果上面的showMatches使用False则直接返回result,如果为True则执行drawMatches()
这个函数的作用是画出匹配,我们先看一下画出匹配的结果
然后我们分析一下,这个参数的参数是imageA(right图),imageB(left图),kspA(right图的关键点),kspB(left图的关键点),matches(两图的匹配),status(关键点匹配状态)
之后我们进入函数,首先我们分别获取两张图像的宽与高
然后我们创造一张空白的图像vis,高为两图的最高值,宽为两图的和,通道为3
然后把图像的左侧放为imageA,右侧放为imageB
然后我们对matches和status打个包,matches中提取trainIdx与queryIdx元素,status就提取器本身的元素
如果能匹配上,则获取两图相应的横纵坐标,queryIdx是right这个图的关键点,所以在kpsA中寻找,int(kpsA[queryIdx][0]是横坐标,int(kpsA[queryIdx][1])是纵坐标,下面那一行同理
点坐标获取完毕后我们使用line()在vis这张图像上把两组点连接上,使用颜色为(0,255,0),线宽为1,然后返回vis
以上就是图像拼接的全部过程
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。