回答編集履歴

2

d

2019/06/13 14:42

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -76,68 +76,230 @@
76
76
 
77
77
 
78
78
 
79
+ > これはどう解釈すればよいでしょうか。
80
+
81
+
82
+
83
+ やっている処理は以下になります。
84
+
85
+
86
+
87
+ 1. アフィン変換 (中心で回転) を行う。
88
+
89
+ 2. 値をスプライン補完で内挿する。
90
+
91
+ 3. 情報がない画素は外挿する。(デフォルトは0なので画像でいうと黒になる)
92
+
93
+
94
+
95
+ ndimage.rotate() の具体的な処理は Github のソースコードで確認できます。
96
+
97
+ [scipy/interpolation.py at v1.3.0 · scipy/scipy](https://github.com/scipy/scipy/blob/v1.3.0/scipy/ndimage/interpolation.py#L627-L754)
98
+
99
+
100
+
101
+ 数値で見るとなにが起こってるのかわかりづらいと思うので、画像で試してみると、実際 45°回転していることがわかります。
102
+
103
+
104
+
105
+ ```python
106
+
107
+ import numpy as np
108
+
109
+ import matplotlib.pyplot as plt
110
+
111
+ from scipy.ndimage import rotate
112
+
113
+
114
+
115
+ img = plt.imread("sample.jpg")
116
+
117
+
118
+
119
+ rotated = rotate(img, 45, reshape=False)
120
+
121
+
122
+
123
+ plt.imshow(img)
124
+
125
+ plt.show()
126
+
127
+ plt.imshow(rotated)
128
+
129
+ plt.show()
130
+
131
+ ```
132
+
133
+
134
+
135
+ ![イメージ説明](ef33c1acf89e383e5dea138494e56737.png)
136
+
137
+
138
+
139
+ ![イメージ説明](3405c4f32133104771a1adc8712bd0d4.png)
140
+
141
+
142
+
79
143
  ## 追記
80
144
 
81
145
 
82
146
 
147
+ > 追加ですが、では以下のような配列を任意の点(配列と配列の間、Xで言えば6.2なども含める)を中心に任意の角度回転させた時、その配列の各点がどこに位置するかを表すような関数ってありますか?
148
+
149
+
150
+
83
- > これはどう解釈すればよいでしょうか
151
+ 行列の各成分が回転後にの位置に写ったか知りたいといことでしょうか
152
+
84
-
153
+ 一発でそのようなことができる関数はありませんが、行列の各成分の点に対して、「ある点を中心にある角度だけ回転するアフィン変換」を行えばよいと思います。
85
-
86
-
154
+
155
+
156
+
87
- やってい処理は以下になります。
157
+ コードにす以下のようになります。
158
+
159
+
160
+
88
-
161
+ * 1. 行列の各成分の点一覧 `XY` を作成する。
162
+
89
-
163
+ ただし、+0.5 して点が各成分の中心となるようにする。
164
+
90
-
165
+ 例えば、行列の (2, 1) 成分の点は (1.5, 2.5) になります。
166
+
167
+
168
+
169
+ ![イメージ説明](ddfbde8f968c00ff1b725df3d2811354.png)
170
+
171
+
172
+
173
+ 上図青の点が `XY` です。
174
+
175
+
176
+
177
+ * 2. 原点中心に反時計回りに angle 度だけ回転する回転行列を作成する。
178
+
179
+
180
+
91
- 1. アフィン変換 (中心で回転) を行う。
181
+ * 3. 点 `XY` に対して、アフィン変換を行う。
92
-
93
- 2. 値をスプライン補完で内挿する。
182
+
94
-
95
- 3. 情報がない画素は外挿する。(デフォルトは0なので画像でいうと黒になる)
96
-
97
-
98
-
99
- ndimage.rotate() の具体的な処理は Github のソースコードで確認できます。
100
-
101
- [scipy/interpolation.py at v1.3.0 · scipy/scipy](https://github.com/scipy/scipy/blob/v1.3.0/scipy/ndimage/interpolation.py#L627-L754)
102
-
103
-
104
-
105
- 数値で見るとなが起こってのかわかりづらいと思うので画像で試してみると実際 45°回転していることがわかります。
183
+ 回転中心を `center` 場合-center だけ平行移動して、回転変換を行い、+center だけ平行移動してす。
184
+
185
+
186
+
187
+ ![イメージ説明](ddfbde8f968c00ff1b725df3d2811354.png)
188
+
189
+
190
+
191
+ 上図緑の点が回転中心、赤の点が変換後の点の位置です。
106
192
 
107
193
 
108
194
 
109
195
  ```python
110
196
 
197
+ import matplotlib.pyplot as plt
198
+
111
199
  import numpy as np
112
200
 
201
+
202
+
113
- import matplotlib.pyplot as plt
203
+ a = np.array([[0, 1, 2, 3],
204
+
114
-
205
+ [0, 1, 2, 3],
206
+
207
+ [0, 1, 2, 3]])
208
+
209
+
210
+
211
+ # 行列の各成分の点一覧を作成する。
212
+
115
- from scipy.ndimage import rotate
213
+ rows, cols = np.indices(a.shape)
214
+
116
-
215
+ XY = np.column_stack((cols.ravel(), rows.ravel())) + 0.5
216
+
217
+
218
+
117
-
219
+ print(XY.shape) # (12, 2)
220
+
118
-
221
+ print(XY)
222
+
223
+ # [[0.5 0.5]
224
+
225
+ # [1.5 0.5]
226
+
227
+ # [2.5 0.5]
228
+
229
+ # [3.5 0.5]
230
+
231
+ # [0.5 1.5]
232
+
233
+ # [1.5 1.5]
234
+
235
+ # [2.5 1.5]
236
+
237
+ # [3.5 1.5]
238
+
239
+ # [0.5 2.5]
240
+
241
+ # [1.5 2.5]
242
+
243
+ # [2.5 2.5]
244
+
245
+ # [3.5 2.5]]
246
+
247
+
248
+
249
+ # 原点中心に反時計回りに angle 度だけ回転する回転行列を作成する。
250
+
251
+ def create_rotation_matrix(deg):
252
+
253
+ rad = np.deg2rad(deg)
254
+
119
- img = plt.imread("sample.jpg")
255
+ return np.array([[np.cos(rad), -np.sin(rad)],
256
+
120
-
257
+ [np.sin(rad), np.cos(rad)]])
258
+
259
+
260
+
121
-
261
+ center = (1.2, 2.2) # 回転する中心
122
-
262
+
123
- rotated = rotate(img, 45, reshape=False)
263
+ rot = create_rotation_matrix(deg=45.0)
264
+
124
-
265
+ # center 周りに回転させるので、
266
+
125
-
267
+ # -center だけ平行移動 → 回転 → +center だけ平行移動
268
+
126
-
269
+ new_XY = (XY - center).dot(rot) + center
270
+
127
- plt.imshow(img)
271
+ print(new_XY)
128
-
272
+
273
+
274
+
129
- plt.show()
275
+ # 元の点がどこに移ったか
130
-
276
+
131
- plt.imshow(rotated)
277
+ for old, new in zip(XY, new_XY):
132
-
278
+
133
- plt.show()
279
+ print(f"{old} -> {new}")
280
+
281
+ # [0.5 0.5] -> [-0.49705627 1.49289322]
282
+
283
+ # [1.5 0.5] -> [0.21005051 0.78578644]
284
+
285
+ # [2.5 0.5] -> [0.91715729 0.07867966]
286
+
287
+ # [3.5 0.5] -> [ 1.62426407 -0.62842712]
288
+
289
+ # [0.5 1.5] -> [0.21005051 2.2 ]
290
+
291
+ # [1.5 1.5] -> [0.91715729 1.49289322]
292
+
293
+ # [2.5 1.5] -> [1.62426407 0.78578644]
294
+
295
+ # [3.5 1.5] -> [2.33137085 0.07867966]
296
+
297
+ # [0.5 2.5] -> [0.91715729 2.90710678]
298
+
299
+ # [1.5 2.5] -> [1.62426407 2.2 ]
300
+
301
+ # [2.5 2.5] -> [2.33137085 1.49289322]
302
+
303
+ # [3.5 2.5] -> [3.03847763 0.78578644]
134
304
 
135
305
  ```
136
-
137
-
138
-
139
- ![イメージ説明](ef33c1acf89e383e5dea138494e56737.png)
140
-
141
-
142
-
143
- ![イメージ説明](3405c4f32133104771a1adc8712bd0d4.png)

1

d

2019/06/13 14:42

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -69,3 +69,75 @@
69
69
 
70
70
 
71
71
  ![イメージ説明](c84d9974ad491961bc0c8f9da2bd2196.png)
72
+
73
+
74
+
75
+ ## 追記
76
+
77
+
78
+
79
+ ## 追記
80
+
81
+
82
+
83
+ > これはどう解釈すればよいでしょうか。
84
+
85
+
86
+
87
+ やっている処理は以下になります。
88
+
89
+
90
+
91
+ 1. アフィン変換 (中心で回転) を行う。
92
+
93
+ 2. 値をスプライン補完で内挿する。
94
+
95
+ 3. 情報がない画素は外挿する。(デフォルトは0なので画像でいうと黒になる)
96
+
97
+
98
+
99
+ ndimage.rotate() の具体的な処理は Github のソースコードで確認できます。
100
+
101
+ [scipy/interpolation.py at v1.3.0 · scipy/scipy](https://github.com/scipy/scipy/blob/v1.3.0/scipy/ndimage/interpolation.py#L627-L754)
102
+
103
+
104
+
105
+ 数値で見るとなにが起こってるのかわかりづらいと思うので、画像で試してみると、実際 45°回転していることがわかります。
106
+
107
+
108
+
109
+ ```python
110
+
111
+ import numpy as np
112
+
113
+ import matplotlib.pyplot as plt
114
+
115
+ from scipy.ndimage import rotate
116
+
117
+
118
+
119
+ img = plt.imread("sample.jpg")
120
+
121
+
122
+
123
+ rotated = rotate(img, 45, reshape=False)
124
+
125
+
126
+
127
+ plt.imshow(img)
128
+
129
+ plt.show()
130
+
131
+ plt.imshow(rotated)
132
+
133
+ plt.show()
134
+
135
+ ```
136
+
137
+
138
+
139
+ ![イメージ説明](ef33c1acf89e383e5dea138494e56737.png)
140
+
141
+
142
+
143
+ ![イメージ説明](3405c4f32133104771a1adc8712bd0d4.png)