Python: 直交座標＋極座標変換

# はじめに

今回は直交座標⇔極座標を行き来する変換を実装していく。

# 実装コード

今回は以下のように実装した。get_rtは極座標系に変換するための対応する直座標系上の座標を取得し、get_xyはその逆を行う。（説明が怪しいが、以降の動作で確認してほしい）

```python
import cv2
import numpy as np
import matplotlib.pyplot as plt


def get_rt(wid, ratio):
    i = np.tile(np.arange(wid).reshape(-1, 1), (1, wid)) - wid / 2
    j = i.T
    r = np.linalg.norm((i, j), axis=0)
    r /= np.max(r)
    r *= (wid - 1) * ratio
    r[r >= wid] = wid - 1
    j[j == 0] = 1
    t = np.arctan(i / j)[::-1]
    t[j < 0] += np.pi
    t -= np.min(t)
    t /= np.max(t)
    t *= (wid - 1)
    t[t >= wid] = wid - 1
    return r.astype('i'), t.astype('i')


def get_xy(wid):
    a = np.arange(wid) / wid
    r = wid / 2
    x = (a.reshape(1, -1) * np.cos(2 * a.reshape(-1, 1) * np.pi) * r + r).astype('i')
    y = (a.reshape(1, -1) * np.sin(2 * a.reshape(-1, 1) * np.pi) * r + r).astype('i')
    x[x < 0] = 0
    x[x >= wid] = wid - 1
    y[y < 0] = 0
    y[y >= wid] = wid - 1
    return x, y
```

# 説明

今回もレナさんの画像を用いる。ということでまずレナさんの画像を読み込みます。そして、一応確認しておく。実行するとこんな感じ。

```python
img = cv2.resize(cv2.imread('lena.jpg', 0), (256, 256))
plt.imshow(img)
plt.show()
```
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/de81dc95-c56c-04d3-bb7d-959b02d19128.png)

次に先ほどの関数で直交座標⇔極座標を行き来する座標関係を作成します。最初の2枚が極座標系に変換するやつで、後の2枚が直交座標系に変換するやつです。

```python

r, t = get_rt(256, np.sqrt(2))
plt.imshow(r)
plt.show()
plt.imshow(t)
plt.show()

x, y = get_xy(256)
plt.imshow(x)
plt.show()
plt.imshow(y)
plt.show()

```


![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/3beb596b-68e3-e49c-753f-8c91295c7244.png)
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/ca51d9c9-ae2c-349f-cce9-7d29b56965be.png)
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/93f8808d-fa51-19ce-3005-831854e2248c.png)
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/6b8fc9e2-6d38-4c10-49cf-2dbcc347fc62.png)


これがつくれたら、後は以下のように座標変換すれば直交座標⇒極座標⇒直交座標のような変換が簡単にできる。

```python
lena = img[t, r]
plt.imshow(lena)
plt.show()
plt.imshow(lena[x, y])
plt.show()
```

![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/7c476d2b-6256-a1f2-4dbc-de4edf2b579e.png)
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/e8aa25cb-c352-de50-f559-3c33d1afc4b1.png)

さっきの逆も簡単にできる

```python
lena = img[x, y]
plt.imshow(lena)
plt.show()
plt.imshow(lena[t, r])
plt.show()
```

![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/52fa9dc7-82c6-e069-38d0-4eb1ad16ef25.png)
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/31e836a6-49ca-c545-5a0c-590a4465278f.png)

極座標系に変換した後さらにそれを極座標系に変換しても戻せる。

```python
lena = img[t, r][t, r]
plt.imshow(lena)
plt.show()
plt.imshow(lena[x, y][x, y])
plt.show()
```

![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/76f0e955-9ff5-9756-c4a0-cace4b0935a0.png)
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/14ec70b8-29be-39c6-524a-700c7bb8703b.png)

逆もできる。

```python
lena = img[x, y][x, y]
plt.imshow(lena)
plt.show()
plt.imshow(lena[t, r][t, r])
plt.show()
```

![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/b6d101f4-76c9-8ad5-1446-f641bb56f7a5.png)
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365961/9ed14d97-746d-b106-10ab-b0f17bfa0010.png)

# まとめ

楽しい！コードも説明も雑ですが・・・気が向いたら整理します(´・ω・｀)