這個程式我最初是用FreeImage寫的,這兩天改成了matlab,再不貼上來,我就要忘了。
看到一篇文章有這樣的變換,挺有意思的,就拿來試了一下,文章點此。
全景圖到穹頂圖變換,通俗的說就是將全景圖首尾相接做成一個圓環的樣子。
先看下面這張圖:
下面的矩形就是我們要處理的全景圖,上面的矩形是變換後的影象。下面影象的底邊對應穹頂圖的內圓,頂邊對應穹頂圖的外圓,當然,反過來也是可以的。
程式流程:
1.定義穹頂圖內圓和外圓的半徑,變換後的畫素就填充在這個內外半徑的圓環中。
2.遍歷穹頂圖,當所處理當前畫素位於圓環內,則通過極座標反變換去全景圖中尋找相應位置的畫素進行填充。
3.遍歷完影象就行了。
用的技巧和影象旋轉或放大縮小都是類似的。
處理結果:
原圖:
結果:
matlab程式碼如下:
clear all; close all; clc; img=imread('pan.jpg'); imshow(img); [m,n]=size(img); r1=100; %內環半徑 r2=r1+m; %外環半徑 imgn=zeros(2*r2,2*r2); [re_m,re_n]=size(imgn); for y=1:re_m for x=1:re_n dis_x=x-re_n/2; dis_y=y-re_m/2; l=sqrt(dis_x^2+dis_y^2); if l<=r2 && l>=r1 theta=0; if y>re_m/2 theta=atan2(dis_y,dis_x); end if y<re_m/2 theta=pi+atan2(-dis_y,-dis_x); end if y==re_m/2 theta=atan2(dis_y,dis_x)+0.0001; end xx=ceil(n*theta/(2*pi)); yy=ceil(l-r1); if yy>=1 && yy<=m && xx>=1 && xx<=n imgn(y,x)=img(yy,xx); end end end end figure; imshow(imgn,[])
最後要說的是,一般我們要是有一張全景圖,通常會用cubic對映,將影象變換為立方體的六個面,然後通過圖形學方法貼到立方體上,就能做出類似谷歌街景的樣子。cubic對映應該才是全景圖最常用的處理方法,不過那又是另一類變換了。