Visual Servoing Platform  version 3.3.0 under development (2020-02-17)
VispDetector.mm
1 // This file is copied and modified from original file, which is distributed under
2 // GNU General Public License v2.0.
3 // VispDetector.mm
4 // https://github.com/AplixCorporation/groma-AprilTag/
5 // See also https://groma.jp for more information.
6 
7 #import "VispDetector.h"
8 #import "ImageConversion.h"
9 #import "ImageDisplay+withContext.h"
10 
12 
13 @implementation VispDetector
14 
15 - (UIImage *)detectAprilTag:(UIImage *)image px:(float)px py:(float)py {
16 
17  // make vpImage for the detection.
18  vpImage<unsigned char> I = [ImageConversion vpImageGrayFromUIImage:image];
19 
20  float u0 = I.getWidth()/2;
21  float v0 = I.getHeight()/2;
22 
23  // in case, intrinsic parameter is not worked.
24  if(px == 0.0 && py == 0.0){
25  px = 1515.0;
26  py = 1515.0;
27  }
28 
29  // AprilTag detections setting
30  float quadDecimate = 3.0;
31  int nThreads = 1;
32  double tagSize = 0.043; // meter
33  detector.setAprilTagQuadDecimate(quadDecimate);
34  detector.setAprilTagNbThreads(nThreads);
35 
36  // Detection.
38  cam.initPersProjWithoutDistortion(px,py,u0,v0);
39  std::vector<vpHomogeneousMatrix> cMo_vec;
40  detector.detect(I, tagSize, cam, cMo_vec);
41 
42  // starts drawing
43  UIGraphicsBeginImageContext(image.size);
44  CGContextRef context = UIGraphicsGetCurrentContext();
45 
46  // draw original image in the current context.
47  [image drawAtPoint:CGPointMake(0,0)];
48 
49  // draw frames by each tag.
50  int tagNums = (int) detector.getNbObjects();
51  for(int i=0; i < tagNums; i++){
52 
53  // parameters
54  std::vector<vpImagePoint> polygon = detector.getPolygon(i);
55  vpImagePoint cog = detector.getCog(i);
56  vpTranslationVector trans = cMo_vec[i].getTranslationVector();
57  UIColor *mainColor = [UIColor blueColor];
58  int tagLineWidth = 10;
59 
60  // tag Id from message: "36h11 id: 1" -> 1
61  NSString * message = [NSString stringWithCString:detector.getMessage(i).c_str() encoding:[NSString defaultCStringEncoding]];
62  NSArray *phases = [message componentsSeparatedByString:@" "];
63  int detectedTagId = [phases[2] intValue];
64 
65  // draw tag id
66  NSString *tagIdStr = [NSString stringWithFormat:@"%d", detectedTagId];
67  [ImageDisplay displayText:tagIdStr :polygon[0].get_u() :polygon[0].get_v() - 50 :600 :100 :mainColor :[UIColor clearColor]];
68 
69  // draw tag frame
70  [ImageDisplay displayLineWithContext:context :polygon :mainColor :tagLineWidth];
71 
72  // draw xyz cordinate.
73  [ImageDisplay displayFrameWithContext:context :cMo_vec[i] :cam :tagSize :6];
74 
75  // draw distance from camera.
76  NSString *meter = [NSString stringWithFormat:@"(%.2f,%.2f,%.2f)",trans[0],trans[1],trans[2]];
77  [ImageDisplay displayText:meter :cog.get_u() :cog.get_v() +50 :600 :100 :[UIColor whiteColor] :[UIColor blueColor]];
78  }
79 
80  image = UIGraphicsGetImageFromCurrentImageContext();
81  UIGraphicsEndImageContext();
82 
83  return image;
84 }
85 
86 @end
AprilTag 36h11 pattern (recommended)
size_t getNbObjects() const
void setAprilTagQuadDecimate(float quadDecimate)
Generic class defining intrinsic camera parameters.
void setAprilTagNbThreads(int nThreads)
vpImagePoint getCog(size_t i) const
void initPersProjWithoutDistortion(double px, double py, double u0, double v0)
unsigned int getHeight() const
Definition: vpImage.h:186
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
unsigned int getWidth() const
Definition: vpImage.h:244
Class that consider the case of a translation vector.
std::vector< std::vector< vpImagePoint > > & getPolygon()
bool detect(const vpImage< unsigned char > &I)