opencv_demo.cc
Go to the documentation of this file.
1 /* Copyright (C) 2013-2016, The Regents of The University of Michigan.
2 All rights reserved.
3 This software was developed in the APRIL Robotics Lab under the
4 direction of Edwin Olson, ebolson@umich.edu. This software may be
5 available under alternative licensing terms; contact the address above.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 1. Redistributions of source code must retain the above copyright notice, this
9  list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation
12  and/or other materials provided with the distribution.
13 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 The views and conclusions contained in the software and documentation are those
24 of the authors and should not be interpreted as representing official policies,
25 either expressed or implied, of the Regents of The University of Michigan.
26 */
27 
28 #include <iostream>
29 #include <iomanip>
30 
31 #include "opencv2/opencv.hpp"
32 
33 extern "C" {
34 #include "apriltag.h"
35 #include "tag36h11.h"
36 #include "tag25h9.h"
37 #include "tag16h5.h"
38 #include "tagCircle21h7.h"
39 #include "tagCircle49h12.h"
40 #include "tagCustom48h12.h"
41 #include "tagStandard41h12.h"
42 #include "tagStandard52h13.h"
43 #include "common/getopt.h"
44 }
45 
46 using namespace std;
47 using namespace cv;
48 
49 
50 int main(int argc, char *argv[])
51 {
53 
54  getopt_add_bool(getopt, 'h', "help", 0, "Show this help");
55  getopt_add_int(getopt, 'c', "camera", "0", "camera ID");
56  getopt_add_bool(getopt, 'd', "debug", 0, "Enable debugging output (slow)");
57  getopt_add_bool(getopt, 'q', "quiet", 0, "Reduce output");
58  getopt_add_string(getopt, 'f', "family", "tag36h11", "Tag family to use");
59  getopt_add_int(getopt, 't', "threads", "1", "Use this many CPU threads");
60  getopt_add_double(getopt, 'x', "decimate", "2.0", "Decimate input image by this factor");
61  getopt_add_double(getopt, 'b', "blur", "0.0", "Apply low-pass blur to input");
62  getopt_add_bool(getopt, '0', "refine-edges", 1, "Spend more time trying to align edges of tags");
63 
64  if (!getopt_parse(getopt, argc, argv, 1) ||
65  getopt_get_bool(getopt, "help")) {
66  printf("Usage: %s [options]\n", argv[0]);
68  exit(0);
69  }
70 
71  cout << "Enabling video capture" << endl;
72 
73  TickMeter meter;
74  meter.start();
75 
76  // Initialize camera
77  VideoCapture cap(getopt_get_int(getopt, "camera"));
78  if (!cap.isOpened()) {
79  cerr << "Couldn't open video capture device" << endl;
80  return -1;
81  }
82 
83  // Initialize tag detector with options
84  apriltag_family_t *tf = NULL;
85  const char *famname = getopt_get_string(getopt, "family");
86  if (!strcmp(famname, "tag36h11")) {
87  tf = tag36h11_create();
88  } else if (!strcmp(famname, "tag25h9")) {
89  tf = tag25h9_create();
90  } else if (!strcmp(famname, "tag16h5")) {
91  tf = tag16h5_create();
92  } else if (!strcmp(famname, "tagCircle21h7")) {
93  tf = tagCircle21h7_create();
94  } else if (!strcmp(famname, "tagCircle49h12")) {
95  tf = tagCircle49h12_create();
96  } else if (!strcmp(famname, "tagStandard41h12")) {
98  } else if (!strcmp(famname, "tagStandard52h13")) {
100  } else if (!strcmp(famname, "tagCustom48h12")) {
101  tf = tagCustom48h12_create();
102  } else {
103  printf("Unrecognized tag family name. Use e.g. \"tag36h11\".\n");
104  exit(-1);
105  }
106 
107 
110 
111  if (errno == ENOMEM) {
112  printf("Unable to add family to detector due to insufficient memory to allocate the tag-family decoder with the default maximum hamming value of 2. Try choosing an alternative tag family.\n");
113  exit(-1);
114  }
115 
116  td->quad_decimate = getopt_get_double(getopt, "decimate");
117  td->quad_sigma = getopt_get_double(getopt, "blur");
118  td->nthreads = getopt_get_int(getopt, "threads");
119  td->debug = getopt_get_bool(getopt, "debug");
120  td->refine_edges = getopt_get_bool(getopt, "refine-edges");
121 
122  meter.stop();
123  cout << "Detector " << famname << " initialized in "
124  << std::fixed << std::setprecision(3) << meter.getTimeSec() << " seconds" << endl;
125 #if CV_MAJOR_VERSION > 3
126  cout << " " << cap.get(CAP_PROP_FRAME_WIDTH ) << "x" <<
127  cap.get(CAP_PROP_FRAME_HEIGHT ) << " @" <<
128  cap.get(CAP_PROP_FPS) << "FPS" << endl;
129 #else
130  cout << " " << cap.get(CV_CAP_PROP_FRAME_WIDTH ) << "x" <<
131  cap.get(CV_CAP_PROP_FRAME_HEIGHT ) << " @" <<
132  cap.get(CV_CAP_PROP_FPS) << "FPS" << endl;
133 #endif
134  meter.reset();
135 
136  Mat frame, gray;
137  while (true) {
138  errno = 0;
139  cap >> frame;
140  cvtColor(frame, gray, COLOR_BGR2GRAY);
141 
142  // Make an image_u8_t header for the Mat data
143  image_u8_t im = {gray.cols, gray.rows, gray.cols, gray.data};
144 
145  zarray_t *detections = apriltag_detector_detect(td, &im);
146 
147  if (errno == EAGAIN) {
148  printf("Unable to create the %d threads requested.\n",td->nthreads);
149  exit(-1);
150  }
151 
152  // Draw detection outlines
153  for (int i = 0; i < zarray_size(detections); i++) {
155  zarray_get(detections, i, &det);
156  line(frame, Point(det->p[0][0], det->p[0][1]),
157  Point(det->p[1][0], det->p[1][1]),
158  Scalar(0, 0xff, 0), 2);
159  line(frame, Point(det->p[0][0], det->p[0][1]),
160  Point(det->p[3][0], det->p[3][1]),
161  Scalar(0, 0, 0xff), 2);
162  line(frame, Point(det->p[1][0], det->p[1][1]),
163  Point(det->p[2][0], det->p[2][1]),
164  Scalar(0xff, 0, 0), 2);
165  line(frame, Point(det->p[2][0], det->p[2][1]),
166  Point(det->p[3][0], det->p[3][1]),
167  Scalar(0xff, 0, 0), 2);
168 
169  stringstream ss;
170  ss << det->id;
171  String text = ss.str();
172  int fontface = FONT_HERSHEY_SCRIPT_SIMPLEX;
173  double fontscale = 1.0;
174  int baseline;
175  Size textsize = getTextSize(text, fontface, fontscale, 2,
176  &baseline);
177  putText(frame, text, Point(det->c[0]-textsize.width/2,
178  det->c[1]+textsize.height/2),
179  fontface, fontscale, Scalar(0xff, 0x99, 0), 2);
180  }
181  apriltag_detections_destroy(detections);
182 
183  imshow("Tag Detections", frame);
184  if (waitKey(30) >= 0)
185  break;
186  }
187 
189 
190  if (!strcmp(famname, "tag36h11")) {
191  tag36h11_destroy(tf);
192  } else if (!strcmp(famname, "tag25h9")) {
193  tag25h9_destroy(tf);
194  } else if (!strcmp(famname, "tag16h5")) {
195  tag16h5_destroy(tf);
196  } else if (!strcmp(famname, "tagCircle21h7")) {
198  } else if (!strcmp(famname, "tagCircle49h12")) {
200  } else if (!strcmp(famname, "tagStandard41h12")) {
202  } else if (!strcmp(famname, "tagStandard52h13")) {
204  } else if (!strcmp(famname, "tagCustom48h12")) {
206  }
207 
208 
210 
211  return 0;
212 }
apriltag_detector::nthreads
int nthreads
Definition: apriltag.h:133
tagStandard41h12_destroy
void tagStandard41h12_destroy(apriltag_family_t *tf)
Definition: tagStandard41h12.c:2246
getopt_destroy
void getopt_destroy(getopt_t *gopt)
Definition: getopt.c:94
getopt_parse
int getopt_parse(getopt_t *gopt, int argc, char *argv[], int showErrors)
Definition: getopt.c:147
getopt_get_int
int getopt_get_int(getopt_t *getopt, const char *lname)
Definition: getopt.c:425
tag36h11_destroy
void tag36h11_destroy(apriltag_family_t *tf)
Definition: tag36h11.c:708
tag16h5_destroy
void tag16h5_destroy(apriltag_family_t *tf)
Definition: tag16h5.c:111
tagCustom48h12_create
apriltag_family_t * tagCustom48h12_create()
Definition: tagCustom48h12.c:42244
getopt_create
getopt_t * getopt_create()
Definition: getopt.c:67
getopt_add_bool
void getopt_add_bool(getopt_t *gopt, char sopt, const char *lname, int def, const char *help)
Definition: getopt.c:326
getopt.h
apriltag_detector_detect
zarray_t * apriltag_detector_detect(apriltag_detector_t *td, image_u8_t *im_orig)
Definition: apriltag.c:1029
getopt
Definition: getopt.c:59
getopt_add_string
void getopt_add_string(getopt_t *gopt, char sopt, const char *lname, const char *def, const char *help)
Definition: getopt.c:376
zarray
Definition: zarray.h:43
getopt_do_usage
void getopt_do_usage(getopt_t *gopt)
Definition: getopt.c:492
zarray_size
static int zarray_size(const zarray_t *za)
Definition: zarray.h:130
tag25h9_create
apriltag_family_t * tag25h9_create()
Definition: tag25h9.c:68
getopt_add_double
void getopt_add_double(getopt_t *gopt, char sopt, const char *lname, const char *def, const char *help)
Definition: getopt.c:371
apriltag.h
tag16h5_create
apriltag_family_t * tag16h5_create()
Definition: tag16h5.c:63
tagCircle49h12_destroy
void tagCircle49h12_destroy(apriltag_family_t *tf)
Definition: tagCircle49h12.c:65682
tagCircle21h7_create
apriltag_family_t * tagCircle21h7_create()
Definition: tagCircle21h7.c:71
getopt_get_string
const char * getopt_get_string(getopt_t *gopt, const char *lname)
Definition: getopt.c:415
apriltag_detector_create
apriltag_detector_t * apriltag_detector_create()
Definition: apriltag.c:354
tagCircle21h7.h
image_u8
Definition: image_types.h:37
getopt_get_double
double getopt_get_double(getopt_t *getopt, const char *lname)
Definition: getopt.c:455
apriltag_detector::debug
bool debug
Definition: apriltag.h:166
apriltag_detections_destroy
void apriltag_detections_destroy(zarray_t *detections)
Definition: apriltag.c:1436
tagCircle21h7_destroy
void tagCircle21h7_destroy(apriltag_family_t *tf)
Definition: tagCircle21h7.c:129
tag16h5.h
apriltag_detector
Definition: apriltag.h:127
tagStandard52h13_destroy
void tagStandard52h13_destroy(apriltag_family_t *tf)
Definition: tagStandard52h13.c:48867
apriltag_family
Definition: apriltag.h:61
tagCustom48h12_destroy
void tagCustom48h12_destroy(apriltag_family_t *tf)
Definition: tagCustom48h12.c:42356
tagStandard52h13.h
apriltag_detector::quad_decimate
float quad_decimate
Definition: apriltag.h:139
apriltag_detection::p
double p[4][2]
Definition: apriltag.h:230
tagCustom48h12.h
tag36h11.h
apriltag_detection::id
int id
Definition: apriltag.h:202
tagCircle49h12.h
apriltag_detector_destroy
void apriltag_detector_destroy(apriltag_detector_t *td)
Definition: apriltag.c:388
tag25h9_destroy
void tag25h9_destroy(apriltag_family_t *tf)
Definition: tag25h9.c:134
apriltag_detector_add_family
static void apriltag_detector_add_family(apriltag_detector_t *td, apriltag_family_t *fam)
Definition: apriltag.h:243
tagCircle49h12_create
apriltag_family_t * tagCircle49h12_create()
Definition: tagCircle49h12.c:65568
zarray_get
static void zarray_get(const zarray_t *za, int idx, void *p)
Definition: zarray.h:195
apriltag_detection
Definition: apriltag.h:196
apriltag_detector::refine_edges
bool refine_edges
Definition: apriltag.h:154
getopt_add_int
void getopt_add_int(getopt_t *gopt, char sopt, const char *lname, const char *def, const char *help)
Definition: getopt.c:365
main
int main(int argc, char *argv[])
Definition: opencv_demo.cc:50
tagStandard52h13_create
apriltag_family_t * tagStandard52h13_create()
Definition: tagStandard52h13.c:48747
tag36h11_create
apriltag_family_t * tag36h11_create()
Definition: tag36h11.c:620
apriltag_detection::c
double c[2]
Definition: apriltag.h:226
apriltag_detector::quad_sigma
float quad_sigma
Definition: apriltag.h:145
tagStandard41h12_create
apriltag_family_t * tagStandard41h12_create()
Definition: tagStandard41h12.c:2148
tag25h9.h
getopt_get_bool
int getopt_get_bool(getopt_t *getopt, const char *lname)
Definition: getopt.c:447
tagStandard41h12.h


apriltag
Author(s): Edwin Olson , Max Krogius
autogenerated on Sun Apr 20 2025 02:08:19