00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "Image/OpenCVUtil.H"
00040 #include "Component/ModelManager.H"
00041 #include "Image/Image.H"
00042 #include "Image/ImageSet.H"
00043 #include "Image/ShapeOps.H"
00044 #include "Image/CutPaste.H"
00045 #include "Image/DrawOps.H"
00046 #include "Image/FilterOps.H"
00047 #include "Image/ColorOps.H"
00048 #include "Image/Transforms.H"
00049 #include "Image/MathOps.H"
00050 #include "Image/Kernels.H"
00051 #include "Image/fancynorm.H"
00052 #include "Image/Layout.H"
00053 #include "Transport/FrameInfo.H"
00054 #include "Raster/Raster.H"
00055 #include "Raster/GenericFrame.H"
00056 #include "GUI/DebugWin.H"
00057 #include "Neuro/EnvVisualCortex.H"
00058 #include "Media/FrameSeries.H"
00059 #include "Util/Timer.H"
00060 #include "RCBot/Motion/MotionEnergy.H"
00061 #include "Neuro/BeoHeadBrain.H"
00062 #include "Devices/Scorbot.H"
00063
00064 #include <unistd.h>
00065 #include <stdio.h>
00066 #include <signal.h>
00067
00068
00069 #define OPENCV_HOUGH 1 // opencv hough transform
00070
00071 #define ORI_QUE 1 //use orientation que
00072
00073
00074 nub::soft_ref<Scorbot> scorbot;
00075
00076 void terminate(int s)
00077 {
00078 LINFO("*** INTERRUPT ***");
00079 scorbot->stopAllMotors();
00080 sleep(1);
00081 scorbot->setMotorPos(Scorbot::BASE, 0);
00082 scorbot->setMotorPos(Scorbot::ELBOW, 0);
00083 scorbot->setMotorPos(Scorbot::SHOLDER, 0);
00084
00085 scorbot->setMotor(Scorbot::WRIST1, 50);
00086 scorbot->setMotor(Scorbot::WRIST2, 50);
00087 scorbot->stopAllMotors();
00088 sleep(1);
00089 exit(0);
00090 }
00091
00092
00093
00094
00095 Image<byte> watershed(Image<float> &img)
00096 {
00097
00098 Image<float> ret(img.getDims(), ZEROS);
00099 Image<byte> Data2(img.getDims(), ZEROS);
00100 int Ydim = img.getHeight();
00101 int Xdim = img.getWidth();
00102
00103
00104 if (false)
00105 {
00106 for (int y = 1; y < (img.getHeight() - 1); y++)
00107 for (int x = 1; x < (img.getWidth() - 1); x++)
00108 {
00109 float Dx = (img.getVal(x+1, y + 1) + 2 * img.getVal(x+1, y) + img.getVal(x+1, y-1)
00110 - img.getVal(x-1, y+1) - 2 * img.getVal(x-1, y) - img.getVal(x-1, y-1)) / 8;
00111 float Dy = (img.getVal(x+1, y + 1) + 2 * img.getVal(x, y+1) + img.getVal(x-1, y+1)
00112 - img.getVal(x+1, y-1) - 2 * img.getVal(x, y-1) - img.getVal(x-1, y-1)) / 8;
00113
00114 ret.setVal(x,y, (float) sqrt((double) (Dx * Dx + Dy * Dy)));
00115 }
00116
00117
00118 for (int y = 1; y < (Ydim - 1); y++)
00119 for (int x = 1; x < (Xdim - 1); x++)
00120 img.setVal(x,y, ret.getVal(x,y));
00121
00122 for (int x = 0; x < Xdim; x++)
00123 {
00124 img.setVal(x, 0, img.getVal(x,1));
00125 img.setVal(x, Ydim-1, img.getVal(x, Ydim - 2));
00126 }
00127 for (int y = 0; y < Ydim; y++)
00128 {
00129 img.setVal(0,y, img.getVal(1,y));
00130 img.setVal(Xdim-1, y, img.getVal(Xdim-2, y));
00131 }
00132 }
00133
00134
00135 float min, max;
00136 getMinMax(img, min, max);
00137
00138 int mask = 2;
00139 for(int y=0; y<Ydim; y++)
00140 for (int x=0; x<Xdim; x++)
00141 {
00142 if (img.getVal(x,y) == min)
00143 {
00144 Data2.setVal(x,y,mask);
00145 }
00146 }
00147
00148
00149 return Data2;
00150
00151
00152 }
00153
00154 float w (float *p, int k)
00155 {
00156 int i;
00157 float x=0.0;
00158
00159 for (i=1; i<=k; i++) x += p[i];
00160 return x;
00161 }
00162
00163 float u (float *p, int k)
00164 {
00165 int i;
00166 float x=0.0;
00167
00168 for (i=1; i<=k; i++) x += (float)i*p[i];
00169 return x;
00170 }
00171
00172 float nu (float *p, int k, float ut, float vt)
00173 {
00174 float x, y;
00175
00176 y = w(p,k);
00177 x = ut*y - u(p,k);
00178 x = x*x;
00179 y = y*(1.0-y);
00180 if (y>0) x = x/y;
00181 else x = 0.0;
00182 return x/vt;
00183 }
00184
00185 Image<float> segmentProb(const Image<float> &img)
00186 {
00187 Image<float> retImg = img;
00188 int hist[260];
00189 float p[260];
00190
00191 inplaceNormalize(retImg, 0.0F, 255.0F);
00192
00193 for(int i=0; i<260; i++)
00194 {
00195 hist[i] = 0;
00196 p[i] = 0;
00197 }
00198
00199 for (int y=0; y<retImg.getHeight(); y++)
00200 for(int x=0; x<retImg.getWidth(); x++)
00201 {
00202 int val = (int)retImg.getVal(x,y);
00203 hist[val+1]++;
00204 }
00205
00206
00207 for (int i=1; i<=256; i++)
00208 p[i] = (float)hist[i]/(float)retImg.getSize();
00209
00210
00211 float ut = 0.0;
00212 for(int i=1; i<=256; i++)
00213 ut += (float)i*p[i];
00214
00215
00216 float vt = 0.0;
00217 for(int i=1; i<=256; i++)
00218 vt += (i-ut)*(i-ut)*p[i];
00219
00220 int j=-1, k=-1;
00221 for(int i=1; i<=256; i++)
00222 {
00223 if ((j<0) && (p[i] > 0.0)) j = i;
00224 if (p[i] > 0.0) k = i;
00225 }
00226
00227 float z = -1.0;
00228 int m = -1;
00229 for (int i=j; i<=k; i++)
00230 {
00231 float y = nu(p,i,ut,vt);
00232
00233 if (y>=z)
00234 {
00235 z = y;
00236 m = i;
00237 }
00238 }
00239
00240 int t = m;
00241
00242 if (t < 0)
00243 LINFO("ERROR");
00244
00245
00246 for (int y=0; y<retImg.getHeight(); y++)
00247 for(int x=0; x<retImg.getWidth(); x++)
00248 {
00249 int val = (int)retImg.getVal(x,y);
00250 if (val < t)
00251 retImg.setVal(x,y,0);
00252 else
00253 retImg.setVal(x,y,255.0);
00254 }
00255
00256
00257 return retImg;
00258 }
00259
00260 Image<float> integralImage(const Image<float> &img)
00261 {
00262
00263 Image<float> integImg(img.getDims(), ZEROS);
00264
00265 int xDim = integImg.getWidth();
00266 int yDim = integImg.getHeight();
00267
00268
00269 float s[xDim];
00270 for (int i=0; i<xDim; i++) s[i] = 0;
00271
00272 for(int y=0; y<yDim; y++)
00273 for(int x=0; x<xDim; x++)
00274 {
00275 float ii = x > 0 ? integImg.getVal(x-1, y) : 0;
00276 s[x] += img.getVal(x,y);
00277 integImg.setVal(x,y, ii+s[x]);
00278 }
00279
00280 return integImg;
00281
00282
00283 }
00284
00285 Image<float> getHaarFeature(Image<float> &integImg, int i)
00286 {
00287
00288 Image<float> fImg(integImg.getDims(), ZEROS);
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 int c = 6+i, s = 8+i;
00310
00311 int x = 320/2, y=240/2;
00312
00313 Rectangle rect(Point2D<int>(x,y),Dims(s,s));
00314 drawRect(fImg, rect, float(255.0));
00315
00316
00317 {
00318 int d = (s-c)/2;
00319 float center = integImg.getVal(x+d,y+d) + integImg.getVal(x+d+c,y+d+c) -
00320 (integImg.getVal(x+d,y+d+c) + integImg.getVal(x+d+c,y+d));
00321 float surround = integImg.getVal(x,y) + integImg.getVal(x+s,y+s) -
00322 (integImg.getVal(x+s,y) + integImg.getVal(x,y+s));
00323
00324 center /= c*2;
00325 surround /= s*2;
00326
00327
00328 }
00329
00330
00331
00332
00333
00334 return fImg;
00335
00336 }
00337
00338 Image<float> getObj(Image<float> &integImg)
00339 {
00340
00341
00342 Image<float> objImg(integImg.getDims(), ZEROS);
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 for(int y=6; y<objImg.getHeight()-60; y++)
00364 for(int x=6; x<objImg.getWidth()-60; x++)
00365 {
00366 int c, s;
00367 float center, surround;
00368 for (int i=0; i<30; i++)
00369 {
00370 c = 3+(i/2);
00371 s = 6+i;
00372
00373 int d = (s-c)/2;
00374 center = integImg.getVal(x+d,y+d) + integImg.getVal(x+d+c,y+d+c) -
00375 (integImg.getVal(x+d,y+d+c) + integImg.getVal(x+d+c,y+d));
00376 surround = integImg.getVal(x,y) + integImg.getVal(x+s,y+s) -
00377 (integImg.getVal(x+s,y) + integImg.getVal(x,y+s)) - center;
00378
00379 center /= (c*c);
00380 surround /= ((s*s) - (c*c));
00381 if (fabs(surround-center) > 5) break;
00382 }
00383
00384 Rectangle rectC(Point2D<int>(x+((s-c)/2),y+((s-c)/2)),Dims(c,c));
00385 Rectangle rectS(Point2D<int>(x,y),Dims(s,s));
00386
00387 drawFilledRect(objImg, rectC, center);
00388 }
00389
00390
00391
00392
00393 return objImg;
00394
00395 }
00396
00397
00398 const double MHI_DURATION = 1;
00399 const double MAX_TIME_DELTA = 0.5;
00400 const double MIN_TIME_DELTA = 0.05;
00401
00402
00403 const int N = 15;
00404
00405
00406 IplImage **buf = 0;
00407 int last = 0;
00408
00409
00410 IplImage *mhi = 0;
00411 IplImage *orient = 0;
00412 IplImage *mask = 0;
00413 IplImage *segmask = 0;
00414 CvMemStorage* storage = 0;
00415
00416
00417
00418
00419
00420 Rectangle update_mhi( IplImage* img, IplImage* dst, int diff_threshold )
00421 {
00422 double timestamp = (double)clock()/CLOCKS_PER_SEC;
00423 CvSize size = cvSize(img->width,img->height);
00424 int i, idx1 = last, idx2;
00425 IplImage* silh;
00426 CvSeq* seq;
00427 CvRect comp_rect;
00428 CvRect maxComp_rect = cvRect(0,0,0,0);
00429 double count;
00430
00431 CvPoint center;
00432
00433 Rectangle rect;
00434
00435
00436
00437 if( !mhi || mhi->width != size.width || mhi->height != size.height ) {
00438 if( buf == 0 ) {
00439 buf = (IplImage**)malloc(N*sizeof(buf[0]));
00440 memset( buf, 0, N*sizeof(buf[0]));
00441 }
00442
00443 for( i = 0; i < N; i++ ) {
00444 cvReleaseImage( &buf[i] );
00445 buf[i] = cvCreateImage( size, IPL_DEPTH_8U, 1 );
00446 cvZero( buf[i] );
00447 }
00448 cvReleaseImage( &mhi );
00449 cvReleaseImage( &orient );
00450 cvReleaseImage( &segmask );
00451 cvReleaseImage( &mask );
00452
00453 mhi = cvCreateImage( size, IPL_DEPTH_32F, 1 );
00454 cvZero( mhi );
00455 orient = cvCreateImage( size, IPL_DEPTH_32F, 1 );
00456 segmask = cvCreateImage( size, IPL_DEPTH_32F, 1 );
00457 mask = cvCreateImage( size, IPL_DEPTH_8U, 1 );
00458 }
00459
00460 cvCvtColor( img, buf[last], CV_BGR2GRAY );
00461
00462 idx2 = (last + 1) % N;
00463 last = idx2;
00464
00465 silh = buf[idx2];
00466 cvAbsDiff( buf[idx1], buf[idx2], silh );
00467
00468 cvThreshold( silh, silh, diff_threshold, 1, CV_THRESH_BINARY );
00469 cvUpdateMotionHistory( silh, mhi, timestamp, MHI_DURATION );
00470
00471
00472 cvCvtScale( mhi, mask, 255./MHI_DURATION,
00473 (MHI_DURATION - timestamp)*255./MHI_DURATION );
00474 cvZero( dst );
00475 cvCvtPlaneToPix( mask, 0, 0, 0, dst );
00476
00477
00478 cvCalcMotionGradient( mhi, mask, orient, MAX_TIME_DELTA, MIN_TIME_DELTA, 3 );
00479
00480 if( !storage )
00481 storage = cvCreateMemStorage(0);
00482 else
00483 cvClearMemStorage(storage);
00484
00485
00486
00487 seq = cvSegmentMotion( mhi, segmask, storage, timestamp, MAX_TIME_DELTA );
00488
00489
00490
00491
00492 float maxMotCount = 0;
00493
00494 for(int i=0; i< seq->total; i++)
00495 {
00496
00497 comp_rect = ((CvConnectedComp*)cvGetSeqElem( seq, i ))->rect;
00498
00499
00500 cvSetImageROI( silh, comp_rect );
00501 cvSetImageROI( mhi, comp_rect );
00502 cvSetImageROI( orient, comp_rect );
00503 cvSetImageROI( mask, comp_rect );
00504
00505
00506 count = cvNorm( silh, 0, CV_L1, 0 );
00507
00508 cvResetImageROI( mhi );
00509 cvResetImageROI( orient );
00510 cvResetImageROI( mask );
00511 cvResetImageROI( silh );
00512
00513 float motCount = count + (comp_rect.width*comp_rect.height);
00514 if (motCount > maxMotCount)
00515 {
00516 maxComp_rect = comp_rect;
00517 maxMotCount = motCount;
00518 }
00519 }
00520
00521 if (maxMotCount > 0)
00522 {
00523
00524
00525 center = cvPoint( (maxComp_rect.x + maxComp_rect.width/2),
00526 (maxComp_rect.y + maxComp_rect.height/2) );
00527
00528 cvCircle( dst, center, cvRound(35), CV_RGB(255,0,0), 3, CV_AA, 0 );
00529
00530
00531
00532 rect = Rectangle(Point2D<int>(maxComp_rect.x, maxComp_rect.y), Dims(maxComp_rect.width, maxComp_rect.height));
00533
00534 }
00535
00536 return rect;
00537 }
00538
00539
00540 void randArmMove()
00541 {
00542
00543 int base = -1500 + randomUpToIncluding(3700);
00544
00545 int sholder = -700 + randomUpToIncluding(1700+700);
00546
00547 LINFO("Generate random position base=%i sholder=%i",
00548 base, sholder);
00549
00550 scorbot->setMotorPos(Scorbot::BASE, base);
00551
00552 scorbot->setMotorPos(Scorbot::SHOLDER, sholder);
00553
00554 }
00555
00556 int main(const int argc, const char **argv)
00557 {
00558
00559 MYLOGVERB = LOG_INFO;
00560 ModelManager *mgr = new ModelManager("Test ObjRec");
00561
00562 nub::ref<InputFrameSeries> ifs(new InputFrameSeries(*mgr));
00563 mgr->addSubComponent(ifs);
00564
00565 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(*mgr));
00566 mgr->addSubComponent(ofs);
00567
00568 nub::ref<EnvVisualCortex> evc(new EnvVisualCortex(*mgr));
00569 mgr->addSubComponent(evc);
00570
00571 nub::soft_ref<BeoHeadBrain> beoHeadBrain(new BeoHeadBrain(*mgr));
00572 mgr->addSubComponent(beoHeadBrain);
00573
00574 scorbot = nub::soft_ref<Scorbot>(new Scorbot(*mgr));
00575 mgr->addSubComponent(scorbot);
00576
00577
00578 signal(SIGHUP, terminate); signal(SIGINT, terminate);
00579 signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00580 signal(SIGALRM, terminate);
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 mgr->exportOptions(MC_RECURSE);
00593
00594 if (mgr->parseCommandLine(
00595 (const int)argc, (const char**)argv, "", 0, 0) == false)
00596 return 1;
00597 mgr->start();
00598
00599
00600
00601
00602
00603
00604
00605 IplImage* motion = 0;
00606
00607 beoHeadBrain->init(ifs->peekDims());
00608
00609 scorbot->setSafety(false);
00610 initRandomNumbers();
00611
00612 Point2D<int> target;
00613 while(1)
00614 {
00615
00616 randArmMove();
00617
00618 scorbot->setMotor(Scorbot::WRIST1, 80);
00619 scorbot->setMotor(Scorbot::WRIST2, 80);
00620
00621
00622 Rectangle rect;
00623 for(int i=0; i<200; i++)
00624 {
00625 Image< PixRGB<byte> > inputImg;
00626 const FrameState is = ifs->updateNext();
00627 if (is == FRAME_COMPLETE)
00628 break;
00629
00630
00631 GenericFrame input = ifs->readFrame();
00632 if (!input.initialized())
00633 break;
00634 inputImg = input.asRgb();
00635
00636 IplImage* image = img2ipl(inputImg);
00637 if( !motion )
00638 {
00639 motion = cvCreateImage( cvSize(inputImg.getWidth(),inputImg.getHeight()), 8, 3 );
00640 cvZero( motion );
00641 motion->origin = image->origin;
00642 }
00643
00644 rect = update_mhi( image, motion, 30 );
00645
00646
00647 if (rect.isValid())
00648 {
00649 drawRect(inputImg, rect, PixRGB<byte>(255,0,0));
00650 Point2D<int> center = rect.topLeft();
00651 center.i += rect.width()/2;
00652 center.j += rect.height()/2;
00653 drawCircle(inputImg, center, 6, PixRGB<byte>(255,0,0));
00654
00655
00656 } else {
00657 LINFO("No motion found\n");
00658 }
00659
00660
00661
00662
00663 ofs->writeRGB(inputImg, "input", FrameInfo("input", SRC_POS));
00664 Image<PixRGB<byte> > mot((PixRGB<byte>*)motion->imageData,
00665 motion->width, motion->height);
00666
00667 ofs->writeRGB(mot, "motion", FrameInfo("motion", SRC_POS));
00668 }
00669
00670
00671 scorbot->setMotor(Scorbot::WRIST1, 0);
00672 scorbot->setMotor(Scorbot::WRIST2, 0);
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693 }
00694
00695
00696 mgr->stop();
00697
00698 return 0;
00699
00700 }