00001 #include "openni_cam.h"
00002
00003 #include <stdio.h>
00004
00005
00006 #include "../../thermo_cam/src/camera.h"
00007 #include "../../thermo_cam/src/error.h"
00008 #include "../../thermo_cam/src/include/Imager.h"
00009 #include "../../thermo_cam/src/ImagerUVC.h"
00010 #include "../../thermo_cam/src/IronPalette.h"
00011
00012
00013 #include <QtGui/QApplication>
00014 #include <QtGui/QLabel>
00015 #include <QtCore/QBasicTimer>
00016 #include <QtGui/QPainter>
00017 #include <QtGui/QDialog>
00018 #include <QtGui/QMainWindow>
00019 #include <QtGui/QMessageBox>
00020 #include <QtGui/QKeyEvent>
00021
00022 #include <string>
00023 #include <iostream>
00024 #include <fstream>
00025 #include <time.h>
00026
00027 #include <cmath>
00028
00029 #include "mex/mex_io.h"
00030 #undef printf
00031
00032 #include <sstream>
00033 #include <pthread.h>
00034
00035
00036 #define NO_EXTTYPE
00037 #include "dynamic/num_array.h"
00038 #include "dynamic/fixed_array2.h"
00039 #include "geom/nmmatrix.h"
00040 #include "dynamic/dynamic.h"
00041 #include "debug/performance.h"
00042
00043 using namespace optris;
00044
00045 class thermo_node {
00046 public:
00047
00048 camera cam;
00049 Imager * imager;
00050 unsigned long serial;
00051 int Width;
00052 int Height;
00053 int count;
00054 bool frame_acquired;
00055 public:
00056 QLabel * L2;
00057 QImage im2;
00058 QLabel * info2;
00059 float tmax;
00060 float tmin;
00061 public:
00062
00063 dynamic::num_array<unsigned short int, 2> IR;
00064
00065
00066 thermo_node() {
00067 };
00068
00069 ~thermo_node() {
00070 delete info2;
00071 delete L2;
00072 delete imager;
00073 };
00074 void init(fptrOptrisFrame pOnFrame) {
00075 cam.find_device();
00076 cam.init_device();
00077 Width = cam.width;
00078 Height = cam.height-1;
00079 IR.resize(exttype::mint2(Width,Height));
00080 serial = cam.dev_serial;
00081 int frequency = cam.frequency;
00082
00083 imager = new Imager(serial, Width, Height+1, frequency, "../../thermo_cam/data/config/12050017.xml");
00084 count = 0;
00085
00086
00087
00088 imager->setFrameCallback(pOnFrame);
00089 frame_acquired = false;
00090
00091
00092 im2 = QImage(Width, Height, QImage::Format_RGB32);
00093 im2.fill(QColor(0,0,0));
00094 L2 = new QLabel();
00095 L2->setScaledContents(true);
00096 L2->resize(Width*4,Height*4);
00097 L2->show();
00098 info2 = new QLabel(L2);
00099 info2->setText("Info");
00100 info2->move(10,10);
00101 info2->show();
00102 };
00103 void triger() {
00104
00105 ++count;
00106 cam.get_image();
00107 imager->process((unsigned char *)cam.buffer.start);
00108
00109 std::stringstream ss;
00110 ss<<count;
00111 info2->setText(QString("<font color='white' size='6'>")+ss.str().c_str()+QString("</font>"));
00112 info2->adjustSize();
00113 return;
00114 if(!frame_acquired){
00115 printf("Thermocam init: ");
00116 while(!frame_acquired){
00117 ++count;
00118
00119
00120 const char * psym = "-\\|/";
00121 if(count>1)std::cout<<"\b";
00122 std::cout<<psym[count % 4];
00123 fflush(stdout);
00124 usleep(100);
00125 };
00126 printf("\n");
00127 };
00128 };
00129
00130 void show(){
00131 tmax=-1e6;
00132 tmin=+1e6;
00133 QRgb * pimg = (QRgb*)im2.bits();
00134
00135 float * vals = new float[Width*Height];
00136
00137 unsigned short * pV = IR.begin();
00138
00139 for(int i = 0; i < (Width) * (Height); ++i) {
00140 vals[i] = ((float)(pV[i])-1000.0)*0.1;
00141 };
00142
00143 float * vals1 = new float[Width*Height];
00144
00145
00146 std::vector<float> a;
00147 a.resize(9);
00148 memset(vals1,0,Width*Height*sizeof(float));
00149 for(int i=1; i<Height-1; ++i) {
00150 for(int j=1; j<Width-1; ++j) {
00151 int ii = i*Width+j;
00152 a[0] = vals[ii];
00153 a[1] = vals[ii+1];
00154 a[2] = vals[ii-1];
00155 a[3] = vals[ii-Width];
00156 a[4] = vals[ii+Width];
00157 a[5] = vals[ii-1-Width];
00158 a[6] = vals[ii-1+Width];
00159 a[7] = vals[ii+1-Width];
00160 a[8] = vals[ii+1+Width];
00161 std::nth_element(a.begin(),a.begin()+5,a.end());
00162 float pixel = a[5];
00163
00164 vals1[ii] = pixel;
00165 if(pixel > tmax)tmax = pixel;
00166 if(pixel < tmin)tmin = pixel;
00167 };
00168 };
00169 for(int i = 0; i < (Width) * (Height); ++i) {
00170 float pixel = vals1[i];
00171 int a = std::min(239,std::max(0,int((pixel-tmin)*240/(tmax-tmin+1))));
00172 pimg[i] = qRgb(Iron[a][0],Iron[a][1],Iron[a][2]);
00173 };
00174 L2->setPixmap(QPixmap::fromImage(im2));
00175 delete vals1;
00176 delete vals;
00177 };
00178
00179 void cbOnFrame(unsigned short* image, unsigned int w, unsigned int h) {
00180
00181 frame_acquired = true;
00182 memcpy(IR.begin(),image,Width*Height*2);
00183 show();
00184 };
00185 };
00186
00187 thermo_node tcam;
00188
00189 class myApp : public QApplication {
00190 public:
00191 openni_cam::openni_cam cam;
00192
00193 int Width;
00194 int Height;
00195 QImage img;
00196 QLabel label;
00197 QLabel * info;
00198 int count;
00199 int framerate;
00200 int o_count;
00201 geom::matrix34 P;
00202 dynamic::num_array<float,2> IR;
00203 bool record;
00204 int r_count;
00205 public:
00206 myApp(int & argc, char **argv):QApplication(argc,argv) {
00207
00208 std::ifstream f("../config/ir_geom_cali_P.txt");
00209 for(int i=0; i<3; ++i) {
00210 for(int j=0; j<4; ++j) {
00211 double v;
00212 f>>v;
00213 P[i][j] = v;
00214 };
00215 };
00216
00217
00218 cam.init();
00219 Width = cam.rgb.size()[1];
00220 Height = cam.rgb.size()[2];
00221 IR.resize(exttype::mint2(Width,Height));
00222
00223 img = QImage(Width, Height, QImage::Format_RGB32);
00224 img.fill(QColor(0,0,0));
00225 label.setScaledContents(true);
00226 label.resize(Width*2,Height*2);
00227 label.show();
00229 info = new QLabel(&label);
00230 info->setText("Info");
00231 info->move(10,10);
00232 info->show();
00233 std::cout<<"\n";
00234 framerate = 20;
00235 startTimer(1000/framerate);
00236 count = 0;
00237 o_count = 0;
00238 record = false;
00239 };
00240 ~myApp() {
00241 };
00242
00243 class tpoint;
00244 class tpoint{
00245 public:
00246 exttype::mint2 pt;
00247 tpoint * next;
00248 };
00249
00250 void ir_reproj() {
00251 dynamic::fixed_array2<tpoint> points;
00252
00253 dynamic::num_array<tpoint *,2> occ;
00254
00255 dynamic::num_array<float,2> Z;
00256
00257 points.resize(IR.size());
00258 IR << 0;
00259 Z.resize(tcam.IR.size());
00260 Z<<1e8;
00261 occ.resize(tcam.IR.size());
00262 occ<<0;
00263
00264 for(int y=0; y<IR.size()[1]; ++y) {
00265 for(int x=0; x<IR.size()[0]; ++x) {
00266 double z = cam.depth(x,y);
00267 if(z<1)continue;
00268 geom::vectn<4> p(x,y,z,1);
00269 geom::vectn<3> q;
00270 q = P*p;
00271 for(int k=0; k<3; ++k) {
00272 int r = 0;
00273 for(int l=0; l<4; ++l) {
00274 r = r+P[k][l]*p[l];
00275 };
00276 q[k] = r;
00277 };
00278 double z1 = q[2];
00279 q/=z1;
00280 int i = floor(q[0]);
00281 int j = floor(q[1]);
00282 if(i<0 || j<0 || i>= tcam.IR.size()[0] || j>= tcam.IR.size()[1])continue;
00283 float delta = 30/1000.0*z;
00284 if(z1<Z(i,j)+delta) {
00285
00286 float v = (float(tcam.IR(i,j))-1000.0)*0.1;
00287 IR(x,y) = v;
00288 if(z1<Z(i,j)-delta){
00289
00290 tpoint * p = occ(i,j);
00291 while(p){
00292 IR[p->pt] = 0;
00293 p = p->next;
00294 };
00295 occ(i,j) = 0;
00296 };
00297
00298 tpoint * p = & points[exttype::mint2(x,y)];
00299 p->pt = exttype::mint2(x,y);
00300 p->next = occ(i,j);
00301 occ(i,j) = p;
00302 };
00303 if(z1<Z(i,j)) {
00304 Z(i,j) = z1;
00305 };
00306 };
00307 };
00308 };
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 void save_images() {
00320 dynamic::num_array<unsigned char,4> rec;
00321 dynamic::num_array<double,1> tt;
00322 int n_frames = 300;
00323 rec.resize(exttype::mint4(3,Width,Height,n_frames));
00324 tt.resize(n_frames);
00325 debug::PerformanceCounter c1;
00326 c1.start();
00327 for(int i=0;i<n_frames;++i){
00328 cam.get_image();
00329 tt(i) = c1.time();
00330 memcpy(&rec(0,0,0,i),cam.rgb.begin(),cam.rgb.byte_size());
00331 };
00332 std::cout<<" recording ";
00333
00334
00335 {
00336 eng_out(rec,"rec");
00337 eng_out(tt,"tt");
00338
00339 {
00340 std::stringstream ss;
00341 ss<<"frames{"<<o_count+1<<"}.brust=rec;";
00342 engEvalString(matlab,ss.str().c_str());
00343 };
00344 {
00345 std::stringstream ss;
00346 ss<<"frames{"<<o_count+1<<"}.tt=tt;";
00347 engEvalString(matlab,ss.str().c_str());
00348 };
00349
00350 }
00351 std::stringstream ss;
00352 char s[20];
00353
00354 sprintf(s,"%.4i",o_count);
00355 ss<<"save('../data/capture/frames_"<<s<<".mat','frames');";
00356
00357 engEvalString(matlab,ss.str().c_str());
00358 std::cout<<"ok\n";
00359 fflush(stdout);
00360 ++o_count;
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 };
00390
00391 bool notify(QObject * receiver, QEvent * ev) {
00392 if(ev->type() == QEvent::MouseButtonPress) {
00393 QMouseEvent * e = static_cast<QMouseEvent *>(ev);
00394 if(e->button()==Qt::LeftButton){
00395
00396 save_images();
00397 return true;
00398 };
00399 };
00400 if(ev->type() == QEvent::KeyPress) {
00401 QKeyEvent * e = static_cast<QKeyEvent *>(ev);
00402 if(e->key() == Qt::Key_Return) {
00403 save_images();
00404 return true;
00405 } else if(e->key() == Qt::Key_Tab) {
00406
00407 return true;
00408 } else if(e->key() == Qt::Key_Escape) {
00409 exit(0);
00410 return true;
00411 };
00412 };
00413 return QApplication::notify(receiver,ev);
00414 };
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 void timerEvent( QTimerEvent * event ) {
00446
00447 int recali_time = 30;
00448
00449 int recali_period = recali_time*framerate;
00450 if(count%recali_period==0){
00451 tcam.imager->forceRecalibration();
00452 };
00453
00454 tcam.triger();
00455
00456 ++count;
00457 cam.get_image();
00458 std::stringstream ss;
00459 ss<<"count="<<count<<";";
00460 engEvalString(matlab,ss.str().c_str());
00461
00462
00463
00464
00465
00466
00467 ir_reproj();
00468
00469 const char * psym = "-\\|/";
00470
00471
00472
00473
00474
00475 QRgb * pimg = (QRgb*)img.bits();
00476 unsigned char * prgb = cam.rgb.begin();
00477 double max_depth = -1e5;
00478 double min_depth = 1e5;
00479 for(int i = 0; i < (Width) * (Height); ++i) {
00480 if(cam.depth[i]>0) {
00481 double v = 1/(double(cam.depth[i]));
00482 if(v>max_depth)max_depth = v;
00483 if(v<min_depth)min_depth = v;
00484 };
00485 };
00486 for(int i = 0; i < (Width) * (Height); ++i) {
00487 unsigned char * pixel = &prgb[i*3];
00488
00489 double V = 1.0;
00490 if(0 & cam.depth[i]>0) {
00491 double v = 1/(double(cam.depth[i]));
00492
00493 V = (v-min_depth)/(max_depth-min_depth);
00494 pimg[i] = qRgb(floor((V)*255),floor((V)*255),0);
00495
00496
00497 } else {
00498 pimg[i] = qRgb(pixel[0],pixel[1],pixel[2]);
00499 };
00500
00501 if(IR[i]>0) {
00502 float pixel = IR[i];
00503 int a = std::min(239,std::max(0,int((pixel-tcam.tmin)*240/(tcam.tmax-tcam.tmin+1))));
00504 pimg[i] = qRgb(Iron[a][0],Iron[a][1],Iron[a][2]);
00505 };
00506
00507
00508 };
00509 label.setPixmap(QPixmap::fromImage(img));
00510 {
00511 std::stringstream ss;
00512 ss<<count;
00513 info->setText(QString("<font color='black' size='6'>")+ss.str().c_str()+QString("</font>"));
00514 info->adjustSize();
00515 };
00518 if(record){
00519 if(r_count==0){
00520 engEvalString(matlab,"rec = {};");
00521 };
00522 dynamic::num_array<unsigned char,3> wimg;
00523 wimg.set_ref(img.bits(),exttype::mint3(4,Width,Height));
00524 eng_out(wimg,"X");
00525 std::stringstream ss;
00526 ++r_count;
00527 ss<<"rec{"<<r_count<<"}=X;";
00528 engEvalString(matlab,ss.str().c_str());
00529 }
00530 };
00531 };
00532
00533
00534 myApp * the_app;
00535
00536 void cbOnFrame(unsigned short* image, unsigned int w, unsigned int h) {
00537 tcam.cbOnFrame(image,w,h);
00538 };
00539
00540
00541 void eng_thread() {
00542
00543
00544
00545
00546
00547
00548
00549
00550 char str[1024];
00551 int BUFSIZE = 1<<20;
00552 char buffer[BUFSIZE+1];
00553 engOutputBuffer(matlab, buffer, BUFSIZE);
00554 while(1) {
00555 buffer[0] = '\0';
00556 fgets(str, 1024, stdin);
00557
00558 engEvalString(matlab, str);
00559 printf("%s", buffer);
00560 };
00561 };
00562
00563 pthread_t tid;
00564
00565
00566 int main (int argc, char *argv[]) {
00567 myApp a(argc, argv);
00568 tcam.init(cbOnFrame);
00569 start_engine();
00570
00571
00572 int err = pthread_create(&tid, NULL, &eng_thread, NULL);
00573 if(err!= 0)exit(1);
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 return a.exec();
00590 };