ar_recog_no_adapt_threshold.cpp
Go to the documentation of this file.
00001 
00002 #include <ros/ros.h>
00003 #include <image_transport/image_transport.h>
00004 #include <opencv/cv.h>
00005 #include <opencv/highgui.h>
00006 #include <cv_bridge/CvBridge.h>
00007 
00008 #include <ar_recog/Tag.h>
00009 #include <ar_recog/Tags.h>
00010 #include <ar_recog/CalibrateDistance.h>
00011 
00012 #include <math.h>
00013 
00014 #include <AR/ar.h>
00015 #include <AR/video.h>
00016 #include <AR/matrix.h>
00017 
00018 
00019 extern "C" { 
00020 #include "object.h" 
00021 }
00022 
00023 #include <iostream>
00024 
00025 #define THRESH 100
00026 #define THRESH_VARIATION 5
00027 #define THRESH_RANGE_LIMIT 40
00028 
00029 char cparam_name[65536];
00030 ARParam cparam;
00031 
00032 char model_name[65536];
00033 ObjectData_T *object;
00034 int objectnum;
00035 double patt_trans[3][4];
00036 
00037 bool using_rectified_images;
00038 
00039 
00040 int thresh = THRESH;        // used by adaptative threshold variation
00041 int threshVariation = THRESH_VARIATION;
00042 int kThresh = 1;
00043 int sign = 1;
00044 
00045 void init(int width, int height) {
00046   ARParam wparam;
00047   if (arParamLoad(cparam_name, 1, &wparam) < 0) {
00048     std::cerr << "Problem loading AR camera parameters." << std::endl;
00049     exit(-1);
00050   }
00051         
00052   /*for (int i = 0; i < 4; i++) {
00053     std::cout << wparam.dist_factor[i] << "\t";
00054   }
00055   std::cout << std::endl;
00056   */
00057   
00058   arParamChangeSize(&wparam, width, height, &cparam);
00059   arInitCparam(&cparam);
00060 
00061   if ((object = read_ObjData(model_name, &objectnum)) == NULL) {
00062     std::cerr << "Problem reading patterns." << std::endl;
00063     exit(-1);
00064   }
00065 }
00066 
00067 
00068 IplImage * drawHistogram(IplImage *img)
00069 {
00070   int numBins = 256;
00071   float range[] = {0, 255};
00072   float *ranges[] = { range };
00073   float scaleX = 2, scaleY = 2;
00074   const int width = 3;
00075 
00076   CvHistogram *hist = cvCreateHist(1, &numBins, CV_HIST_ARRAY, ranges, 1);
00077   cvClearHist(hist);
00078 
00079   IplImage *im_gray = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
00080   cvCvtColor(img, im_gray, CV_RGB2GRAY);
00081 
00082   cvCalcHist(&im_gray, hist, 0, 0);
00083   IplImage *imgHistGray = cvCreateImage(cvSize(256*scaleX, 64*scaleY), 8, 3);
00084   cvZero(imgHistGray);
00085 
00086   float histMax = 0;
00087   cvGetMinMaxHistValue(hist, 0, &histMax, 0, 0);
00088 
00089    for(int i=0;i<255;i++)
00090    {
00091         float histValue = cvQueryHistValue_1D(hist, i);
00092         float nextValue = cvQueryHistValue_1D(hist, i+1);
00093  
00094         CvPoint pt1 = cvPoint(i*scaleX, 64*scaleY);
00095         CvPoint pt2 = cvPoint(i*scaleX+scaleX, 64*scaleY);
00096         CvPoint pt3 = cvPoint(i*scaleX+scaleX, (64-nextValue*64/histMax)*scaleY);
00097         CvPoint pt4 = cvPoint(i*scaleX, (64-histValue*64/histMax)*scaleY);
00098  
00099         int numPts = 5;
00100         CvPoint pts[] = {pt1, pt2, pt3, pt4, pt1};
00101  
00102         cvFillConvexPoly(imgHistGray, pts, numPts, CV_RGB(255,255,255));
00103    }
00104   
00105   cvLine(imgHistGray,cvPoint(thresh*scaleX, 0), 
00106            cvPoint(thresh*scaleX, 64*scaleY),
00107            CV_RGB(255,0,0),width);
00108     
00109 
00110   cvReleaseImage(&im_gray);
00111   cvReleaseHist(&hist);
00112 
00113   return imgHistGray;
00114 }
00115 
00116 //int count;
00117 double haov, vaov;
00118 bool ar_smooth = true;
00119 ros::Publisher tags_pub;
00120 image_transport::Publisher ar_img; //used by the handling functions
00121 image_transport::Publisher ar_hist;
00122 int last_reported_distance; // Saved by the publisher for use by the calibration service
00123 
00124 void handleImage(const sensor_msgs::ImageConstPtr& in, const sensor_msgs::CameraInfoConstPtr& camera_info) {
00125   sensor_msgs::CvBridge bridge;
00126   double icpara[3][4], trans[3][4];
00127   IplImage* img = bridge.imgMsgToCv(in, "rgb8");
00128 
00129   if (img->width != arImXsize || img->height != arImYsize) init(img->width, img->height);
00130   IplImage *hist = drawHistogram(img);
00131 
00132   ARUint8 *data = (ARUint8*) malloc(sizeof(ARUint8)*img->width*img->height*3);
00133   int i = 0;
00134   for (int y = 0; y < img->height; y++) {
00135     for (int x = 0; x < img->width; x++) {
00136       for (int j = 0; j < 3; j++) {
00137         data[i++] = img->imageData[y*(img->widthStep/sizeof(uchar))+x*3+j];
00138       }
00139     }
00140   }
00141   
00142   // draw histogram over image
00143   cvSetImageROI(img, cvRect(img->width - hist->width, img->height - hist->height,
00144                             img->width, img->height));
00145   cvCopy(hist, img);
00146   cvResetImageROI(img);
00147 
00148 
00149   ARMarkerInfo *marker_info;
00150   int marker_num;
00151   if(arDetectMarker(data, thresh, &marker_info, &marker_num) < 0) {
00152     std::cerr << "Problem running detect marker." << std::endl;
00153     exit(-1);
00154   }
00155 
00156   if( arParamDecompMat(cparam.mat, icpara, trans) < 0 ) {
00157         printf("gConvGLcpara: Parameter error!!\n");
00158         exit(0);
00159     }
00160 
00161 
00162     for( int i = 0; i < 3; i++ ) {
00163         for( int j = 0; j < 3; j++ ) {
00164             icpara[i][j] = icpara[i][j] / icpara[2][2];
00165             printf("%.3f ", icpara[i][j]);
00166         }
00167         printf("\n");
00168     }
00169 
00170   /*
00171   for(int i = 0; i < marker_num; i++) {
00172     const int width = 3;
00173     cvLine(img,cvPoint(marker_info[i].vertex[0][0],marker_info[i].vertex[0][1]),
00174            cvPoint(marker_info[i].vertex[1][0],marker_info[i].vertex[1][1])
00175            ,CV_RGB(0,255,0),width);
00176     cvLine(img,cvPoint(marker_info[i].vertex[1][0],marker_info[i].vertex[1][1]),
00177            cvPoint(marker_info[i].vertex[2][0],marker_info[i].vertex[2][1])
00178            ,CV_RGB(0,255,0),width);
00179     cvLine(img,cvPoint(marker_info[i].vertex[2][0],marker_info[i].vertex[2][1]),
00180            cvPoint(marker_info[i].vertex[3][0],marker_info[i].vertex[3][1])
00181            ,CV_RGB(0,255,0),width);
00182     cvLine(img,cvPoint(marker_info[i].vertex[3][0],marker_info[i].vertex[3][1]),
00183            cvPoint(marker_info[i].vertex[0][0],marker_info[i].vertex[0][1])
00184            ,CV_RGB(0,255,0),width);
00185   }*/
00186 
00187   if (using_rectified_images) {
00188     // Potential non-portability issue here... P uses ROS float64, but
00189     // I'm just using doubles for now.
00190 
00191     // These numbers are not always accurate after a calibration.  It
00192     // may be that our checkerboard calibrators are insufficient to
00193     // nail down the parameters of cheap webcams, or that the
00194     // calibration routines within opencv are not the greatest.
00195     // Uncalibrated raw image data seems to work pretty well, though,
00196     // once you've measured a known distance.
00197 
00198     double y_foc = camera_info->P[5];
00199     double y_princ = camera_info->P[6];
00200     double x_foc = camera_info->P[0];
00201     double x_princ = camera_info->P[2];
00202 
00203     // Camera angle of view
00204     haov = 2.0 * atan(x_princ / x_foc);
00205     vaov = 2.0 * atan(y_princ / y_foc);
00206 
00207     ROS_INFO("entrando por using_rectified_images");
00208   }
00209   else {
00210     vaov = haov * ((double)img->height / (double)img->width);
00211     ROS_INFO("no entrando por using_rectified_images");
00212   } 
00213 
00214   ar_recog::Tags tags;  
00215   tags.image_width = img->width;
00216   tags.image_height = img->height;
00217   tags.angle_of_view = haov;
00218 
00219   // Record the time stamp close to the observation, not the reporting.
00220   tags.header.stamp = ros::Time::now();
00221 
00222   for( int i = 0; i < objectnum; i++ ) {
00223     int k = -1;
00224     for( int j = 0; j < marker_num; j++ ) {
00225 
00226       if( object[i].id == marker_info[j].id) {
00227               /*********************
00228               if( k == -1 ) 
00229                 k = j;
00230               else // make sure you have the best pattern (highest confidence factor) 
00231                 ROS_INFO("objnum=%d, objid=%d, markid=%d", objectnum, object[i].id, marker_info[j].id);
00232 
00233                 if( marker_info[k].cf < marker_info[j].cf ) k = j;
00234               ********************************/
00235                 k=j;
00236       //----------------------------------------------------------------------}
00237     //-----------------------------------------------------------------------}
00238 
00239     if( k == -1 ) {
00240       object[i].visible = 0;
00241       continue;
00242     }
00243                 
00244     /* calculate the transform for each marker */
00245     if( (!ar_smooth) || (object[i].visible == 0) ) {
00246       arGetTransMat(&marker_info[k], 
00247                     object[i].marker_center, 
00248                     object[i].marker_width, 
00249                     object[i].trans);
00250     } else {
00251       arGetTransMatCont(&marker_info[k], 
00252                         object[i].trans, 
00253                         object[i].marker_center, 
00254                         object[i].marker_width, 
00255                         object[i].trans);
00256     }
00257 
00258     object[i].visible = 1;
00259     /*for (int k = 0; k < 3; k++)
00260       for (int l= 0; l < 4; l++)
00261         patt_trans[k][l] = object[i].trans[k][l];
00262     */
00263     const int width = 3;
00264     cvLine(img,cvPoint(marker_info[k].vertex[0][0],marker_info[k].vertex[0][1]),
00265            cvPoint(marker_info[k].vertex[1][0],marker_info[k].vertex[1][1])
00266            ,CV_RGB(0,255,0),width);
00267     cvLine(img,cvPoint(marker_info[k].vertex[1][0],marker_info[k].vertex[1][1]),
00268            cvPoint(marker_info[k].vertex[2][0],marker_info[k].vertex[2][1])
00269            ,CV_RGB(0,255,0),width);
00270     cvLine(img,cvPoint(marker_info[k].vertex[2][0],marker_info[k].vertex[2][1]),
00271            cvPoint(marker_info[k].vertex[3][0],marker_info[k].vertex[3][1])
00272            ,CV_RGB(0,255,0),width);
00273     cvLine(img,cvPoint(marker_info[k].vertex[3][0],marker_info[k].vertex[3][1]),
00274            cvPoint(marker_info[k].vertex[0][0],marker_info[k].vertex[0][1])
00275            ,CV_RGB(0,255,0),width);
00276     
00277         ARMat cameraMatrix, cubeMatrix, proyMatrix, kMatrix, pMatrix;
00278     double cube[4][4] = { {0, 10, 0, 0}, {0, 0, 10, 0}, {0, 0, 0, 10}, {1, 1, 1, 1}};
00279     double proy[3][4];
00280     double cam[3][4];
00281     double km[3][3];
00282 
00283     pMatrix.m = &cam[0][0];
00284     pMatrix.row = 3;
00285     pMatrix.clm = 4;
00286 
00287     cameraMatrix.m = &object[i].trans[0][0];
00288     cameraMatrix.row = 3;
00289     cameraMatrix.clm = 4;
00290 
00291     kMatrix.m = &km[0][0];
00292     kMatrix.row = 3;
00293     kMatrix.clm = 3;
00294 
00295     cubeMatrix.m = &cube[0][0];
00296     cubeMatrix.row = 4;
00297     cubeMatrix.clm = 4;
00298 
00299     proyMatrix.m = &proy[0][0];
00300     proyMatrix.row = 3;
00301     proyMatrix.clm = 4;
00302     
00303     for (int k = 0 ; k < 3; k++) {
00304       for (int l = 0; l < 3; l++)
00305         kMatrix.m[k*3+l] = icpara[k][l];
00306     }    
00307     arMatrixMul(&pMatrix, &kMatrix, &cameraMatrix);
00308     arMatrixMul(&proyMatrix, &pMatrix, &cubeMatrix);
00309 
00310     /*cvLine(img, cvPoint(proyMatrix.m[4]/proyMatrix.m[8]+img->width/2, proyMatrix.m[4]/proyMatrix.m[8]+img->height/2),
00311            cvPoint(proyMatrix.m[1]/proyMatrix.m[9]+img->width/2, proyMatrix.m[5]/proyMatrix.m[9]+img->height/2),
00312            CV_RGB(255,0,0), width);*/
00313 
00314     cvLine(img, cvPoint(proyMatrix.m[0]/proyMatrix.m[8], proyMatrix.m[4]/proyMatrix.m[8]),
00315            cvPoint(proyMatrix.m[1]/proyMatrix.m[9], proyMatrix.m[5]/proyMatrix.m[9]),
00316            CV_RGB(0,0,255), width);
00317 
00318     cvLine(img, cvPoint(proyMatrix.m[0]/proyMatrix.m[8], proyMatrix.m[4]/proyMatrix.m[8]),
00319            cvPoint(proyMatrix.m[2]/proyMatrix.m[10], proyMatrix.m[6]/proyMatrix.m[10]),
00320            CV_RGB(255,0,0), width);
00321 
00322     cvLine(img, cvPoint(proyMatrix.m[0]/proyMatrix.m[8], proyMatrix.m[4]/proyMatrix.m[8]),
00323            cvPoint(proyMatrix.m[3]/proyMatrix.m[11], proyMatrix.m[7]/proyMatrix.m[11]),
00324            CV_RGB(127,0,127), width);
00325 
00326     CvFont font;
00327     cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 2, CV_AA);
00328     char posZ[16];
00329     sprintf(posZ, "%.1f", object[i].trans[2][3]/20);
00330     cvPutText(img, posZ, cvPoint(marker_info[k].pos[0], marker_info[k].pos[1]+32),
00331                    &font, cvScalar(255,145,0, 0));
00332 
00333 
00334 
00335     printf("origen x = %.2f\n", marker_info[k].vertex[0][0]);
00336     printf("origen y = %.2f\n", marker_info[k].vertex[0][1]);
00337 
00338     for (int k = 0; k < 3; k++) {
00339       for (int l = 0; l < 4; l++) {
00340          printf("%.2f ", pMatrix.m[k*4+l]);
00341       }
00342       printf("\n");
00343     }
00344 
00345 
00346     printf("---------------\n");
00347 
00348     for (int k = 0; k < 3; k++) {
00349       for (int l = 0; l < 3; l++) {
00350          printf("%.2f ", kMatrix.m[k*3+l]);
00351       }
00352       printf("\n");
00353     }
00354 
00355 
00356     printf("---------------\n");
00357 
00358     for (int k = 0; k < 3; k++) {
00359       for (int l = 0; l < 4; l++) {
00360          printf("%.2f ", icpara[k][l]);
00361       }
00362       printf("\n");
00363     }
00364 
00365 
00366     printf("---------------\n");
00367     for (int k = 0; k < 2; k++) {
00368       for (int l = 0; l < 4; l++) {
00369          //printf("%.2f ", proyMatrix.m[k*4+l]);
00370          printf("%.2f ", proyMatrix.m[k*4+l]/proyMatrix.m[2*4+l]);
00371       }
00372       printf("\n");
00373     }
00374        
00375 
00376     int x, y;
00377     double diameter;
00378     double xRot, yRot, zRot;
00379     double xMetric, yMetric, zMetric;
00380 
00381     x = marker_info[k].pos[0];
00382     y = marker_info[k].pos[1];
00383     //diameter = (int) ((double) .5 + (double) sqrt(marker_info[k].area));
00384 
00385     // Transformation below pinched and modified from 
00386     // http://paulbourke.net/geometry/eulerangle/Aij-to-Eulerangles.pdf
00387     xRot = -asin(-object[i].trans[1][2]);
00388     yRot = -atan2(object[i].trans[0][2],-object[i].trans[2][2]);
00389     zRot = atan2(object[i].trans[1][0],-object[i].trans[1][1]);
00390 
00391     // This relative x and y stuff corrects for the distortion that
00392     // comes from an AR tag moving out of the fovea.  When the tag is
00393     // at the edge of the image, it appears rotated, even when it is
00394     // parallel to the image plane.  This is not the behavior we want,
00395     // and leads to inaccurate distance measurement, for one thing.
00396     double x_delta = (double)(2*x-img->width)/(double)img->width;
00397     double y_delta = (double)(2*y-img->height)/(double)img->height;
00398     double rel_theta = x_delta * haov / 2.0;
00399     double rel_phi = y_delta * vaov / 2.0;
00400 
00401     // xRot is rotation around the horizontal axis, which means
00402     // changes in apparent _vertical_ size, and vice versa with yRot.
00403     // Which is why these look backwards.
00404 
00405     // Whoa.  AR Toolkit appears to have fixed this behavior.  So this
00406     // fix was making things worse.
00407 
00408     // xRot -= y_delta * rel_phi;
00409     // yRot -= x_delta * rel_theta;
00410 
00411     // Figure out the tag's area from the quadrilateral's corners
00412     double x1 = marker_info[k].vertex[0][0] - marker_info[k].vertex[2][0];
00413     double y1 = marker_info[k].vertex[0][1] - marker_info[k].vertex[2][1];
00414     double x2 = marker_info[k].vertex[1][0] - marker_info[k].vertex[3][0];
00415     double y2 = marker_info[k].vertex[1][1] - marker_info[k].vertex[3][1];
00416     double area = 0.5 * fabs(x1*y2 - x2*y1);
00417     double unrotated_area = area / (cos(xRot)*cos(yRot));
00418     diameter = sqrt(unrotated_area);
00419 
00420     double theta_object = haov * (diameter / (double)img->width);
00421     //double phi_object = vaov * (diameter / (double)img->height);
00422     // Whichever measurement is closer to the center of the image is likelier to be more accurate.
00423     //int dist = object[i].marker_width / tan(x_delta < y_delta ? theta_object : phi_object);
00424     // However, it also makes the measurement less stable.
00425     int dist = object[i].marker_width / tan(theta_object);
00426 
00427     xMetric = dist * cos(rel_theta) / 1000.0;
00428     yMetric = -dist * sin(rel_theta) * cos(rel_phi) / 1000.0;
00429     zMetric = -dist * cos(rel_theta) * sin(rel_phi) / 1000.0;
00430     
00431     ar_recog::Tag tag;
00432     tag.id = i;
00433     tag.cf = marker_info[k].cf; 
00434     tag.x = x;
00435     tag.y = y;
00436     tag.diameter = diameter;
00437     tag.distance = dist/1000.0; // Convert to meters
00438     tag.xRot = xRot;
00439     tag.yRot = yRot;
00440     tag.zRot = zRot;
00441     tag.xMetric = xMetric;
00442     tag.yMetric = yMetric;
00443     tag.zMetric = zMetric;
00444     int b = marker_info[k].dir;
00445     int idx[4];
00446     //rotate based on direction
00447     switch (b) {
00448     case 0:
00449       idx[0] = 0;
00450       idx[1] = 1;
00451       idx[2] = 2;
00452       idx[3] = 3;
00453       break;
00454     case 3:
00455       idx[0] = 1;
00456       idx[1] = 2;
00457       idx[2] = 3;
00458       idx[3] = 0;
00459       break;
00460     case 2:
00461       idx[0] = 2;
00462       idx[1] = 3;
00463       idx[2] = 0;
00464       idx[3] = 1;
00465       break;
00466     default: //1
00467       idx[0] = 3;
00468       idx[1] = 0;
00469       idx[2] = 1;
00470       idx[3] = 2;
00471       break;
00472     }
00473 
00474     tag.cwCorners[0] = marker_info[k].vertex[idx[0]][0];
00475     tag.cwCorners[1] = marker_info[k].vertex[idx[0]][1]; //upper left
00476     tag.cwCorners[2] = marker_info[k].vertex[idx[1]][0];
00477     tag.cwCorners[3] = marker_info[k].vertex[idx[1]][1]; //upper right
00478     tag.cwCorners[4] = marker_info[k].vertex[idx[2]][0];
00479     tag.cwCorners[5] = marker_info[k].vertex[idx[2]][1]; //lower right
00480     tag.cwCorners[6] = marker_info[k].vertex[idx[3]][0];
00481     tag.cwCorners[7] = marker_info[k].vertex[idx[3]][1]; //lower left
00482 
00483     // TESTING ONLY
00484     // tag.c3[0] = object[i].trans[0][3];
00485     // tag.c3[1] = object[i].trans[1][3];
00486     // tag.c3[2] = object[i].trans[2][3];
00487 
00488     // tag.t0[0] = object[i].trans[0][0];
00489     // tag.t0[1] = object[i].trans[0][1];
00490     // tag.t0[2] = object[i].trans[0][2];
00491 
00492     // tag.t1[0] = object[i].trans[1][0];
00493     // tag.t1[1] = object[i].trans[1][1];
00494     // tag.t1[2] = object[i].trans[1][2];
00495 
00496     // tag.t2[0] = object[i].trans[2][0];
00497     // tag.t2[1] = object[i].trans[2][1];
00498     // tag.t2[2] = object[i].trans[2][2];
00499     // END TESTING ONLY
00500 
00501     tags.tags.push_back(tag);
00502 
00503     last_reported_distance = dist;
00504     
00505     // adaptative threshold variation
00506       }
00507     }
00508   }
00509  
00510   ROS_INFO("markernum=%d", marker_num); 
00511   if (marker_num == 0) {
00512       thresh += sign * kThresh * threshVariation;
00513       kThresh = kThresh + 1;
00514       sign = -sign;
00515       
00516       if (abs(thresh - THRESH) > THRESH_RANGE_LIMIT) {
00517         thresh = THRESH;
00518         kThresh = 1;
00519         sign = 1;
00520       }
00521   }
00522     
00523     ROS_INFO("THRESH=%d\n", thresh);
00524 
00525   tags.tag_count = tags.tags.size();
00526 
00527   sensor_msgs::ImagePtr out = sensor_msgs::CvBridge::cvToImgMsg(img, "bgr8");
00528   sensor_msgs::ImagePtr outhist = sensor_msgs::CvBridge::cvToImgMsg(hist, "passthrough");
00529   ar_img.publish(out);
00530   ar_hist.publish(outhist);
00531 
00532   tags_pub.publish(tags);
00533 
00534   free(data);
00535 }
00536 
00537 void handleRawImage(const sensor_msgs::ImageConstPtr& in) {
00538         if (using_rectified_images) return;
00539         const sensor_msgs::CameraInfoConstPtr ign;
00540         handleImage(in,ign);
00541 }
00542 
00543 bool calibrateDistance(ar_recog::CalibrateDistance::Request &req,
00544                        ar_recog::CalibrateDistance::Response &resp) {
00545 
00546   using_rectified_images = false;
00547   haov = haov*((double)last_reported_distance / (double)req.dist);
00548   resp.aov = haov;
00549   return true;
00550 }
00551 
00552 int main(int argc, char **argv) {
00553   ros::init(argc, argv, "image_listener");
00554   ros::NodeHandle nh;
00555 
00556   std::string tmp;
00557   nh.param<std::string>("camera_para", tmp, "camera_para.dat");
00558   strcpy(cparam_name, tmp.c_str());
00559   nh.param<std::string>("model_name", tmp, "object_data");
00560   strcpy(model_name, tmp.c_str());
00561 
00562   if (nh.getParam("aov", haov)) {
00563     using_rectified_images = false;
00564     //nh.param<double>("aov", theta, 0.67018834495304758);
00565     std::cout << "aov-: " << haov << std::endl;
00566   }
00567   else {
00568     using_rectified_images = true;
00569   }
00570 
00571   if (nh.getParam("ar_smooth", ar_smooth)) {
00572       std::cout << "ar_smooth: " << ar_smooth << std::endl;
00573     } else {
00574       std::cout << "ar_smooth parameter missing, will implement smoothing" << std::endl;
00575     }
00576 
00577   tags_pub = nh.advertise<ar_recog::Tags>("tags",1);
00578 
00579   ros::ServiceServer calibrate_distance = nh.advertiseService("ar/calibrate_distance", calibrateDistance);
00580 
00581   image_transport::ImageTransport it(nh);
00582   ar_img = it.advertise("ar/image", 1);
00583   ar_hist = it.advertise("ar/hist", 1);
00584 
00585   arImXsize = arImYsize = 0;
00586   //count = 0;
00587 
00588   image_transport::CameraSubscriber sub = it.subscribeCamera("image", 1, handleImage);
00589   image_transport::Subscriber subRaw = it.subscribe("image", 1, handleRawImage);
00590   ros::spin();
00591 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


ar_recog
Author(s): Graylin Trevor Jay and Christopher Crick
autogenerated on Fri Jan 25 2013 12:14:59