全景圖是2:1比例的圖片,一般是多張圖像拼接而成。全景圖2:1的比例可以很方便的映射到球面,而球坐標可以很方便的實現各種有趣的投影。比如小行星,水晶球,局部透視投影等。
今天來說說怎么將全景圖投影到小行星視圖:
首先,要有一副2:1的全景圖,如下:
風景秀麗是不是。
然后,將全景圖按照經緯展開法重新貼到球面,圖像的寬就是緯度0-2π,圖像的高就是經度0-π。
接下來,需要一種下面這樣的投影。將一個球面上的坐標投影到平面上。投影中心在球心到球面之間。
從百度百科上盜的圖,各位將就著看。
這種投影方式中,下半球面會全部投影在平面圖中的一個圓內,上半球面會全部投影到圓的外面,并且分布越來越稀疏。
投影過程可以理解為:
1. 首先建立球坐標系,將經緯度的全景圖貼到球面上,這個過程我之前的一篇博客中魚眼圖轉經緯圖講過,原理一樣。只不過是逆過程。
2. 設定投影中心點的坐標,然后連接投影中心點和球面上一點,得到一條直線。當然此時需要設置一個視場角FOV,即選擇投影的視場角是多大。視場角越大,最后得到的小行星視圖中間圖像被擠壓的越厲害。
3. 建立投影平面,以上圖為例,該投影平面與球面相切與南極點。計算該直線與該投影平面的交點,即可得到投影后的平面坐標。
4. 上述三步均在球坐標系下完成,得到各個球面點的平面坐標后,根據具體想要得到的平面圖像尺寸,將平面坐標轉換為圖像坐標。至此完成。
上述是正向投影過程,如果采用反向投影,原理類似,不過倒過來從原全景圖像素點取值即可。
上述過程可以很方便用C++代碼實現,讀取圖像的操作可以用OpenCV:
投影后得到的小行星視圖如下,FOV和投影中心位置都會影響小行星在圖像中的大小:
這個是投影點在北極點,FOV設置的120度
投影點在北極點,FOV=170度,則如下:
投影點在北極點與球心的中點,FOV=120度,則如下:
同樣道理,如果投影點在南極點,投影平面放在北極,則如下圖:
同理,如果在球體內隨意移動投影點,投影得到的效果也會不同,可以實現不同視角的小行星。
生成了一段繞固定軸旋轉的小行星gif圖,效果如下: