ros_victim1_node.cpp
Go to the documentation of this file.
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 //messages
00012 #include <openni_cam/thermo_info.h>
00013 #include <vision_msgs/PoseEstimate.h>
00014 #include <sensor_msgs/PointCloud2.h>
00015 
00016 //#include <boost/shared_ptr.hpp>
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 //#include "IronPalette.h"
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 //#include <QtGui/QMessageBox>
00032 #include <QtGui/QKeyEvent>
00033 #include <QtGui/QMouseEvent>
00034 //
00035 //
00036 //
00037 //#define DISPLAY
00038 //#define MATLAB
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 //#include "exttype/arrayn.h"
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 //#include <debug/logs.h>
00057 //
00058 
00059 #include <sstream>
00060 
00061 /*
00062 
00063 -lmx
00064 -leng
00065 -L$(MATLAB)/bin/glnx86
00066 -L$(MATLAB)/extern/lib/glnx86
00067 -L$(MATLAB)/sys/os/glnx86
00068 -Wl,-rpath,$(MATLAB)/bin/glnx86
00069 -Wl,-rpath,$(MATLAB)/extern/lib/glnx86
00070 -Wl,-rpath,$(MATLAB)/sys/os/glnx86
00071 -L$(MATLAB)/bin/glnxa64
00072 -L$(MATLAB)/extern/lib/glnxa64
00073 -L$(MATLAB)/sys/os/glnxa64
00074 -Wl,-rpath,$(MATLAB)/bin/glnxa64
00075 -Wl,-rpath,$(MATLAB)/extern/lib/glnxa64
00076 -Wl,-rpath,$(MATLAB)/sys/os/glnxa64
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; //rgb image [3 x width x height]
00101     dynamic::num_array<unsigned short int,2> depth; // [width x height]
00102     dynamic::num_array<unsigned short int,2> laser_image; // [width x height] but might be [0x0] if empty
00103 //    dynamic::num_array<unsigned short,2> temp;
00104     //dynamic::num_array<float,2> f0temp;
00105     dynamic::num_array<float,2> ftemp; //not reprojected IR
00106     //dynamic::num_array<unsigned char,2> intftemp;
00107     dynamic::num_array<float,2> IR; // reprojected IR
00108     dynamic::num_array<float,2> resp1; // responce of human temperature likelihood
00109     dynamic::num_array<float,3> dresp; // response in the disparity space
00110     //
00111     dynamic::num_array<float,2> resp2; // boxed response
00112     dynamic::num_array<mint2,3> boxes; // boxed response
00113     std::vector<point> points;
00114     //
00115     std_msgs::Header h;
00116     //
00117     dynamic::num_array<int,2> fw_IR_map; // map IR cam coords -> kinect coords
00118     dynamic::num_array<int,2> bw_IR_map; // map IR cam coords -> kinect coords
00119     array_tn<geom::vect2,4> corners;
00120     array_tn<geom::vect2,4> Corners;
00121     //int seq;
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; // reprojected IR
00153     bool initialized;
00154     //
00155     victim1() {
00156         initialized = false;
00157     };
00158     //
00159     void init() {
00160         //std::stringstream ss;
00161         //ss<<"../config/<<
00162         //std::ifstream f("../config/ir_geom_cali_P.txt");
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             //std::ifstream f("../config/ir_geom_cali_Pinv.txt");
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             //src->depth<<-1;
00218             int s = src->depth.size()[0];
00219             for(int i=0; i<src->depth.length(); ++i) {
00220                 //src->depth[i] = (unsigned int)(src->laser_image[i]*1000);
00221                 //if(i/s < i%s){//
00222                 if(src->depth[i] == 0) {
00223                     src->depth[i] = src->laser_image[i];//(unsigned short int)(src->laser_image[i]*1000);
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;//10 cm
00243             src->max_depth = 5000.0;//5  m
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                 for(int k=0; k<3; ++k) {
00292                     int r = 0;
00293                     for(int l=0; l<4; ++l) {
00294                         r = r+reproj_P[k][l]*p[l];
00295                     };
00296                     q[k] = r;
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;// errors increase with distance
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) { //really a different surface
00312                         //black out all occluded pixels
00313                         int p = occ(i,j);
00314                         while(p>0) {
00315                             src->IR(p) = 0; // black out
00316                             p = next(p);
00317                         };
00318                         occ(i,j) = -1;
00319                     };
00320                     // add current point to occ
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             //geom::vect2 v = src->geom::vect2[i];
00335             geom::vect3 p = src->corners[i]|1.0;//geom::vect3(v[0],v[1],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         //int t_bg = std::max(std::min(int(src->t_min),64),1)-1;
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         //src->dresp.cumsum();
00369         for(iter2 ii(src->resp1.size()); ii.allowed(); ++ii) {
00370             float z = src->depth[ii];
00371             if(z==0)continue;
00372             //float delta = 30/1000.0*z;// errors increase with distance
00373             //int disp = floor((1/z - 1.0/src->max_depth)/(1.0/src->min_depth -1.0/src->max_depth)*(D-1));
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                 //exit(1);
00382             };
00383 
00384             src->dresp[ii|disp] = std::max(0.0f,src->resp1[ii]);
00385             //src->dresp[ii|disp] = src->resp1[ii];
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; // 10 pixels at 1000 mm
00396         for(iter2 ii(src->resp1.size()); ii.allowed(); ++ii) {
00397             //for(int i=0; i<src->resp1.length(); ++i) {
00398             //float z = src->depth[ii];
00399             //if(z==0)z = 5000; // 5m
00400             float z = src->depth[ii];
00401             //if(z==0)continue;//z = 5000; // 5m
00402             //float delta = 30/1000.0*z;// errors increase with distance
00403             //int disp = floor((1/z - 1/src->max_depth)/(1/src->min_depth -1/src->max_depth)*D);
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             //float n = std::max(1,(L-l).prod());
00423             n = std::max(1,n);
00424             src->resp2[ii] = r/10;//r/n;
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             //std::sort(list.begin(),list.end());
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             //float & val = *list[0].val;
00459             if(*kv.val>src->r2_max) {
00460                 src->r2_max = *kv.val;
00461             };
00462             if(*kv.val > 10) {
00463                 int i = kv.key;//list[0].key;
00464                 //save point with confidence
00465                 mint2 ii = src->resp2.mindex(i);
00466                 //debug::stream<<i<<"="<<ii<<"="<<resp2.linindex(ii)<<" ";
00467                 //src->pts.push_back(pt_detection(geom::vect3(ii[0],ii[1],src->depth[i]),val));
00468                 //src->pts.push_back(pt_detection(geom::vect3(ii[0],ii[1],src->depth[i]),val));
00469                 mint2 l = src->boxes[ii|0];
00470                 mint2 L = src->boxes[ii|1];
00471                 //debug::stream<<ii<<" ["<<l<<";"<<L<<"]"<<"\n";
00472                 //supress the neighbors
00473                 // for(range_iter2 jj(l,L); jj.allowed(); ++jj){
00474                 //    resp2[jj] = - 1; // supress
00475                 //};
00476                 //remember this point
00477                 sources::point pt;
00478                 pt.x = geom::vect2(ii[1],ii[0]);
00479                 //pt.depth = src->depth[i]/1000.0; //(in meters)
00480                 int z = src->depth[i];
00481                 if(z>0) {
00482                     pt.depth = src->depth[i]/1000.0; //(in meters)
00483                 } else {
00484                     pt.depth = 3;//3 m
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                         //resp2(j1,j2) = -1;
00495                         //if(resp2.linindex(mint2(j1,j2))==i){
00496                         //debug::stream<<i<<"ok"<<"  ";
00497                         //};
00498                     };
00499                 }
00500                 if(*kv.val>0) {
00501                     perror("bad");
00502                     throw debug_exception("bad");
00503                 };
00504                 //val = -1;
00505                 src->resp2[i] = src->r1_max;
00506             } else break;
00507         };
00508         //for(iter2 ii(src->resp1.size()); ii.allowed();++ii){
00509     };
00510     void publish_points() {
00511         //here loop over all remembered points, make PoseEstimate structure and send it
00512         for(int i=0; i<std::min((int)src->points.size(),10); ++i) {
00513             //Compute the outer 3D coords
00514             vision_msgs::PoseEstimate e;
00515             e.header = src->h;
00516             //e.header.frame_id = "openni_camera";
00517             //e.header.seq = src->seq;
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             //e.pose
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         //++count;
00583         int Width = src->rgb_width();
00584         int Height = src->rgb_height();
00585         if(!label)init(Width,Height);
00586 // display image
00587         QRgb * pimg = (QRgb*)img.bits();
00588         const unsigned char * prgb = src->rgb.begin();
00589         //double max_depth = 1;
00590         //double min_depth = 1;
00591         //for(int i = 0; i < (Width) *(Height); ++i) {
00592         //    if(src->depth[i]>0) {
00593         //        double v = 1/(double(src->depth[i]));
00594         //        if(v>max_depth)max_depth = v;
00595         //        if(v<min_depth)min_depth = v;
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                 if(src->resp1[i]>0) {
00605                         float pixel = src->resp1[i];
00606                         int a = std::min(239,std::max(0,int((pixel)*240/(src->r1_max+1))));
00607                         pimg[i] = qRgb(Iron[a][0],Iron[a][1],Iron[a][2]);
00608                 };
00609                 */
00610             };
00611             if(vmode == 1) {//resp1
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) {//resp2
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             if(vmode == 3) {
00627                 if(src->IR[i]>0) {
00628                     float pixel = src->IR[i];
00629                     int a = std::min(239,std::max(0,int((pixel-src->t_min)*240/(src->t_max-src->t_min+1))));
00630                     pimg[i] = qRgb(Iron[a][0],Iron[a][1],Iron[a][2]);
00631                 };
00632             };
00633             */
00634             if(vmode == 3) {// depth
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) {//ftemp
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                     //v = src->IR[ii];
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             //ss<<count;
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         msgs.resize(mint2(3,5));
00757         for(iter2 ii(msgs.size()); ii.allowed(); ++ii) {
00758             //msgs[ii] = 0;
00759         };
00760         counts << 0;
00761         */
00762         startTimer(1000/100);
00763         //victim.init();
00764         victim.src = &src;
00765         count = 0;
00766         timer_count = 0;
00767         o_count = 1;
00768     };
00769     //
00770     ~myApp() {
00771     };
00772     /*
00773     void shift_msgs() {
00774         for(int i=0; i<msgs.size()[0]; ++i) {
00775             for(int j=0; j<counts[i]-1; ++j) {
00776                 msgs(i,j) = msgs(i,j+1);
00777             };
00778         };
00779         for(int i=0; i<msgs.size()[0]; ++i) {
00780             //msgs(i,counts[j]) = 0;
00781             counts[i] = std::max(0,counts[i]-1);
00782         };
00783     };
00784     */
00785     //
00786     /*
00787     void imageCallback_rgb(const sensor_msgs::ImageConstPtr & msg) {//rgb
00788         msgs(0,counts[0]) = msg;
00789         if(++counts[0] == msgs.size()[1]) { //overflow, shift all
00790             shift_msgs();
00791         };
00792         //std::cout<<"1"; fflush(stdout);
00793         //
00794         //++view.count;
00795         //src.rgb.resize(exttype::mint3(3,msg->width,msg->height));
00796         //memcpy(src.rgb.begin(),&msg->data[0],src.rgb.byte_size());
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         //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) {
00801         //std::cout<<"WOW"<<"\n";
00802         //std::cout.flush();
00803         //return;
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             //src.seq = msg->header.seq;
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             //src.f0temp.resize(exttype::mint2(msg->width,msg->height));
00847             //src.intftemp.resize(exttype::mint2(msg->width,msg->height));
00848             src.ftemp.resize(exttype::mint2(msg->width,msg->height));
00849             memcpy(src.ftemp.begin(),&msg->data[0],num_bytes);
00850 
00851             //memcpy(src.intftemp.begin(),&msg->data[0],num_bytes);
00852             //for(int i=0;i<src.intftemp.length();++i){
00853             //    src.f0temp[i] = float(src.intftemp[i]);
00854             //    src.ftemp[i] = float(src.intftemp[i]);
00855             //};
00856             std::cout<<msg->header.seq<<"               \n";
00857             //std::cout<<" "<<src.ftemp.size()[0]<<"x"<<src.ftemp.size()[1]<<"|"<<src.ftemp.byte_size()<<"\n";
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         //std::cout<<"\n";
00866         //fflush(stdout);
00867         //
00868         //
00869         //
00870         if(!victim.initialized)victim.init();
00871         //if(!src.depth.is_empty() && !src.rgb.is_empty() && !src.temp.is_empty()) {
00872         //view.show(cam);
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         static tf::TransformBroadcaster br;
00887         tf::Transform transform;
00888         transform.setOrigin( tf::Vector3(0, 1.0, 0) );
00889         transform.setRotation( tf::Quaternion(0, 0, 0) );
00890         br.sendTransform(tf::StampedTransform(transform, msg->header.stamp, "/base_link", "/thermo_camera"));
00891         */
00892         // publish output image
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             //ros::shutdown();
00911             printf("victim1_node quitting\n");
00912             //fflush(stdout);
00913             std::cout.flush();
00914             abort();
00915         };
00916         ros::spinOnce();
00917         //std::cout<<".";
00918         //std::cout.flush();
00919         ++timer_count;
00920         if(true) { //count<1) {
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         //o_count = 1;
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             // save reprojected IR
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             // save reprojected IR
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             // save reprojected IR
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         //if(o_count==30){
00982         //   o_count = 1;
00983         //engEvalString(matlab,"save('frames.mat','frames');");
00984         //};
00985 #endif
00986     };
00987 
00988     /*
00989         void mousePressEvent(QMouseEvent * e){
00990             printf("mouse press 1\n");
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                 //printf("mouse press Left\n");
00999                 save_images();
01000                 return true;
01001             };
01002         };
01003         if(ev->type() == QEvent::KeyPress) {
01004             QKeyEvent * e = static_cast<QKeyEvent *>(ev);
01005             //QMessageBox* box = new QMessageBox();
01006             //box->setWindowTitle(QString("Hello"));
01007             //box->setText(QString("You Pressed: ")+ e->text());
01008             //box->show();
01009             if(e->key() == Qt::Key_Backspace) {
01010                 save_images();
01011                 // Special tab handling
01012                 return true;
01013             } else if(e->key() == Qt::Key_Return) {
01014                 //++view.vmode;
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 //      fprintf(stderr, "\tOLDMASK: 0x%x\n", context->uc_mcontext.oldmask);
01123 //      fprintf(stderr, "\t    CR2: 0x%x\n", context->uc_mcontext.cr2);
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 //    struct sigaction sa;
01131 //     sa.sa_sigaction=print_mex;// warning here: assignment from incompatible pointer type
01132 //     sa.sa_flags=SA_SIGINFO;
01133 //     sigaction(SIGSEGV,&sa,NULL);
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]); // rgb image [3 x width x height]
01149         src->depth = mx_array<unsigned short int,2>(prhs[1]); // [width x height]
01150         src->IR = mx_array<float,2>(prhs[2]); // temperature [width x height]
01151         //
01152         src->t_max = src->IR.max().first;
01153         //mexPrintf("Ok\n");
01154         src->sserial = "12090028";
01155         //return;
01156         if(!victim->initialized)victim->init();
01157         //victim->filter_ir(); // computes t_med;
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         // detection
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
 All Classes Namespaces Files Functions Variables Typedefs Defines


openni_cam
Author(s): Alexander Shekhovtsov
autogenerated on Sun Dec 1 2013 17:19:20