回答編集履歴

5

d

2018/11/20 15:52

投稿

tiitoi
tiitoi

スコア21954

test CHANGED
@@ -170,8 +170,6 @@
170
170
 
171
171
  std::vector<cv::Point3f> src = {{20, 20, 20}}, dst;
172
172
 
173
- // 点 (30, 30) を中心に60°回転する回転行列を作成する。
174
-
175
173
  cv::Mat M = getRotationMatrix3D(CV_PI / 3, CV_PI / 4, CV_PI / 2);
176
174
 
177
175
  std::cout << M << std::endl;

4

f

2018/11/20 15:52

投稿

tiitoi
tiitoi

スコア21954

test CHANGED
@@ -195,3 +195,11 @@
195
195
  }
196
196
 
197
197
  ```
198
+
199
+
200
+
201
+ ![イメージ説明](a7f433d04bc1682c74c0cddf3004c47f.png)
202
+
203
+
204
+
205
+ [オイラー角とそれが表す回転行列](http://pynote.hatenablog.com/entry/math-euler-angles)

3

d

2018/11/20 15:45

投稿

tiitoi
tiitoi

スコア21954

test CHANGED
@@ -75,3 +75,123 @@
75
75
  [20, 20]-> [9.01924, 60.9808]
76
76
 
77
77
  ```
78
+
79
+
80
+
81
+ ----
82
+
83
+
84
+
85
+ ## 追記
86
+
87
+
88
+
89
+ 変換は cv::transform() が使えますが、3次元回転行列を作成する関数はないので、オイラー角とかで適当に作ってください。
90
+
91
+
92
+
93
+ ```cpp
94
+
95
+ #include <cmath>
96
+
97
+ #include <iostream>
98
+
99
+ #include <opencv2/opencv.hpp>
100
+
101
+
102
+
103
+ /**
104
+
105
+ * @brief getRotationMatrix3D
106
+
107
+ * @param alpha x 軸周りの回転角度
108
+
109
+ * @param beta y 軸周りの回転角度
110
+
111
+ * @param gamma z 軸周りの回転角度
112
+
113
+ * @return 回転行列
114
+
115
+ */
116
+
117
+ cv::Mat getRotationMatrix3D(double alpha, double beta, double gamma)
118
+
119
+ {
120
+
121
+ // clang-format off
122
+
123
+ // X 軸周りの回転行列
124
+
125
+ cv::Mat R_x =
126
+
127
+ (cv::Mat_<double>(3, 3) << 1, 0, 0,
128
+
129
+ 0, std::cos(alpha), -std::sin(alpha),
130
+
131
+ 0, std::sin(alpha), std::cos(alpha));
132
+
133
+
134
+
135
+ // Y 軸周りの回転行列
136
+
137
+ cv::Mat R_y =
138
+
139
+ (cv::Mat_<double>(3, 3) << std::cos(beta), 0, std::sin(beta),
140
+
141
+ 0, 1, 0,
142
+
143
+ -std::sin(beta), 0, std::cos(beta));
144
+
145
+
146
+
147
+ // Z 軸周りの回転行列
148
+
149
+ cv::Mat R_z =
150
+
151
+ (cv::Mat_<double>(3, 3) << std::cos(gamma), -std::sin(gamma), 0,
152
+
153
+ std::sin(gamma), std::cos(gamma), 0,
154
+
155
+ 0, 0, 1);
156
+
157
+ // clang-format on
158
+
159
+
160
+
161
+ return R_z * R_y * R_x;
162
+
163
+ }
164
+
165
+
166
+
167
+ int main()
168
+
169
+ {
170
+
171
+ std::vector<cv::Point3f> src = {{20, 20, 20}}, dst;
172
+
173
+ // 点 (30, 30) を中心に60°回転する回転行列を作成する。
174
+
175
+ cv::Mat M = getRotationMatrix3D(CV_PI / 3, CV_PI / 4, CV_PI / 2);
176
+
177
+ std::cout << M << std::endl;
178
+
179
+
180
+
181
+ // 回転行列を適用する。
182
+
183
+ cv::transform(src, dst, M);
184
+
185
+
186
+
187
+ // 結果出力
188
+
189
+ for (size_t i = 0; i < src.size(); ++i) {
190
+
191
+ std::cout << src[i] << "-> " << dst[i] << std::endl;
192
+
193
+ }
194
+
195
+ }
196
+
197
+ ```

2

2018/11/20 15:43

投稿

tiitoi
tiitoi

スコア21954

test CHANGED
@@ -18,10 +18,6 @@
18
18
 
19
19
  {
20
20
 
21
- cv::Mat img(100, 100, CV_8UC3, cv::Scalar(255, 255, 255));
22
-
23
-
24
-
25
21
  std::vector<cv::Point2f> src = {{20, 20}}, dst;
26
22
 
27
23
  // 点 (30, 30) を中心に反時計回りに60°回転する回転行列を作成する。
@@ -32,11 +28,15 @@
32
28
 
33
29
 
34
30
 
31
+ // 回転行列 M に src を適用し、結果を dst で得る。
32
+
35
33
  cv::transform(src, dst, M);
36
34
 
37
35
 
38
36
 
39
- // 変換前の点
37
+ // 結果を描画する。
38
+
39
+ cv::Mat img(100, 100, CV_8UC3, cv::Scalar(255, 255, 255));
40
40
 
41
41
  for (size_t i = 0; i < src.size(); ++i) {
42
42
 

1

d

2018/11/20 14:55

投稿

tiitoi
tiitoi

スコア21954

test CHANGED
@@ -1,15 +1,77 @@
1
1
  [cv::transform()](https://docs.opencv.org/master/d2/de8/group__core__array.html#ga393164aa54bb9169ce0a8cc44e08ff22) が使えます。
2
+
3
+
4
+
5
+ 変換前及び変換後は点の一覧で指定する必要があるため、変換する点が1点の場合でも `std::vector<cv::Point2f> src = {{20, 20}}` のようにしてください。
2
6
 
3
7
 
4
8
 
5
9
  ```cpp
6
10
 
7
- cv::Mat src; // 3x1行列
11
+ #include <iostream>
8
12
 
9
- cv::Mat dst; // 結果を格納する行列
13
+ #include <opencv2/opencv.hpp>
10
14
 
11
- cv::Mat mat; // アフィン変換行列
12
15
 
16
+
17
+ int main()
18
+
19
+ {
20
+
21
+ cv::Mat img(100, 100, CV_8UC3, cv::Scalar(255, 255, 255));
22
+
23
+
24
+
25
+ std::vector<cv::Point2f> src = {{20, 20}}, dst;
26
+
27
+ // 点 (30, 30) を中心に反時計回りに60°回転する回転行列を作成する。
28
+
29
+ cv::Mat M = cv::getRotationMatrix2D({50.f, 50.f}, 60., 1.);
30
+
31
+ std::cout << M << std::endl;
32
+
33
+
34
+
13
- cv::transform(src, dst, mat)
35
+ cv::transform(src, dst, M);
36
+
37
+
38
+
39
+ // 変換前の点
40
+
41
+ for (size_t i = 0; i < src.size(); ++i) {
42
+
43
+ std::cout << src[i] << "-> " << dst[i] << std::endl;
44
+
45
+ // 変換前の点を青で描画する。
46
+
47
+ cv::circle(img, src[i], 2, cv::Scalar(255, 0, 0), -1);
48
+
49
+ // 変換後の点を緑で描画する。
50
+
51
+ cv::circle(img, dst[i], 2, cv::Scalar(0, 255, 0), -1);
52
+
53
+ }
54
+
55
+
56
+
57
+ cv::imshow("image", img);
58
+
59
+ cv::waitKey();
60
+
61
+ }
62
+
63
+
14
64
 
15
65
  ```
66
+
67
+
68
+
69
+ ```
70
+
71
+ [0.5000000000000001, 0.8660254037844386, -18.30127018922194;
72
+
73
+ -0.8660254037844386, 0.5000000000000001, 68.30127018922192]
74
+
75
+ [20, 20]-> [9.01924, 60.9808]
76
+
77
+ ```