00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "stoc.h"
00033 #include <SVS/svsclass.h>
00034
00035 using namespace sensor_msgs;
00036 using namespace deprecated_msgs;
00037
00039 #define STOC_EXCEPT(except, msg) \
00040 { \
00041 char buf[100]; \
00042 snprintf(buf, 100, "[STOC::%s]: " msg, __FUNCTION__); \
00043 throw except(buf); \
00044 }
00045
00047 #define STOC_EXCEPT_ARGS(except, msg, ...) \
00048 { \
00049 char buf[100]; \
00050 snprintf(buf, 100, "[STOC::%s]: " msg, __FUNCTION__, __VA_ARGS__); \
00051 throw except(buf); \
00052 }
00053
00054 stoc::STOC::STOC () : capture_type_(-1), format_(-1), channel_(-1), swap_mode_(false), color_mode_(0),
00055
00056 color_alg_(2), proc_mode_(PROC_MODE_NONE), rate_(15), frame_div_(-1), size_w_(640), size_h_(480),
00057 rectification_(1), z_max_(5), multiproc_en_(true), cut_di_(64), speckle_diff_(-1),
00058 speckle_size_(400), horopter_(-1), corrsize_(15), unique_(10), tex_thresh_(5), ndisp_(64),
00059 debug_(true)
00060 {
00061 process_ = new svsStereoProcess ();
00062 multiproc_ = new svsMultiProcess ();
00063 video_ = getVideoObject ();
00064
00065 intrinsic_ = cvCreateMat (3, 3, CV_64FC1);
00066 distortion_ = cvCreateMat (1, 4, CV_64FC1);
00067 cvmSet (intrinsic_, 0, 0, 429.609702); cvmSet (intrinsic_, 0, 1, 0.0); cvmSet (intrinsic_, 0, 2, 309.444590);
00068 cvmSet (intrinsic_, 1, 0, 0.0); cvmSet (intrinsic_, 1, 1, 429.070702); cvmSet (intrinsic_, 1, 2, 222.472089);
00069 cvmSet (intrinsic_, 2, 0, 0.0); cvmSet (intrinsic_, 2, 1, 0.0); cvmSet (intrinsic_, 2, 2, 1.0);
00070 cvmSet (distortion_, 0, 0, -0.006479); cvmSet (distortion_, 0, 1, 0.039474); cvmSet (distortion_, 0, 2, 0.0); cvmSet (distortion_, 0, 3, 0.0);
00071 }
00072
00073 stoc::STOC::~STOC ()
00074 {
00075 }
00076
00078
00079 void
00080 stoc::STOC::readParametersFromFile (const char* parameter_file)
00081 {
00082 if (parameter_file != NULL)
00083 {
00084 video_->ReadParams ((char*)parameter_file);
00085 fprintf (stderr, ">> Using camera parameters from %s\n", parameter_file);
00086 }
00087 }
00088
00090
00091 void
00092 stoc::STOC::sendInternalParameters ()
00093 {
00094 if (capture_type_ != -1)
00095 {
00096 if (video_->SetCapture (capture_type_))
00097 { if (debug_) fprintf (stderr, "[STOC] >> Set capture type to %d\n", capture_type_); }
00098 else
00099 STOC_EXCEPT_ARGS(stoc::Exception, "Error while setting capture type to %d!", capture_type_);
00100 }
00101
00102 if (format_ != -1)
00103 {
00104 if (video_->SetFormat (format_))
00105 { if (debug_) fprintf (stderr, "[STOC] >> Set format type to %d\n", format_); }
00106 else
00107 STOC_EXCEPT_ARGS(stoc::Exception, "Error setting format type to %d!", format_);
00108 }
00109
00110 if (channel_ != -1)
00111 {
00112 if (video_->SetChannel (channel_))
00113 { if (debug_) fprintf (stderr, "[STOC] >> Set channel type to %d\n", channel_); }
00114 else
00115 STOC_EXCEPT_ARGS(stoc::Exception, "Error setting channel type to %d!", channel_);
00116 }
00117
00118 if (swap_mode_)
00119 {
00120 if (video_->SetSwap (swap_mode_))
00121 { if (debug_) fprintf (stderr, "[STOC] >> Swap mode enabled\n"); }
00122 else
00123 STOC_EXCEPT(stoc::Exception, "Error enabling swap mode!");
00124 }
00125
00126 if (color_mode_ != -1)
00127 {
00128 bool r = false;
00129 if (color_mode_ == 0) r = video_->SetColor (true, true);
00130 if (color_mode_ == 1) r = video_->SetColor (true, false);
00131 if (color_mode_ == 2) r = video_->SetColor (false, true);
00132 if (r & debug_)
00133 fprintf (stderr, "[STOC] >> Color mode set to %d\n", color_mode_);
00134 else
00135 STOC_EXCEPT_ARGS(stoc::Exception, "Error setting color mode to %d!", color_mode_);
00136 }
00137
00138 if (color_alg_ != -1)
00139 {
00140 if (video_->SetColorAlg (color_alg_))
00141 { if (debug_) fprintf (stderr, "[STOC] >> Color algorithm set to %d\n", color_alg_); }
00142 else
00143 STOC_EXCEPT_ARGS(stoc::Exception, "Error setting color algorithm to %d!", color_alg_);
00144 }
00145
00146 if (video_->SetSize (size_w_, size_h_))
00147 { if (debug_) fprintf (stderr, "[STOC] >> Image size set to %dx%d\n", size_w_, size_h_); }
00148 else
00149 STOC_EXCEPT_ARGS(stoc::Exception, "Error setting image size to %dx%d!", size_w_, size_h_);
00150
00151 if (frame_div_ != -1)
00152 {
00153 if (video_->SetFrameDiv (frame_div_))
00154 { if (debug_) fprintf (stderr, "[STOC] >> Image sampling set to %d\n", frame_div_); }
00155 else
00156 STOC_EXCEPT_ARGS(stoc::Exception, "Error setting image sampling to %d!", frame_div_);
00157 }
00158
00159 if (rate_ != -1)
00160 {
00161 if (video_->SetRate (rate_))
00162 { if (debug_) fprintf (stderr, "[STOC] >> Image rate set to %d\n", rate_); }
00163 else
00164 STOC_EXCEPT_ARGS(stoc::Exception, "Error setting image rate to %d!", rate_);
00165 }
00166
00167 if (proc_mode_ != -1)
00168 {
00169 if (video_->SetProcMode (proc_mode_type(proc_mode_)))
00170 { if (debug_) fprintf (stderr, "[STOC] >> Processing mode set to %d\n", proc_mode_); }
00171 else
00172 STOC_EXCEPT_ARGS(stoc::Exception, "Error setting STOC processing mode to %d!", proc_mode_);
00173 }
00174
00175 if (rectification_ != -1)
00176 {
00177 if (video_->SetRect (rectification_))
00178 { if (debug_) fprintf (stderr, "[STOC] >> Image rectification set to %d\n", rectification_); }
00179 else
00180 STOC_EXCEPT_ARGS(stoc::Exception, "Error setting image rectification to %d!", rectification_);
00181 }
00182 }
00183
00185
00186 void
00187 stoc::STOC::sendStereoParameters ()
00188 {
00189 if (cut_di_ != 0 && debug_)
00190 fprintf (stderr, "[STOC] >> Disconsidering the last %d lines from the bottom of the disparity image...\n", cut_di_);
00191 if (ndisp_ != -1)
00192 {
00193 video_->SetNDisp (ndisp_);
00194 if (debug_) fprintf (stderr, "[STOC] >> Number of disparities set to %d\n", ndisp_);
00195 }
00196 if (tex_thresh_ != -1)
00197 {
00198 video_->SetThresh (tex_thresh_);
00199 if (debug_) fprintf (stderr, "[STOC] >> Texture filter threshold set to %d\n", tex_thresh_);
00200 }
00201 if (unique_ != -1)
00202 {
00203 video_->SetUnique (unique_);
00204 if (debug_) fprintf (stderr, "[STOC] >> Uniqueness filter threshold set to %d\n", unique_);
00205 }
00206 if (corrsize_ != -1)
00207 {
00208 video_->SetCorrsize (corrsize_);
00209 if (debug_) fprintf (stderr, "[STOC] >> Correlation window size set to %d\n", corrsize_);
00210 }
00211 if (horopter_ != -1)
00212 {
00213 video_->SetHoropter (horopter_);
00214 if (debug_) fprintf (stderr, "[STOC] >> Horopter (X-Offset) value set to %d\n", horopter_);
00215 }
00216 if (speckle_size_ != -1)
00217 {
00218 video_->SetSpeckleSize (speckle_size_);
00219 if (debug_) fprintf (stderr, "[STOC] >> Minimum disparity region size set to %d\n", speckle_size_);
00220 }
00221 if (speckle_diff_ != -1)
00222 {
00223 video_->SetSpeckleDiff (speckle_diff_);
00224 if (debug_) fprintf (stderr, "[STOC] >> Disparity region neighbor diff to %d\n", speckle_diff_);
00225 }
00226 }
00227
00229
00230 int
00231 stoc::STOC::open ()
00232 {
00233 int res;
00234 int nr_cam = video_->Enumerate ();
00235
00236
00237 if (nr_cam == 0)
00238 {
00239 STOC_EXCEPT(stoc::Exception, "No cameras found!");
00240 return (-1);
00241 }
00242
00243 if (debug_)
00244 for (int i = 0; i < nr_cam; i++)
00245 fprintf (stderr, "[STOC] > Found camera %d: %s\n", i, video_->DeviceIDs ()[i]);
00246
00247
00248 res = video_->Open (nr_cam - 1);
00249 device_id_ = video_->DeviceIDs ()[nr_cam - 1];
00250
00251 if (!res)
00252 {
00253 STOC_EXCEPT(stoc::Exception, "Failed to open camera port!");
00254 return (-1);
00255 }
00256
00257 res = video_->ReadParams ();
00258 if (!res)
00259 {
00260 STOC_EXCEPT(stoc::Exception, "Could not query camera for intrinsic parameters!");
00261 return (-1);
00262 }
00263
00264 sendInternalParameters ();
00265 video_->binning = 1;
00266
00267 sendStereoParameters ();
00268
00269
00270 res = video_->Start ();
00271 if (!res)
00272 STOC_EXCEPT(stoc::Exception, "Failed to start data acquisition!");
00273
00274 return (0);
00275 }
00276
00278
00279 int
00280 stoc::STOC::close ()
00281 {
00282 int res = video_->Stop ();
00283
00284 res = video_->Close ();
00285 if (!res)
00286 return (-1);
00287 return (0);
00288 }
00289
00291
00292 void
00293 stoc::STOC::undistort (uint8_t *img, uint8_t *un_img, int width, int height)
00294 {
00295 CvMat *src = cvCreateMatHeader (height, width, CV_8UC3);
00296 cvSetData (src, img, width * 3);
00297 CvMat *dst = cvCreateMatHeader (height, width, CV_8UC3);
00298 cvSetData (dst, un_img, width * 3);
00299
00300 cvUndistort2 (src, dst, intrinsic_, distortion_);
00301 }
00302
00303
00305
00306 void
00307 stoc::STOC::readData (PointCloud &cloud, ImageArray &images)
00308 {
00309 svsStereoImage *si = video_->GetImage (10);
00310 if (si == NULL && debug_)
00311 STOC_EXCEPT(stoc::Exception, "No image, timed out...");
00312
00313
00314 if (multiproc_en_)
00315 multiproc_->CalcStereo (si);
00316 else
00317 process_->CalcStereo (si);
00318
00319
00320 for (int i = si->ip.height - cut_di_; i < si->ip.height; i++)
00321 for (int j = 0; j < si->ip.width; j++)
00322 si->disparity[i * si->ip.width + j] = -2;
00323
00324
00325 if (multiproc_en_)
00326 multiproc_->Calc3D (si, 0, 0, 0, 0, NULL, NULL, z_max_);
00327 else
00328 process_->Calc3D (si, 0, 0, 0, 0, NULL, NULL, z_max_);
00329
00330
00331 int nr_points = 0;
00332
00333
00334 cloud.points.resize (si->ip.height * si->ip.width);
00335 cloud.channels.resize (1);
00336 cloud.channels[0].name = "i";
00337 cloud.channels[0].values.resize (cloud.points.size ());
00338
00339
00340 if (si->haveColor)
00341 {
00342 cloud.channels.resize (3);
00343 cloud.channels[0].name = "r";
00344 cloud.channels[0].values.resize (cloud.points.size ());
00345 cloud.channels[1].name = "g";
00346 cloud.channels[1].values.resize (cloud.points.size ());
00347 cloud.channels[2].name = "b";
00348 cloud.channels[2].values.resize (cloud.points.size ());
00349 }
00350
00351 if (si->have3D)
00352 {
00353 svs3Dpoint *pts = si->pts3D;
00354 for (int i = 0; i < si->ip.height; i++)
00355 {
00356 for (int j = 0; j < si->ip.width; j++, pts++)
00357 {
00358
00359 if (pts->A <= 0)
00360 continue;
00361
00362 cloud.points[nr_points].x = pts->X;
00363 cloud.points[nr_points].y = pts->Y;
00364 cloud.points[nr_points].z = pts->Z;
00365
00366 if (si->haveColor)
00367 {
00368 svsColorPixel *mpc = (svsColorPixel*)(si->color + (i*si->ip.width + j) * 4);
00369 cloud.channels[0].values[nr_points] = mpc->r;
00370 cloud.channels[1].values[nr_points] = mpc->g;
00371 cloud.channels[2].values[nr_points] = mpc->b;
00372 }
00373 else
00374 cloud.channels[0].values[nr_points] = (unsigned char)si->Left ()[i*si->ip.width + j];
00375
00376 nr_points++;
00377 }
00378 }
00379
00380 }
00381 cloud.points.resize (nr_points);
00382 cloud.channels[0].values.resize (nr_points);
00383
00384 if (si->haveColor)
00385 {
00386 cloud.channels[1].values.resize (nr_points);
00387 cloud.channels[2].values.resize (nr_points);
00388 }
00389
00390
00391 if (si->haveDisparity)
00392 images.set_images_size (3);
00393 else
00394 images.set_images_size (2);
00395
00396
00397 images.images[0].width = si->ip.width;
00398 images.images[0].height = si->ip.height;
00399 images.images[0].compression = "raw";
00400 images.images[0].label = "stoc-left";
00401 images.images[0].set_data_size (si->ip.width * si->ip.height);
00402
00403 if (si->haveColor)
00404 {
00405 images.images[0].set_data_size (images.images[0].get_data_size () * 3);
00406 images.images[0].colorspace = "rgb24";
00407 unsigned char *in_left = (unsigned char*)si->Color ();
00408
00409
00410 uint8_t *img_tmp = (uint8_t*)malloc (si->ip.width * si->ip.height * 3);
00411
00412 for (int i = 0, j = 0; i < si->ip.width * si->ip.height; i++, j+=3, in_left +=4)
00413 {
00414
00415
00416
00417 img_tmp[j + 0] = in_left[0];
00418 img_tmp[j + 1] = in_left[1];
00419 img_tmp[j + 2] = in_left[2];
00420 }
00421 memcpy (&(images.images[0].data[0]), img_tmp, si->ip.width * si->ip.height * 3);
00422
00423 free (img_tmp);
00424 }
00425 else
00426 {
00427 images.images[0].colorspace = "mono8";
00428 memcpy (&(images.images[0].data[0]), si->Left (), images.images[0].get_data_size ());
00429 }
00430
00431
00432 images.images[1].width = si->ip.width;
00433 images.images[1].height = si->ip.height;
00434 images.images[1].compression = "raw";
00435 images.images[1].label = "stoc-right";
00436 images.images[1].set_data_size (si->ip.width * si->ip.height);
00437
00438 if (si->haveColorRight)
00439 {
00440 images.images[1].set_data_size (images.images[1].get_data_size () * 3);
00441 images.images[1].colorspace = "rgb24";
00442 unsigned char *in_right = (unsigned char*)si->ColorRight ();
00443 for (int i = 0, j = 0; i < si->ip.width * si->ip.height; i++, j+=3, in_right +=4)
00444 {
00445 images.images[1].data[j + 0] = in_right[0];
00446 images.images[1].data[j + 1] = in_right[1];
00447 images.images[1].data[j + 2] = in_right[2];
00448 }
00449 }
00450 else
00451 {
00452 images.images[1].colorspace = "mono8";
00453 memcpy (&(images.images[1].data[0]), si->Right (), images.images[1].get_data_size ());
00454 }
00455
00456
00457 if (si->haveDisparity)
00458 {
00459 images.images[2].width = si->dp.dwidth;
00460 images.images[2].height = si->dp.dheight;
00461 images.images[2].colorspace = "mono16";
00462 images.images[2].compression = "raw";
00463 images.images[2].label = "stoc-disparity";
00464 images.images[2].set_data_size (si->dp.dwidth * si->dp.dheight * 2);
00465 memcpy (&(images.images[2].data[0]), si->disparity, images.images[2].get_data_size ());
00466 }
00467
00468 cloud.header.stamp = ros::Time::now ();
00469 images.header.stamp = ros::Time::now ();
00470 return;
00471 }
00472
00474
00475 void
00476 stoc::STOC::readDataLeft (PointCloud &cloud, Image &left_image)
00477 {
00478 svsStereoImage *si = video_->GetImage (10);
00479 if (si == NULL && debug_)
00480 STOC_EXCEPT(stoc::Exception, "No image, timed out...");
00481
00482
00483 if (multiproc_en_)
00484 multiproc_->CalcStereo (si);
00485 else
00486 process_->CalcStereo (si);
00487
00488
00489 for (int i = si->ip.height - cut_di_; i < si->ip.height; i++)
00490 for (int j = 0; j < si->ip.width; j++)
00491 si->disparity[i * si->ip.width + j] = -2;
00492
00493
00494 if (multiproc_en_)
00495 multiproc_->Calc3D (si, 0, 0, 0, 0, NULL, NULL, z_max_);
00496 else
00497 process_->Calc3D (si, 0, 0, 0, 0, NULL, NULL, z_max_);
00498
00499
00500 int nr_points = 0;
00501
00502
00503 cloud.points.resize (si->ip.height * si->ip.width);
00504 cloud.channels.resize (1);
00505 cloud.channels[0].name = "i";
00506 cloud.channels[0].values.resize (cloud.points.size ());
00507
00508
00509 if (si->haveColor)
00510 {
00511 cloud.channels.resize (3);
00512 cloud.channels[0].name = "r";
00513 cloud.channels[0].values.resize (cloud.points.size ());
00514 cloud.channels[1].name = "g";
00515 cloud.channels[1].values.resize (cloud.points.size ());
00516 cloud.channels[2].name = "b";
00517 cloud.channels[2].values.resize (cloud.points.size ());
00518 }
00519
00520 if (si->have3D)
00521 {
00522 svs3Dpoint *pts = si->pts3D;
00523 for (int i = 0; i < si->ip.height; i++)
00524 {
00525 for (int j = 0; j < si->ip.width; j++, pts++)
00526 {
00527
00528 if (pts->A <= 0)
00529 continue;
00530
00531 cloud.points[nr_points].x = pts->X;
00532 cloud.points[nr_points].y = pts->Y;
00533 cloud.points[nr_points].z = pts->Z;
00534
00535 if (si->haveColor)
00536 {
00537 svsColorPixel *mpc = (svsColorPixel*)(si->color + (i*si->ip.width + j) * 4);
00538 cloud.channels[0].values[nr_points] = mpc->r;
00539 cloud.channels[1].values[nr_points] = mpc->g;
00540 cloud.channels[2].values[nr_points] = mpc->b;
00541 }
00542 else
00543 cloud.channels[0].values[nr_points] = (unsigned char)si->Left ()[i*si->ip.width + j];
00544
00545 nr_points++;
00546 }
00547 }
00548
00549 }
00550 cloud.points.resize (nr_points);
00551 cloud.channels[0].values.resize (nr_points);
00552
00553 if (si->haveColor)
00554 {
00555 cloud.channels[1].values.resize (nr_points);
00556 cloud.channels[2].values.resize (nr_points);
00557 }
00558
00559
00560 left_image.width = si->ip.width;
00561 left_image.height = si->ip.height;
00562 left_image.compression = "raw";
00563 left_image.label = "stoc-left";
00564 left_image.set_data_size (si->ip.width * si->ip.height);
00565
00566 if (si->haveColor)
00567 {
00568 left_image.set_data_size (left_image.get_data_size () * 3);
00569 left_image.colorspace = "rgb24";
00570 unsigned char *in_left = (unsigned char*)si->Color ();
00571 for (int i = 0, j = 0; i < si->ip.width * si->ip.height; i++, j+=3, in_left +=4)
00572 {
00573 left_image.data[j + 0] = in_left[0];
00574 left_image.data[j + 1] = in_left[1];
00575 left_image.data[j + 2] = in_left[2];
00576 }
00577 }
00578 else
00579 {
00580 left_image.colorspace = "mono8";
00581 memcpy (&(left_image.data[0]), si->Left (), left_image.get_data_size ());
00582 }
00583
00584 cloud.header.stamp = ros::Time::now ();
00585 left_image.header.stamp = ros::Time::now ();
00586 return;
00587 }