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