scipy.ndimage は主に画像を対象として回転させる関数ですので、行列を 90°ずつ回転させたい場合は、numpy.rot90 をお使いください。
numpy.rot90 — NumPy v1.15 Manual
python
1import matplotlib.pyplot as plt
2import numpy as np
3from scipy.ndimage import rotate
4
5X = np.arange(20).reshape(4, -1)
6# Y = rotate(X, 90, reshape=False)
7Y = np.rot90(X, k=1) # 反時計回りに90° (90*k°) 回転する。
8
9print(X)
10# [[ 0 1 2 3 4]
11# [ 5 6 7 8 9]
12# [10 11 12 13 14]
13# [15 16 17 18 19]]
14print()
15print(Y)
16# [[ 4 9 14 19]
17# [ 3 8 13 18]
18# [ 2 7 12 17]
19# [ 1 6 11 16]
20# [ 0 5 10 15]]
21
22plt.imshow(X)
23plt.colorbar()
24plt.show()
25
26plt.imshow(Y)
27plt.colorbar()
28plt.show()
追記
これはどう解釈すればよいでしょうか。
やっている処理は以下になります。
- アフィン変換 (中心で回転) を行う。
- 値をスプライン補完で内挿する。
- 情報がない画素は外挿する。(デフォルトは0なので画像でいうと黒になる)
ndimage.rotate() の具体的な処理は Github のソースコードで確認できます。
scipy/interpolation.py at v1.3.0 · scipy/scipy
数値で見るとなにが起こってるのかわかりづらいと思うので、画像で試してみると、実際 45°回転していることがわかります。
python
1import numpy as np
2import matplotlib.pyplot as plt
3from scipy.ndimage import rotate
4
5img = plt.imread("sample.jpg")
6
7rotated = rotate(img, 45, reshape=False)
8
9plt.imshow(img)
10plt.show()
11plt.imshow(rotated)
12plt.show()
追記
追加ですが、では以下のような配列を任意の点(配列と配列の間、Xで言えば6.2なども含める)を中心に任意の角度回転させた時、その配列の各点がどこに位置するかを表すような関数ってありますか?
行列の各成分が回転後にどの位置に写ったか知りたいということでしょうか?
一発でそのようなことができる関数はありませんが、行列の各成分の点に対して、「ある点を中心にある角度だけ回転するアフィン変換」を行えばよいと思います。
コードにすると以下のようになります。
ただし、+0.5 して点が各成分の中心となるようにする。
例えば、行列の (2, 1) 成分の点は (1.5, 2.5) になります。
上図青の点が XY
です。
-
- 原点中心に反時計回りに angle 度だけ回転する回転行列を作成する。
-
- 点
XY
に対して、アフィン変換を行う。
回転中心を center
にする場合、-center だけ平行移動して、回転変換を行い、+center だけ平行移動して戻す。
上図緑の点が回転中心、赤の点が変換後の点の位置です。
python
1import matplotlib.pyplot as plt
2import numpy as np
3
4a = np.array([[0, 1, 2, 3],
5 [0, 1, 2, 3],
6 [0, 1, 2, 3]])
7
8# 行列の各成分の点一覧を作成する。
9rows, cols = np.indices(a.shape)
10XY = np.column_stack((cols.ravel(), rows.ravel())) + 0.5
11
12print(XY.shape) # (12, 2)
13print(XY)
14# [[0.5 0.5]
15# [1.5 0.5]
16# [2.5 0.5]
17# [3.5 0.5]
18# [0.5 1.5]
19# [1.5 1.5]
20# [2.5 1.5]
21# [3.5 1.5]
22# [0.5 2.5]
23# [1.5 2.5]
24# [2.5 2.5]
25# [3.5 2.5]]
26
27# 原点中心に反時計回りに angle 度だけ回転する回転行列を作成する。
28def create_rotation_matrix(deg):
29 rad = np.deg2rad(deg)
30 return np.array([[np.cos(rad), -np.sin(rad)],
31 [np.sin(rad), np.cos(rad)]])
32
33center = (1.2, 2.2) # 回転する中心
34rot = create_rotation_matrix(deg=45.0)
35# center 周りに回転させるので、
36# -center だけ平行移動 → 回転 → +center だけ平行移動
37new_XY = (XY - center).dot(rot) + center
38print(new_XY)
39
40# 元の点がどこに移ったか
41for old, new in zip(XY, new_XY):
42 print(f"{old} -> {new}")
43# [0.5 0.5] -> [-0.49705627 1.49289322]
44# [1.5 0.5] -> [0.21005051 0.78578644]
45# [2.5 0.5] -> [0.91715729 0.07867966]
46# [3.5 0.5] -> [ 1.62426407 -0.62842712]
47# [0.5 1.5] -> [0.21005051 2.2 ]
48# [1.5 1.5] -> [0.91715729 1.49289322]
49# [2.5 1.5] -> [1.62426407 0.78578644]
50# [3.5 1.5] -> [2.33137085 0.07867966]
51# [0.5 2.5] -> [0.91715729 2.90710678]
52# [1.5 2.5] -> [1.62426407 2.2 ]
53# [2.5 2.5] -> [2.33137085 1.49289322]
54# [3.5 2.5] -> [3.03847763 0.78578644]
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/13 07:13
2019/06/13 07:49
2019/06/13 13:25
2019/06/13 14:46
2019/06/14 11:53