zoukankan      html  css  js  c++  java
  • MATLAB 透视投影,把lena贴到billboard上

    本练习程序是受到了这个老外博文的启发,感觉挺有意思,就尝试了一下。他用的是opencv,我这里用的是matlab。

    过去写过透视投影,当时是用来做倾斜校正的,这次同样用到了透视投影,不过更有意思,是将一张图像贴到另一张图像上。

    两个透视投影都需要先计算投影矩阵,倾斜校正那一篇是通过解线性方程组求的变换矩阵,而这一篇是通过奇异值分解求的变换矩阵。

    为了对齐两张图像,还需要对投影后的图像做一次仿射变换,其实就是坐标平移。

    这里做投影和仿射直接调用了matlab的系统函数,方便一些。

    还是先介绍下如何投影吧:

    比如我们解单应性方程组或奇异值分解得到了投影矩阵:

    那么变换方程就可以写为:

    其中,x,y为原图像像素坐标,X,Y为目标图像像素坐标。

    做一些正反点匹配变换的时候我会用这个公式,不过大多数情况下在做图像投影的时候,我并不用上面的公式,而是用下面这个公式:

    其中,x,y为原图像像素坐标,X,Y为目标图像像素坐标。

    第一个公式计算后图像会出现空洞,第二个公式计算量明显变大了,各有利弊吧。

    这么复杂的一个公式,我可推不出来,是用Mathematica推的,这个软件真是极大的提高了我的效率。

    话说matlab应该也能推,不过matlab的符号计算毕竟不是强项,我也就没去了解matlab的这项功能。

    看看效果吧。

    原图:

    广告牌:

    结果:

    matlab代码如下:

    main.m

     1 clear all;close all;clc;
     2 
     3 img1=imread('lena.jpg');
     4 [h1 w1]=size(img1);
     5 mask=uint8(ones(h1,w1));    %二值模板,方便最后的合成
     6 
     7 img2=imread('pai.jpg');
     8 [h2 w2]=size(img2);
     9 
    10 imshow(img1);
    11 figure;imshow(img2);
    12 
    13 p1=[1,1;w1,1;1,h1;w1,h1];
    14 p2=ginput();        %依次点击公告牌左上、右上、左下、右下
    15 
    16 T=calc_homography(p1,p2);   %计算单应性矩阵
    17 T=maketform('projective',T);   %投影矩阵
    18 
    19 [imgn X Y]=imtransform(img1,T);     %投影
    20 mask=imtransform(mask,T);
    21 
    22 T2=eye(3);
    23 if X(1)>0, T2(3,1)= X(1); end
    24 if Y(1)>0, T2(3,2)= Y(1); end
    25 T2=maketform('affine',T2);      %仿射矩阵
    26 
    27 imgn=imtransform(imgn,T2,'XData',[1 w2],'YData',[1 h2]);    %仿射
    28 mask=imtransform(mask,T2,'XData',[1 w2],'YData',[1 h2]);
    29 
    30 img=img2.*(1-mask)+imgn.*mask;  %合成
    31 figure;imshow(img,[])

    calc_homography

     1 function T = calc_homography(points1, points2)
     2 
     3     xaxb = points2(:,1) .* points1(:,1);
     4     xayb = points2(:,1) .* points1(:,2);
     5     yaxb = points2(:,2) .* points1(:,1);
     6     yayb = points2(:,2) .* points1(:,2);
     7 
     8     A = zeros(size(points1, 1)*2, 9);
     9     A(1:2:end,3) = 1;
    10     A(2:2:end,6) = 1;
    11     A(1:2:end,1:2) = points1;
    12     A(2:2:end,4:5) = points1;
    13     A(1:2:end,7) = -xaxb;
    14     A(1:2:end,8) = -xayb;
    15     A(2:2:end,7) = -yaxb;
    16     A(2:2:end,8) = -yayb;
    17     A(1:2:end,9) = -points2(:,1);
    18     A(2:2:end,9) = -points2(:,2);
    19 
    20     [junk1,junk2,V] = svd(A);
    21     h = V(:,9) ./ V(9,9);
    22     T= reshape(h,3,3);
    23 end
  • 相关阅读:
    概率与数学期望初步
    $Luogu$ $P4316$ 绿豆蛙的归宿(附期望 $dp$ 的设计总结)
    $Luogu$ $P4427$ $[BJOI2018]$ 求和
    $SP3978$ $DISQUERY$ $-$ $Distance$ $Query$
    最近公共祖先模板(未完待续)
    $Luogu$ $P3052$ $[USACO12MAR]$ 摩天大楼里的奶牛 $Cows$ $in$ $a$ $Skyscraper$
    $Luogu$ $P2622$ 关灯问题 $mathrm{II}$
    [转载] $CF633F$ 题解
    [转载] $Luogu$ $P3933$ 题解
    2020高考回忆录(随便写写
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/13645769.html
Copyright © 2011-2022 走看看