JeVoisBase  1.16
JeVois Smart Embedded Machine Vision Toolkit Base Modules
Share this page:
ArUco.C
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 by Laurent Itti, the University of Southern
4 // California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5 //
6 // This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7 // redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8 // Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10 // License for more details. You should have received a copy of the GNU General Public License along with this program;
11 // if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 //
13 // Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14 // Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 /*! \file */
17 
20 #include <jevois/Core/Module.H>
21 #include <opencv2/calib3d.hpp> // for projectPoints()
22 #include <opencv2/imgproc/imgproc.hpp>
23 
24 #include <Eigen/Geometry> // for AngleAxis and Quaternion
25 
26 // ##############################################################################################################
28 { }
29 
30 // ##############################################################################################################
32 {
33  // Defer reading camera parameters to first processed frame, so we know the resolution:
35 
36  // Initialize default detector parameters:
37  itsDetectorParams = cv::aruco::DetectorParameters::create();
38 
39  // Init detector parameters:
41  switch (aruco::dictionary::get())
42  {
43  case aruco::Dict::ATAG_16h5:
44  case aruco::Dict::ATAG_25h9:
45  case aruco::Dict::ATAG_36h10:
46  case aruco::Dict::ATAG_36h11:
47  itsDetectorParams->cornerRefinementMethod = cv::aruco::CORNER_REFINE_APRILTAG;
48  break;
49 
50  default:
51  itsDetectorParams->cornerRefinementMethod = cv::aruco::CORNER_REFINE_SUBPIX;
52  }
53 
54  // Read detector parameters if any:
56  std::string const dpf = aruco::detparams::get();
57  if (dpf.empty() == false)
58  {
59  cv::FileStorage fs(dpf, cv::FileStorage::READ);
60  if (fs.isOpened())
61  {
62  fs["adaptiveThreshWinSizeMin"] >> itsDetectorParams->adaptiveThreshWinSizeMin;
63  fs["adaptiveThreshWinSizeMax"] >> itsDetectorParams->adaptiveThreshWinSizeMax;
64  fs["adaptiveThreshWinSizeStep"] >> itsDetectorParams->adaptiveThreshWinSizeStep;
65  fs["adaptiveThreshConstant"] >> itsDetectorParams->adaptiveThreshConstant;
66  fs["minMarkerPerimeterRate"] >> itsDetectorParams->minMarkerPerimeterRate;
67  fs["maxMarkerPerimeterRate"] >> itsDetectorParams->maxMarkerPerimeterRate;
68  fs["polygonalApproxAccuracyRate"] >> itsDetectorParams->polygonalApproxAccuracyRate;
69  fs["minCornerDistanceRate"] >> itsDetectorParams->minCornerDistanceRate;
70  fs["minDistanceToBorder"] >> itsDetectorParams->minDistanceToBorder;
71  fs["minMarkerDistanceRate"] >> itsDetectorParams->minMarkerDistanceRate;
72  fs["cornerRefinementMethod"] >> itsDetectorParams->cornerRefinementMethod;
73  fs["cornerRefinementWinSize"] >> itsDetectorParams->cornerRefinementWinSize;
74  fs["cornerRefinementMaxIterations"] >> itsDetectorParams->cornerRefinementMaxIterations;
75  fs["cornerRefinementMinAccuracy"] >> itsDetectorParams->cornerRefinementMinAccuracy;
76  fs["markerBorderBits"] >> itsDetectorParams->markerBorderBits;
77  fs["perspectiveRemovePixelPerCell"] >> itsDetectorParams->perspectiveRemovePixelPerCell;
78  fs["perspectiveRemoveIgnoredMarginPerCell"] >> itsDetectorParams->perspectiveRemoveIgnoredMarginPerCell;
79  fs["maxErroneousBitsInBorderRate"] >> itsDetectorParams->maxErroneousBitsInBorderRate;
80  fs["minOtsuStdDev"] >> itsDetectorParams->minOtsuStdDev;
81  fs["errorCorrectionRate"] >> itsDetectorParams->errorCorrectionRate;
82 
83  fs["aprilTagQuadDecimate"] >> itsDetectorParams->aprilTagQuadDecimate;
84  fs["aprilTagQuadSigma"] >> itsDetectorParams->aprilTagQuadSigma;
85  fs["aprilTagMinClusterPixels"] >> itsDetectorParams->aprilTagMinClusterPixels;
86  fs["aprilTagMaxNmaxima"] >> itsDetectorParams->aprilTagMaxNmaxima;
87  fs["aprilTagCriticalRad"] >> itsDetectorParams->aprilTagCriticalRad;
88  fs["aprilTagMaxLineFitMse"] >> itsDetectorParams->aprilTagMaxLineFitMse;
89  fs["aprilTagMinWhiteBlackDiff"] >> itsDetectorParams->aprilTagMinWhiteBlackDiff;
90  fs["aprilTagDeglitch"] >> itsDetectorParams->aprilTagDeglitch;
91  fs["detectInvertedMarker"] >> itsDetectorParams->detectInvertedMarker;
92  }
93  else LERROR("Failed to read detector parameters from file [" << dpf << "] -- IGNORED");
94  }
95 
96  // Instantiate the dictionary:
97  switch (aruco::dictionary::get())
98  {
99  case aruco::Dict::Original: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_ARUCO_ORIGINAL);break;
100  case aruco::Dict::D4X4_50: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_50); break;
101  case aruco::Dict::D4X4_100: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_100); break;
102  case aruco::Dict::D4X4_250: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_250); break;
103  case aruco::Dict::D4X4_1000: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_1000); break;
104  case aruco::Dict::D5X5_50: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_5X5_50); break;
105  case aruco::Dict::D5X5_100: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_5X5_100); break;
106  case aruco::Dict::D5X5_250: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_5X5_250); break;
107  case aruco::Dict::D5X5_1000: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_5X5_1000); break;
108  case aruco::Dict::D6X6_50: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_50); break;
109  case aruco::Dict::D6X6_100: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_100); break;
110  case aruco::Dict::D6X6_250: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250); break;
111  case aruco::Dict::D6X6_1000: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_1000); break;
112  case aruco::Dict::D7X7_50: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_7X7_50); break;
113  case aruco::Dict::D7X7_100: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_7X7_100); break;
114  case aruco::Dict::D7X7_250: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_7X7_250); break;
115  case aruco::Dict::D7X7_1000: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_7X7_1000); break;
116 
117  case aruco::Dict::ATAG_16h5: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_APRILTAG_16h5); break;
118  case aruco::Dict::ATAG_25h9: itsDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_APRILTAG_25h9); break;
119  case aruco::Dict::ATAG_36h10: itsDictionary=cv::aruco::getPredefinedDictionary(cv::aruco::DICT_APRILTAG_36h10); break;
120  case aruco::Dict::ATAG_36h11: itsDictionary=cv::aruco::getPredefinedDictionary(cv::aruco::DICT_APRILTAG_36h11); break;
121  }
122 }
123 
124 // ##############################################################################################################
126 {
127  itsDictionary.release();
128  itsDetectorParams.release();
129  itsCamMatrix = cv::Mat();
130  itsDistCoeffs = cv::Mat();
134 }
135 
136 // ##############################################################################################################
137 void ArUco::detectMarkers(cv::InputArray image, cv::OutputArray ids, cv::OutputArrayOfArrays corners)
138 {
139  if (itsCamMatrix.empty())
140  {
141  std::string const cpf = std::string(JEVOIS_SHARE_PATH) + "/camera/" + aruco::camparams::get() +
142  std::to_string(image.cols()) + 'x' + std::to_string(image.rows()) + ".yaml";
143 
144  cv::FileStorage fs(cpf, cv::FileStorage::READ);
145  if (fs.isOpened())
146  {
147  fs["camera_matrix"] >> itsCamMatrix;
148  fs["distortion_coefficients"] >> itsDistCoeffs;
149  LINFO("Loaded camera calibration from " << cpf);
150  }
151  else
152  {
153  LERROR("Failed to read camera parameters from file [" << cpf << "] -- IGNORED");
154  itsCamMatrix = cv::Mat::eye(3, 3, CV_64F);
155  itsDistCoeffs = cv::Mat::zeros(5, 1, CV_64F);
156  }
157  }
158 
159  cv::aruco::detectMarkers(image, itsDictionary, corners, ids, itsDetectorParams);
160 }
161 
162 // ##############################################################################################################
163 void ArUco::estimatePoseSingleMarkers(cv::InputArrayOfArrays corners, cv::OutputArray rvecs, cv::OutputArray tvecs)
164 {
165  cv::aruco::estimatePoseSingleMarkers(corners, markerlen::get(), itsCamMatrix, itsDistCoeffs, rvecs, tvecs);
166 }
167 
168 // ##############################################################################################################
169 void ArUco::sendSerial(jevois::StdModule * mod, std::vector<int> ids, std::vector<std::vector<cv::Point2f> > corners,
170  unsigned int w, unsigned int h, std::vector<cv::Vec3d> const & rvecs,
171  std::vector<cv::Vec3d> const & tvecs)
172 {
173  if (rvecs.empty() == false)
174  {
175  float const siz = markerlen::get();
176 
177  // If we have rvecs and tvecs, we are doing 3D pose estimation, so send a 3D message:
178  for (size_t i = 0; i < corners.size(); ++i)
179  {
180  cv::Vec3d const & rv = rvecs[i];
181  cv::Vec3d const & tv = tvecs[i];
182 
183  // Compute quaternion:
184  float theta = std::sqrt(rv[0] * rv[0] + rv[1] * rv[1] + rv[2] * rv[2]);
185  Eigen::Vector3f axis(rv[0], rv[1], rv[2]);
186  Eigen::Quaternion<float> q(Eigen::AngleAxis<float>(theta, axis));
187 
188  mod->sendSerialStd3D(tv[0], tv[1], tv[2], // position
189  siz, siz, 1.0F, // size
190  q.w(), q.x(), q.y(), q.z(), // pose
191  "U" + std::to_string(ids[i])); // decoded ID with "U" prefix for ArUco
192  }
193  }
194  else
195  {
196  // Send one 2D message per marker:
197  for (size_t i = 0; i < corners.size(); ++i)
198  {
199  std::vector<cv::Point2f> const & currentMarker = corners[i];
200  mod->sendSerialContour2D(w, h, currentMarker, "U" + std::to_string(ids[i]));
201  }
202  }
203 }
204 
205 // ##############################################################################################################
206 void ArUco::drawDetections(jevois::RawImage & outimg, int txtx, int txty, std::vector<int> ids,
207  std::vector<std::vector<cv::Point2f> > corners, std::vector<cv::Vec3d> const & rvecs,
208  std::vector<cv::Vec3d> const & tvecs)
209 {
210  // This code is like drawDetectedMarkers() in cv::aruco, but for YUYV output image:
211  int nMarkers = int(corners.size());
212  for (int i = 0; i < nMarkers; ++i)
213  {
214  std::vector<cv::Point2f> const & currentMarker = corners[i];
215 
216  // draw marker sides and prepare serial out string:
217  for (int j = 0; j < 4; ++j)
218  {
219  cv::Point2f const & p0 = currentMarker[j];
220  cv::Point2f const & p1 = currentMarker[ (j+1) % 4 ];
221  jevois::rawimage::drawLine(outimg, int(p0.x + 0.5F), int(p0.y + 0.5F),
222  int(p1.x + 0.5F), int(p1.y + 0.5F), 1, jevois::yuyv::LightGreen);
223  }
224 
225  // draw first corner mark
226  jevois::rawimage::drawDisk(outimg, int(currentMarker[0].x + 0.5F), int(currentMarker[0].y + 0.5F),
227  3, jevois::yuyv::LightGreen);
228 
229  // draw ID
230  if (ids.empty() == false)
231  {
232  cv::Point2f cent(0.0F, 0.0F); for (int p = 0; p < 4; ++p) cent += currentMarker[p] * 0.25F;
233  jevois::rawimage::writeText(outimg, std::string("id=") + std::to_string(ids[i]),
234  int(cent.x + 0.5F), int(cent.y + 0.5F) - 5, jevois::yuyv::LightGreen);
235  }
236  }
237 
238  // This code is like drawAxis() in cv::aruco, but for YUYV output image:
239  if (dopose::get() && ids.empty() == false)
240  {
241  float const length = markerlen::get() * 0.4F;
242 
243  for (size_t i = 0; i < ids.size(); ++i)
244  {
245  // Project axis points:
246  std::vector<cv::Point3f> axisPoints;
247  axisPoints.push_back(cv::Point3f(0.0F, 0.0F, 0.0F));
248  axisPoints.push_back(cv::Point3f(length, 0.0F, 0.0F));
249  axisPoints.push_back(cv::Point3f(0.0F, length, 0.0F));
250  axisPoints.push_back(cv::Point3f(0.0F, 0.0F, length));
251 
252  std::vector<cv::Point2f> imagePoints;
253  cv::projectPoints(axisPoints, rvecs[i], tvecs[i], itsCamMatrix, itsDistCoeffs, imagePoints);
254 
255  // Draw axis lines
256  jevois::rawimage::drawLine(outimg, int(imagePoints[0].x + 0.5F), int(imagePoints[0].y + 0.5F),
257  int(imagePoints[1].x + 0.5F), int(imagePoints[1].y + 0.5F),
258  2, jevois::yuyv::MedPurple);
259  jevois::rawimage::drawLine(outimg, int(imagePoints[0].x + 0.5F), int(imagePoints[0].y + 0.5F),
260  int(imagePoints[2].x + 0.5F), int(imagePoints[2].y + 0.5F),
261  2, jevois::yuyv::MedGreen);
262  jevois::rawimage::drawLine(outimg, int(imagePoints[0].x + 0.5F), int(imagePoints[0].y + 0.5F),
263  int(imagePoints[3].x + 0.5F), int(imagePoints[3].y + 0.5F),
264  2, jevois::yuyv::MedGrey);
265 
266  // Also draw a cube if requested:
267  if (showcube::get())
268  {
269  float const len = markerlen::get() * 0.5F;
270 
271  std::vector<cv::Point3f> cubePoints;
272  cubePoints.push_back(cv::Point3f(-len, -len, 0.0F));
273  cubePoints.push_back(cv::Point3f(len, -len, 0.0F));
274  cubePoints.push_back(cv::Point3f(len, len, 0.0F));
275  cubePoints.push_back(cv::Point3f(-len, len, 0.0F));
276  cubePoints.push_back(cv::Point3f(-len, -len, len * 2.0F));
277  cubePoints.push_back(cv::Point3f(len, -len, len * 2.0F));
278  cubePoints.push_back(cv::Point3f(len, len, len * 2.0F));
279  cubePoints.push_back(cv::Point3f(-len, len, len * 2.0F));
280 
281  std::vector<cv::Point2f> cuf;
282  cv::projectPoints(cubePoints, rvecs[i], tvecs[i], itsCamMatrix, itsDistCoeffs, cuf);
283 
284  // Round all the coordinates:
285  std::vector<cv::Point> cu;
286  for (auto const & p : cuf) cu.push_back(cv::Point(int(p.x + 0.5F), int(p.y + 0.5F)));
287 
288  // Draw cube lines:
289  jevois::rawimage::drawLine(outimg, cu[0].x, cu[0].y, cu[1].x, cu[1].y, 2, jevois::yuyv::LightGreen);
290  jevois::rawimage::drawLine(outimg, cu[1].x, cu[1].y, cu[2].x, cu[2].y, 2, jevois::yuyv::LightGreen);
291  jevois::rawimage::drawLine(outimg, cu[2].x, cu[2].y, cu[3].x, cu[3].y, 2, jevois::yuyv::LightGreen);
292  jevois::rawimage::drawLine(outimg, cu[3].x, cu[3].y, cu[0].x, cu[0].y, 2, jevois::yuyv::LightGreen);
293  jevois::rawimage::drawLine(outimg, cu[4].x, cu[4].y, cu[5].x, cu[5].y, 2, jevois::yuyv::LightGreen);
294  jevois::rawimage::drawLine(outimg, cu[5].x, cu[5].y, cu[6].x, cu[6].y, 2, jevois::yuyv::LightGreen);
295  jevois::rawimage::drawLine(outimg, cu[6].x, cu[6].y, cu[7].x, cu[7].y, 2, jevois::yuyv::LightGreen);
296  jevois::rawimage::drawLine(outimg, cu[7].x, cu[7].y, cu[4].x, cu[4].y, 2, jevois::yuyv::LightGreen);
297  jevois::rawimage::drawLine(outimg, cu[0].x, cu[0].y, cu[4].x, cu[4].y, 2, jevois::yuyv::LightGreen);
298  jevois::rawimage::drawLine(outimg, cu[1].x, cu[1].y, cu[5].x, cu[5].y, 2, jevois::yuyv::LightGreen);
299  jevois::rawimage::drawLine(outimg, cu[2].x, cu[2].y, cu[6].x, cu[6].y, 2, jevois::yuyv::LightGreen);
300  jevois::rawimage::drawLine(outimg, cu[3].x, cu[3].y, cu[7].x, cu[7].y, 2, jevois::yuyv::LightGreen);
301  }
302 
303  }
304  }
305 
306  if (txtx >=0 && txty >= 0)
307  jevois::rawimage::writeText(outimg, "Detected " + std::to_string(ids.size()) + " ArUco markers.",
308  txtx, txty, jevois::yuyv::White);
309 }
310 
311 #ifdef JEVOIS_PRO
312 // ##############################################################################################################
313 void ArUco::drawDetections(jevois::GUIhelper & helper, std::vector<int> ids,
314  std::vector<std::vector<cv::Point2f> > corners, std::vector<cv::Vec3d> const & rvecs,
315  std::vector<cv::Vec3d> const & tvecs)
316 {
317  ImU32 const col = ImColor(128, 255, 128, 255); // light green for lines
318 
319  // This code is like drawDetectedMarkers() in cv::aruco, but for ImGui:
320  int nMarkers = int(corners.size());
321  for (int i = 0; i < nMarkers; ++i)
322  {
323  std::vector<cv::Point2f> const & currentMarker = corners[i];
324 
325  // draw marker sides and prepare serial out string:
326  helper.drawPoly(currentMarker, col, true);
327 
328  // draw first corner mark
329  helper.drawCircle(currentMarker[0].x, currentMarker[0].y, 3.0F, col, true);
330 
331  // draw ID
332  if (ids.empty() == false)
333  {
334  cv::Point2f cent(0.0F, 0.0F); for (int p = 0; p < 4; ++p) cent += currentMarker[p] * 0.25F;
335  helper.drawText(cent.x, cent.y - 10, ("id=" + std::to_string(ids[i])).c_str(), col);
336  }
337  }
338 
339  // This code is like drawAxis() in cv::aruco, but for ImGui:
340  if (dopose::get() && ids.empty() == false)
341  {
342  float const length = markerlen::get() * 0.4F;
343 
344  for (size_t i = 0; i < ids.size(); ++i)
345  {
346  // Project axis points:
347  std::vector<cv::Point3f> axisPoints;
348  axisPoints.push_back(cv::Point3f(0.0F, 0.0F, 0.0F));
349  axisPoints.push_back(cv::Point3f(length, 0.0F, 0.0F));
350  axisPoints.push_back(cv::Point3f(0.0F, length, 0.0F));
351  axisPoints.push_back(cv::Point3f(0.0F, 0.0F, length));
352 
353  std::vector<cv::Point2f> imagePoints;
354  cv::projectPoints(axisPoints, rvecs[i], tvecs[i], itsCamMatrix, itsDistCoeffs, imagePoints);
355 
356  // Draw axis lines
357  helper.drawLine(imagePoints[0].x, imagePoints[0].y, imagePoints[1].x, imagePoints[1].y, 0xff0000ff);
358  helper.drawLine(imagePoints[0].x, imagePoints[0].y, imagePoints[2].x, imagePoints[2].y, 0xff00ff00);
359  helper.drawLine(imagePoints[0].x, imagePoints[0].y, imagePoints[3].x, imagePoints[3].y, 0xffff0000);
360 
361  // Also draw a cube if requested:
362  if (showcube::get())
363  {
364  float const len = markerlen::get() * 0.5F;
365 
366  std::vector<cv::Point3f> cubePoints;
367  cubePoints.push_back(cv::Point3f(-len, -len, 0.0F));
368  cubePoints.push_back(cv::Point3f(len, -len, 0.0F));
369  cubePoints.push_back(cv::Point3f(len, len, 0.0F));
370  cubePoints.push_back(cv::Point3f(-len, len, 0.0F));
371  cubePoints.push_back(cv::Point3f(-len, -len, len * 2.0F));
372  cubePoints.push_back(cv::Point3f(len, -len, len * 2.0F));
373  cubePoints.push_back(cv::Point3f(len, len, len * 2.0F));
374  cubePoints.push_back(cv::Point3f(-len, len, len * 2.0F));
375 
376  std::vector<cv::Point2f> cuf;
377  cv::projectPoints(cubePoints, rvecs[i], tvecs[i], itsCamMatrix, itsDistCoeffs, cuf);
378 
379  auto drawface =
380  [&](int a, int b, int c, int d)
381  {
382  std::vector<cv::Point2f> p { cuf[a], cuf[b], cuf[c], cuf[d] };
383  helper.drawPoly(p, col, true);
384  };
385 
386  // Draw cube lines and faces. For faces, vertices must be in clockwise order:
387  drawface(0, 1, 2, 3);
388  drawface(0, 1, 5, 4);
389  drawface(1, 2, 6, 5);
390  drawface(2, 3, 7, 6);
391  drawface(3, 0, 4, 7);
392  drawface(4, 5, 6, 7);
393  }
394  }
395  }
396 
397  helper.itext("Detected " + std::to_string(ids.size()) + " ArUco markers.");
398 }
399 
400 #endif
ArUco::detectMarkers
void detectMarkers(cv::InputArray image, cv::OutputArray ids, cv::OutputArrayOfArrays corners)
Detect markers.
Definition: ArUco.C:137
jevois::rawimage::drawDisk
void drawDisk(RawImage &img, int x, int y, unsigned int rad, unsigned int col)
jevois::StdModule::sendSerialContour2D
void sendSerialContour2D(unsigned int camw, unsigned int camh, std::vector< cv::Point_< T > > points, std::string const &id="", std::string const &extra="")
jevois::GUIhelper::drawCircle
void drawCircle(float x, float y, float r, ImU32 col=IM_COL32(128, 255, 128, 255), bool filled=true)
jevois::GUIhelper::itext
void itext(char const *txt, ImU32 const &col=IM_COL32_BLACK_TRANS, int line=-1)
Module.H
jevois::GUIhelper
ArUco::postUninit
void postUninit() override
Un-initialize, nuke allocated resources.
Definition: ArUco.C:125
jevois::RawImage
LERROR
#define LERROR(msg)
jevois::GUIhelper::drawLine
void drawLine(float x1, float y1, float x2, float y2, ImU32 col=IM_COL32(128, 255, 128, 255))
ArUco::estimatePoseSingleMarkers
void estimatePoseSingleMarkers(cv::InputArrayOfArrays corners, cv::OutputArray rvecs, cv::OutputArray tvecs)
Estimate pose of individual markers.
Definition: ArUco.C:163
jevois::rawimage::writeText
void writeText(RawImage &img, std::string const &txt, int x, int y, unsigned int col, Font font=Font6x10)
F
float F
jevois::GUIhelper::drawPoly
void drawPoly(std::vector< cv::Point > const &pts, ImU32 col=IM_COL32(128, 255, 128, 255), bool filled=true)
ArUco::~ArUco
virtual ~ArUco()
Destructor.
Definition: ArUco.C:27
ArUco::itsDistCoeffs
cv::Mat itsDistCoeffs
Our current distortion coefficients.
Definition: ArUco.H:184
jevois::GUIhelper::drawText
void drawText(float x, float y, char const *txt, ImU32 col=IM_COL32(128, 255, 128, 255))
RawImageOps.H
ArUco::drawDetections
void drawDetections(jevois::RawImage &outimg, int txtx, int txty, std::vector< int > ids, std::vector< std::vector< cv::Point2f > > corners, std::vector< cv::Vec3d > const &rvecs, std::vector< cv::Vec3d > const &tvecs)
Draw any markers previously detected by detectMarkers()
Definition: ArUco.C:206
to_string
std::string to_string(T const &val)
unFreeze
void unFreeze()
ArUco::itsDictionary
cv::Ptr< cv::aruco::Dictionary > itsDictionary
Definition: ArUco.H:188
ArUco.H
h
int h
jevois::StdModule::sendSerialStd3D
void sendSerialStd3D(float x, float y, float z, float w=0.0F, float h=0.0F, float d=0.0F, float q1=0.0F, float q2=0.0F, float q3=0.0f, float q4=0.0F, std::string const &id="", std::string const &extra="")
ArUco::itsCamMatrix
cv::Mat itsCamMatrix
Our current camera matrix.
Definition: ArUco.H:181
freeze
void freeze()
ArUco::postInit
void postInit() override
Initialize, create the detector and read the config files.
Definition: ArUco.C:31
jevois::StdModule
jevois::rawimage::drawLine
void drawLine(RawImage &img, int x1, int y1, int x2, int y2, unsigned int thick, unsigned int col)
LINFO
#define LINFO(msg)
ArUco::sendSerial
void sendSerial(jevois::StdModule *mod, std::vector< int > ids, std::vector< std::vector< cv::Point2f > > corners, unsigned int w, unsigned int h, std::vector< cv::Vec3d > const &rvecs, std::vector< cv::Vec3d > const &tvecs)
Send serial messages about detections.
Definition: ArUco.C:169
ArUco::itsDetectorParams
cv::Ptr< cv::aruco::DetectorParameters > itsDetectorParams
Definition: ArUco.H:187