通常の画像を極座標に変換するコードを、numpyのmeshgridを使って作ってみた。
ポイントは、通常の画像(カーテシアン座標系)から極座標の画像に変換する際は、極座標(theta, r)からカーテシアン座標(x,y)に変換するマップを作るところである。以下は、作ったコードの例:
import pickle import pdb import math import numpy as np import matplotlib.pylab as plt import cv2 width=height=274 #------------ # polar to cartesian transformation radius = np.linspace(0,width/2,width) theta = np.linspace(0,2*np.pi,height) R,T = np.meshgrid(radius,theta) X = R * np.cos(T) + width/2 Y = -R * np.sin(T) + height/2 #------------ #------------ # load image img = cv2.imread('color_dir.png') img_polar = img[Y.astype(int)-1,X.astype(int)-1] #---------------------- # plot images fig = plt.figure() fig.add_subplot(1,2,1) plt.imshow(img,cmap="gray") plt.title('cartesian coordinate',fontsize=12) plt.xlabel('X',fontsize=12) plt.ylabel('Y',fontsize=12) fig.add_subplot(1,2,2) plt.imshow(img_polar,cmap="gray") plt.title('polar coordinate',fontsize=12) plt.xlabel('radius',fontsize=12) plt.ylabel('theta',fontsize=12) inds = np.arange(0,width,width/10).astype(int) plt.xticks(inds,np.round(radius[inds],2)) plt.yticks(inds,np.round(theta[inds],2)) plt.tight_layout() plt.show() #----------------------
つまり、極座標の縦軸(角度theta)と、横軸(半径radius)に対しmeshgridで2Dメッシュを作成し、それぞれのセルに対応するカーテシアン座標系の縦軸(y)と読軸(x)のインデックスを格納した行列YとXを作成している。
そして、読み込んだ画像の行列imgからインデックス(YとX)に対応する値を取ってきている。
また、カーテシアン座標系は画像の場合、Y軸の原点は画像の上にあるので、マイナスを付けて反転する必要があるので注意が必要。
以下は、動作確認用に作った画像と実行結果である。
画像中心から放射線状に伸びる同じ太さの線でも、極座標系では、中心に近い(radiusが0に近い)ほど太く、離れるほど細くなっているのがわかる。