00001 #include "openni_cam.h"
00002
00003 #include <ros/ros.h>
00004 #include <image_transport/image_transport.h>
00005 #include <sensor_msgs/image_encodings.h>
00006
00007
00008
00009 #include <sensor_msgs/CameraInfo.h>
00010 #include <geometry_msgs/TransformStamped.h>
00011 #include <openni_cam/thermo_info.h>
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020
00021 #include <cmath>
00022
00023 #include "camera.h"
00024 #include <stdio.h>
00025 #include "error.h"
00026
00027 #include "include/Imager.h"
00028 #include "ImagerUVC.h"
00029
00030 #include <QtGui/QApplication>
00031 #include <QtGui/QKeyEvent>
00032
00033 using namespace optris;
00034 using namespace exttype;
00035
00036 image_transport::Publisher publisher1;
00037 image_transport::Publisher publisher2;
00038 image_transport::Publisher publisher_ir;
00039
00040 ros::Publisher publisher_rgb_info;
00041 ros::Publisher publisher_ir_info;
00042 ros::Publisher publisher_ir_info1;
00043
00044
00045
00046
00047 class thermo_node {
00048 public:
00049 camera cam;
00050 Imager * imager;
00051 unsigned long serial;
00052 int Width;
00053 int Height;
00054 int count;
00055 int acq_count;
00056 bool frame_acquired;
00057 bool frame_processed;
00058 bool recali;
00059 unsigned short int bimage[5];
00060 dynamic::num_array<unsigned short int,2> image;
00061 dynamic::num_array<float,2> ftemp;
00062
00063
00064 float t_max;
00065 float t_min;
00066 float t_med;
00067
00068 public:
00069
00070 unsigned char * buff;
00071
00072 thermo_node():buff(0) {
00073 };
00074
00075 ~thermo_node() {
00076 if(buff)delete buff;
00077 delete imager;
00078 };
00079 void init(fptrOptrisFrame pOnFrame) {
00080 cam.find_device();
00081 cam.init_device();
00082 Width = cam.width;
00083 Height = cam.height-1;
00084 serial = cam.dev_serial;
00085 int frequency = cam.frequency;
00086
00087 imager = new Imager(serial, Width, Height+1, frequency, "../../thermo_cam/data/config/12050017.xml");
00088 count = 0;
00089 imager->forceRecalibration();
00090 buff = new unsigned char[Width*(Height+1)*2];
00091 imager->setFrameCallback(pOnFrame);
00092 bimage[0] = 0;
00093 acq_count = 0;
00094 recali = true;
00095 };
00096 void triger() {
00097
00098
00099
00100
00101 cam.get_image();
00102
00103
00104
00105
00106 };
00107
00108 void process() {
00109 imager->process((unsigned char *)cam.buffer.start);
00110 };
00111
00112 void force_recali() {
00113 imager->forceRecalibration();
00114 recali = true;
00115 for(int i=0;i<5;++i){
00116 get_image();
00117 };
00118 };
00119
00120 void get_image() {
00121 frame_acquired = false;
00122 while(!frame_acquired) {
00123 triger();
00124 process();
00125 const char * psym = "-\\|/";
00126 std::cout<<"\b"<<psym[count % 4];
00127 fflush(stdout);
00128 ++count;
00129 };
00130 ++acq_count;
00131 recali = false;
00132
00133 };
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 void filter_ir() {
00166 exttype::mint2 sz = image.size();
00167 dynamic::num_array<float,2> vals;
00168 ftemp.resize(sz);
00169 vals.resize(sz);
00170
00171
00172 for(int i=0; i<image.length(); ++i) {
00173 vals[i] = ((float)(image[i])-1000.0)*0.1;
00174 };
00175 ftemp << 0;
00176 int Width = sz[0];
00177 int Height = sz[1];
00178
00179 float max=-1e6;
00180 float min=+1e6;
00181
00182 std::vector<float> a;
00183 a.resize(9);
00184 for(int i=1; i<Height-1; ++i) {
00185 for(int j=1; j<Width-1; ++j) {
00186
00187 int ii = i*Width+j;
00188 a[0] = vals[ii];
00189 a[1] = vals[ii+1];
00190 a[2] = vals[ii-1];
00191 a[3] = vals[ii-Width];
00192 a[4] = vals[ii+Width];
00193 a[5] = vals[ii-1-Width];
00194 a[6] = vals[ii-1+Width];
00195 a[7] = vals[ii+1-Width];
00196 a[8] = vals[ii+1+Width];
00197 std::nth_element(a.begin(),a.begin()+5,a.end());
00198 float pixel = a[5];
00199
00200 ftemp(j,i) = pixel;
00201
00202 if(pixel > max)max = pixel;
00203 if(pixel < min)min = pixel;
00204 };
00205 };
00206 t_max = max;
00207 t_min = min;
00208
00209 int med_pos = vals.length()/2;
00210
00211
00212
00213
00214
00215
00216
00217 };
00218
00219 void cbOnFrame(unsigned short* image, unsigned int w, unsigned int h) {
00220
00221 int num_bytes = Width*Height*2;
00222
00223 int i0 = num_bytes/4;
00224 if(bimage[0]==0 || bimage[0]==image[i0]) {
00225 bimage[0]=image[i0];
00226
00227 frame_acquired = false;
00228 frame_processed = true;
00229 return;
00230 };
00231
00232 bimage[0]=image[i0];
00233 this->image.resize(mint2(w,h));
00234 memcpy(this->image.begin(),image,num_bytes);
00235 frame_acquired = true;
00236 frame_processed = true;
00237 return;
00238 };
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 };
00260
00261 thermo_node tcam;
00262 openni_cam::openni_cam cam;
00263
00264
00265
00266
00267
00268 class myApp : public QApplication {
00269 public:
00270 int count;
00271 int rcount;
00272 int recali_time;
00273 int loop_rate;
00274 public:
00275 myApp(int & argc, char ** argv, ros::NodeHandle & nhh):QApplication(argc,argv) {
00276 count = 0;
00277 rcount = 0;
00278 recali_time = 10;
00279
00280 nhh.param<int>("loop_rate",loop_rate,5);
00281 startTimer(1000/loop_rate);
00282 };
00283
00284 ~myApp() {
00285 };
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 void timerEvent(QTimerEvent * event) {
00310 ros::spinOnce();
00311 if(!ros::ok()) {
00312 printf("quitting");
00313 fflush(stdout);
00314 exit(0);
00315 };
00316 ++rcount;
00317 if(rcount>=recali_time*loop_rate) {
00318 tcam.force_recali();
00319
00320 rcount = 0;
00321 };
00322
00323 tcam.get_image();
00324
00325 ros::Time t1 = ros::Time::now();
00326 cam.get_image();
00327 tcam.get_image();
00328 tcam.filter_ir();
00329 printf("\b\b\b\b\b\b\b\b\b\b\b\b%4.4i %4.4i ",(count%10000),(count%10000));
00330
00331 fflush(stdout);
00332 ++count;
00333
00334 {
00335
00336 sensor_msgs::ImagePtr msg(new sensor_msgs::Image());
00337 msg->header.stamp = t1;
00338
00339 int num_bytes = tcam.ftemp.byte_size();
00340 msg->data.resize(num_bytes);
00341 memcpy(&msg->data[0],tcam.ftemp.begin(),num_bytes);
00342 msg->encoding = sensor_msgs::image_encodings::TYPE_32FC1;
00343 msg->step = tcam.ftemp.byte_stride(0,1);
00344 msg->height = tcam.ftemp.size()[1];
00345 msg->width = tcam.ftemp.size()[0];
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 msg->header.seq = count;
00360 publisher_ir.publish(msg);
00361
00362
00363 openni_cam::thermo_info info;
00364
00365
00366 info.serial = tcam.serial;
00367 info.header.stamp = t1;
00368 info.header.seq = count;
00369 info.header.frame_id = "";
00370 info.t_min = tcam.t_min;
00371 info.t_max = tcam.t_max;
00372 publisher_ir_info1.publish(info);
00373 {
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 sensor_msgs::CameraInfoPtr ci(new sensor_msgs::CameraInfo());
00406 ci->header = msg->header;
00407 ci->height = msg->height;
00408 ci->width = msg->width;
00409 geom::matrix3 K;
00410 K << 0;
00411
00412 double fx = 1.0/(msg->width/2);
00413 double fy = 1.0/(msg->height/2);
00414 K(0,0) = fx;
00415 K(1,1) = fy;
00416 K(0,2) = msg->width/2;
00417 K(1,2) = msg->height/2;
00418 K(2,2) = 1;
00419 for(int i=0; i<3; ++i) {
00420 ci->P[i*4 + 3] = 0;
00421 for(int j=0; j<3; ++j) {
00422 ci->R[i*3+j] = (i==j);
00423 ci->P[i*4+j] = K(i,j);
00424 ci->K[i*3+j] = K(i,j);
00425 };
00426 }
00427 ci->distortion_model = "";
00428
00429 ci->roi.height = msg->height;
00430 ci->roi.width = msg->width;
00431 ci->binning_x = 1;
00432 ci->binning_y = 1;
00433 publisher_ir_info.publish(ci);
00434 }
00435 };
00436
00437 {
00438
00439 sensor_msgs::ImagePtr msg(new sensor_msgs::Image());
00440 msg->header.stamp = t1;
00441 int num_bytes = cam.rgb.byte_size();
00442 msg->data.resize(num_bytes);
00443 memcpy(&msg->data[0],cam.rgb.begin(),num_bytes);
00444 msg->encoding = sensor_msgs::image_encodings::RGB8;
00445 msg->step = cam.rgb.byte_stride(0,0,1);
00446 msg->width = cam.rgb.size()[1];
00447 msg->height = cam.rgb.size()[2];
00448 msg->header.frame_id = "openni_camera";
00449 msg->header.seq = count;
00450 publisher1.publish(msg);
00451
00452
00453 sensor_msgs::CameraInfoPtr ci(new sensor_msgs::CameraInfo());
00454 ci->header = msg->header;
00455 ci->height = msg->height;
00456 ci->width = msg->width;
00457 for(int i=0; i<3; ++i) {
00458 ci->P[i*4 + 3] = 0;
00459 for(int j=0; j<3; ++j) {
00460 ci->R[i*3+j] = (i==j);
00461 ci->P[i*4+j] = cam.K(i,j);
00462 ci->K[i*3+j] = cam.K(i,j);
00463 };
00464 }
00465 ci->distortion_model = "";
00466
00467 ci->roi.height = msg->height;
00468 ci->roi.width = msg->width;
00469 ci->binning_x = 1;
00470 ci->binning_y = 1;
00471 publisher_rgb_info.publish(ci);
00472
00473
00474
00475
00476
00477
00478 };
00479 {
00480
00481 sensor_msgs::ImagePtr msg(new sensor_msgs::Image());
00482 msg->header.stamp = t1;
00483 int num_bytes = cam.depth.byte_size();
00484 msg->data.resize(num_bytes);
00485 memcpy(&msg->data[0],cam.depth.begin(),num_bytes);
00486 msg->encoding = sensor_msgs::image_encodings::MONO16;
00487 msg->step = cam.depth.byte_stride(0,1);
00488 msg->width = cam.depth.size()[0];
00489 msg->height = cam.depth.size()[1];
00490 msg->header.frame_id = "openni_camera";
00491 msg->header.seq = count;
00492 publisher2.publish(msg);
00493 };
00494 };
00495
00496
00497 bool notify(QObject * receiver, QEvent * ev) {
00498 if(ev->type() == QEvent::KeyPress) {
00499 QKeyEvent * e = static_cast<QKeyEvent *>(ev);
00500
00501
00502
00503
00504 if(e->key() == Qt::Key_Return) {
00505 printf("Return");
00506 fflush(stdout);
00507 return true;
00508 } else if(e->key() == Qt::Key_Tab) {
00509 printf("Tab");
00510 fflush(stdout);
00511 return true;
00512 } else if(e->key() == Qt::Key_Escape) {
00513 printf("ESC");
00514 fflush(stdout);
00515 exit(0);
00516 return true;
00517 };
00518 };
00519 return QApplication::notify(receiver,ev);
00520 };
00521 };
00522
00523 myApp * a;
00524
00525 void cbOnFrame(unsigned short* image, unsigned int w, unsigned int h) {
00526 tcam.cbOnFrame(image,w,h);
00527 };
00528
00529
00530 int main(int argc, char **argv) {
00531 ros::init(argc, argv, "openni_node");
00532 ros::NodeHandle nh;
00533 ros::NodeHandle nhh("~");
00534 image_transport::ImageTransport it(nh);
00535 publisher1 = it.advertise("openni_camera/rgb", 1);
00536 publisher2 = it.advertise("openni_camera/depth", 1);
00537 publisher_ir = it.advertise("thermo_camera/ftemp", 1);
00538 publisher_ir_info = nh.advertise<sensor_msgs::CameraInfo>("/thermo_camera/camera_info", 1);
00539 publisher_ir_info1 = nh.advertise<openni_cam::thermo_info>("thermo_camera/info", 1);
00540
00541 publisher_rgb_info = nh.advertise<sensor_msgs::CameraInfo>("openni_camera/camera_info", 1);
00542
00543 cam.init();
00544 tcam.init(cbOnFrame);
00545
00546 printf("openni_thermo_node %4.4i %4.4i ",0,0);
00547 fflush(stdout);
00548
00549
00550 a = new myApp(argc, argv, nhh);
00551 a->exec();
00552 delete a;
00553 };