柱面投影介紹與python實現(一)

簡介

本文主要介紹柱面投影變換,將這種變換用於圖像處理,可以產生圖像扭曲的效果,如下圖所示,產生了將平面圖像投影到了柱面上的視覺效果。博客最後給出了柱面投影的python實現,供讀者參考。


     


數學原理

如下圖所示,矩形GHEF爲待處理的原圖,投影到柱面上之後則變成了曲面JDILCK。我們假設相機模型爲針孔模型,且所處位置爲N點,下面分析原圖GHEF與投影曲面JDILCK各像素之間的對應關係。



俯視圖如下圖所示,我們以原圖像的中心(W/2, H/2)爲原點,假設相機的焦距爲ff的值我們可以隨意選擇,不需要相機的真實焦距)。


下面我們進行幾何分析,點 –W/2 映射到 –W/2 ,點W/2 映射到W/2 ,因此直線【–W/2W/2】爲原圖X方向,曲線【–W/2 O W/2】爲投影曲面的X方向。


假設原平面上有一點x, 映射到曲面上爲x‘(在投影曲面X方向上的座標爲x, 即弧長爲x’),設角xNO爲θ,θ = arctan

(x/f),弧長x’ = f×θ。因此X方向上柱面投影的映射關係爲 x‘ = f × arctan(x/f)


接下來看側視圖,以確定Y方向上原圖與投影圖像素的對應關係。側視圖中的紅色虛線與俯視圖中的紅色虛線相對

應。由俯視圖可得線段xN = f / cos(θ),由側視圖中的相似三角形關係可得y‘ / f = y /(f/cos(θ))。

綜上所述,可得原圖與投影曲面各像素的對應關係如下

根據上面三個式子,我們便可以對圖片進行柱面投影變換了。python實現代碼如下所示。
from skimage.io import imread, imshow ,imsave
from skimage.transform import resize
import math
import numpy as np

img = imread('img.jpg')
img = (resize(img , [1000,800])*255).astype(np.uint8)

###圓柱投影
def cylindrical_projection(img , f) :
   rows = img.shape[0]
   cols = img.shape[1]
   
   #f = cols / (2 * math.tan(np.pi / 8))

   blank = np.zeros_like(img)
   center_x = int(cols / 2)
   center_y = int(rows / 2)
   
   for  y in range(rows):
       for x in range(cols):
           theta = math.atan((x- center_x )/ f)
           point_x = int(f * math.tan( (x-center_x) / f) + center_x)
           point_y = int( (y-center_y) / math.cos(theta) + center_y)
           
           if point_x >= cols or point_x < 0 or point_y >= rows or point_y < 0:
               pass
           else:
               blank[y , x, :] = img[point_y , point_x ,:]
   return blank

waved_img = cylindrical_projection(img,500)
imshow(waved_img)

補充:

1、從上面的程序我們可以看出,程序中對三個公式的應用是反的。這是因爲程序中兩個for循環中的x與y對應的是

柱面投影的曲面,point_x 與point_y對應的是原圖中的座標點。


2、此外,我們可以將相機的位置N點進行移動,產生不同的柱面變換。在程序實現時,我們直接更改center_x與

center_y的值即可。例如,center_x = int(cols/3), center_y = int(rows/2), 產生的效果圖如下所示。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章