柱面投影matlab程序
2015-10-22 15:59
417 查看
拼接之前要进行柱面、立方体面或者球面投影,《全景拼接的关键技术研究》选的是柱面投影,根据其理论有:
%假设相机市场角为45度
%反投影到柱面时左右有缝隙了
A=imread('F:\fisheye\kk.jpg');
[H,W,k]=size(A);
f=W/(2*tan(pi/4/2)); %视场角越小则弯曲越小
C=zeros(H,W);
for i=1:H
for j=1:W
yy=f*tan((j-W/2)/f)+W/2;
xx=(i-H/2)*sqrt((j-W/2)^2+f^2)/f+H/2;
xx=round(xx);
yy=round(yy);
if(xx<1||yy<1||xx>H||yy>W)
nn=nn+1;
continue;
end
C(i,j,1)=A(xx,yy,1);
C(i,j,2)=A(xx,yy,2);
C(i,j,3)=A(xx,yy,3);
end
end
C=uint8(C);
原图(网上下载的美女图 假设相机视场角是pi/4):
则柱面投影结果图:
如果直接用书上那个公式变换下,即:yy=f*tan((j-f*atan(W/2/f))/f)+W/2; 那么缝隙就移到一边去了,即成了这样:
所以还是用原来的,然后再计算左右两边的缝隙,并把这个缝隙除掉:
len=round(f*atan(-W/2/f)+W/2);
D=zeros(H-1,W-2*len-1);
for i=1:H
for j=len+1:W-len
ii=i;
jj=j-len;
D(ii,jj,1)=C(i,j,1);
D(ii,jj,2)=C(i,j,2);
D(ii,jj,3)=C(i,j,3);
end
end
D=uint8(D);
结果:
这样就差不多行了
换张校正后的鱼眼图片试试,我知道之前我用鱼眼校正图进行柱面投影时候为什么出来是个黑屏了 因为我依然用的是鱼眼相机的视场角180度 其实校正后的鱼眼图进行柱面投影时就不能把它当做180了 因为其实它已经是个正常图片了,所以假设它是正常相机的60度左右就行,结果:
但是有个大叔坚持认为校正后的鱼眼图片和普通图片不一样 校正后的鱼眼图片进行拼接之前不用进行柱面投影 而且也不能像我一样把它当成普通图片视场角60度左右!
但我觉得不是他说的这样,等我把普通图片的拼接做完,就来试鱼眼图片拼接,看是我认为的这样还是他认为的那样!
1,SIFT/SURF等进行特征点检测和匹配
这一步之前编过SIFT 但最后还是有问题 所以还是直接用OpenCV上的特征点检测和匹配程序,然后再把得到的匹配对输出给MATLAB,因为我只要它的结果。
2,计算出变换矩阵H
这是鱼眼图像拼接正式开始的第一步:就是根据SIFT匹配(或者别的匹配方法)找到的构成匹配对的特征点位置信息计算出两幅或几幅图像之间的变换矩阵,即看待拼接图像之间存在什么关系(平移、旋转、仿射等等),我在MATLAB里做的,理论部分根据论文《鱼眼图像全景拼接系统》,论文里只取4对匹配对就够了,我取了5对。
data1=load('matchdata1.txt'); %这是OpenCV中得到的匹配对中第一幅图的坐标
data2=load('matchdata2.txt');
[m,n]=size(data1);
A=zeros(10,8);
n=1;
arr=[1,1,2,2,3,3,4,4,5,5];
b=zeros(10,1);
for i=1:10
nn=n/2;
nnn=fix(nn);
nnnn=nn-nnn;
if(nnnn~=0)
A(i,1)=data1(arr(i),1);
A(i,2)=data1(arr(i),2);
A(i,3)=1;
A(i,4)=0;
A(i,5)=0;
A(i,6)=0;
A(i,7)=-data1(arr(i),1)*data2(arr(i),1);
A(i,8)=-data1(arr(i),1)*data2(arr(i),2);
b(i)=data2(arr(i),1);
else
A(i,1)=0;
A(i,2)=0;
A(i,3)=0;
A(i,4)=data1(arr(i),1);
A(i,5)=data1(arr(i),2);
A(i,6)=1;
A(i,7)=-data1(arr(i),1)*data2(arr(i),2);
A(i,8)=-data1(arr(i),2)*data2(arr(i),2);
b(i)=data2(arr(i),2);
end
n=n+1;
end
H=A\b;
H =
0.6179
-0.0088
-135.7927
-0.1784
0.6745
46.5215
-0.0011
-0.0001
3,拼接融合算法
3.1取平均值法
论文中这部分写得不清楚,无法用来编程,我再找找有没写得比较清晰的关于线性融合的论文。我找了个论文《全景拼接的关键技术研究》这里面几种拼接融合算法写得 比较清晰,我想都实现出来,这个取平均值法融合是最简单的 ,同时也是效果最不好的,我没用投影到柱面,也没用求得的变换矩阵H,因为我目前没弄懂这两个对后续 拼接融合的具体意义,等我弄清楚了再编它们再用,这个取平均值法融合 我是直接用SIFT匹配的结果 直接按照论文中取平均来拼的 可能是位置不太准确吧
重影、拼接线、 错位等问题都存在:
原图:
结果:
%《全景拼接的关键技术研究》取平均值融合
%其实最好先判断这两幅是否同样大小,若不,则把这两幅图调成一样大小,这里我懒得调了 它们差不多大小
A=imread('F:\fisheye\mosaic1.jpg');
B=imread('F:\fisheye\mosaic2.jpg');
%先找两幅图的重叠区域
data1=218; %直接用的OpenCV里SIFT匹配的结果
data2=89;
[m1,n1,k1]=size(A);
[m2,n2,k2]=size(B);
if m1<m2
M=m2;
m=m1;
else
M=m1;
m=m2;
end
nn1=n1-data1;
if nn1>data2
n=nn1;
else
n=data2;
end
z1=zeros(m,n);
z2=z1;
Rect=z1;
for i=1:m
for j=1:n
z1(i,j,1)=A(i,data1-1+j,1);
z1(i,j,2)=A(i,data1-1+j,2);
z1(i,j,3)=A(i,data1-1+j,3);
z2(i,j,1)=B(i,j,1);
z2(i,j,2)=B(i,j,2);
z2(i,j,3)=B(i,j,3);
Rect(i,j,1)=(z1(i,j,1)+z2(i,j,1))/2;
Rect(i,j,2)=(z1(i,j,2)+z2(i,j,2))/2;
Rect(i,j,3)=(z1(i,j,3)+z2(i,j,3))/2;
end
end
Rect=uint8(Rect);
N=round(data1+n+n2-data2);
C=zeros(M,N);
for i=1:M
for j=1:N
if(j<=data1)
if(i>m1||j>n1)
continue;
end
C(i,j,1)=A(i,j,1);
C(i,j,2)=A(i,j,2);
C(i,j,3)=A(i,j,3);
elseif(j<=data1+n)
if(i>m||j-data1>n)
continue;
end
C(i,j,1)=Rect(i,j-data1,1);
C(i,j,2)=Rect(i,j-data1,2);
C(i,j,3)=Rect(i,j-data1,3);
else
if(i>m||j-data1>n2)
continue;
end
C(i,j,1)=B(i,j-data1,1);
C(i,j,2)=B(i,j-data1,2);
C(i,j,3)=B(i,j-data1,3);
end
end
end
C=uint8(C);
3.2 渐入渐出融合
还是根据这篇论文,渐入渐出融合,依然是直接拼的 没有用投影到同一坐标系 也没用变换矩阵H 因为还是不知道它们的作用啊 好想找到人请教下 没人:
结果:
虽然还是有拼接线 但是重影问题已经好多了 看来还是不能像取平均值法融合一样总是取相同的权值各为1/2 这样重影严重 这个渐入渐出的权值是像论文中写的一样随着位置变化 所以基本消除了重影 但拼接线。。。。
%假设相机市场角为45度
%反投影到柱面时左右有缝隙了
A=imread('F:\fisheye\kk.jpg');
[H,W,k]=size(A);
f=W/(2*tan(pi/4/2)); %视场角越小则弯曲越小
C=zeros(H,W);
for i=1:H
for j=1:W
yy=f*tan((j-W/2)/f)+W/2;
xx=(i-H/2)*sqrt((j-W/2)^2+f^2)/f+H/2;
xx=round(xx);
yy=round(yy);
if(xx<1||yy<1||xx>H||yy>W)
nn=nn+1;
continue;
end
C(i,j,1)=A(xx,yy,1);
C(i,j,2)=A(xx,yy,2);
C(i,j,3)=A(xx,yy,3);
end
end
C=uint8(C);
原图(网上下载的美女图 假设相机视场角是pi/4):
则柱面投影结果图:
如果直接用书上那个公式变换下,即:yy=f*tan((j-f*atan(W/2/f))/f)+W/2; 那么缝隙就移到一边去了,即成了这样:
所以还是用原来的,然后再计算左右两边的缝隙,并把这个缝隙除掉:
len=round(f*atan(-W/2/f)+W/2);
D=zeros(H-1,W-2*len-1);
for i=1:H
for j=len+1:W-len
ii=i;
jj=j-len;
D(ii,jj,1)=C(i,j,1);
D(ii,jj,2)=C(i,j,2);
D(ii,jj,3)=C(i,j,3);
end
end
D=uint8(D);
结果:
这样就差不多行了
换张校正后的鱼眼图片试试,我知道之前我用鱼眼校正图进行柱面投影时候为什么出来是个黑屏了 因为我依然用的是鱼眼相机的视场角180度 其实校正后的鱼眼图进行柱面投影时就不能把它当做180了 因为其实它已经是个正常图片了,所以假设它是正常相机的60度左右就行,结果:
但是有个大叔坚持认为校正后的鱼眼图片和普通图片不一样 校正后的鱼眼图片进行拼接之前不用进行柱面投影 而且也不能像我一样把它当成普通图片视场角60度左右!
但我觉得不是他说的这样,等我把普通图片的拼接做完,就来试鱼眼图片拼接,看是我认为的这样还是他认为的那样!
1,SIFT/SURF等进行特征点检测和匹配
这一步之前编过SIFT 但最后还是有问题 所以还是直接用OpenCV上的特征点检测和匹配程序,然后再把得到的匹配对输出给MATLAB,因为我只要它的结果。
2,计算出变换矩阵H
这是鱼眼图像拼接正式开始的第一步:就是根据SIFT匹配(或者别的匹配方法)找到的构成匹配对的特征点位置信息计算出两幅或几幅图像之间的变换矩阵,即看待拼接图像之间存在什么关系(平移、旋转、仿射等等),我在MATLAB里做的,理论部分根据论文《鱼眼图像全景拼接系统》,论文里只取4对匹配对就够了,我取了5对。
data1=load('matchdata1.txt'); %这是OpenCV中得到的匹配对中第一幅图的坐标
data2=load('matchdata2.txt');
[m,n]=size(data1);
A=zeros(10,8);
n=1;
arr=[1,1,2,2,3,3,4,4,5,5];
b=zeros(10,1);
for i=1:10
nn=n/2;
nnn=fix(nn);
nnnn=nn-nnn;
if(nnnn~=0)
A(i,1)=data1(arr(i),1);
A(i,2)=data1(arr(i),2);
A(i,3)=1;
A(i,4)=0;
A(i,5)=0;
A(i,6)=0;
A(i,7)=-data1(arr(i),1)*data2(arr(i),1);
A(i,8)=-data1(arr(i),1)*data2(arr(i),2);
b(i)=data2(arr(i),1);
else
A(i,1)=0;
A(i,2)=0;
A(i,3)=0;
A(i,4)=data1(arr(i),1);
A(i,5)=data1(arr(i),2);
A(i,6)=1;
A(i,7)=-data1(arr(i),1)*data2(arr(i),2);
A(i,8)=-data1(arr(i),2)*data2(arr(i),2);
b(i)=data2(arr(i),2);
end
n=n+1;
end
H=A\b;
H =
0.6179
-0.0088
-135.7927
-0.1784
0.6745
46.5215
-0.0011
-0.0001
3,拼接融合算法
3.1取平均值法
论文中这部分写得不清楚,无法用来编程,我再找找有没写得比较清晰的关于线性融合的论文。我找了个论文《全景拼接的关键技术研究》这里面几种拼接融合算法写得 比较清晰,我想都实现出来,这个取平均值法融合是最简单的 ,同时也是效果最不好的,我没用投影到柱面,也没用求得的变换矩阵H,因为我目前没弄懂这两个对后续 拼接融合的具体意义,等我弄清楚了再编它们再用,这个取平均值法融合 我是直接用SIFT匹配的结果 直接按照论文中取平均来拼的 可能是位置不太准确吧
重影、拼接线、 错位等问题都存在:
原图:
结果:
%《全景拼接的关键技术研究》取平均值融合
%其实最好先判断这两幅是否同样大小,若不,则把这两幅图调成一样大小,这里我懒得调了 它们差不多大小
A=imread('F:\fisheye\mosaic1.jpg');
B=imread('F:\fisheye\mosaic2.jpg');
%先找两幅图的重叠区域
data1=218; %直接用的OpenCV里SIFT匹配的结果
data2=89;
[m1,n1,k1]=size(A);
[m2,n2,k2]=size(B);
if m1<m2
M=m2;
m=m1;
else
M=m1;
m=m2;
end
nn1=n1-data1;
if nn1>data2
n=nn1;
else
n=data2;
end
z1=zeros(m,n);
z2=z1;
Rect=z1;
for i=1:m
for j=1:n
z1(i,j,1)=A(i,data1-1+j,1);
z1(i,j,2)=A(i,data1-1+j,2);
z1(i,j,3)=A(i,data1-1+j,3);
z2(i,j,1)=B(i,j,1);
z2(i,j,2)=B(i,j,2);
z2(i,j,3)=B(i,j,3);
Rect(i,j,1)=(z1(i,j,1)+z2(i,j,1))/2;
Rect(i,j,2)=(z1(i,j,2)+z2(i,j,2))/2;
Rect(i,j,3)=(z1(i,j,3)+z2(i,j,3))/2;
end
end
Rect=uint8(Rect);
N=round(data1+n+n2-data2);
C=zeros(M,N);
for i=1:M
for j=1:N
if(j<=data1)
if(i>m1||j>n1)
continue;
end
C(i,j,1)=A(i,j,1);
C(i,j,2)=A(i,j,2);
C(i,j,3)=A(i,j,3);
elseif(j<=data1+n)
if(i>m||j-data1>n)
continue;
end
C(i,j,1)=Rect(i,j-data1,1);
C(i,j,2)=Rect(i,j-data1,2);
C(i,j,3)=Rect(i,j-data1,3);
else
if(i>m||j-data1>n2)
continue;
end
C(i,j,1)=B(i,j-data1,1);
C(i,j,2)=B(i,j-data1,2);
C(i,j,3)=B(i,j-data1,3);
end
end
end
C=uint8(C);
3.2 渐入渐出融合
还是根据这篇论文,渐入渐出融合,依然是直接拼的 没有用投影到同一坐标系 也没用变换矩阵H 因为还是不知道它们的作用啊 好想找到人请教下 没人:
结果:
虽然还是有拼接线 但是重影问题已经好多了 看来还是不能像取平均值法融合一样总是取相同的权值各为1/2 这样重影严重 这个渐入渐出的权值是像论文中写的一样随着位置变化 所以基本消除了重影 但拼接线。。。。
相关文章推荐
- 解析在main函数之前调用函数以及对设计的作用详解
- java和matlab画多边形闭合折线图示例讲解
- C#调用Matlab生成的dll方法的详细说明
- 从java中调用matlab详细介绍
- VC++与Matlab混合编程的快速实现
- Matlab 矩阵运算
- matlab与opencv部分函数的对照
- matlab神经网络工具箱创建神经网络
- Matlab
- MATLAB 入门教程
- matlab函数_连通区域
- MATLAB中函数模式和命令模式的区别
- MATLAB 添加自定义的模块到simulink库浏览器
- MATLAB for Mac使编辑器支持中文
- [转]matlab中plot用法
- 初学数模-MATLAB Quick Start! Part I
- 初学数模-MATLAB Quick Start! Part II
- matlab程序优化以及eclipse与github的结合
- matlab中的rand函数(用于产生随机数)
- 图像增强算法四种,图示与源码,包括retinex(ssr、msr、msrcr)和一种混合算法