00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <stdio.h>
00011 #include <stdarg.h>
00012
00013 #include "outlet_pose_estimation/detail/one_way_outlets.h"
00014
00015 #if defined(_VERBOSE)
00016 static int PRINTF( const char* fmt, ... )
00017 {
00018 va_list args;
00019 va_start(args, fmt);
00020 int ret = vprintf(fmt, args);
00021 return ret;
00022 }
00023 #else
00024 static int PRINTF( const char*, ... )
00025 {
00026 return 0;
00027 }
00028 #endif // _VERBOSE
00029
00030
00031 #include "outlet_pose_estimation/detail/outlet_detector.h"
00032 #include "outlet_pose_estimation/detail/planar.h"
00033 #include "outlet_pose_estimation/detail/outlet_tuple.h"
00034 #include "outlet_pose_estimation/detail/gh_outlets.h"
00035
00036 #include "highgui.h"
00037
00038 using namespace std;
00039
00040 int detect_outlet_tuple(IplImage* src, CvMat* intrinsic_matrix, CvMat* distortion_params,
00041 vector<outlet_t>& outlets, const outlet_template_t& outlet_templ,
00042 const char* output_path, const char* filename, float* scale_ranges)
00043 {
00044 #if 1
00045 if (distortion_params) {
00046
00047 IplImage* _img = cvCloneImage(src);
00048
00049 cvUndistort2(_img, src, intrinsic_matrix, distortion_params);
00050
00051
00052 cvReleaseImage(&_img);
00053 }
00054 #endif
00055
00056 int ret = 1;
00057
00058 #if !defined(_GHT)
00059 if(outlet_templ.get_color() == outletOrange && outlet_templ.get_count() == 4)
00060 {
00061 ret = detect_outlet_tuple_2x2_orange(src, intrinsic_matrix, distortion_params, outlets, outlet_templ, output_path, filename);
00062 }
00063 else if(outlet_templ.get_count() == 2)
00064 {
00065 ret = detect_outlet_tuple_2x1(src, intrinsic_matrix, distortion_params, outlets, outlet_templ, output_path, filename);
00066 }
00067 #else
00068 CvRect roi = cvGetImageROI(src);
00069 IplImage* red = cvCreateImage(cvSize(roi.width, roi.height), IPL_DEPTH_8U, 1);
00070 #if defined(_RED)
00071 cvSetImageCOI(src, 3);
00072 cvCopy(src, red);
00073 cvSetImageCOI(src, 0);
00074 #else
00075 cvSetZero(red);
00076 cvSetImageCOI(src, 3);
00077 cvCopy(src, red);
00078 cvConvertScale(red, red, 0.5);
00079 IplImage* red1 = cvCloneImage(red);
00080 cvSetImageCOI(src, 2);
00081 cvCopy(src, red1);
00082 cvConvertScale(red1, red1, 0.5);
00083 cvAdd(red, red1, red);
00084 cvReleaseImage(&red1);
00085 cvSetImageCOI(src, 0);
00086 #endif //_RED
00087
00088 #if 1
00089 detect_outlets_one_way(red, outlet_templ, outlets, src,output_path, filename, scale_ranges);
00090 #else
00091
00092 #endif
00093
00094
00095
00096
00097 for(size_t i = 0; i < outlets.size(); i++)
00098 {
00099 outlets[i].hole1 = cv::Point2d(outlets[i].hole1) + cv::Point2d(roi.x, roi.y);
00100 outlets[i].hole2 = cv::Point2d(outlets[i].hole2) + cv::Point2d(roi.x, roi.y);
00101 outlets[i].ground_hole = cv::Point2d(outlets[i].ground_hole) + cv::Point2d(roi.x, roi.y);
00102 }
00103
00104
00105 #endif
00106 cvReleaseImage(&red);
00107
00108 if(outlets.size() != (size_t)outlet_templ.get_count())
00109 {
00110
00111 return 0;
00112 }
00113 else
00114 {
00115 ret = 1;
00116 }
00117
00118 #if 0
00119 calc_outlet_3d_coord_2x2(intrinsic_matrix, outlet_templ, outlets);
00120 #else
00121
00122
00123 #ifdef _DO_POSE_ESTIMATE_IN_DETECTOR
00124 if (intrinsic_matrix)
00125 {
00126 #if 0
00127 CvPoint3D32f* object_holes_3d = new CvPoint3D32f[outlet_templ.get_count()*3];
00128 CvPoint2D32f* object_holes_2d = new CvPoint2D32f[outlet_templ.get_count()*3];
00129 CvPoint2D32f* image_holes = new CvPoint2D32f[outlet_templ.get_count()*3];
00130
00131 outlet_templ.get_holes_2d(object_holes_2d);
00132 outlet_templ.get_holes_3d(object_holes_3d);
00133 for(size_t i = 0; i < outlets.size(); i++)
00134 {
00135 image_holes[3*i] = cvPoint2D32f(outlets[i].hole1.x, outlets[i].hole1.y);
00136 image_holes[3*i + 1] = cvPoint2D32f(outlets[i].hole2.x, outlets[i].hole2.y);
00137 image_holes[3*i + 2] = cvPoint2D32f(outlets[i].ground_hole.x, outlets[i].ground_hole.y);
00138 }
00139
00140 CvMat* homography = cvCreateMat(3, 3, CV_32FC1);
00141 CvMat* inv_homography = cvCreateMat(3, 3, CV_32FC1);
00142
00143 CvMat* image_holes_mat = cvCreateMat(outlet_templ.get_count()*3, 2, CV_32FC1);
00144 CvMat* object_holes_mat = cvCreateMat(outlet_templ.get_count()*3, 2, CV_32FC1);
00145 for(int i = 0; i < outlet_templ.get_count()*3; i++)
00146 {
00147 cvmSet(image_holes_mat, i, 0, image_holes[i].x);
00148 cvmSet(image_holes_mat, i, 1, image_holes[i].y);
00149 cvmSet(object_holes_mat, i, 0, object_holes_2d[i].x);
00150 cvmSet(object_holes_mat, i, 1, object_holes_2d[i].y);
00151 }
00152 cvFindHomography(image_holes_mat, object_holes_mat, homography);
00153 cvFindHomography(object_holes_mat, image_holes_mat, inv_homography);
00154 cvReleaseMat(&image_holes_mat);
00155 cvReleaseMat(&object_holes_mat);
00156
00157 CvPoint3D32f origin;
00158 CvPoint2D32f origin_2d;
00159 map_point_homography(image_holes[0], homography, origin_2d);
00160 origin = cvPoint3D32f(origin_2d.x, origin_2d.y, 0.0);
00161 CvPoint2D32f scale = cvPoint2D32f(1.0, 1.0);
00162
00163 CvMat* rotation_vector = cvCreateMat(3, 1, CV_32FC1);
00164 CvMat* translation_vector = cvCreateMat(3, 1, CV_32FC1);
00165 calc_camera_pose(intrinsic_matrix, 0, outlet_templ.get_count()*3, object_holes_3d, image_holes,
00166 rotation_vector, translation_vector);
00167 calc_outlet_coords(outlets, homography, origin, scale, rotation_vector, translation_vector, inv_homography);
00168
00169 delete object_holes_2d;
00170 delete object_holes_3d;
00171 delete image_holes;
00172 cvReleaseMat(&rotation_vector);
00173 cvReleaseMat(&translation_vector);
00174 cvReleaseMat(&homography);
00175 cvReleaseMat(&inv_homography);
00176 #else
00177 if(outlets.size() >= 4)
00178 {
00179 calc_outlet_coords_ground(outlets, outlet_templ, intrinsic_matrix, 0);
00180 }
00181 else
00182 {
00183 calc_outlet_coords(outlets, outlet_templ, intrinsic_matrix, 0);
00184
00185 }
00186
00187 #endif
00188 }
00189 #endif // Whether to do pose estimation at all
00190 #endif
00191
00192 return ret;
00193 }
00194
00195 void calc_outlet_3d_coord_2x2(CvMat* intrinsic_matrix, const outlet_template_t& outlet_templ, vector<outlet_t>& outlets)
00196 {
00197
00198 CvMat* homography = 0;
00199 CvPoint3D32f origin;
00200 CvPoint2D32f scale;
00201
00202 homography = cvCreateMat(3, 3, CV_32FC1);
00203 CvMat* inv_homography = cvCreateMat(3, 3, CV_32FC1);
00204
00205 CvPoint2D32f centers[4];
00206 for(int i = 0; i < 4; i++)
00207 {
00208 centers[i] = cvPoint2D32f((outlets[i].hole1.x + outlets[i].hole2.x)*0.5,
00209 (outlets[i].hole1.y + outlets[i].hole2.y)*0.5);
00210 }
00211
00212 calc_outlet_homography(centers, homography,
00213 outlet_templ, inv_homography);
00214
00215
00216 calc_origin_scale(centers, homography, &origin, &scale);
00217
00218 CvMat* rotation_vector = cvCreateMat(3, 1, CV_32FC1);
00219 CvMat* translation_vector = cvCreateMat(3, 1, CV_32FC1);
00220 calc_camera_outlet_pose(intrinsic_matrix, 0, outlet_templ, centers, rotation_vector, translation_vector);
00221 calc_outlet_coords(outlets, homography, origin, scale, rotation_vector, translation_vector, inv_homography);
00222 cvReleaseMat(&rotation_vector);
00223 cvReleaseMat(&translation_vector);
00224 cvReleaseMat(&inv_homography);
00225 }
00226
00227 int detect_outlet_tuple_2x2_orange(IplImage* src, CvMat* intrinsic_matrix, CvMat* distortion_params,
00228 vector<outlet_t>& outlets, const outlet_template_t& outlet_templ,
00229 const char* output_path, const char* filename)
00230 {
00231 outlet_tuple_t outlet_tuple;
00232
00233 outlet_tuple.tuple_mask = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1);
00234 int ret = find_outlet_centroids(src, outlet_tuple, output_path, filename);
00235 if(!ret)
00236 {
00237 PRINTF("find_outlet_centroids did not find a tuple\n");
00238 return 0;
00239 }
00240
00241 vector<outlet_feature_t> features;
00242 detect_outlets(src, features, outlets, &outlet_tuple, output_path, filename);
00243
00244 CvPoint2D32f hor_dir = outlet_tuple.centers[1] - outlet_tuple.centers[0];
00245
00246
00247
00248 CvMat* homography = 0;
00249 CvPoint3D32f origin;
00250 CvPoint2D32f scale;
00251
00252 homography = cvCreateMat(3, 3, CV_32FC1);
00253 CvMat* inv_homography = cvCreateMat(3, 3, CV_32FC1);
00254
00255
00256 const int iter_count = 1;
00257 for(int j = 0; j < iter_count; j++)
00258 {
00259 calc_outlet_homography(outlet_tuple.centers, homography,
00260 outlet_templ, inv_homography);
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 }
00287
00288 calc_origin_scale(outlet_tuple.centers, homography, &origin, &scale);
00289
00290 CvMat* rotation_vector = cvCreateMat(3, 1, CV_32FC1);
00291 CvMat* translation_vector = cvCreateMat(3, 1, CV_32FC1);
00292 calc_camera_outlet_pose(intrinsic_matrix, 0, outlet_templ, outlet_tuple.centers, rotation_vector, translation_vector);
00293 calc_outlet_coords(outlets, homography, origin, scale, rotation_vector, translation_vector, inv_homography);
00294 cvReleaseMat(&rotation_vector);
00295 cvReleaseMat(&translation_vector);
00296 cvReleaseMat(&inv_homography);
00297
00298 filter_outlets_size(outlets);
00299
00300 filter_outlets_tuple(outlets, outlet_tuple.tuple_mask, hor_dir);
00301
00302 #if defined(_VERBOSE)
00303 if(output_path && filename)
00304 {
00305 IplImage* temp = cvCloneImage(src);
00306 draw_outlets(temp, outlets);
00307
00308 char buf[1024];
00309 sprintf(buf, "%s/output_filt/%s", output_path, filename);
00310 strcpy(buf + strlen(buf) - 3, "jpg");
00311 cvSaveImage(buf, temp);
00312
00313 cvReleaseImage(&temp);
00314 }
00315 #endif //_VERBOSE
00316
00317 PRINTF(" found %d holes, %d outlets\n", features.size(), outlets.size());
00318
00319 if(homography == 0)
00320 {
00321 PRINTF("Homography mask not found.\n");
00322 return 0;
00323 }
00324 else if(outlets.size() != 4)
00325 {
00326 cvReleaseMat(&homography);
00327 PRINTF("Outlet tuple not found!\n");
00328 return 0;
00329 }
00330
00331 cvReleaseMat(&homography);
00332
00333 return 1;
00334 }
00335
00336 int detect_outlet_tuple_2x1(IplImage* src, CvMat* intrinsic_matrix, CvMat* distortion_params,
00337 vector<outlet_t>& outlets, const outlet_template_t& outlet_templ,
00338 const char* output_path, const char* filename)
00339 {
00340 vector<feature_t> holes;
00341
00342 IplImage* img_small = cvCreateImage(cvSize(src->width/2, src->height/2), IPL_DEPTH_8U, 3);
00343 cvResize(src, img_small);
00344
00345 IplImage* red = cvCreateImage(cvSize(img_small->width, img_small->height), IPL_DEPTH_8U, 1);
00346 cvSetImageCOI(img_small, 3);
00347 cvCopy(img_small, red);
00348 cvSetImageCOI(img_small, 0);
00349
00350 detect_outlets_2x1_one_way(red, outlet_templ.get_one_way_descriptor_base(), holes, img_small, output_path, filename);
00351 cvReleaseImage(&red);
00352 cvReleaseImage(&img_small);
00353
00354 if(holes.size() == 6)
00355 {
00356 features2outlets_2x1(holes, outlets);
00357
00358 CvPoint2D32f centers[6];
00359 for(int i = 0; i < 6; i++)
00360 {
00361 centers[i] = cvPoint2D32f(holes[i].pt.x*2, holes[i].pt.y*2);
00362 }
00363
00364 CvPoint2D32f object_points[6];
00365 generate_object_points_2x1(object_points);
00366
00367 CvMat* homography = cvCreateMat(3, 3, CV_32FC1);
00368 cvGetPerspectiveTransform(centers, object_points, homography);
00369
00370 CvMat* rotation_vector = cvCreateMat(3, 1, CV_32FC1);
00371 CvMat* translation_vector = cvCreateMat(3, 1, CV_32FC1);
00372
00373 calc_camera_outlet_pose(intrinsic_matrix, distortion_params, outlet_templ, centers, rotation_vector, translation_vector);
00374
00375 calc_outlet_coords(outlets, homography, cvPoint3D32f(0.0f, 0.0f, 0.0f), cvPoint2D32f(1.0f, 1.0f),
00376 rotation_vector, translation_vector);
00377
00378 return 1;
00379 }
00380 else
00381 {
00382 return 0;
00383 }
00384 }
00385
00386 void features2outlets_2x1(const vector<feature_t>& features, vector<outlet_t>& outlets)
00387 {
00388 outlet_t outlet;
00389 outlet.hole1 = features[0].pt*2;
00390 outlet.hole2 = features[1].pt*2;
00391 outlet.ground_hole = features[4].pt*2;
00392 outlets.push_back(outlet);
00393
00394 outlet.hole1 = features[2].pt*2;
00395 outlet.hole2 = features[3].pt*2;
00396 outlet.ground_hole = features[5].pt*2;
00397 outlets.push_back(outlet);
00398 }