您的位置:首页 > 编程语言 > MATLAB

柱面投影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  这样重影严重  这个渐入渐出的权值是像论文中写的一样随着位置变化  所以基本消除了重影 但拼接线。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  鱼眼拼接 MATLAB