Draw.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ALVAR, A Library for Virtual and Augmented Reality.
3  *
4  * Copyright 2007-2012 VTT Technical Research Centre of Finland
5  *
6  * Contact: VTT Augmented Reality Team <alvar.info@vtt.fi>
7  * <http://www.vtt.fi/multimedia/alvar.html>
8  *
9  * ALVAR is free software; you can redistribute it and/or modify it under the
10  * terms of the GNU Lesser General Public License as published by the Free
11  * Software Foundation; either version 2.1 of the License, or (at your option)
12  * any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
17  * for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with ALVAR; if not, see
21  * <http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html>.
22  */
23 
24 #include "ar_track_alvar/Draw.h"
25 #include <cassert>
26 
27 using namespace std;
28 
29 namespace alvar {
30 using namespace std;
31 
32 void DrawPoints(IplImage *image, const vector<CvPoint>& points, CvScalar color)
33 {
34  for(unsigned i = 0; i < points.size(); ++i)
35  cvLine(image, cvPoint(points[i].x,points[i].y), cvPoint(points[i].x,points[i].y), color);
36 }
37 
38 void DrawLine(IplImage* image, const Line line, CvScalar color)
39 {
40  double len = 100;
41  CvPoint p1, p2;
42  p1.x = int(line.c.x); p1.y = int(line.c.y);
43  p2.x = int(line.c.x+line.s.x*len); p2.y = int(line.c.y+line.s.y*len);
44  cvLine(image, p1, p2, color);
45 
46  p1.x = int(line.c.x); p1.y = int(line.c.y);
47  p2.x = int(line.c.x-line.s.x*len); p2.y = int(line.c.y-line.s.y*len);
48  cvLine(image, p1, p2, color);
49 }
50 
51 void DrawPoints(IplImage* image, const CvSeq* contour, CvScalar color)
52 {
53  for(int i = 0; i < contour->total; ++i)
54  {
55  CvPoint* pt = (CvPoint*)cvGetSeqElem( contour, i);
56  cvLine(image, cvPoint(pt->x, pt->y), cvPoint(pt->x, pt->y), color);
57  }
58 }
59 
60 void DrawCircles(IplImage* image, const CvSeq* contour, int radius, CvScalar color)
61 {
62  for(int i = 0; i < contour->total; ++i)
63  {
64  CvPoint* pt = (CvPoint*)cvGetSeqElem( contour, i);
65  cvCircle(image, cvPoint(pt->x, pt->y), radius, color);
66  }
67 }
68 
69 void DrawLines(IplImage* image, const CvSeq* contour, CvScalar color)
70 {
71  if(contour->total >= 2)
72  {
73  for(int i = 0; i < contour->total; ++i)
74  {
75  CvPoint* pt1 = (CvPoint*)cvGetSeqElem( contour, i);
76  CvPoint* pt2 = (CvPoint*)cvGetSeqElem( contour, (i+1)%(contour->total));
77  cvLine(image, cvPoint(pt1->x, pt1->y), cvPoint(pt2->x, pt2->y), color);
78  }
79  }
80 }
81 
82 void DrawCVEllipse(IplImage* image, CvBox2D& ellipse, CvScalar color, bool fill/*=false*/, double par)
83 {
84  CvPoint center;
85  center.x = static_cast<int>(ellipse.center.x);
86  center.y = static_cast<int>(ellipse.center.y);
87  int type = 1;
88  if(fill)
89  type = CV_FILLED;
90 
91  //cout<<center.x<<" "<<center.y<<" "<<ellipse.size.width/2<<" "<<ellipse.size.height/2<<" "<<ellipse.angle<<endl;
92  cvEllipse(image, center, cvSize(static_cast<int>(par+ellipse.size.width/2), static_cast<int>(par+ellipse.size.height/2)), -ellipse.angle, 0, 360, color, type);
93 }
94 
95 void BuildHideTexture(IplImage *image, IplImage *hide_texture,
96  Camera *cam, double gl_modelview[16],
97  PointDouble topleft, PointDouble botright)
98 {
99  assert(image->origin == 0); // Currently only top-left origin supported
100  double kx=1.0;
101  double ky=1.0;
102 
103  double width = abs(botright.x - topleft.x);
104  double height = abs(botright.y - topleft.y);
105 
106  //GLint vp[4]; //viewport
107  //GLdouble winx[8]; // point's coordinates in windowcoordinates
108  //GLdouble winy[8];
109  //GLdouble winz[8];
110  double objx;
111  double objy;
112  //GLdouble objz;
113  unsigned char pixels[8][3];
114  unsigned char color[3]={0,0,0};
115 
116  int i=0,j=0,t=0;
117  double ox,oy,ya,yb,xc,xd,offset;
118  double sizex = width/4, size2x=width/2;
119  double sizey = height/4, size2y=height/2;
120 
121  // Calculate extended coordinates of detected marker (+ border)
122  objx = width/2*kx;
123  objy = height/2*ky;
124 
125  //cout<<hide_texture->width<<","<<hide_texture->height<<endl;
126 
127  double l2r=2*width*kx;
128  double l2s=2*height*ky;
129  double lr=width*kx;
130  double ls=height*ky;
131  double r,s;
132  double xstep=2*objx/hide_texture->width,ystep=2*objy/hide_texture->height;
133  for(i=0;i<hide_texture->width;i++){
134  ox = -objx+i*xstep;
135  offset = fmod((objx-ox), size2x);
136  if( offset < sizex)
137  xc = objx + offset;
138  else
139  xc = objx+size2x-offset;
140  offset = fmod((objx+ox), size2x);
141  if( offset < sizex)
142  xd = -objx - offset;
143  else
144  xd = -objx-size2x+offset;
145  r=(ox+objx);
146  for(j=0;j<hide_texture->height;j++){
147  oy = -objy+j*ystep;
148  offset = fmod((objy-oy), size2y);
149  if( offset < sizey)
150  ya = objy + offset;
151  else
152  ya = objy+size2y-offset;
153  offset = fmod((oy+objy), size2y);
154  if( offset < sizey)
155  yb = -objy - offset;
156  else
157  yb = -objy-size2y+offset;
158  s=(oy+objy);
159 
160  double points3d[4][3] = {
161  ox, ya, 0,
162  ox, yb, 0,
163  xc, oy, 0,
164  xd, oy, 0,
165  };
166  double points2d[4][2];
167  CvMat points3d_mat, points2d_mat;
168  cvInitMatHeader(&points3d_mat, 4, 3, CV_64F, points3d);
169  cvInitMatHeader(&points2d_mat, 4, 2, CV_64F, points2d);
170  cam->ProjectPoints(&points3d_mat, gl_modelview, &points2d_mat);
171  int kuvanx4 = (int)Limit(points2d[0][0], 0, image->width-1); int kuvany4 = (int)Limit(points2d[0][1], 0, image->height-1);
172  int kuvanx5 = (int)Limit(points2d[1][0], 0, image->width-1); int kuvany5 = (int)Limit(points2d[1][1], 0, image->height-1);
173  int kuvanx6 = (int)Limit(points2d[2][0], 0, image->width-1); int kuvany6 = (int)Limit(points2d[2][1], 0, image->height-1);
174  int kuvanx7 = (int)Limit(points2d[3][0], 0, image->width-1); int kuvany7 = (int)Limit(points2d[3][1], 0, image->height-1);
175 
176  pixels[4][0] = (unsigned char)cvGet2D(image, kuvany4, kuvanx4).val[0];
177  pixels[4][1] = (unsigned char)cvGet2D(image, kuvany4, kuvanx4).val[1];
178  pixels[4][2] = (unsigned char)cvGet2D(image, kuvany4, kuvanx4).val[2];
179  pixels[5][0] = (unsigned char)cvGet2D(image, kuvany5, kuvanx5).val[0];
180  pixels[5][1] = (unsigned char)cvGet2D(image, kuvany5, kuvanx5).val[1];
181  pixels[5][2] = (unsigned char)cvGet2D(image, kuvany5, kuvanx5).val[2];
182  pixels[6][0] = (unsigned char)cvGet2D(image, kuvany6, kuvanx6).val[0];
183  pixels[6][1] = (unsigned char)cvGet2D(image, kuvany6, kuvanx6).val[1];
184  pixels[6][2] = (unsigned char)cvGet2D(image, kuvany6, kuvanx6).val[2];
185  pixels[7][0] = (unsigned char)cvGet2D(image, kuvany7, kuvanx7).val[0];
186  pixels[7][1] = (unsigned char)cvGet2D(image, kuvany7, kuvanx7).val[1];
187  pixels[7][2] = (unsigned char)cvGet2D(image, kuvany7, kuvanx7).val[2];
188 
189  // make the borders of the texture partly transparent
190  int opaque;
191  const int w=1;
192  if((i<w)|(j<w)|(i>hide_texture->width-w)|(j>hide_texture->width-w))
193  opaque=60;
194  else if ((i<2*w)|(j<2*w)|(i>hide_texture->width-2*w)|(j>hide_texture->width-2*w))
195  opaque=100;
196  else if ((i<3*w)|(j<3*w)|(i>hide_texture->width-3*w)|(j>hide_texture->width-3*w))
197  opaque=140;
198  else if ((i<4*w)|(j<4*w)|(i>hide_texture->width-4*w)|(j>hide_texture->width-4*w))
199  opaque=200;
200  else
201  opaque=255;
202 
203  cvSet2D(hide_texture, j, i, cvScalar(
204  (((lr-r)*pixels[7][0] + r*pixels[6][0]+ s* pixels[4][0] + (ls-s)* pixels[5][0])/l2r),
205  (((lr-r)*pixels[7][1] + r*pixels[6][1]+ s* pixels[4][1] + (ls-s)* pixels[5][1])/l2r),
206  (((lr-r)*pixels[7][2] + r*pixels[6][2]+ s* pixels[4][2] + (ls-s)* pixels[5][2])/l2r),
207  opaque
208  ));
209  }
210  }
211 }
212 
213 void DrawTexture(IplImage *image, IplImage *texture,
214  Camera *cam, double gl_modelview[16],
215  PointDouble topleft, PointDouble botright)
216 {
217  assert(image->origin == 0); // Currently only top-left origin supported
218  double width = abs(botright.x - topleft.x);
219  double height = abs(botright.y - topleft.y);
220  double objx = width/2;
221  double objy = height/2;
222 
223  // Project corners
224  double points3d[4][3] = {
225  -objx, -objy, 0,
226  -objx, objy, 0,
227  objx, objy, 0,
228  objx, -objy, 0,
229  };
230  double points2d[4][2];
231  CvMat points3d_mat, points2d_mat;
232  cvInitMatHeader(&points3d_mat, 4, 3, CV_64F, points3d);
233  cvInitMatHeader(&points2d_mat, 4, 2, CV_64F, points2d);
234  cam->ProjectPoints(&points3d_mat, gl_modelview, &points2d_mat);
235 
236  // Warp texture and mask using the perspective that is based on the corners
237  double map[9];
238  CvMat map_mat = cvMat(3, 3, CV_64F, map);
239  CvPoint2D32f src[4] = {
240  { 0, 0 },
241  { 0, float(texture->height-1) },
242  { float(texture->width-1), float(texture->height-1) },
243  { float(texture->width-1), 0 },
244  };
245  CvPoint2D32f dst[4] = {
246  { float(points2d[0][0]), float(points2d[0][1]) },
247  { float(points2d[1][0]), float(points2d[1][1]) },
248  { float(points2d[2][0]), float(points2d[2][1]) },
249  { float(points2d[3][0]), float(points2d[3][1]) },
250  };
251  cvGetPerspectiveTransform(src, dst, &map_mat);
252  IplImage *img = cvCloneImage(image);
253  IplImage *img2 = cvCloneImage(image);
254  IplImage *mask = cvCreateImage(cvSize(image->width, image->height), 8, 1);
255  IplImage *mask2 = cvCreateImage(cvSize(image->width, image->height), 8, 1);
256  cvZero(img);
257  cvZero(img2);
258  cvZero(mask);
259  cvZero(mask2);
260  for (int j=0; j<texture->height; j++) { //ttesis: why must we copy the texture first?
261  for (int i=0; i<texture->width; i++) {
262  CvScalar s = cvGet2D(texture, j, i);
263  cvSet2D(img, j, i, s);
264  if ((i>0) && (j>0) && (i<(texture->width-1)) && (j<(texture->height-1)))
265  cvSet2D(mask, j, i, cvScalar(1)); //ttesis: why are edges not included?
266  }
267  }
268  cvWarpPerspective(img, img2, &map_mat);
269  cvWarpPerspective(mask, mask2, &map_mat, 0);
270 
271  cvCopy(img2, image, mask2);
272 
273  cvReleaseImage(&img);
274  cvReleaseImage(&img2);
275  cvReleaseImage(&mask);
276  cvReleaseImage(&mask2);
277 }
278 
279 } // namespace alvar
Main ALVAR namespace.
Definition: Alvar.h:174
void ALVAR_EXPORT DrawCircles(IplImage *image, const CvSeq *contour, int radius, CvScalar color=CV_RGB(255, 0, 0))
Draws circles to the contour points that are obtained by Labeling class.
Definition: Draw.cpp:60
PointDouble s
Direction vector.
Definition: Line.h:58
This file implements a collection of functions that are used to visualize lines, contours and corners...
void ALVAR_EXPORT DrawTexture(IplImage *image, IplImage *texture, Camera *cam, double gl_modelview[16], PointDouble topleft, PointDouble botright)
Draws the texture generated by BuildHideTexture to given video frame. For better performance, use OpenGL instead. See SampleMarkerHide.cpp for example implementation.
Definition: Draw.cpp:213
XmlRpcServer s
unsigned char * image
Definition: GlutViewer.cpp:155
TFSIMD_FORCE_INLINE const tfScalar & y() const
int height
Definition: GlutViewer.cpp:160
Simple Camera class for calculating distortions, orientation or projections with pre-calibrated camer...
Definition: Camera.h:82
Struct representing a line. The line is parametrized by its center and direction vector.
Definition: Line.h:41
void ProjectPoints(std::vector< CvPoint3D64f > &pw, Pose *pose, std::vector< CvPoint2D64f > &pi) const
Project points.
int width
Definition: GlutViewer.cpp:159
void ALVAR_EXPORT DrawLine(IplImage *image, const Line line, CvScalar color=CV_RGB(0, 255, 0))
Draws a line.
Definition: Draw.cpp:38
TFSIMD_FORCE_INLINE const tfScalar & x() const
TFSIMD_FORCE_INLINE const tfScalar & w() const
ALVAR_EXPORT Point< CvPoint2D64f > PointDouble
The default double point type.
Definition: Util.h:108
void ALVAR_EXPORT BuildHideTexture(IplImage *image, IplImage *hide_texture, Camera *cam, double gl_modelview[16], PointDouble topleft, PointDouble botright)
This function is used to construct a texture image which is needed to hide a marker from the original...
Definition: Draw.cpp:95
void DrawPoints(IplImage *image, const vector< CvPoint > &points, CvScalar color)
Definition: Draw.cpp:32
Camera * cam
void DrawLines(IplImage *image, const std::vector< PointType > &points, CvScalar color, bool loop=true)
Draws lines between consecutive points stored in vector (polyline).
Definition: Draw.h:88
void ALVAR_EXPORT DrawCVEllipse(IplImage *image, CvBox2D &ellipse, CvScalar color, bool fill=false, double par=0)
Draws OpenCV ellipse.
Definition: Draw.cpp:82
r
double ALVAR_EXPORT Limit(double val, double min_val, double max_val)
Limits a number to between two values.
Definition: Util.cpp:241
PointDouble c
Line center.
Definition: Line.h:54


ar_track_alvar
Author(s): Scott Niekum
autogenerated on Mon Jun 10 2019 12:47:04