20 #include <opencv2/calib3d/calib3d.hpp>
21 #include <opencv2/imgproc/imgproc.hpp>
30 Marker3DInfo::Marker3DInfo()
33 Marker3DInfo::Marker3DInfo(
int _id) : id(_id)
60 cv::FileStorage fs(sfile, cv::FileStorage::WRITE);
68 fs <<
"aruco_bc_nmarkers" << (int)size();
69 fs <<
"aruco_bc_mInfoType" << (int)
mInfoType;
70 fs <<
"aruco_bc_markers"
72 for (
size_t i = 0; i < size(); i++)
79 for (
size_t c = 0; c < at(i).size(); c++)
95 cv::FileStorage fs(sfile, cv::FileStorage::READ);
97 throw cv::Exception(81818,
"MarkerMap::readFromFile",
98 string(
" file not opened ") + sfile, __FILE__, __LINE__);
101 catch (std::exception& ex)
103 throw cv::Exception(81818,
"MarkerMap::readFromFile",
104 ex.what() +
string(
" file=)") + sfile, __FILE__, __LINE__);
114 if (fs[
"aruco_bc_nmarkers"].name() !=
"aruco_bc_nmarkers")
115 throw cv::Exception(81818,
"MarkerMap::readFromFile",
"invalid file type", __FILE__, __LINE__);
116 fs[
"aruco_bc_nmarkers"] >> aux;
119 cv::FileNode markers = fs[
"aruco_bc_markers"];
121 for (FileNodeIterator it = markers.begin(); it != markers.end(); ++it, i++)
123 at(i).id = (*it)[
"id"];
124 FileNode FnCorners = (*it)[
"corners"];
125 for (FileNodeIterator itc = FnCorners.begin(); itc != FnCorners.end(); ++itc)
127 vector<float> coordinates3d;
128 (*itc) >> coordinates3d;
129 if (coordinates3d.size() != 3)
130 throw cv::Exception(81818,
"MarkerMap::readFromFile",
"invalid file type 3",
132 cv::Point3f point(coordinates3d[0], coordinates3d[1], coordinates3d[2]);
133 at(i).push_back(point);
137 if (fs[
"aruco_bc_dict"].name() ==
"aruco_bc_dict")
145 for (
size_t i = 0; i < size(); i++)
147 return static_cast<int>(i);
155 for (
size_t i = 0; i < size(); i++)
158 throw cv::Exception(111,
"MarkerMap::getMarker3DInfo",
159 "Marker with the id given is not found", __FILE__, __LINE__);
165 bool invalid =
false;
166 for (
int i = 0; i < 3 && !invalid; i++)
168 if (Tvec.at<
float>(i, 0) != -999999)
170 if (Rvec.at<
float>(i, 0) != -999999)
174 throw cv::Exception(9002,
"extrinsic parameters are not set",
175 "Marker::getModelViewMatrix", __FILE__, __LINE__);
176 Mat Rot(3, 3, CV_32FC1), Jacob;
177 Rodrigues(Rvec, Rot, Jacob);
180 for (
int i = 0; i < 3; i++)
181 for (
int j = 0; j < 3; j++)
182 para[i][j] = Rot.at<
float>(i, j);
184 para[0][3] = Tvec.at<
float>(0, 0);
185 para[1][3] = Tvec.at<
float>(1, 0);
186 para[2][3] = Tvec.at<
float>(2, 0);
189 modelview_matrix[0 + 0 * 4] = para[0][0];
191 modelview_matrix[0 + 1 * 4] = para[0][1];
192 modelview_matrix[0 + 2 * 4] = para[0][2];
193 modelview_matrix[0 + 3 * 4] = para[0][3];
195 modelview_matrix[1 + 0 * 4] = para[1][0];
196 modelview_matrix[1 + 1 * 4] = para[1][1];
197 modelview_matrix[1 + 2 * 4] = para[1][2];
198 modelview_matrix[1 + 3 * 4] = para[1][3];
200 modelview_matrix[2 + 0 * 4] = -para[2][0];
201 modelview_matrix[2 + 1 * 4] = -para[2][1];
202 modelview_matrix[2 + 2 * 4] = -para[2][2];
203 modelview_matrix[2 + 3 * 4] = -para[2][3];
204 modelview_matrix[3 + 0 * 4] = 0.0;
205 modelview_matrix[3 + 1 * 4] = 0.0;
206 modelview_matrix[3 + 2 * 4] = 0.0;
207 modelview_matrix[3 + 3 * 4] = 1.0;
210 modelview_matrix[12] *= scale;
211 modelview_matrix[13] *= scale;
212 modelview_matrix[14] *= scale;
220 const cv::Mat& Rvec,
const cv::Mat& Tvec)
223 bool invalid =
false;
224 for (
int i = 0; i < 3 && !invalid; i++)
226 if (Tvec.at<
float>(i, 0) != -999999)
228 if (Rvec.at<
float>(i, 0) != -999999)
232 throw cv::Exception(9003,
"extrinsic parameters are not set",
233 "Marker::getModelViewMatrix", __FILE__, __LINE__);
236 position[0] = -Tvec.ptr<
float>(0)[0];
237 position[1] = -Tvec.ptr<
float>(0)[1];
238 position[2] = +Tvec.ptr<
float>(0)[2];
241 cv::Mat Rot(3, 3, CV_32FC1);
242 cv::Rodrigues(Rvec, Rot);
247 stAxes[0][0] = -Rot.at<
float>(0, 0);
248 stAxes[0][1] = -Rot.at<
float>(1, 0);
249 stAxes[0][2] = +Rot.at<
float>(2, 0);
251 stAxes[1][0] = -Rot.at<
float>(0, 1);
252 stAxes[1][1] = -Rot.at<
float>(1, 1);
253 stAxes[1][2] = +Rot.at<
float>(2, 1);
255 stAxes[2][0] = stAxes[0][1] * stAxes[1][2] - stAxes[0][2] * stAxes[1][1];
256 stAxes[2][1] = -stAxes[0][0] * stAxes[1][2] + stAxes[0][2] * stAxes[1][0];
257 stAxes[2][2] = stAxes[0][0] * stAxes[1][1] - stAxes[0][1] * stAxes[1][0];
261 axes[0][0] = stAxes[0][0];
262 axes[1][0] = stAxes[0][1];
263 axes[2][0] = stAxes[0][2];
265 axes[0][1] = stAxes[1][0];
266 axes[1][1] = stAxes[1][1];
267 axes[2][1] = stAxes[1][2];
269 axes[0][2] = stAxes[2][0];
270 axes[1][2] = stAxes[2][1];
271 axes[2][2] = stAxes[2][2];
275 double fTrace = axes[0][0] + axes[1][1] + axes[2][2];
281 fRoot = sqrt(fTrace + 1.0);
282 orientation[0] = 0.5 * fRoot;
284 orientation[1] = (axes[2][1] - axes[1][2]) * fRoot;
285 orientation[2] = (axes[0][2] - axes[2][0]) * fRoot;
286 orientation[3] = (axes[1][0] - axes[0][1]) * fRoot;
291 static unsigned int s_iNext[3] = { 1, 2, 0 };
293 if (axes[1][1] > axes[0][0])
295 if (axes[2][2] > axes[i][i])
297 unsigned int j = s_iNext[i];
298 unsigned int k = s_iNext[j];
300 fRoot = sqrt(axes[i][i] - axes[j][j] - axes[k][k] + 1.0);
301 double* apkQuat[3] = { &orientation[1], &orientation[2], &orientation[3] };
302 *apkQuat[i] = 0.5 * fRoot;
304 orientation[0] = (axes[k][j] - axes[j][k]) * fRoot;
305 *apkQuat[j] = (axes[j][i] + axes[i][j]) * fRoot;
306 *apkQuat[k] = (axes[k][i] + axes[i][k]) * fRoot;
316 for (
size_t i = 0; i < size(); i++)
317 ids.push_back(at(i).id);
323 throw cv::Exception(-1,
"The board is not expressed in pixels",
324 "MarkerMap::convertToMeters", __FILE__, __LINE__);
326 int markerSizePix =
static_cast<int>(cv::norm(at(0)[0] - at(0)[1]));
330 float pixSize = markerSize_meters / float(markerSizePix);
333 for (
size_t i = 0; i < BInfo.size(); i++)
334 for (
int c = 0; c < 4; c++)
336 BInfo[i][c] *= pixSize;
343 throw cv::Exception(-1,
"The board is not valid mInfoType==NONE ",
344 "MarkerMap::getImage", __FILE__, __LINE__);
346 throw cv::Exception(-1,
"The board is not expressed in pixels and not METER2PIX indicated",
347 "MarkerMap::getImage", __FILE__, __LINE__);
352 cv::Point pmin(std::numeric_limits<int>::max(), std::numeric_limits<int>::max()),
353 pmax(std::numeric_limits<int>::lowest(), std::numeric_limits<int>::lowest());
356 for (
auto p : b.points)
358 pmin.x = min(
int(p.x), pmin.x);
359 pmin.y = min(
int(p.y), pmin.y);
360 pmax.x = max(
int(p.x + 0.5), pmax.x);
361 pmax.y = max(
int(p.y + 0.5), pmax.y);
366 cv::Point psize = pmax - pmin;
367 cv::Mat image(cv::Size(psize.x, psize.y), CV_8UC1);
368 image.setTo(cv::Scalar::all(255));
370 vector<Marker3DInfo> p3d = *
this;
374 for (
auto& p : m.points)
376 p -= cv::Point3f(
static_cast<float>(pmin.x),
static_cast<float>(pmax.y), 0.f);
383 const float size =
static_cast<float>(cv::norm(m[0] - m[1]));
384 auto im1 = Dict.getMarkerImage_id(m.id,
int(size / 8));
387 cv::resize(im1, im2, cv::Size(
static_cast<int>(size),
static_cast<int>(size)));
389 auto ry = cv::Range(
int(m[0].y),
int(m[2].y));
390 auto rx = cv::Range(
int(m[0].x),
int(m[2].x));
391 cv::Mat sub = image(ry, rx);
399 std::vector<int> indices;
400 for (
size_t i = 0; i < markers.size(); i++)
403 for (
size_t j = 0; j < size() && !found; j++)
405 if (markers[i].
id == at(j).id)
408 indices.push_back(
static_cast<int>(i));
416 str <<
mInfoType <<
" " << size() <<
" ";
417 for (
size_t i = 0; i < size(); i++)
429 for (
size_t i = 0; i < size(); i++)
430 at(i).fromStream(str);
434 float markerSize, cv::Mat CameraMatrix,
437 vector<cv::Point2f> p2d;
443 vector<cv::Point3f> p3d;
444 for (
auto marker : markers)
446 auto it = find(m_meters.begin(), m_meters.end(), marker.id);
447 if (it != m_meters.end())
449 for (
auto p : marker)
451 for (
auto p : it->points)
459 cv::solvePnPRansac(p3d, p2d, CameraMatrix, Distorsion, rvec, tvec);
461 if (rvec.type() == CV_64F)
462 rvec.convertTo(rvec, CV_64F);
463 if (tvec.type() == CV_64F)
464 tvec.convertTo(tvec, CV_64F);
465 return make_pair(rvec, tvec);