-
2021-04-27 03:04:05
多幅图像拼接matlab实现拼接
matlab
2020-10-25
下载地址
https://www.codedown123.com/45723.html
多幅图像拼接matlab实现 sift特征提取、描述、匹配、RANSAC、仿射变换
资源下载此资源下载价格为2D币,请先登录
资源文件列表
PA1/.DS_Store , 12292
PA1/alternate template for LaTeX users/cvpr.sty , 8435
PA1/alternate template for LaTeX users/yourSUNetID_PA1.tex , 10285
PA1/checkpoint/Affine_ref.mat , 207
PA1/checkpoint/Match_input.mat , 987133
PA1/checkpoint/Match_ref.mat , 255
PA1/checkpoint/SIFT_ref.mat , 76813
PA1/ComputeAffineMatrix.m , 2387
PA1/data/campus_000.jpg , 64410
PA1/data/campus_001.jpg , 52963
PA1/data/campus_002.jpg , 36253
PA1/data/campus_003.jpg , 39294
PA1/data/campus_004.jpg , 57098
PA1/data/pine1.jpg , 108679
PA1/data/pine2.jpg , 128952
PA1/data/pine3.jpg , 126069
PA1/data/pine4.jpg , 120636
PA1/data/trees_000.jpg , 195037
PA1/data/trees_001.jpg , 230526
PA1/data/trees_002.jpg , 253284
PA1/data/trees_003.jpg , 267269
PA1/data/uttower1.jpg , 39785
PA1/data/uttower2.jpg , 39568
PA1/data/uttower2_bad.jpg , 38794
PA1/data/uttower2_scaledup.jpg , 169535
PA1/data/yard1.jpg , 21755
PA1/data/yard2.jpg , 19016
PA1/data/yard3.jpg , 15919
PA1/data/yard4.jpg , 14347
PA1/data/yosemite1.jpg , 203176
PA1/data/yosemite2.jpg , 199756
PA1/data/yosemite3.jpg , 183602
PA1/data/yosemite4.jpg , 253504
PA1/EvaluateAffineMatrix.m , 687
PA1/EvaluateSIFTDescriptor.m , 720
PA1/EvaluateSIFTMatcher.m , 576
PA1/KeypointDetect/affine.m , 1093
PA1/KeypointDetect/build_pyramid.m , 2054
PA1/KeypointDetect/construct_key.m , 817
PA1/KeypointDetect/detect_features.m , 3458
PA1/KeypointDetect/drawbox.m , 244
PA1/KeypointDetect/eliminate_edges.m , 137
PA1/KeypointDetect/filter_gaussian.m , 1539
PA1/KeypointDetect/filter_laplacian.m , 1803
PA1/KeypointDetect/find_extrema.m , 2761
PA1/KeypointDetect/find_features.m , 6216
PA1/KeypointDetect/fit_parabola.m , 119
PA1/KeypointDetect/fit_paraboloid.m , 432
PA1/KeypointDetect/fmransac_test2.m , 7004
PA1/KeypointDetect/f_class.m , 397
PA1/KeypointDetect/gauss1d.m , 236
PA1/KeypointDetect/gauss2dx.m , 573
PA1/KeypointDetect/generate_parta_comparisons.m , 406
PA1/KeypointDetect/getpts.m , 6081
PA1/KeypointDetect/get_dvtime.m , 615
PA1/KeypointDetect/interp.m , 408
PA1/KeypointDetect/kill_edges.m , 170
PA1/KeypointDetect/make_cost.m , 227
PA1/KeypointDetect/match_dv_odometry.m , 392
PA1/KeypointDetect/motion_corr.m , 6466
PA1/KeypointDetect/motion_corr2.m , 4570
PA1/KeypointDetect/mv2.m , 166
PA1/KeypointDetect/plotpoints.m , 1035
PA1/KeypointDetect/plot_matched.m , 718
PA1/KeypointDetect/process_loop.m , 283
PA1/KeypointDetect/refine_features.m , 8948
PA1/KeypointDetect/resample_bilinear.m , 1248
PA1/KeypointDetect/showfeatures.m , 1487
PA1/KeypointDetect/show_plist.m , 194
PA1/KeypointDetect/show_points.m , 97
PA1/KeypointDetect/structure2.m , 678
PA1/KeypointDetect/symmetric_match.m , 975
PA1/least_squares_handout.pdf , 110129
PA1/lecture_panorama.pdf , 1286882
PA1/MatcherTester.m , 651
PA1/MultipleStitch.m , 7906
PA1/PA1.pdf , 1269194
PA1/PairStitch.m , 2005
PA1/PlotMatch.m , 10216
PA1/PlotSIFTDescriptor.m , 4333
PA1/RANSACFit.m , 5248
PA1/SIFT paper.pdf , 455074
PA1/SIFTDescriptor.m , 17189
PA1/SIFTSimpleMatcher.m , 2444
PA1/SIFTTester.m , 514
PA1/StitchTester.m , 1969
PA1/TransformationTester.m , 1109
PA1/Untitled.m , 52
PA1/uttower_pano.jpg , 145377
PA1/yosemite.jpg , 200625
PA1/yourSUNetID_PA1.doc , 48128
更多相关内容 -
opencv实现多张图像拼接
2020-08-26 10:31:50主要为大家详细介绍了opencv实现多张图像拼接功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
多幅图像拼接matlab实现 源码下载
2017-03-06 14:33:20多幅图像拼接matlab实现 sift特征提取、描述、匹配、RANSAC、仿射变换 -
多幅图像拼接matlab实现.zip
2020-01-11 13:49:33多幅图像拼接matlab实现 sift特征提取、描述、匹配、RANSAC、仿射变换 多幅图像拼接matlab实现 sift特征提取、描述、匹配、RANSAC、仿射变换 -
Panorama:使用opencv和python3进行多幅图像全景拼接
2021-05-07 04:26:45该存储库包含多个图像拼接的实现。 高分辨率图像处理缓慢。 图像必须按从左到右的顺序提供,反之亦然。 演示->>> 要求 python3.7.1 的opencv3.4.2 或使用opencv-contrib-python,因为某些非免费功能不可用 pip ... -
多幅图像拼接matlab实现源代码下载 sift特征提取、描述、匹配、RANSAC、仿射变换
2021-11-10 17:23:16多幅图像拼接matlab实现源代码下载 多幅图像拼接matlab实现 sift特征提取、描述、匹配、RANSAC、仿射变换 -
基于SIFT多幅图像拼接系统
2013-06-18 21:07:13多幅图像拼接,虚拟漫游实现。这里只是运行程序,源代码等改完后上传。 -
完整版 多幅图像拼接matlab实现 源码下载.rar
2019-12-19 15:37:01亲测好用,挺不错的资源,大家快来下载吧!挺有用的!需要的话可以来下载哦! 多幅图像拼接matlab实现 sift特征提取、描述、匹配、RANSAC、仿射变换 -
利用Python语言实现多幅图像拼接创建全景图
2019-03-31 22:14:19一、明确图像拼接整体流程 提供一组图像集,实现特征匹配(相邻图像之间要有重复区域) 通过匹配特征计算图像之间的变换结构 利用图像变换结构,实现图像映射 针对叠加后的图像,采用APAP之类的算法,对齐特征点...一、明确图像拼接整体流程
- 提供一组图像集,实现特征匹配(相邻图像之间要有重复区域)
- 通过匹配特征计算图像之间的变换结构
- 利用图像变换结构,实现图像映射
扩展: - 针对叠加后的图像,采用APAP之类的算法,对齐特征点
- 通过图割方法,自动选取拼接缝
1.1实现图像集之间的特征匹配
关于使用SIFT特征实现图像之间的特征匹配原理及例子请阅读这篇博文(https://mp.csdn.net/mdeditor/88585677#),这里便不再详细解释了。
在本实验中,如下代码能够实现特征匹配import sift featname = ['D:输入图片/Univ'+str(i+1)+'.sift' for i in range(5)] imname = ['D:输入图片/Univ'+str(i+1)+'.jpg' for i in range(5)] l = {} d = {} for i in range(5): sift.process_image(imname[i],featname[i]) l[i],d[i] = sift.read_features_from_file(featname[i]) matches = {} for i in range(4): matches[i] = sift.match(d[i+1],d[i])
实现结果如下所示:
1.2使用RANSAC求解单应性矩阵
RANSAC(Random Sample Consensus)即随机采样一致性,对SIFT算法产生的128维特征描述符进行剔除错误匹配点。
它的基本思想是:数据中包含正确的点和噪声点,给定一个合理的模型,这个模型应该能够在描述正确数据点的同时摒弃噪声点。
在本实验中,在上一步特征匹配获得的匹配点对中抽取几对匹配点,计算变换矩阵,并将这几对点记录为”inliers”。继续寻找配准点对中的"outliers",若这些配准点对符合矩阵,则将其添加到"inliers"。当"inliers"中的点对数大于设定阈值时,则判定此矩阵为精确的变换矩阵。依照以上方法,随机采样 N 次,选取"inliers"数最大集合,剔除"outliers"等误配点对。
实现此功能的代码如下:class RansacModel(object): def __init__(self,debug=False): self.debug = debug def fit(self, data): #计算选取的4个对应点对,拟合一个单应性矩阵。 #将这些矩阵转置,来调用H_from_points()计算单应性矩阵 data = data.T #映射的起始点 fp = data[:3,:4] #映射的目标点 tp = data[3:,:4] #计算单应性矩阵,然后返回 return H_from_points(fp,tp) def get_error( self, data, H): #对所有的对应点计算单应性矩阵,然后对每个变换后的点,返回相应的误差 data = data.T #映射的起始点 fp = data[:3] #映射的目标点 tp = data[3:] #变换fp fp_transformed = dot(H,fp) #归一化齐次坐标 fp_transformed = normalize(fp_transformed) #返回每个点的误差 return sqrt( sum((tp-fp_transformed)**2,axis=0) )
fit()方法对选择的4个点对拟合一个单应性矩阵。get_error()方法对每个对应点对使用该单应性矩阵,然后返回相应的平方距离之和,所以RANSAC算法能够判断哪些点对是正确的,哪些是错误的。
之前也说过,还需要设置一个阈值,来决定哪些单应性矩阵是合理的。
代码如下:def H_from_ransac(fp,tp,model,maxiter=1000,match_theshold=10): from PCV.tools import ransac data = vstack((fp,tp)) H,ransac_data = ransac.ransac(data.T,model,4,maxiter,match_theshold,10,return_all=True) return H,ransac_data['inliers']
该函数最重要的参数是最大的迭代次数,程序退出去太早可能得到一个坏解,迭代次数太多会占用太多时间。 最后结果是返回单应性矩阵和对应该单应性矩阵的正确点对。
1.3拼接图像
经过之前的步骤,已经估计出图像间的单应性矩阵,现在要将所有的图像扭曲到一个公共平面上。通常,这里的公共平面为中心图像平面(否则,需要进行大量变形)。一种方法是创建一个很大的图像,比如图像中全部填充0,使其和中心图像平行,然后将所有的图像扭曲到上面。本实验使用的是较为简单的步骤:将中心图像左边或者右边的区域填充0,以便为扭曲的图像腾出空间。
代码如下:def panorama(H,fromim,toim,padding=2400,delta=2400): #使用单应性矩阵H,协调两幅图片,创建水平全景图像,结果为一幅和toim具有相同高度的图像。padding指定填充像素的数目,delta指定额外的平移量。 #检查图像是灰度图像还是彩色图像 is_color = len(fromim.shape) == 3 def transf(p): p2 = dot(H,[p[0],p[1],1]) return (p2[0]/p2[2],p2[1]/p2[2]) if H[1,2]<0: #fromin在右边 print ('warp - right') if is_color:#如果是彩色图像 #在目标图像的右边填充0 toim_t = hstack((toim,zeros((toim.shape[0],padding,3)))) fromim_t = zeros((toim.shape[0],toim.shape[1]+padding,toim.shape[2])) for col in range(3): fromim_t[:,:,col] = ndimage.geometric_transform(fromim[:,:,col], transf,(toim.shape[0],toim.shape[1]+padding)) else:#如果是灰度图像 #在目标图像的右边填充0 toim_t = hstack((toim,zeros((toim.shape[0],padding)))) fromim_t = ndimage.geometric_transform(fromim,transf, (toim.shape[0],toim.shape[1]+padding)) else:#fromin在左边 print ('warp - left') #为了填充补偿效果,在左边加入平移量 H_delta = array([[1,0,0],[0,1,-delta],[0,0,1]]) H = dot(H,H_delta) 在目标图像左边填充0的代码与上述类似,便不再列出。
transf()函数通过将像素和单应性矩阵H相乘,然后对齐次坐标进行归一化来实现像素间的映射。注意:当填充区域在目标图像的左边时,这时,目标图像的坐标也随之右移,所以在这种情况下,需要在单应性矩阵中加入平移。
最后操作:将fromin放置在toim上,代码如下:
if is_color: alpha = ((fromim_t[:,:,0] * fromim_t[:,:,1] * fromim_t[:,:,2] ) > 0) for col in range(3): toim_t[:,:,col] = fromim_t[:,:,col]*alpha + toim_t[:,:,col]*(1-alpha) else: alpha = (fromim_t > 0) toim_t = fromim_t*alpha + toim_t*(1-alpha) return toim_t
这里再次使用了alpha通道方法,原理再回顾一下:
alpha通道方法是设置toim的目标区域部分值为1,其他区域值为0,(0是背景为黑色,1是前景为白色),先映射出一张和toim一样的图像a(相当于先建立一个蒙板),然后在蒙板里把不需要的地方填充成黑色,需要的地方即目标区域留成白色,这个时候实际上是做了一次乘法。用黑色所代表的数值0去乘以toim ,那么这个地方就变透明了,用白色所代表的数值乘以目标区域,再将两者相加,这样fromin就能贴在toim的目标区域上。最后实现的全景拼接图如下:
1.4根据上述方法实现的例子
1.4.1一组室内图像
最后拼接的全景图:
在运行程序时出现了错误:did not meet fit acceptance criteria,原因为最初我在拍摄一组图像时,并不是从同一视角出发拍摄所有图像,也就是说你需要站在同一个地点从左往右拍摄图像,而不能在拍摄的同时随着拍摄景物的移动身体也跟着移动。
记住拍摄完图像之后,要将图像从右往左排序,因为匹配是从最右边的图像开始计算出来的。
这组图像拼接效果不好,整体往左边扭曲了。1.4.2一组室外景深落差较大的图像
最后拼接的全景图:
这组输入的图像较为清晰,相邻两张图像重复区域适中,并且没有过于相似的建筑物,所以在特征匹配的时候错误匹配较少,拼接的全景图也较为令人满意。当然不足的地方还是有的,比如拼接缝过于明显且不同区域曝光度不同,这些都是需要后期再进行处理的。1.4.3一组室外景深落差较小的图像
最后拼接的全景图:
如结果所示这只是完成了拼接,清晰度等其他细节处处理的并不好,与上一组图像相比较可以得知,进行图像拼接的原素材图像也是非常重要的。但是,这最后两组图像并未像第一组图像那样在拼接后形成了一张扭曲的全景图。1.5扩展:如何消除图像拼接中的"鬼影"现象
可以使用APAP(As-Projective-As-Possible)算法,此算法是将图像切割成无数多个小方块,对每个小方块的单应性矩阵逐一估计。指路这条博文(https://blog.csdn.net/xuanwu_yan/article/details/9400321)里面较为详细地介绍了APAP算法的原理。
1.6扩展:如何选取最佳拼接缝
寻找最佳拼接缝算法中,Graph Cut很经典。它将计算机视觉问题和网络流联系在一起。寻找最佳拼接缝等价于求网络流的最小割。 在网络流问题中,最小割和最大流相等。
1.首先介绍最小割问题
一个有向图,并有一个源顶点(source vertex)和目标顶点(target vertex).边的权值为正,又称之为容量(capacity).如下图
一个st-cut(简称割cut)会把有向图的顶点分成两个不相交的集合,其中s在一个集合中,t在另外一个集合中。
这个割的容量(capacity of the cut)就是A到B所有边的容量和。注意这里不包含B到A的。参见下面几幅图。最小割问题就是要找到割容量最小的情况。
2.介绍最大流问题
跟mincut问题类似,maxflow要处理的情况也是一个有向图,并有一个原顶点(source vertex)和目标(target vertex).边的权值为正,又称之为容量(capacity).如下图
一个st-flow(简称flow)是为每条边附一个值,这个值需要满足两个条件1 0<=边的flow <<边的capacity2 除了s和t外,每个顶点的inflow要等于outflow
一个flow的值(value of the flow)就是t的inflow.Maxflow就是找到这个最大值。
后面会发现Mincut和maxflow的问题是对偶的,解出了maxflow也就知道了mincut的解。再
介绍一种解maxflow的算法Ford-Fulkerson,为了方便,简称FF算法。
(1)初始化,所有边的flow都初始化为0
(2)沿着增广路径增加flow。增广路径是一条从s到t的无向路径,但也有些条件,可以经过没有满容量的前向路径(s到t)或者是不为空的反向路径(t->s)
3 maxflow-mincut理论证明对偶性(optional)
首先定义一个概念net flow,经过一个割cut(A,B)的net flow等于从A到B的边flow的和减去从B到A边flow的和。
然后我们就有了flow-value引理:f为任意的流,(A,B)为任意的割,那么f的值 value of flow(也就是t的inflow)等于经过(A,B)的netflow.如下图,value offlow = 8+9+10 = 27 , 而割的net flow = 8+2+7-2+12 = 27.
Weak duality(弱对偶):f为任意的流,(A,B)为任意的割,那么Valueof flow <= capacity of cut(A,B)因为cut(A,B)等于从A到B流量,而value offlow等于cut(A,B)的netflow,还得减去从B到A边的流量。
那么现在我们可以引出两个定理:增广路径定理(Augmenting Path theorem):一个流f是最大流当且仅当没有增广路径。
最小割最大流定理(Maxflow-mincut theorem):Maxflow的值等于最小割的容量。 -
python实现多张图片拼接成大图
2020-09-19 17:38:46主要为大家详细介绍了python实现多张图片拼接成大图,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
python opencv 图像拼接的实现方法
2020-09-19 05:13:11高级图像拼接也叫作基于特征匹配的图像拼接,拼接时消去两幅图像相同的部分,实现拼接合成全景图。这篇文章主要介绍了python opencv 图像拼接,需要的朋友可以参考下 -
基于SIFT多幅图像拼接系统 毕设源码 vc
2013-11-17 16:39:29使用了Rob Hess的sift 库。编译环境:vc6.0 需安装opencv1.0,gsl1.8,及opengl库 -
ENVI遥感图像进行图像拼接的多光谱遥感数据
2018-04-25 21:08:45可用于ENVI或者其他遥感数字图像处理的多光谱图像拼接数据 -
Python实现拼接多张图片的方法
2020-12-25 16:26:31本文实例讲述了Python实现拼接多张图片的方法。分享给大家供大家参考。具体分析如下: 这里所述计划实现如下操作: ① 用Latex写原始博文,生成PDF文档; ② 将PDF转成高清的PNG格式的图片; ③ 将多个PNG格式的... -
C#Winform图片剪切拼接终结版(多幅图片拼接、左右上下拼接)
2013-08-02 10:10:53这个比上次传的功能,多了去掉剪切的框框的功能。...图片裁剪和图片拼接,四幅图,先左右排列拼接,后上下拼接。使用鼠标裁剪后拼接的图片,是选取两个图片中的最大高度, 两个图片的平均宽度进行拼接的。 -
多幅图像拼接算法实践研究
2011-03-02 00:00:33多图像拼接算法研究,能实现多幅图像的拼接 -
opencv实现指定目录下多幅图像读取与拼接
2017-09-13 17:38:26读取指定目录下按照一定命名规格命名的图片,可循环读取多幅图片,并进行图像拼接。按照类似原理,可实现按照一定命名规格将图片存储到指定目录下。 -
Python+OpenCV实现图像的全景拼接
2020-12-20 15:03:03图片越多拼接可能就会越夸张。 本算法是将图片进行桶形矫正。目的就是来缩减透视变换(Homography)之后图片产生的变形,从而使拼接图片变得畸形。 步骤2:特征点匹配 本算法使用的sift算法匹配,它具有旋转不变性... -
OpenCV简单的拼接多幅图像
2018-11-04 10:05:05由于最近在学习超分辨率算法,但是大多数开源程序输入图片太大就显示显存不够,因此就把手机拍摄的图片先分割成一系列小的图片,超分辨率之后再拼接在一块 OpenCV的程序如下:比较简单,对5x5即25张图片进行拼接: ...由于最近在学习超分辨率算法,但是大多数开源程序输入图片太大就显示显存不够,因此就把手机拍摄的图片先分割成一系列小的图片,超分辨率之后再拼接在一块
OpenCV的程序如下:比较简单,对5x5即25张图片进行拼接:
#include <iostream>
#include <core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<opencv2/stitching.hpp>using namespace std;
using namespace cv;
int main()
{
int i = 0,j=0;
Mat combine;
Mat row[5][5], column[5];
Mat com_row[5][5], con_column[5];row[0][0] = imread("C:\\test\\pic_div\\1-1.jpg");
row[0][1] = imread("C:\\test\\pic_div\\1-2.jpg");
row[0][2] = imread("C:\\test\\pic_div\\1-3.jpg");
row[0][3] = imread("C:\\test\\pic_div\\1-4.jpg");
row[0][4] = imread("C:\\test\\pic_div\\1-5.jpg");row[1][0] = imread("C:\\test\\pic_div\\2-1.jpg");
row[1][1] = imread("C:\\test\\pic_div\\2-2.jpg");
row[1][2] = imread("C:\\test\\pic_div\\2-3.jpg");
row[1][3] = imread("C:\\test\\pic_div\\2-4.jpg");
row[1][4] = imread("C:\\test\\pic_div\\2-5.jpg");row[2][0] = imread("C:\\test\\pic_div\\3-1.jpg");
row[2][1] = imread("C:\\test\\pic_div\\3-2.jpg");
row[2][2] = imread("C:\\test\\pic_div\\3-3.jpg");
row[2][3] = imread("C:\\test\\pic_div\\3-4.jpg");
row[2][4] = imread("C:\\test\\pic_div\\3-5.jpg");row[3][0] = imread("C:\\test\\pic_div\\4-1.jpg");
row[3][1] = imread("C:\\test\\pic_div\\4-2.jpg");
row[3][2] = imread("C:\\test\\pic_div\\4-3.jpg");
row[3][3] = imread("C:\\test\\pic_div\\4-4.jpg");
row[3][4] = imread("C:\\test\\pic_div\\4-5.jpg");row[4][0] = imread("C:\\test\\pic_div\\5-1.jpg");
row[4][1] = imread("C:\\test\\pic_div\\5-2.jpg");
row[4][2] = imread("C:\\test\\pic_div\\5-3.jpg");
row[4][3] = imread("C:\\test\\pic_div\\5-4.jpg");
row[4][4] = imread("C:\\test\\pic_div\\5-5.jpg");//cv::resize(a, a, cv::Size(1984, 1488), 0, 0, CV_INTER_LINEAR);
//cv::resize(b, b, cv::Size(1984, 1488), 0, 0, CV_INTER_LINEAR);
//cv::resize(c, c, cv::Size(1984, 1488), 0, 0, CV_INTER_LINEAR);
//cv::resize(d, d, cv::Size(1984, 1488), 0, 0, CV_INTER_LINEAR);
//水平拼接
com_row[0][0] = row[0][0];
com_row[1][0] = row[1][0];
com_row[2][0] = row[2][0];
com_row[3][0] = row[3][0];
com_row[4][0] = row[4][0];
for (i = 0; i < 5; i = i + 1)
{
for (j = 0; j < 4; j = j + 1)
{
hconcat(com_row[i][j], row[i][j+1], com_row[i][j+1]);
}
column[i] = com_row[i][4]; //产生的每一行的拼接图片
}
//垂直拼接
con_column[0] = column[0];
for (i = 0; i < 4; i = i + 1)
{
vconcat(con_column[i], column[i + 1], con_column[i + 1]);
}
combine = con_column[4];
namedWindow("Combine", CV_WINDOW_AUTOSIZE);
imshow("Combine", combine);
imwrite("Combine.png", combine);
cv::waitKey(1);system("pause");
return 0;
}拼接 之前的图片:
拼接之后: