00001 #include <ros/ros.h>
00002 #include <image_transport/image_transport.h>
00003 #include <sensor_msgs/image_encodings.h>
00004 #include <sensor_msgs/CameraInfo.h>
00005 #include <geometry_msgs/TransformStamped.h>
00006 #include <tf/tf.h>
00007 #include <tf/transform_listener.h>
00008 #include <tf/transform_datatypes.h>
00009 #include <tf/transform_broadcaster.h>
00010
00011
00012 #include <openni_cam/thermo_info.h>
00013 #include <vision_msgs/PoseEstimate.h>
00014 #include <sensor_msgs/PointCloud2.h>
00015
00016
00017
00018 #include <message_filters/subscriber.h>
00019 #include <message_filters/time_synchronizer.h>
00020 #include <message_filters/sync_policies/approximate_time.h>
00021 #include <image_transport/subscriber_filter.h>
00022
00023
00024
00025 #include <QtGui/QApplication>
00026 #include <QtGui/QLabel>
00027 #include <QtCore/QBasicTimer>
00028 #include <QtGui/QPainter>
00029 #include <QtGui/QDialog>
00030 #include <QtGui/QMainWindow>
00031
00032 #include <QtGui/QKeyEvent>
00033 #include <QtGui/QMouseEvent>
00034
00035
00036
00037
00038
00039
00040 #if defined(MATLAB) || defined(MATLAB_MEX_FILE)
00041 #include "mex/mex_io.h"
00042 #undef printf
00043 #endif
00044
00045
00046
00047 #define NO_EXTTYPE
00048 #include <stdio.h>
00049
00050 #include "exttype/intn.h"
00051 #include "victim1_node.h"
00052 #include "../../thermo_cam/src/IronPalette.h"
00053 #include "geom/nmmatrix.h"
00054 #include "dynamic/fixed_array2.h"
00055
00056
00057
00058
00059 #include <sstream>
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 image_transport::Publisher publisher1;
00083 ros::Publisher publisher2;
00084 ros::Publisher publisher3;
00085
00086 using namespace exttype;
00087 using namespace dynamic;
00088 using namespace sensor_msgs;
00089 using namespace message_filters;
00090
00091
00092 class sources {
00093 public:
00094 struct point {
00095 geom::vect2 x;
00096 float depth;
00097 float conf;
00098 };
00099 public:
00100 dynamic::num_array<unsigned char,3> rgb;
00101 dynamic::num_array<unsigned short int,2> depth;
00102 dynamic::num_array<unsigned short int,2> laser_image;
00103
00104
00105 dynamic::num_array<float,2> ftemp;
00106
00107 dynamic::num_array<float,2> IR;
00108 dynamic::num_array<float,2> resp1;
00109 dynamic::num_array<float,3> dresp;
00110
00111 dynamic::num_array<float,2> resp2;
00112 dynamic::num_array<mint2,3> boxes;
00113 std::vector<point> points;
00114
00115 std_msgs::Header h;
00116
00117 dynamic::num_array<int,2> fw_IR_map;
00118 dynamic::num_array<int,2> bw_IR_map;
00119 array_tn<geom::vect2,4> corners;
00120 array_tn<geom::vect2,4> Corners;
00121
00122
00123 geom::matrix3 K;
00124 geom::matrix3 Kinv;
00125
00126 float t_max;
00127 float t_min;
00128 float t_med;
00129 float r1_min;
00130 float r1_max;
00131 float r2_max;
00132 float max_depth;
00133 float min_depth;
00134 bool lack_depth;
00135 std::string sserial;
00136 public:
00137 sources() {
00138 };
00139 int rgb_width()const {
00140 return rgb.size()[1];
00141 };
00142 int rgb_height()const {
00143 return rgb.size()[2];
00144 };
00145 };
00146
00147 class victim1 {
00148 public:
00149 sources * src;
00150 geom::matrix34 reproj_P;
00151 geom::matrix3 Pinv;
00152 dynamic::num_array<float,2> temp_li;
00153 bool initialized;
00154
00155 victim1() {
00156 initialized = false;
00157 };
00158
00159 void init() {
00160
00161
00162
00163 std::string fname1 = std::string("../config/")+src->sserial+"_ir_geom_cali_P.txt";
00164 std::ifstream f(fname1.c_str());
00165 if(!f.is_open()) {
00166 throw debug_exception(std::string("cant load geometry calibration file "+fname1));
00167 };
00168 for(int i=0; i<3; ++i) {
00169 for(int j=0; j<4; ++j) {
00170 double v;
00171 f>>v;
00172 reproj_P[i][j] = v;
00173 };
00174 };
00175 {
00176
00177 std::string fname1 = std::string("../config/")+src->sserial+"_ir_geom_cali_Pinv.txt";
00178 std::ifstream f(fname1.c_str());
00179 if(!f.is_open()) {
00180 throw debug_exception(std::string("cant load geometry calibration file "+fname1));
00181 };
00182 for(int i=0; i<3; ++i) {
00183 for(int j=0; j<3; ++j) {
00184 double v;
00185 f>>v;
00186 Pinv[i][j] = v;
00187 };
00188 };
00189 };
00190 {
00191 temp_li.resize(exttype::mint2(64,64));
00192 std::ifstream f("../config/temp_model.txt");
00193 if(!f.is_open()) {
00194 throw debug_exception("cant load geometry calibration file ../config/temp_model.txt");
00195 };
00196 for(int j=0; j<64; ++j) {
00197 for(int i=0; i<64; ++i) {
00198 double v;
00199 f>>v;
00200 temp_li(i,j) = v;
00201 };
00202 };
00203 };
00204 initialized = true;
00205 };
00206
00207 void filter_ir() {
00208 dynamic::num_array<float,2> a = src->ftemp;
00209 int med_pos = a.length()/2;
00210 std::nth_element(a.begin(),a.begin()+med_pos,a.end());
00211 src->t_med = a[med_pos];
00212 };
00213
00214 void fuse_depth() {
00215 if(!src->laser_image.is_empty()) {
00216 assert(src->laser_image.size()==src->depth.size());
00217
00218 int s = src->depth.size()[0];
00219 for(int i=0; i<src->depth.length(); ++i) {
00220
00221
00222 if(src->depth[i] == 0) {
00223 src->depth[i] = src->laser_image[i];
00224 };
00225 };
00226 };
00227 };
00228
00229 void depth_range() {
00230 src->min_depth = 1e6;
00231 src->max_depth = -1e6;
00232 int nnzd = 0;
00233 for(int i=0; i<src->depth.length(); ++i) {
00234 double z = src->depth(i);
00235 if(z>0) {
00236 ++nnzd;
00237 if(z < src->min_depth)src->min_depth = z;
00238 if(z > src->max_depth)src->max_depth = z;
00239 };
00240 };
00241 if(nnzd==0) {
00242 src->min_depth = 100.0;
00243 src->max_depth = 5000.0;
00244 };
00245 src->lack_depth = nnzd<src->depth.length()/4;
00246
00247 char s [1024];
00248 sprintf(s,"depth [%5.2f,%5.2f]",src->min_depth/1000.0,src->max_depth/1000.0);
00249 std::cout<<s;
00250 std::cout.flush();
00251
00252 for(int l=0; l<strlen(s); ++l)std::cout<<"\b";
00253 std::cout.flush();
00254
00255 };
00256
00257
00258 void ir_reproj() {
00259 dynamic::num_array<int,2> next;
00260 dynamic::num_array<int,2> occ;
00261 dynamic::num_array<float,2> Z;
00262
00263 exttype::mint2 sz1 = src->ftemp.size();
00264 exttype::mint2 sz2 = src->depth.size();
00265
00266 src->IR.resize(sz2);
00267 src->fw_IR_map.resize(sz1);
00268 src->fw_IR_map << -1;
00269 src->IR << 0;
00270 next.resize(sz2);
00271 next<< -1;
00272 Z.resize(sz1);
00273 Z<<1e8;
00274 occ.resize(sz1);
00275 occ << -1;
00276
00277 depth_range();
00278
00279 for(int y=0; y<sz2[1]; ++y) {
00280 for(int x=0; x<sz2[0]; ++x) {
00281 double z = src->depth(x,y);
00282 if(z<1 && 0 && src->lack_depth) {
00283 z = 5000;
00284 };
00285 z = 5000;
00286 if(z<1)continue;
00287 geom::vectn<4> p(x,y,1,1.0/z);
00288 geom::vectn<3> q;
00289 q = reproj_P*p;
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 double z1 = q[2];
00300 q/=z1;
00301 int i = floor(q[0]);
00302 int j = floor(q[1]);
00303 if(i<0 || j<0 || i>= sz1[0] || j>= sz1[1])continue;
00304 z1 = z;
00305 float delta = 30/1000.0*z;
00306 if(z1<Z(i,j)+delta) {
00307 int xy = src->IR.linindex(exttype::mint2(x,y));
00308 float v = src->ftemp(i,j);
00309 src->IR(x,y) = v;
00310 src->fw_IR_map(i,j) = xy;
00311 if(z1<Z(i,j)-delta) {
00312
00313 int p = occ(i,j);
00314 while(p>0) {
00315 src->IR(p) = 0;
00316 p = next(p);
00317 };
00318 occ(i,j) = -1;
00319 };
00320
00321 next(xy) = occ(i,j);
00322 occ(i,j) = xy;
00323 };
00324 if(z1<Z(i,j)) {
00325 Z(i,j) = z1;
00326 };
00327 };
00328 };
00329 src->corners[0] = geom::vect2(0,0);
00330 src->corners[1] = geom::vect2(sz1[0]-1,0);
00331 src->corners[2] = geom::vect2(sz1[0]-1,sz1[1]-1);
00332 src->corners[3] = geom::vect2(0,sz1[1]-1);
00333 for(int i=0; i<4; ++i) {
00334
00335 geom::vect3 p = src->corners[i]|1.0;
00336 geom::vect3 q = Pinv*p;
00337 q/=q[2];
00338 src->Corners[i] = q.sub<2>();
00339 };
00340 };
00341 void process1() {
00342 src->resp1.resize(src->IR.size());
00343 src->r1_min = 1e5;
00344 src->r1_max = -1e5;
00345 int t_bg = std::max(std::min(int(src->t_med),64),1)-1;
00346
00347 for(int i=0; i<src->IR.length(); ++i) {
00348 float temp = src->IR[i];
00349 if(temp<1 || temp>64) {
00350 src->resp1[i] = -1;
00351 } else {
00352 int itemp = int(temp)-1;
00353 float L = temp_li(itemp,t_bg);
00354 src->resp1[i] = L;
00355 };
00356 if(src->resp1[i] <src->r1_min)src->r1_min = src->resp1[i];
00357 if(src->resp1[i] >src->r1_max)src->r1_max = src->resp1[i];
00358 };
00359 };
00360 void process2() {
00361 int D = 30;
00362 int delta_d = 1;
00363 int box_size = 50;
00364 src->dresp.resize(src->resp1.size()|D);
00365 dynamic::num_array<int,3> nn(src->dresp.size());
00366 src->dresp << 0;
00367 nn << 0;
00368
00369 for(iter2 ii(src->resp1.size()); ii.allowed(); ++ii) {
00370 float z = src->depth[ii];
00371 if(z==0)continue;
00372
00373
00374 int disp = floor((z - src->min_depth)/(src->max_depth -src->min_depth)*(D-1));
00375
00376 if(disp<0 || disp>=D) {
00377 std::cout<<disp<<"\n";
00378 std::cout.flush();
00379 perror("bad disparity");
00380 throw debug_exception("bad disparity");
00381
00382 };
00383
00384 src->dresp[ii|disp] = std::max(0.0f,src->resp1[ii]);
00385
00386 nn[ii|disp] = 1;
00387 };
00388 for(int d = 0; d<D; ++d) {
00389 src->dresp.subdim<2>(d).cumsum();
00390 nn.subdim<2>(d).cumsum();
00391 };
00392
00393 src->resp2.resize(src->resp1.size());
00394 src->boxes.resize(src->resp1.size()|2);
00395 float box = box_size*1000.0;
00396 for(iter2 ii(src->resp1.size()); ii.allowed(); ++ii) {
00397
00398
00399
00400 float z = src->depth[ii];
00401
00402
00403
00404 int disp = floor((z - src->min_depth)/(src->max_depth -src->min_depth)*(D-1));
00405 float w;
00406 if(z>0) {
00407 w = std::max(box/z/2,float(2.0));
00408 } else {
00409 w = 10;
00410 };
00411 mint2 l = mint2::max(mint2(0,0),mint2(ii[0]-w,ii[1]-w));
00412 mint2 L = mint2::min(src->resp1.size()-1, mint2(ii[0]+w,ii[1]+w));
00413
00414 float r = 0;
00415 int n = 0;
00416 for(int d=std::max(0,disp-delta_d); d<std::min(D-1,disp+delta_d); ++d) {
00417 dynamic::num_array<float,2> rs = src->dresp.subdim<2>(d);
00418 r += rs(l[0],l[1])+rs(L[0],L[1])-rs(L[0],l[1])-rs(l[0],L[1]);
00419 dynamic::num_array<int,2> rn = nn.subdim<2>(d);
00420 n += rn(l[0],l[1])+rn(L[0],L[1])-rn(L[0],l[1])-rn(l[0],L[1]);
00421 };
00422
00423 n = std::max(1,n);
00424 src->resp2[ii] = r/10;
00425 src->boxes[ii|0] = l;
00426 src->boxes[ii|1] = L;
00427 };
00428 };
00429 struct keyval {
00430 public:
00431 float * val;
00432 int key;
00433 bool operator < (const keyval & b)const {
00434 return *val < *b.val;
00435 };
00436 };
00437 void nonmax_supress() {
00438 src->points.resize(0);
00439 src->points.reserve(10000);
00440 src->points.resize(0);
00441
00442 dynamic::num_array<float,2> resp2 = src->resp2;
00443 dynamic::fixed_array1<keyval> list(src->resp2.length());
00444 for(int i=0; i<src->resp1.length(); ++i) {
00445 list[i].key = i;
00446 list[i].val = &resp2[i];
00447 };
00448 src->r2_max=-1;
00449 while(true) {
00450 std::make_heap(list.begin(),list.end());
00451
00452 while(list.size()>0 && *list.back().val < 0) {
00453 list.resize(list.size()-1);
00454 };
00455 std::pop_heap(list.begin(),list.end());
00456 keyval kv = list.back();
00457 list.resize(list.size()-1);
00458
00459 if(*kv.val>src->r2_max) {
00460 src->r2_max = *kv.val;
00461 };
00462 if(*kv.val > 10) {
00463 int i = kv.key;
00464
00465 mint2 ii = src->resp2.mindex(i);
00466
00467
00468
00469 mint2 l = src->boxes[ii|0];
00470 mint2 L = src->boxes[ii|1];
00471
00472
00473
00474
00475
00476
00477 sources::point pt;
00478 pt.x = geom::vect2(ii[1],ii[0]);
00479
00480 int z = src->depth[i];
00481 if(z>0) {
00482 pt.depth = src->depth[i]/1000.0;
00483 } else {
00484 pt.depth = 3;
00485 };
00486 pt.conf = *kv.val;
00487 src->points.push_back(pt);
00488
00489 for(int j2=l[1]; j2<=L[1]; ++j2) {
00490 float * pv = &resp2(l[0],j2);
00491 for(int j1=l[0]; j1<=L[0]; ++j1) {
00492 *pv = -1;
00493 ++pv;
00494
00495
00496
00497
00498 };
00499 }
00500 if(*kv.val>0) {
00501 perror("bad");
00502 throw debug_exception("bad");
00503 };
00504
00505 src->resp2[i] = src->r1_max;
00506 } else break;
00507 };
00508
00509 };
00510 void publish_points() {
00511
00512 for(int i=0; i<std::min((int)src->points.size(),10); ++i) {
00513
00514 vision_msgs::PoseEstimate e;
00515 e.header = src->h;
00516
00517
00518 geom::vect3 v = src->Kinv*(src->points[i].x|1);
00519 e.pose.position.x = v[0];
00520 e.pose.position.y = v[1];
00521 e.pose.position.z = src->points[i].depth;
00522 e.pose.orientation.x = 0;
00523 e.pose.orientation.y = 0;
00524 e.pose.orientation.z = 0;
00525 e.pose.orientation.w = 1;
00526 e.id = 12345;
00527 e.confidence = src->points[i].conf;
00528 publisher2.publish(e);
00529
00530 };
00531 };
00532 };
00533
00534 class QView {
00535 public:
00536 QImage img;
00537 QLabel * label;
00538 QLabel * info;
00539 public:
00540 int vmode;
00541 std::string vmodes[10];
00542 int count;
00543 public:
00544 QView():label(0),count(0) {
00545 vmode = 2;
00546
00547 vmodes[0] = "outline";
00548 vmodes[1] = "resp1";
00549 vmodes[2] = "resp2";
00550 vmodes[3] = "depth";
00551 vmodes[4] = "ftemp";
00552
00553 };
00554
00555 void init(int Width, int Height) {
00556 if(!label) {
00557 img = QImage(Width, Height, QImage::Format_RGB32);
00558 img.fill(QColor(0,0,0));
00559 label = new QLabel();
00560 #ifndef DISPLAY
00561 label->setVisible(false);
00562 #else
00563 label->show();
00564 #endif
00565 label->setScaledContents(true);
00566 label->resize(Width*2,Height*2);
00567 info = new QLabel(label);
00568 info->setText("Info");
00569 info->move(10,10);
00570 info->show();
00571 };
00572
00573 };
00574 ~QView() {
00575 if(label) {
00576 delete info;
00577 delete label;
00578 };
00579 };
00580 void show(const sources * src) {
00581 vmode = vmode % 5;
00582
00583 int Width = src->rgb_width();
00584 int Height = src->rgb_height();
00585 if(!label)init(Width,Height);
00586
00587 QRgb * pimg = (QRgb*)img.bits();
00588 const unsigned char * prgb = src->rgb.begin();
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 for(int i = 0; i < (Width) *(Height); ++i) {
00599 const unsigned char * pixel = &prgb[i*3];
00600 double V = 1.0;
00601 pimg[i] = qRgb(pixel[0],pixel[1],pixel[2]);
00602 if(vmode == 0) {
00603
00604
00605
00606
00607
00608
00609
00610 };
00611 if(vmode == 1) {
00612 if(src->resp1[i]>0) {
00613 float pixel = src->resp1[i];
00614 int a = std::min(239,std::max(0,int((pixel)*240/(src->r1_max+1))));
00615 pimg[i] = qRgb(Iron[a][0],Iron[a][1],Iron[a][2]);
00616 };
00617 };
00618 if(vmode == 2) {
00619 if(src->resp2[i]>1) {
00620 float pixel = src->resp2[i];
00621 int a = std::min(239,std::max(0,int((pixel)*240/(src->r2_max+1))));
00622 pimg[i] = qRgb(Iron[a][0],Iron[a][1],Iron[a][2]);
00623 };
00624 };
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 if(vmode == 3) {
00635 if(src->depth[i]>0) {
00636 double v = 1/(double(src->depth[i]));
00637 double V = (v-1/src->max_depth)/(1/src->min_depth-1/src->max_depth);
00638 pimg[i] = qRgb(floor((V)*255),floor((V)*255),0);
00639 };
00640 };
00641 if(vmode == 4) {
00642 geom::vect2 p = src->Corners[0];
00643 int a = (i%Width)-p[0];
00644 int b = (i/Width)-p[1];
00645 exttype::mint2 sz1 = src->ftemp.size();
00646 if(a>=0 && a<=sz1[0] && b>=0 && b<sz1[1]) {
00647 float pixel = src->ftemp(a,b);
00648 int v = std::min(239,std::max(0,int((pixel-src->t_min)*240/(src->t_max-src->t_min+1))));
00649 pimg[i] = qRgb(Iron[v][0],Iron[v][1],Iron[v][2]);
00650 };
00651 };
00652 };
00653 if(vmode == 0) {
00654 int nn = 8;
00655 int shift[nn];
00656 int k=0;
00657 for(int k1=-1; k1<2; ++k1) {
00658 for(int k2=-1; k2<2; ++k2) {
00659 if(k1==0 && k2==0)continue;
00660 shift[k] = src->resp1.stride(k1,k2);
00661 ++k;
00662 };
00663 };
00664 for(int j = 5; j < Height-5; ++j) {
00665 for(int i = 5; i < Width-5; ++i) {
00666 int ii = src->resp1.linindex(mint2(i,j));
00667 float v = src->resp1[ii];
00668 float z = src->depth[ii];
00669 int pc = 0;
00670 int nc = 0;
00671 for(int k=0; k<nn; ++k) {
00672 float v1 = src->resp1[ii+shift[k]];
00673 if(v1>0.1) {
00674 ++pc;
00675 };
00676 if(v1<-0.1) {
00677 ++nc;
00678 };
00679 };
00680 if(pc>1 && nc>1) {
00681 pimg[ii] = qRgb(0,255,0);
00682 };
00683
00684 int pc1 = 0;
00685 int pc2 = 0;
00686 nc = 0;
00687 for(int k=0; k<nn; ++k) {
00688 float v1 = src->IR[ii+shift[k]];
00689 if(v1>70) {
00690 ++pc2;
00691 } else if(v1>40) {
00692 ++pc1;
00693 };
00694 if(v1<40) {
00695 ++nc;
00696 };
00697 };
00698 if(pc1>1 && nc>1) {
00699 pimg[ii] = qRgb(255,255,0);
00700 };
00701 if(pc2>1 && (pc1+nc)>1) {
00702 pimg[ii] = qRgb(255,0,0);
00703 };
00704 };
00705 };
00706 };
00707
00708 QPainter painter(&img);
00709
00710 for(int i=0; i<4; ++i) {
00711 geom::vect2 v = src->Corners[(i+3)%4];
00712 geom::vect2 p = src->Corners[i];
00713 geom::vect2 q = src->Corners[(i+1)%4];
00714 geom::vect2 p1 = p+(v-p).normalized()*20;
00715 geom::vect2 p2 = p+(q-p).normalized()*20;
00716 painter.setPen(QPen(Qt::black, 1));
00717 painter.drawLine(p1[0],p1[1],p[0],p[1]);
00718 painter.drawLine(p[0],p[1],p2[0],p2[1]);
00719 painter.setPen(QPen(Qt::white, 1));
00720 painter.drawLine(p1[0]-1,p1[1]-1,p[0]-1,p[1]-1);
00721 painter.drawLine(p[0]-1,p[1]-1,p2[0]-1,p2[1]-1);
00722 };
00723
00724 label->setPixmap(QPixmap::fromImage(img));
00725 {
00726 std::stringstream ss;
00727
00728 ss<<count<<" "<<vmodes[vmode];
00729 info->setText(QString("<font color='black' size='6'>")+ss.str().c_str()+QString("</font>"));
00730 info->adjustSize();
00731 };
00733
00734 };
00735 };
00736
00737
00738
00739
00740
00741 class myApp : public QApplication {
00742 public:
00743 QView view;
00744 sources src;
00745 victim1 victim;
00746 int count;
00747 int timer_count;
00748 int o_count;
00749
00750 dynamic::num_array<sensor_msgs::ImageConstPtr ,2> msgs;
00751 mint3 counts;
00752
00753 public:
00754 myApp(int & argc, char ** argv):QApplication(argc,argv) {
00755
00756
00757
00758
00759
00760
00761
00762 startTimer(1000/100);
00763
00764 victim.src = &src;
00765 count = 0;
00766 timer_count = 0;
00767 o_count = 1;
00768 };
00769
00770 ~myApp() {
00771 };
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799 void callback_synch(const ImageConstPtr& rgb, const ImageConstPtr& depth, const CameraInfoConstPtr& cam_info, const ImageConstPtr& ftemp, const boost::shared_ptr<openni_cam::thermo_info const> & info,const ImageConstPtr& laser) {
00800
00801
00802
00803
00804 timer_count = 0;
00805 {
00806 const sensor_msgs::ImageConstPtr & msg = rgb;
00807 int num_bytes = msg->step*msg->height;
00808 src.rgb.resize(exttype::mint3(3,msg->width,msg->height));
00809 memcpy(src.rgb.begin(),&msg->data[0],num_bytes);
00810
00811 src.h = msg->header;
00812 std::cout<<msg->header.seq<<"-";
00813 fflush(stdout);
00814 }
00815 {
00816 const sensor_msgs::ImageConstPtr & msg = laser;
00817 int num_bytes = msg->step*msg->height;
00818 src.laser_image.resize(exttype::mint2(msg->width,msg->height));
00819 memcpy(src.laser_image.begin(),&msg->data[0],num_bytes);
00820 src.h = msg->header;
00821 std::cout<<msg->header.seq<<"-";
00822 fflush(stdout);
00823 }
00824
00825 {
00826 int k=0;
00827 for(int i=0; i<3; ++i) {
00828 for(int j=0; j<3; ++j) {
00829 src.K(i,j) = cam_info->K[k];
00830 ++k;
00831 };
00832 };
00833 src.Kinv = src.K.invert();
00834 }
00835 {
00836 const sensor_msgs::ImageConstPtr & msg = depth;
00837 int num_bytes = msg->step*msg->height;
00838 src.depth.resize(exttype::mint2(msg->width,msg->height));
00839 memcpy(src.depth.begin(),&msg->data[0],num_bytes);
00840 std::cout<<msg->header.seq<<"-";
00841 fflush(stdout);
00842 };
00843 {
00844 const sensor_msgs::ImageConstPtr & msg = ftemp;
00845 int num_bytes = msg->step*msg->height;
00846
00847
00848 src.ftemp.resize(exttype::mint2(msg->width,msg->height));
00849 memcpy(src.ftemp.begin(),&msg->data[0],num_bytes);
00850
00851
00852
00853
00854
00855
00856 std::cout<<msg->header.seq<<" \n";
00857
00858 fflush(stdout);
00859 };
00860 src.t_min = info->t_min;
00861 src.t_max = info->t_max;
00862 std::stringstream ss;
00863 ss << info->serial;
00864 src.sserial = ss.str();
00865
00866
00867
00868
00869
00870 if(!victim.initialized)victim.init();
00871
00872
00873 victim.filter_ir();
00874 victim.fuse_depth();
00875 victim.ir_reproj();
00876 victim.process1();
00877 victim.process2();
00878 victim.nonmax_supress();
00879 victim.publish_points();
00880 view.show(&src);
00881
00882 sensor_msgs::ImagePtr msg(new sensor_msgs::Image());
00883 msg->header.stamp = ros::Time::now();
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 QImage I = view.img.convertToFormat(QImage::Format_RGB888);
00895 int num_bytes = I.byteCount();
00896 msg->data.resize(num_bytes);
00897 memcpy(&msg->data[0],I.bits(),num_bytes);
00898 msg->encoding = sensor_msgs::image_encodings::RGB8;
00899 msg->step = I.bytesPerLine();
00900 msg->width = I.width();
00901 msg->height = I.height();
00902 msg->header.frame_id = cam_info->header.frame_id;
00903 msg->header.seq = count;
00904 publisher1.publish(msg);
00905 ++count;
00906 };
00907
00908 void timerEvent(QTimerEvent * event) {
00909 if(!ros::ok()) {
00910
00911 printf("victim1_node quitting\n");
00912
00913 std::cout.flush();
00914 abort();
00915 };
00916 ros::spinOnce();
00917
00918
00919 ++timer_count;
00920 if(true) {
00921 if(timer_count % 100 ==0) {
00922 std::cout<<"waiting for inputs\n";
00923 std::cout.flush();
00924 };
00925 };
00926
00927 };
00928
00929
00930 void save_images() {
00931 #ifdef MATLAB
00932 int O_count = o_count;
00933
00934 eng_out(src.rgb,"X");
00935 {
00936 std::stringstream ss;
00937 ss<<"frames{"<<o_count<<"}.rgb=X;";
00938 engEvalString(matlab,ss.str().c_str());
00939 }
00940 {
00941 eng_out(src.depth,"X");
00942 std::stringstream ss;
00943 ss<<"frames{"<<o_count<<"}.depth=X;";
00944 engEvalString(matlab,ss.str().c_str());
00945 }
00946 {
00947 eng_out(src.ftemp,"X");
00948 std::stringstream ss;
00949 ss<<"frames{"<<o_count<<"}.IR_src=X;";
00950 engEvalString(matlab,ss.str().c_str());
00951 }
00952 {
00953
00954 eng_out(src.IR,"X");
00955 std::stringstream ss;
00956 ss<<"frames{"<<o_count<<"}.IR=X;";
00957 engEvalString(matlab,ss.str().c_str());
00958 }
00959 {
00960
00961 eng_out(src.resp1,"X");
00962 std::stringstream ss;
00963 ss<<"frames{"<<o_count<<"}.resp1=X;";
00964 engEvalString(matlab,ss.str().c_str());
00965 };
00966 {
00967
00968 eng_out(src.resp2,"X");
00969 std::stringstream ss;
00970 ss<<"frames{"<<o_count<<"}.resp2=X;";
00971 engEvalString(matlab,ss.str().c_str());
00972 };
00973 std::stringstream ss;
00974 char s[20];
00975 o_count = O_count;
00976
00977 sprintf(s,"%.4i",o_count);
00978 ss<<"save('capture/frames_"<<s<<".mat','frames');";
00979 engEvalString(matlab,ss.str().c_str());
00980 ++o_count;
00981
00982
00983
00984
00985 #endif
00986 };
00987
00988
00989
00990
00991
00992
00993
00994 bool notify(QObject * receiver, QEvent * ev) {
00995 if(ev->type() == QEvent::MouseButtonPress) {
00996 QMouseEvent * e = static_cast<QMouseEvent *>(ev);
00997 if(e->button()==Qt::LeftButton) {
00998
00999 save_images();
01000 return true;
01001 };
01002 };
01003 if(ev->type() == QEvent::KeyPress) {
01004 QKeyEvent * e = static_cast<QKeyEvent *>(ev);
01005
01006
01007
01008
01009 if(e->key() == Qt::Key_Backspace) {
01010 save_images();
01011
01012 return true;
01013 } else if(e->key() == Qt::Key_Return) {
01014
01015 save_images();
01016 return true;
01017 } else if(e->key() == Qt::Key_Tab) {
01018 ++view.vmode;
01019 return true;
01020 } else if(e->key() == Qt::Key_Escape) {
01021 exit(0);
01022 return true;
01023 };
01024 };
01025 return QApplication::notify(receiver,ev);
01026 };
01027 };
01028
01029 #ifndef MATLAB_MEX_FILE
01030
01031 int main(int argc, char ** argv) {
01032 ros::init(argc, argv, "victim1_node");
01033 ros::NodeHandle nh;
01034 image_transport::ImageTransport it1(nh);
01035
01036 publisher1 = it1.advertise("openni_camera/detections", 1);
01037 publisher2 = nh.advertise<vision_msgs::PoseEstimate>("openni_camera/points", 1);
01038
01039 message_filters::Subscriber<sensor_msgs::Image> image_rgb(nh, "/openni_camera/rgb", 3);
01040 message_filters::Subscriber<sensor_msgs::Image> image_depth(nh, "/openni_camera/depth", 3);
01041 message_filters::Subscriber<sensor_msgs::CameraInfo> cam_info(nh, "/openni_camera/camera_info", 3);
01042 message_filters::Subscriber<sensor_msgs::Image> image_ftemp(nh, "/thermo_camera/ftemp", 3);
01043 message_filters::Subscriber<openni_cam::thermo_info> info(nh, "/thermo_camera/info", 3);
01044 message_filters::Subscriber<sensor_msgs::Image> image_laser(nh, "/openni_camera/laser_image", 3);
01045
01046 TimeSynchronizer<sensor_msgs::Image,sensor_msgs::Image,sensor_msgs::CameraInfo,sensor_msgs::Image,openni_cam::thermo_info,sensor_msgs::Image> sync(image_rgb,image_depth,cam_info,image_ftemp,info,image_laser, 3);
01047 #ifdef MATLAB
01048 start_engine();
01049 #endif
01050
01051 int argc1=0;
01052 myApp * a = new myApp(argc1, (char**)(0));
01053 sync.registerCallback(&myApp::callback_synch,a);
01054 a->exec();
01055 delete a;
01056 };
01057 #endif
01058
01059
01060 #ifdef MATLAB_MEX_FILE
01061
01062 #include <signal.h>
01063 #include <stdio.h>
01064 #include <stdlib.h>
01065 #include <ucontext.h>
01066
01067 static const char *gregs[] = {
01068 "GS",
01069 "FS",
01070 "ES",
01071 "DS",
01072 "EDI",
01073 "ESI",
01074 "EBP",
01075 "ESP",
01076 "EBX",
01077 "EDX",
01078 "ECX",
01079 "EAX",
01080 "TRAPNO",
01081 "ERR",
01082 "EIP",
01083 "CS",
01084 "EFL",
01085 "UESP",
01086 "SS"
01087 };
01088
01089 void print_mex(int sig, siginfo_t *info, void *c)
01090 {
01091 ucontext_t *context = c;
01092
01093 fprintf(stderr,
01094 "si_signo: %d\n"
01095 "si_code: %s\n"
01096 "si_errno: %d\n"
01097 "si_pid: %d\n"
01098 "si_uid: %d\n"
01099 "si_addr: %p\n"
01100 "si_status: %d\n"
01101 "si_band: %ld\n",
01102 info->si_signo,
01103 (info->si_code == SEGV_MAPERR) ? "SEGV_MAPERR" : "SEGV_ACCERR",
01104 info->si_errno, info->si_pid, info->si_uid, info->si_addr,
01105 info->si_status, info->si_band
01106 );
01107
01108 fprintf(stderr,
01109 "uc_flags: 0x%x\n"
01110 "ss_sp: %p\n"
01111 "ss_size: %d\n"
01112 "ss_flags: 0x%X\n",
01113 context->uc_flags,
01114 context->uc_stack.ss_sp,
01115 context->uc_stack.ss_size,
01116 context->uc_stack.ss_flags
01117 );
01118
01119 fprintf(stderr, "General Registers:\n");
01120 for(int i = 0; i < 19; i++)
01121 fprintf(stderr, "\t%7s: 0x%x\n", gregs[i], context->uc_mcontext.gregs[i]);
01122
01123
01124
01125 throw debug_exception("Segmentation Fault");
01126 }
01127 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
01128 using namespace exttype;
01129
01130
01131
01132
01133
01134
01135
01136 try {
01137 if(nrhs!=3) {
01138 mexErrMsgTxt((std::string("[resp1 resp2] = emaxflow_mex(rgb,depth,ftemp)::input error:\n")+"\n"+
01139 "Input: uint8 rgb[3 x width x height], uint16 depth[width x height], float ftemp [width x neight].\n"+
01140 "Output: float resp1[ width x height], float resp1[ width x height];").c_str());
01141 return;
01142 };
01143
01144 sources * src = new(sources);
01145 victim1 * victim = new(victim1);
01146 victim->src = src;
01147
01148 src->rgb = mx_array<unsigned char,3>(prhs[0]);
01149 src->depth = mx_array<unsigned short int,2>(prhs[1]);
01150 src->IR = mx_array<float,2>(prhs[2]);
01151
01152 src->t_max = src->IR.max().first;
01153
01154 src->sserial = "12090028";
01155
01156 if(!victim->initialized)victim->init();
01157
01158 {
01159 dynamic::num_array<float,2> a = src->IR;
01160 int nz=0;
01161 src->t_min = src->t_max;
01162 for(int i=0;i<src->IR.length();++i){
01163 float t = src->IR[i];
01164 if(t==0){
01165 ++nz;
01166 a[i] = -1000;
01167 };
01168 if(t<src->t_min){
01169 src->t_min = t;
01170 };
01171 };
01172 int med_pos = nz+(a.length()-nz)/2;
01173 std::nth_element(a.begin(),a.begin()+med_pos,a.end());
01174 src->t_med = a[med_pos];
01175 };
01176 victim->depth_range();
01177
01178
01179 victim->process1();
01180 victim->process2();
01181 victim->nonmax_supress();
01182
01183
01184 plhs[0] = mx_array<float,2>(src->resp1).get_mxArray_andDie();
01185 plhs[1] = mx_array<float,2>(src->resp2).get_mxArray_andDie();
01186
01187 delete victim;
01188 delete src;
01189
01190 } catch(const std::exception & e) {
01191 mexErrMsgTxt(e.what());
01192 };
01193 };
01194
01195 #endif