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/fancynorm.H"
00051 #include "Transport/FrameInfo.H"
00052 #include "Raster/Raster.H"
00053 #include "Raster/GenericFrame.H"
00054 #include "GUI/DebugWin.H"
00055 #include "Neuro/EnvVisualCortex.H"
00056 #include "Media/FrameSeries.H"
00057 #include "Util/Timer.H"
00058
00059
00060 #define OPENCV_HOUGH 1 // opencv hough transform
00061
00062 #define ORI_QUE 1 //use orientation que
00063
00064 ModelManager *mgr;
00065
00066 bool debug = 0;
00067 Timer timer;
00068 int smap_level = 0;
00069
00070 #define halfPi ((float)(CV_PI*0.5))
00071 #define Pi ((float)CV_PI)
00072 #define a0 0
00073 #define a1 1.000025f
00074 #define a2 -2.652905e-4f
00075 #define a3 -0.165624f
00076 #define a4 -1.964532e-3f
00077 #define a5 1.02575e-2f
00078 #define a6 -9.580378e-4f
00079
00080 #define _sin(x) ((((((a6*(x) + a5)*(x) + a4)*(x) + a3)*(x) + a2)*(x) + a1)*(x) + a0)
00081 #define _cos(x) _sin(halfPi - (x))
00082 #define NUMANGLE 180
00083 float tabSin[NUMANGLE];
00084 float tabCos[NUMANGLE];
00085
00086
00087 void display(Image<PixRGB<byte> > &leftImg,
00088 const Image<PixRGB<byte> > &leftSmap,
00089 const Image<PixRGB<byte> > &hough,
00090 const Point2D<int> &leftWinner,
00091 const byte maxVal,
00092 const Point2D<int> &targetLoc,
00093 nub::ref<OutputFrameSeries> ofs);
00094
00095
00096 int biasProc(const char *tagName,
00097 env_size_t clev,
00098 env_size_t slev,
00099 struct env_image *cmap,
00100 const struct env_image *center,
00101 const struct env_image *surround)
00102 {
00103
00104
00105 ENV_SHOWIMG(cmap, 512, 512);
00106
00107
00108
00109
00110
00111
00112
00113
00114 return 0;
00115 }
00116
00117 void putLine(Image<PixRGB<byte> > &img, float r, float m)
00118 {
00119 double a = cos(m), b = sin(m);
00120 double x0 = a*r, y0 = b*r;
00121 Point2D<int> p1(cvRound(x0 + 1000*(-b)), cvRound(y0 + 1000*(a)));
00122 Point2D<int> p2(cvRound(x0 - 1000*(-b)), cvRound(y0 - 1000*(a)));
00123
00124 drawLine(img, p1, p2, PixRGB<byte>(255,0,0));
00125
00126 }
00127
00128 Image<float> houghTrans(const Image<float> &edge, const Image<float> &ori,
00129 const Image<float> &smap)
00130 {
00131
00132 int w = edge.getWidth();
00133 int h = edge.getHeight();
00134 float theta = CV_PI/180;
00135 int rho = 1;
00136 int numangle = int(CV_PI/theta);
00137 int numrho = int(((w+h)*2 +1) / rho);
00138
00139 Image<float> acc(numrho+2,numangle+2,ZEROS);
00140
00141
00142 Image<float>::const_iterator magPtr = edge.begin();
00143 Image<float>::iterator accPtr = acc.beginw();
00144
00145 #ifdef ORI_QUE
00146 Image<float>::const_iterator oriPtr = ori.begin();
00147 #endif
00148
00149 for(int y=0; y<h; y++)
00150 for(int x=0; x<w; x++)
00151 {
00152 float val = magPtr[y*w+x];
00153 if (val > 100)
00154 {
00155 int minOri = 0, maxOri = numangle;
00156 #ifdef ORI_QUE
00157 int oriQue = int((oriPtr[y*w+x]*180/M_PI));
00158 if (oriQue < 0) oriQue += 180;
00159
00160 minOri = (oriQue - 25); if (minOri < 0) minOri = 0;
00161 maxOri = (oriQue + 25); if (maxOri > numangle) maxOri = numangle-1;
00162 #endif
00163
00164 for(int m=minOri; m<maxOri; m++)
00165 {
00166 int r = int(x*tabCos[m] + y*tabSin[m]);
00167 r += (numrho -1) /2;
00168 accPtr[(m+1) * (numrho+2) + r+1] += val;
00169 }
00170 }
00171 }
00172
00173 return acc;
00174
00175 }
00176
00177 Image<PixRGB<byte> > showHough(const Image<float> &acc, const Image<float> &mag)
00178 {
00179
00180 Image<float> tmpAcc = acc;
00181 Image<PixRGB<byte> > retImg = mag;
00182
00183 int numrho = acc.getWidth()-2;
00184
00185
00186 Point2D<int> maxPos;
00187 float maxVal;
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 for(int i=0; i<10; i++)
00210 {
00211 findMax(tmpAcc, maxPos, maxVal);
00212 int r = maxPos.i;
00213 int m = maxPos.j;
00214 float rho = (r - (numrho - 1)*0.5f);
00215 float theta = (m * CV_PI/180);
00216 putLine(retImg, rho, theta);
00217
00218 drawDisk(tmpAcc, Point2D<int>(r,m), 5 , float(0));
00219
00220
00221 }
00222
00223
00224 return retImg;
00225 }
00226
00227 float w (float *p, int k)
00228 {
00229 int i;
00230 float x=0.0;
00231
00232 for (i=1; i<=k; i++) x += p[i];
00233 return x;
00234 }
00235
00236 float u (float *p, int k)
00237 {
00238 int i;
00239 float x=0.0;
00240
00241 for (i=1; i<=k; i++) x += (float)i*p[i];
00242 return x;
00243 }
00244
00245 float nu (float *p, int k, float ut, float vt)
00246 {
00247 float x, y;
00248
00249 y = w(p,k);
00250 x = ut*y - u(p,k);
00251 x = x*x;
00252 y = y*(1.0-y);
00253 if (y>0) x = x/y;
00254 else x = 0.0;
00255 return x/vt;
00256 }
00257
00258
00259 Image<float> segmentProb(const Image<float> &img)
00260 {
00261 Image<float> retImg = img;
00262 int hist[260];
00263 float p[260];
00264
00265 inplaceNormalize(retImg, 0.0F, 255.0F);
00266
00267 for(int i=0; i<260; i++)
00268 {
00269 hist[i] = 0;
00270 p[i] = 0;
00271 }
00272
00273 for (int y=0; y<retImg.getHeight(); y++)
00274 for(int x=0; x<retImg.getWidth(); x++)
00275 {
00276 int val = (int)retImg.getVal(x,y);
00277 hist[val+1]++;
00278 }
00279
00280
00281 for (int i=1; i<=256; i++)
00282 p[i] = (float)hist[i]/(float)retImg.getSize();
00283
00284
00285 float ut = 0.0;
00286 for(int i=1; i<=256; i++)
00287 ut += (float)i*p[i];
00288
00289
00290 float vt = 0.0;
00291 for(int i=1; i<=256; i++)
00292 vt += (i-ut)*(i-ut)*p[i];
00293
00294 int j=-1, k=-1;
00295 for(int i=1; i<=256; i++)
00296 {
00297 if ((j<0) && (p[i] > 0.0)) j = i;
00298 if (p[i] > 0.0) k = i;
00299 }
00300
00301 float z = -1.0;
00302 int m = -1;
00303 for (int i=j; i<=k; i++)
00304 {
00305 float y = nu(p,i,ut,vt);
00306
00307 if (y>=z)
00308 {
00309 z = y;
00310 m = i;
00311 }
00312 }
00313
00314 int t = m;
00315
00316 if (t < 0)
00317 LINFO("ERROR");
00318 else
00319 LINFO("THreshold is %i", t);
00320
00321
00322 for (int y=0; y<retImg.getHeight(); y++)
00323 for(int x=0; x<retImg.getWidth(); x++)
00324 {
00325 int val = (int)retImg.getVal(x,y);
00326 if (val < t)
00327 retImg.setVal(x,y,0);
00328 else
00329 retImg.setVal(x,y,255.0);
00330
00331 }
00332
00333
00334 return retImg;
00335 }
00336
00337 float entropy (float *h, int a, float p)
00338 {
00339 if (h[a] > 0.0 && p>0.0)
00340 return -(h[a]/p * (float)log((double)(h[a])/p));
00341 return 0.0;
00342 }
00343
00344
00345 Image<float> segment(const Image<float> &img)
00346 {
00347 Image<float> retImg = img;
00348 float hist[300];
00349 float pt[300];
00350 float F[300];
00351
00352 inplaceNormalize(retImg, 0.0F, 255.0F);
00353
00354 for(int i=0; i<256; i++)
00355 {
00356 hist[i] = 0;
00357 pt[i] = 0;
00358 }
00359
00360 for (int y=0; y<retImg.getHeight(); y++)
00361 for(int x=0; x<retImg.getWidth(); x++)
00362 {
00363 int val = (int)retImg.getVal(x,y);
00364 hist[val]++;
00365 }
00366
00367
00368 for (int i=0; i<256; i++)
00369 hist[i] = (float)hist[i]/(float)retImg.getSize();
00370
00371
00372 pt[0] = hist[0];
00373 for(int i=1; i<256; i++)
00374 pt[i] = pt[i-1] + hist[i];
00375
00376 int t = -1;
00377
00378 for(int i=0; i<256; i++)
00379 {
00380 float Hb = 0, Hw = 0;
00381 for(int j=0; j<256; j++)
00382 if (j<=i)
00383 Hb += entropy(hist, j, pt[i]);
00384 else
00385 Hw += entropy(hist, j, 1.0-pt[i]);
00386 F[i] = Hb+Hw;
00387 if (i>0 && F[i] > F[t]) t = i;
00388 }
00389 if (t < 0)
00390 LINFO("ERROR");
00391 else
00392 LINFO("THreshold is %i", t);
00393
00394
00395 for (int y=0; y<retImg.getHeight(); y++)
00396 for(int x=0; x<retImg.getWidth(); x++)
00397 {
00398 int val = (int)retImg.getVal(x,y);
00399 if (val < t)
00400 retImg.setVal(x,y,0);
00401 else
00402 retImg.setVal(x,y,255.0);
00403
00404 }
00405
00406
00407 return retImg;
00408 }
00409
00410
00411
00412 int main(const int argc, const char **argv)
00413 {
00414
00415 MYLOGVERB = LOG_INFO;
00416 mgr = new ModelManager("Test ObjRec");
00417
00418 nub::ref<InputFrameSeries> ifs(new InputFrameSeries(*mgr));
00419 mgr->addSubComponent(ifs);
00420
00421 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(*mgr));
00422 mgr->addSubComponent(ofs);
00423
00424 nub::ref<EnvVisualCortex> evc(new EnvVisualCortex(*mgr));
00425 mgr->addSubComponent(evc);
00426
00427 mgr->exportOptions(MC_RECURSE);
00428
00429
00430
00431
00432
00433
00434
00435
00436 evc->setFweight(0);
00437 evc->setMweight(0);
00438 evc->setCweight(0);
00439 evc->setOweight(0);
00440
00441 if (mgr->parseCommandLine(
00442 (const int)argc, (const char**)argv, "image", 0, 0) == false)
00443 return 1;
00444
00445 mgr->start();
00446
00447
00448
00449
00450 ifs->startStream();
00451
00452
00453 float ang;
00454 int i;
00455 for(ang =0,i=0; i < 180; ang += CV_PI/180, i++)
00456 {
00457 tabSin[i] = (float)(sin(ang));
00458 tabCos[i] = (float)(cos(ang));
00459 }
00460
00461 while(1)
00462 {
00463 Image< PixRGB<byte> > inputImg;
00464 const FrameState is = ifs->updateNext();
00465 LINFO("Frame %i\n", ifs->frame());
00466 if (is == FRAME_COMPLETE)
00467 break;
00468
00469
00470 GenericFrame input = ifs->readFrame();
00471 if (!input.initialized())
00472 break;
00473 inputImg = input.asRgb();
00474
00475 int fw = 100;
00476 Image<PixRGB<byte> > fimg = crop(inputImg,
00477 Point2D<int>((inputImg.getWidth()/2)-(fw/2), (inputImg.getHeight()/2)-(fw/2)), Dims(fw,fw));
00478
00479
00480
00481
00482
00483
00484 fimg = rescale(fimg, inputImg.getDims());
00485 evc->input(fimg);
00486
00487 Image<float> vcxMap = evc->getVCXmap();
00488 Image<float> lum = luminance(fimg);
00489
00490
00491 vcxMap = rescale(vcxMap, inputImg.getDims());
00492 lum = rescale(lum, inputImg.getDims());
00493
00494 Image<float> mag, ori;
00495 gradientSobel(lum, mag, ori, 3);
00496
00497
00498 mag = (vcxMap);
00499
00500
00501 Image<float> seg = segment(mag);
00502
00503 gradientSobel(lum, mag, ori, 3);
00504 lum =mag;
00505
00506 Image<PixRGB<byte> > salHoughDisp;
00507 Image<PixRGB<byte> > opencvHoughDisp;
00508
00509
00510 Image<float> acc = houghTrans(mag, ori, vcxMap);
00511
00512
00513 salHoughDisp = showHough(acc, mag);
00514
00515
00516
00517 #ifdef SALIENCY_HOUGH
00518 Image<float> mag, ori;
00519 gradientSobel(vcxMap, mag, ori, 3);
00520 mag *= vcxMap;
00521 inplaceNormalize(mag, 0.0F, 255.0F);
00522
00523
00524 Image<float> acc = houghTrans(mag, ori, vcxMap);
00525
00526
00527 salHoughDisp = showHough(acc, mag);
00528 #endif
00529
00530 #ifdef OPENCV_HOUGH
00531
00532
00533 inplaceNormalize(lum, 0.0F, 255.0F);
00534 CvMemStorage* storage = cvCreateMemStorage(0);
00535 IplImage *dst = cvCreateImage( cvGetSize(img2ipl(lum)), 8, 1 );
00536 cvCanny( img2ipl((Image<byte>)lum), dst, 150, 200, 3 );
00537
00538 Image<float> edge = ipl2float(dst);
00539 opencvHoughDisp = edge;
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 CvSeq *lines = cvHoughLines2( dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 10, 5, 1 );
00561 for( i = 0; i < lines->total; i++ )
00562 {
00563 CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
00564 drawLine(opencvHoughDisp, Point2D<int>(line[0].x,line[0].y), Point2D<int>(line[1].x, line[1].y), PixRGB<byte>(255,0,0));
00565 }
00566
00567 #endif
00568
00569
00570 display(inputImg, vcxMap, lum, Point2D<int>(-1, -1), 2, Point2D<int>(-1, -1), ofs);
00571
00572
00573 }
00574
00575
00576
00577
00578 mgr->stop();
00579
00580 return 0;
00581
00582 }
00583
00584
00585 void display(Image<PixRGB<byte> > &leftImg,
00586 const Image<PixRGB<byte> > &leftSmap,
00587 const Image<PixRGB<byte> > &hough,
00588 const Point2D<int> &leftWinner,
00589 const byte maxVal,
00590 const Point2D<int> &targetLoc,
00591 nub::ref<OutputFrameSeries> ofs)
00592 {
00593 static int avgn = 0;
00594 static uint64 avgtime = 0;
00595 static double fps = 0;
00596 char msg[255];
00597
00598 Image<PixRGB<byte> > outDisp(leftImg.getWidth()*2,leftImg.getHeight()*2+20, ZEROS);
00599
00600
00601
00602 inplacePaste(outDisp, leftImg, Point2D<int>(0,0));
00603 inplacePaste(outDisp, leftSmap, Point2D<int>(0,leftImg.getHeight()));
00604 inplacePaste(outDisp, hough, Point2D<int>(leftImg.getWidth(),leftImg.getHeight()));
00605
00606
00607
00608 avgn++;
00609 avgtime += timer.getReset();
00610 if (avgn == 20)
00611 {
00612 fps = 1000.0F / double(avgtime) * double(avgn);
00613 avgtime = 0;
00614 avgn = 0;
00615 }
00616
00617 sprintf(msg, "%.1ffps ", fps);
00618
00619 Image<PixRGB<byte> > infoImg(leftImg.getWidth()*2, 20, NO_INIT);
00620 writeText(infoImg, Point2D<int>(0,0), msg,
00621 PixRGB<byte>(255), PixRGB<byte>(127));
00622 inplacePaste(outDisp, infoImg, Point2D<int>(0,leftImg.getHeight()*2));
00623
00624 ofs->writeRGB(outDisp, "output", FrameInfo("output", SRC_POS));
00625 }
00626
00627