回答編集履歴

1

a

2018/10/21 17:29

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -25,3 +25,181 @@
25
25
 
26
26
 
27
27
  [参考リンク](http://pynote.hatenablog.com/entry/opencv-contour-manipulation#%E8%BC%AA%E9%83%AD%E3%82%92%E8%BF%91%E4%BC%BC%E3%81%99%E3%82%8B)
28
+
29
+
30
+
31
+
32
+
33
+ ## 追記
34
+
35
+
36
+
37
+ ### 回転した長方形の4点から中心、回転角度、大きさを計算するコード
38
+
39
+
40
+
41
+ ```python
42
+
43
+ def get_rect_info(rect):
44
+
45
+ # 長方形の中心
46
+
47
+ center = (rect[0] + rect[2]) / 2
48
+
49
+
50
+
51
+ # 長さが異なる2つの辺の長さをそれぞれ計算する。
52
+
53
+ vec1 = rect[0] - rect[1]
54
+
55
+ vec2 = rect[1] - rect[2]
56
+
57
+ vec1_len = np.linalg.norm(vec1)
58
+
59
+ vec2_len = np.linalg.norm(vec2)
60
+
61
+
62
+
63
+ # 長辺が幅、短辺が高さとする。
64
+
65
+ if vec1_len < vec2_len:
66
+
67
+ widht, height = vec2_len, vec1_len
68
+
69
+ vecw = vec2
70
+
71
+ else:
72
+
73
+ widht, height = vec1_len, vec2_len
74
+
75
+ vecw = vec1
76
+
77
+
78
+
79
+ # x 軸と長辺のなす角を計算する。
80
+
81
+ if np.isclose(vecw[0], 0):
82
+
83
+ angle = 0
84
+
85
+ else:
86
+
87
+ angle = -np.arctan(vecw[1] / vecw[0])
88
+
89
+ angle = np.rad2deg(angle)
90
+
91
+
92
+
93
+ return {'center': center, 'angle': angle, 'size': (width, height)}
94
+
95
+ ```
96
+
97
+
98
+
99
+ ### テスト
100
+
101
+
102
+
103
+ ```python
104
+
105
+ import cv2
106
+
107
+ import matplotlib.pyplot as plt
108
+
109
+ import numpy as np
110
+
111
+ from matplotlib.patches import Polygon
112
+
113
+
114
+
115
+ x, y = 100, 150
116
+
117
+ width, height = 300, 100
118
+
119
+ rect = np.array([
120
+
121
+ [x, y],
122
+
123
+ [x + width, y],
124
+
125
+ [x + width, y + height],
126
+
127
+ [x, y + height],
128
+
129
+ [x, y]], dtype=float)
130
+
131
+
132
+
133
+ # 長方形を描画する。
134
+
135
+ fig, axes = plt.subplots(figsize=(6, 6))
136
+
137
+ axes.set_xlim(0, 500)
138
+
139
+ axes.set_ylim(0, 500)
140
+
141
+
142
+
143
+ for angle in range(0, 360, 40):
144
+
145
+ # 長方形の中心周りに -angle 回転させる回転行列を作成する。
146
+
147
+ center = tuple(((rect[0] + rect[2]) / 2).astype(int))
148
+
149
+ R = cv2.getRotationMatrix2D(center, -angle, 1.)
150
+
151
+
152
+
153
+ # 回転行列を適用し、回転した長方形の点を計算する。
154
+
155
+ rotated_rect = cv2.transform(rect.reshape(1, -1, 2), R)[0]
156
+
157
+
158
+
159
+ # 確認用に描画する。
160
+
161
+ axes.add_patch(Polygon(rotated_rect, fill=None, lw=2., color='b'))
162
+
163
+
164
+
165
+ # 4点の座標から中心、回転角度、大きさを計算する。
166
+
167
+ info = get_rect_info(rotated_rect)
168
+
169
+
170
+
171
+ print('center: {}, angle: {:.2f}, size: {}'.format(info['center'], info['angle'], info['size']))
172
+
173
+
174
+
175
+ plt.show()
176
+
177
+ ```
178
+
179
+
180
+
181
+ ```
182
+
183
+ center: [250. 200.], angle: 0.00, size: (300, 100.0)
184
+
185
+ center: [250. 200.], angle: -40.00, size: (300, 100.00000000000001)
186
+
187
+ center: [250. 200.], angle: -80.00, size: (300, 100.00000000000004)
188
+
189
+ center: [250. 200.], angle: 60.00, size: (300, 100.00000000000004)
190
+
191
+ center: [250. 200.], angle: 20.00, size: (300, 99.99999999999999)
192
+
193
+ center: [250. 200.], angle: -20.00, size: (300, 100.00000000000004)
194
+
195
+ center: [250. 200.], angle: -60.00, size: (300, 100.00000000000001)
196
+
197
+ center: [250. 200.], angle: 80.00, size: (300, 100.00000000000006)
198
+
199
+ center: [250. 200.], angle: 40.00, size: (300, 100.00000000000001)
200
+
201
+ ```
202
+
203
+
204
+
205
+ ![イメージ説明](e37b0dea807681ee1451cedeecf2a231.png)