覚え書きブログ

極座標変換のpythonコード

通常の画像を極座標に変換するコードを、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軸の原点は画像の上にあるので、マイナスを付けて反転する必要があるので注意が必要。

以下は、動作確認用に作った画像と実行結果である。
f:id:hirotaka_hachiya:20210722114322p:plain
f:id:hirotaka_hachiya:20210722183243p:plain

画像中心から放射線状に伸びる同じ太さの線でも、極座標系では、中心に近い(radiusが0に近い)ほど太く、離れるほど細くなっているのがわかる。