2016-02-05 26 views
4

我必須變換並將等軸矩形圖像重新映射到具有90°卷的另一個等矩形圖像。變換並重新映射90°卷的等矩形圖像

我用Pano2VR做了。

問題是我必須從服務器端以編程方式執行。所以我不能使用G.U.I.去做吧。

首先,我將我的研究導向imagemagick。我試過Fred ImageMagick scripts,但找不到任何人做我想做的事。此外,與Pano2VR相比,圖像的處理時間顯得非常長。

我指示我的調查OpenCVlibgnomonic。這是目前最有趣的方式。該庫允許te用戶轉換投影(equirectangular爲直線,反之亦然)或make equirectangular mapping transformation。我玩Norama-suite這包含一些腳本來處理圖書館。例如,我會將直線圖像轉換爲等矩形圖像,但是輸出只是一個黑色背景圖像(爲什麼?我沒有找到答案)。

但是,這第二個鏈接可以解決我的問題。我有這樣的形象:

,我想將它轉化到該圖像

嗯,我不舒服C. 在所有我想我應該用這兩個文件:

但我不知道如何。最重要的是,我想了解。

我是否正確?第一張圖像上應用了什麼轉換?有沒有辦法用python或bash腳本來做到這一點?

恩,謝謝你的幫忙。


** python中的C編輯換位** 下面的代碼沒有工作,返回和IndexError。 但是我試圖抓住並通過例外,圖像的第一個右側部分似乎沒有改變。

import math 
from PIL import Image 

img = Image.open("img1.jpg") 
img = img.convert('RGB') 
pixel = img.load() 
width, height = img.size 

img2 = img.copy() 
for y in xrange(height): 
    for x in xrange(width): 
     xx = 2*(y+0.5)/width - 1.0 
     yy = 2*(y+0.5)/ height - 1.0 
     lng = math.pi * xx 
     lat = 0.5 * math.pi * yy 

     # NOTE! These axes are transposed because that's what the question is about 
     Z = math.cos(lat) * math.cos(lng) # normally X 
     Y = math.cos(lat) * math.sin(lng) # normally Y 
     X = -math.sin(lat)     # normally -Z 
     D = math.sqrt(X*X+Y*Y) 

     lat = math.atan2(Z, D)    # ? normally lat = math.asin(Z) 
     lng = math.atan2(Y, X) 

     #ix and iy must be integers 
     ix = int((0.5 * lng/math.pi + 0.5) * width - 0.5) 
     iy = int((lat/math.pi + 0.5) * height - 0.5) 

     #not sure of this part to remap the image 
     newpixel = pixel[ix, iy] 
     img2.putpixel([(x+width/4) % width, y], newpixel) 
     #I tries as mentionned in the following code to invert x and y in the two previous lines but the index error out of range comes back 
img2.show() 

回答

3

您的轉換有兩個步驟。第一步是投影球體的變換,第二步是90°滾動。

等軸矩形圖像的90°滾動只是圖像寬度四分之一的水平移位。第一個轉換比較複雜:你基本上想要旋轉球體,使北極在0緯度和0緯度(在幾內亞灣的某處,如果你以地球爲參照)

你可以去關於這些轉變與這些步驟;

  • 翻譯x和每個像素的y位置到經度,− π ≤長≤ π,以及緯度,− π/2 ≤ LAT ≤ π/2。這是一個線性變換。
  • 在單位球體上創建相應經度和緯度的x,y和z座標;正z是北極。
  • 旋轉這些直角座標。在你的情況下,你只需交換一些維度,但這可能是任何變換矩陣的一般變換。
  • 計算旋轉座標的longituide和緯度。
  • 將新的經度和緯度轉換爲像素位置。

以下是可用的C代碼。 (我知道你已經用Python標記了這個問題,但是下面的代碼大部分都是在python中類似工作的公式,你必須注意:除了像素指針外,所有數字都是浮點數x,y,ixiy我會在Python已經這樣做了,但我有使用Python圖像庫沒有經驗。)

for (y = 0; y < height; y++) { 
    for (x = 0; x < width; x++) { 
     double xx = 2 * (x + 0.5)/width - 1.0; 
     double yy = 2 * (y + 0.5)/height - 1.0; 
     double lng = pi * xx; 
     double lat = 0.5 * pi * yy; 

     double X, Y, Z; 
     double D; 
     int ix, iy; 

     Z = cos(lat) * cos(lng); // corresponds to original x 
     Y = cos(lat) * sin(lng); // corresponds to original y 
     X = -sin(lat);    // corresponds to original z 

     D = sqrt(X*X + Y*Y);  // distance in the XY plane 
     lat = atan2(Z, D); 
     lng = atan2(Y, X); 

     ix = (0.5 * lng/pi + 0.5) * width - 0.5; 
     iy = (lat/pi + 0.5) * height - 0.5; 

     dest[y][(x + width/4) % width] = src[iy][ix]; 
            // width/4 offset ist the 90° roll 
            // % width wraps the longitude 
    } 
} 

所產生的圖像的質量是好的,但不如你的參考圖像,尤其是靠近兩極。更好的算法會使顏色值平均並平滑。上面的算法只是將一個目標像素映射到源像素。

+0

非常感謝您的解釋。那麼,我會嘗試在python模塊中實現你的代碼。但是,在C中結果應該更好更快。我可能會嘗試使用Cython。 – pep

+0

那麼,我做到了,但結果很糟糕。我認爲我的代碼的最後一部分不好。 – pep

+0

乍一看:您沒有將模運算符'%'應用於'x'座標。這意味着上一季度的x座標超出範圍。嘗試使用'img2.putpixel([(x + width/4)%width,y],newpixel)''。 –