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
00040
00041
00042
00043 #include "Channels/OrientationChannel.H"
00044 #include "Component/ModelManager.H"
00045 #include "GUI/XWinManaged.H"
00046 #include "Image/CutPaste.H"
00047 #include "Image/DrawOps.H"
00048 #include "Image/ImageSet.H"
00049 #include "Image/MathOps.H"
00050 #include "Image/PyramidOps.H"
00051 #include "Image/ShapeOps.H"
00052 #include "Image/Transforms.H"
00053 #include "Neuro/StdBrain.H"
00054 #include "Neuro/VisualCortex.H"
00055 #include "Raster/Raster.H"
00056
00057
00058 #include "Gist/FFN.H"
00059 #include "Gist/ModelFace.H"
00060
00061 #define LEARN_RATE 0.5
00062 #define TRAIN_START_INDEX 277
00063 #define NUM_TRAIN_SAMPLE 200
00064 #define TEST_START_INDEX 234
00065 #define NUM_TEST_SAMPLE 100
00066
00067 CloseButtonListener wList; XWinManaged *imgWin;
00068 Image<byte> targetmask;
00069
00070 Image<float> getPartImage(char* iName, Rectangle pr);
00071 Image<float> getPartImage(Image<float> img, Rectangle pr);
00072
00073 Rectangle getPartRect(char* iName, char* dName, FacePart part, int opp);
00074 Rectangle getPartRect(Image<float> img, char* dName, FacePart part, int opp);
00075
00076 void getFeature(Rectangle r, FacePart part, Image<double> features);
00077 void getEyeFeature (Rectangle r, Image<double> features);
00078 void getNoseFeature (Rectangle r, Image<double> features);
00079 void getMouthFeature(Rectangle r, Image<double> features);
00080
00081 void train
00082 (FeedForwardNetwork* ffn, FacePart part, nub::soft_ref<StdBrain> brain);
00083 void fillEyeData
00084 ( int start, std::vector<Image<double> > pData,
00085 std::vector<Image<double> >nData, int *pCt, int *nCt);
00086 void fillNoseData
00087 ( int start, std::vector<Image<double> > pData,
00088 std::vector<Image<double> > nData, int *pCt, int *nCt);
00089 void fillMouthData
00090 ( int start, std::vector<Image<double> > pData,
00091 std::vector<Image<double> > nData, int *pCt, int *nCt);
00092
00093 bool within(Rectangle r, int x, int y);
00094
00095 nub::soft_ref<OrientationChannel> oriChan;
00096
00097
00098
00099 Image<float> currImg;
00100 ImageSet<float> currGaPyr[NUM_DIR];
00101
00102 void printRegion(Image<float> img,int sX,int eX,int dX, int sY,int eY, int dY);
00103
00104
00105 int main(const int argc, const char **argv)
00106 {
00107
00108
00109 ModelManager manager("Face Recognition Model");
00110
00111
00112 nub::soft_ref<StdBrain> brain(new StdBrain(manager));
00113 manager.addSubComponent(brain);
00114
00115
00116 if (manager.parseCommandLine(argc, argv,"", 0, 0) == false)
00117 return(1);
00118
00119
00120 manager.start();
00121 LFATAL("fixme");
00122 nub::soft_ref<VisualCortex> vc;
00123
00124
00125
00126 srand((unsigned)time(0));
00127
00128
00129 FeedForwardNetwork *ffn_e = new FeedForwardNetwork();
00130 FeedForwardNetwork *ffn_n = new FeedForwardNetwork();
00131 FeedForwardNetwork *ffn_m = new FeedForwardNetwork();
00132
00133
00134 char h1EName[200],h2EName[200],oEName[200];
00135 sprintf(h1EName,"%s%s%s",WEIGHT_DATA_FOLDER,FILE_TAGNAME,"hidden1EYE.dat");
00136 sprintf(h2EName,"%s%s%s",WEIGHT_DATA_FOLDER,FILE_TAGNAME,"hidden2EYE.dat");
00137 sprintf(oEName ,"%s%s%s",WEIGHT_DATA_FOLDER,FILE_TAGNAME,"outEYE.dat");
00138
00139 char h1NName[200],h2NName[200],oNName[200];
00140 sprintf(h1NName,"%s%s%s",WEIGHT_DATA_FOLDER,FILE_TAGNAME,"hidden1NOSE.dat");
00141 sprintf(h2NName,"%s%s%s",WEIGHT_DATA_FOLDER,FILE_TAGNAME,"hidden2NOSE.dat");
00142 sprintf(oNName ,"%s%s%s",WEIGHT_DATA_FOLDER,FILE_TAGNAME,"outNOSE.dat");
00143
00144 char h1MName[200],h2MName[200],oMName[200];
00145 sprintf(h1MName,"%s%s%s",WEIGHT_DATA_FOLDER,FILE_TAGNAME,"hidden1MOUTH.dat");
00146 sprintf(h2MName,"%s%s%s",WEIGHT_DATA_FOLDER,FILE_TAGNAME,"hidden2MOUTH.dat");
00147 sprintf(oMName ,"%s%s%s",WEIGHT_DATA_FOLDER,FILE_TAGNAME,"outMOUTH.dat");
00148
00149
00150
00151 ffn_e->init3L(h1EName, h2EName, oEName,
00152 RE_INPUT, RE_HIDDEN_1, RE_HIDDEN_2, 1, LEARN_RATE, 0.0);
00153 ffn_n->init3L(h1NName, h2NName, oNName,
00154 N_INPUT, N_HIDDEN_1, N_HIDDEN_2, 1, LEARN_RATE, 0.0);
00155 ffn_m->init3L(h1MName, h2MName, oMName,
00156 M_INPUT, M_HIDDEN_1, M_HIDDEN_2, 1, LEARN_RATE, 0.0);
00157
00158
00159 train(ffn_e, EYE, brain);
00160 train(ffn_n, NOSE, brain);
00161 train(ffn_m, MOUTH, brain);
00162
00163
00164
00165
00166
00167 }
00168
00169
00170
00171 void train(FeedForwardNetwork *ffn, FacePart part, nub::soft_ref<StdBrain> brain)
00172 {
00173
00174 int pW = 0, pH = 0;
00175 switch(part)
00176 {
00177 case EYE:
00178 pW = MODEL_EYE_WIDTH;
00179 pH = MODEL_EYE_HEIGHT;
00180 break;
00181 case NOSE:
00182 pW = MODEL_NOSE_WIDTH;
00183 pH = MODEL_NOSE_HEIGHT;
00184 break;
00185 case MOUTH:
00186 pW = MODEL_MOUTH_WIDTH;
00187 pH = MODEL_MOUTH_HEIGHT;
00188 break;
00189 default:
00190 LFATAL("Unknown face part");
00191 }
00192
00193
00194
00195 std::vector<Image<double> > pData(NUM_TRAIN_SAMPLE);
00196 std::vector<Image<double> > nData(NUM_TRAIN_SAMPLE);
00197
00198
00199
00200
00201 int pCount = 0, nCount = 0;
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 printf("Start Training\n");
00218 int nfc = NUM_TRAIN_SAMPLE;
00219 Image<double> trueout(1,1,ZEROS);
00220 double errSum = double(2*NUM_TRAIN_SAMPLE);
00221 int nTrials = 0;
00222 Image<double> ffnOut;
00223 while(nTrials < 0)
00224 {
00225 errSum = 0.0; nfc = 0; int i = 0;
00226 while (i < pCount || i < nCount)
00227 {
00228
00229 if(i < pCount)
00230 {
00231 ffn->run3L(pData[i]);
00232 ffnOut = ffn->getOutput();
00233 errSum += fabs(1.0 - ffnOut[0]);
00234 if(ffnOut[0] < .5)
00235 {
00236 nfc++;
00237 printf("falsePOS o: %f, err: %f\n",ffnOut[0], 1.0-ffnOut[0]);
00238 }
00239 trueout[0] = 1.0; ffn->backprop3L(trueout);
00240 }
00241
00242
00243 if(i < nCount)
00244 {
00245 ffn->run3L(nData[i]);
00246 ffnOut = ffn->getOutput();
00247 errSum += fabs(ffnOut[0]);
00248 if(ffnOut[0] > .5)
00249 {
00250 nfc++;
00251 printf("falseNEG: out: %f, err: %f\n",ffnOut[0],ffnOut[0]);
00252 }
00253 trueout[0] = 0.0; ffn->backprop3L(trueout);
00254 }
00255 i++;
00256 }
00257 nTrials++;
00258
00259
00260 if(nTrials %10 == 0)
00261 printf("Trial_%04d_Err: %f, nfc: %d \n",
00262 nTrials,errSum/double(pCount+nCount),nfc);
00263 }
00264
00265
00266 printf("Final Trial_%04d_Err: %f, nfc: %d \n",
00267 nTrials,errSum/double(pCount+nCount),nfc);
00268
00269
00270 printf("Testing Phase\n");
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 int tNum = 333;
00315 char tName[200];
00316 sprintf(tName, "%s%s%04d%s",IMAGE_FOLDER,FILE_TAGNAME,tNum,IMAGE_FILE_EXT);
00317 Image<float> tImg = Raster::ReadGray(tName);
00318
00319 currImg = tImg;
00320 float cMean = float(mean(currImg));
00321 float cStdev = float(stdev(currImg));
00322 currImg -= cMean;
00323 currImg /= cStdev;
00324 for(int i = 0; i< NUM_DIR; i++)
00325 currGaPyr[i] = buildPyrGabor(currImg,0,4,i*45,7,1,9,0);
00326
00327 ImageSet<float> tImgPyr = buildPyrGaussian(currImg, 0, 9, 3);
00328 Image<double> tData;
00329 Image<float> apa;
00330
00331 Image<float> res(tImgPyr[1].getWidth(), tImgPyr[1].getHeight(), ZEROS);
00332 for(int i = 0; i < tImgPyr[1].getWidth() - pW; i++)
00333 for(int j = 0; j < tImgPyr[1].getHeight() - pH; j++)
00334 {
00335 Rectangle a = Rectangle::tlbrI(j,i,j+pH-1,i+pW-1);
00336 getFeature(a, part, tData);
00337 ffn->run3L(tData);
00338 Image<double> ffnOut = ffn->getOutput();
00339 res.setVal(i+pW/2,j+pH/2,ffnOut[0]);
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 }
00357 XWinManaged *eWin = new XWinManaged(Dims(2*2*tImgPyr[1].getWidth(),
00358 2*tImgPyr[1].getHeight()),
00359 700,0,"TestImage");
00360 wList.add(*eWin);
00361 eWin->drawImage(tImg+(zoomXY(res, 2,-1)*255),0,0);
00362 eWin->drawImage(zoomXY(res, 2,-1),2*tImgPyr[1].getWidth(),0);
00363 Raster::waitForKey();
00364 }
00365
00366
00367 void fillEyeData
00368 (int start,
00369 std::vector<Image<double> > pData,
00370 std::vector<Image<double> > nData,
00371 int *pCt, int *nCt)
00372 {
00373 int pW = MODEL_EYE_WIDTH, pH = MODEL_EYE_HEIGHT;
00374 char iName[200],dName[200];
00375 int pCount = 0; int nCount = 0;
00376
00377
00378 for(int s = 0; s < NUM_TRAIN_SAMPLE/2; s++)
00379 {
00380 sprintf(iName, "%s%s%04d%s",
00381 IMAGE_FOLDER,FILE_TAGNAME,start+s,IMAGE_FILE_EXT);
00382 sprintf(dName, "%s%s%04d%s",
00383 DATA_FOLDER, FILE_TAGNAME,start+s,DATA_FILE_EXT );
00384 if(s%10 == 0)
00385 printf("setting up positive image %d\n",s);
00386
00387 currImg = Raster::ReadGray(iName);
00388 float cMean = float(mean(currImg));
00389 float cStdev = float(stdev(currImg));
00390 currImg -= cMean;
00391 currImg /= cStdev;
00392
00393 for(int i = 0; i< NUM_DIR; i++)
00394 currGaPyr[i] = buildPyrGabor(currImg,0,4,i*45,7,1,9,0);
00395
00396
00397 getEyeFeature(getPartRect(currImg, dName, L_EYE, 0),
00398 pData[pCount]);
00399 pCount++;
00400
00401
00402 getEyeFeature(getPartRect(currImg, dName, R_EYE, 0),
00403 pData[pCount]);
00404 pCount++;
00405 }
00406
00407
00408 Rectangle ler = getPartRect(currImg, dName, L_EYE, 0);
00409 Rectangle rer = getPartRect(currImg, dName, R_EYE, 0);
00410 int w = currImg.getWidth(), h = currImg.getHeight();
00411
00412
00413
00414 for (int i = w/5/2+5; i < 2*w/5-10; i+= pW/2)
00415 for(int j = 15; j < std::min(ler.top(),rer.top())-10;j+= pH)
00416 {
00417 getEyeFeature(Rectangle(Point2D<int>(i,j), Dims(pW, pH)),
00418 nData[nCount]); nCount++;
00419 }
00420
00421
00422 for (int i = w/5/2; i < 2*w/5-10; i+= pW/2)
00423 for(int j = std::max(ler.bottomI(),rer.bottomI())+5; j < h/2-pH; j+= pH)
00424 {
00425 getEyeFeature(Rectangle(Point2D<int>(i,j), Dims(pW, pH)),
00426 nData[nCount]); nCount++;
00427 }
00428
00429 *nCt = nCount;
00430 *pCt = pCount;
00431 printf("pCount: %d, nCount: %d \n", pCount, nCount);
00432 }
00433
00434
00435 void fillNoseData
00436 (int start,
00437 std::vector<Image<double> > pData,
00438 std::vector<Image<double> > nData,
00439 int *pCt, int *nCt)
00440 {
00441 int pW = MODEL_NOSE_WIDTH, pH = MODEL_NOSE_HEIGHT;
00442 char iName[200],dName[200];
00443 int pCount = 0; int nCount = 0;
00444
00445
00446 for(int s = 0; s < NUM_TRAIN_SAMPLE; s++)
00447 {
00448 sprintf(iName, "%s%s%04d%s",
00449 IMAGE_FOLDER,FILE_TAGNAME,start+s,IMAGE_FILE_EXT);
00450 sprintf(dName, "%s%s%04d%s",
00451 DATA_FOLDER, FILE_TAGNAME,start+s,DATA_FILE_EXT );
00452 if(s%10 == 0)
00453 printf("setting up positive image %d\n",s);
00454
00455 currImg = Raster::ReadGray(iName);
00456 float cMean = float(mean(currImg));
00457 float cStdev = float(stdev(currImg));
00458 currImg -= cMean;
00459 currImg /= cStdev;
00460 for(int i = 0; i< NUM_DIR; i++)
00461 currGaPyr[i] = buildPyrGabor(currImg,0,4,i*45,7,1,9,0);
00462
00463
00464 getNoseFeature(getPartRect(currImg, dName, NOSE, 0),
00465 pData[pCount]);
00466 pCount++;
00467 }
00468
00469
00470 Rectangle nr = getPartRect(currImg, dName, NOSE, 0);
00471 int w = currImg.getWidth(), h = currImg.getHeight();
00472
00473
00474 for (int i = w/5/2; i < 2*w/5; i+= pW/3)
00475 for(int j = 0; j < nr.top()-pH;j+= pH/2)
00476 {
00477 getNoseFeature(Rectangle(Point2D<int>(i,j), Dims(pW, pH)),
00478 nData[nCount]); nCount++;
00479 }
00480
00481
00482 for (int i = w/5/2; i < 2*w/5; i+= pW/2)
00483 for(int j = nr.bottomI(); j < h/2-pH; j+= pH/2)
00484 {
00485 getNoseFeature(Rectangle(Point2D<int>(i,j), Dims(pW, pH)),
00486 nData[nCount]); nCount++;
00487 }
00488
00489
00490 for (int i = w/5/2; i < nr.left()-10; i+= pW/2)
00491 for(int j = nr.top()-pH; j < nr.bottomI()+pH; j+= pH/2)
00492 {
00493 getNoseFeature(Rectangle(Point2D<int>(i,j), Dims(pW, pH)),
00494 nData[nCount]); nCount++;
00495 }
00496
00497
00498 for (int i = nr.rightI() + 5; i < 2*w/5; i+= pW/2)
00499 for(int j = nr.top()-pH; j < nr.bottomI()+pH; j+= pH/2)
00500 {
00501 getNoseFeature(Rectangle(Point2D<int>(i,j), Dims(pW, pH)),
00502 nData[nCount]); nCount++;
00503 }
00504 *nCt = nCount;
00505 *pCt = pCount;
00506 printf("pCount: %d, nCount: %d \n",pCount,nCount);
00507 }
00508
00509
00510 void fillMouthData
00511 ( int start,
00512 std::vector<Image<double> > pData,
00513 std::vector<Image<double> > nData,
00514 int *pCt, int *nCt)
00515 {
00516 int pW = MODEL_MOUTH_WIDTH, pH = MODEL_MOUTH_HEIGHT;
00517 char iName[200],dName[200];
00518 int pCount = 0; int nCount = 0;
00519
00520
00521 for(int s = 0; s < NUM_TRAIN_SAMPLE; s++)
00522 {
00523 sprintf(iName, "%s%s%04d%s",
00524 IMAGE_FOLDER,FILE_TAGNAME,start+s,IMAGE_FILE_EXT);
00525 sprintf(dName, "%s%s%04d%s",
00526 DATA_FOLDER, FILE_TAGNAME,start+s,DATA_FILE_EXT );
00527 if(s%10 == 0)
00528 printf("setting up positive image %d\n",s);
00529
00530 currImg = Raster::ReadGray(iName);
00531 float cMean = float(mean(currImg));
00532 float cStdev = float(stdev(currImg));
00533 currImg -= cMean;
00534 currImg /= cStdev;
00535 for(int i = 0; i< NUM_DIR; i++)
00536 currGaPyr[i] = buildPyrGabor(currImg,0,4,i*45,7,1,9,0);
00537
00538
00539 getMouthFeature(getPartRect(currImg, dName, MOUTH, 0),
00540 pData[pCount]);
00541 pCount++;
00542 }
00543
00544
00545 Rectangle mr = getPartRect(currImg, dName, MOUTH, 0);
00546 int w = currImg.getWidth(), h = currImg.getHeight();
00547
00548
00549 for (int i = w/5/2; i < 2*w/5; i+= pW/2)
00550 for(int j = 0; j < mr.top()-pH;j+= pH/2)
00551 {
00552 getMouthFeature(Rectangle(Point2D<int>(i,j), Dims(pW, pH)),
00553 nData[nCount]); nCount++;
00554 }
00555
00556
00557 for (int i = w/5/2; i < 2*w/5; i+= pW/2)
00558 for(int j = mr.bottomI(); j < h/2-pH; j+= pH/2)
00559 {
00560 getMouthFeature(Rectangle(Point2D<int>(i,j), Dims(pW, pH)),
00561 nData[nCount]); nCount++;
00562 }
00563
00564
00565 for (int i = w/5/2; i < mr.left()-10; i+= pW/2)
00566 for(int j = mr.top(); j < mr.bottomI(); j+= pH/2)
00567 {
00568 getMouthFeature(Rectangle(Point2D<int>(i,j), Dims(pW, pH)),
00569 nData[nCount]); nCount++;
00570 }
00571
00572
00573 for (int i = mr.rightI() + 5; i < 2*w/5; i+= pW/2)
00574 for(int j = mr.top(); j < mr.bottomI(); j+= pH/2)
00575 {
00576 getMouthFeature(Rectangle(Point2D<int>(i,j), Dims(pW, pH)),
00577 nData[nCount]); nCount++;
00578 }
00579
00580 *nCt = nCount;
00581 *pCt = pCount;
00582 printf("pCount: %d, nCount: %d \n",pCount,nCount);
00583 }
00584
00585
00586
00587 void getFeature(Rectangle r, FacePart part, Image<double> features)
00588 {
00589 switch(part)
00590 {
00591 case EYE: getEyeFeature (r, features); break;
00592 case NOSE: getNoseFeature (r, features); break;
00593 case MOUTH: getMouthFeature(r, features); break;
00594 default:
00595 LFATAL("Unknown face part");
00596 }
00597 }
00598
00599
00600
00601 void getEyeFeature(Rectangle r, Image<double> features)
00602 {
00603
00604
00605 int k = 0;
00606 Rectangle r2 =
00607 Rectangle::tlbrI(r.top()/2 , r.left()/2 ,
00608 r.top()/2+r.height()/2-1, r.left()/2+r.width()/2-1 );
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 int totalF1 = 24;
00625 int xF1[24] = { 4, 5, 6, 7, 4, 5, 6, 7, 0, 3, 8,11,
00626 0, 3, 8,11, 0, 3, 8,11, 0, 3, 8,11 };
00627 int yF1[24] = { 0, 0, 0, 0, 5, 5, 5, 5, 1, 1, 1, 1,
00628 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 };
00629
00630
00631
00632
00633
00634
00635
00636 int totalF2 = 8;
00637 int xF2[8] = { 2, 3, 0, 2, 3, 5, 2, 3 };
00638 int yF2[8] = { 0, 0, 1, 1, 1, 1, 2, 2 };
00639
00640
00641 for(int n = 0; n < NUM_DIR; n++)
00642 {
00643 for(int i = 0; i< totalF1; i++)
00644 {
00645 features[k] = double(currGaPyr[n][1].getVal(
00646 r.left()+xF1[i], r.top()+yF1[i]));
00647 k++;
00648 }
00649
00650 for(int i = 0; i< totalF2; i++)
00651 {
00652 features[k] = double(currGaPyr[n][2].getVal(
00653 r2.left()+xF2[i], r2.top()+yF2[i]));
00654 k++;
00655 }
00656 }
00657 }
00658
00659
00660
00661 void getNoseFeature(Rectangle r, Image<double> features)
00662 {
00663
00664
00665 int k = 0;
00666 Rectangle r2 =
00667 Rectangle::tlbrI(r.top()/2 , r.left()/2 ,
00668 r.top()/2+r.height()/2-1, r.left()/2+r.width()/2-1 );
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698 int totalF1 = 44;
00699 int xF1[44] = { 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7,
00700 3, 4, 5, 6, 7, 8, 9,10, 3,10, 3,10, 3,10, 3,10, 3, 4, 5, 6,
00701 7, 8, 9,10 };
00702 int yF1[44] = { 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,11,11,
00703 12,12,12,12,12,12,12,12,13,13,14,14,15,15,16,16,17,17,17,17,
00704 17,17,17,17 };
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719 int totalF2 = 17;
00720 int xF2[17] = { 3, 3, 3, 3, 3, 1, 2, 3, 4, 5, 1, 5, 1, 2, 3, 4, 5 };
00721 int yF2[17] = { 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 8 };
00722
00723
00724 for(int n = 0; n < NUM_DIR; n++)
00725 {
00726 for(int i = 0; i< totalF1; i++)
00727 {
00728 features[k] = double(currGaPyr[n][1].getVal(
00729 r.left()+xF1[i], r.top()+yF1[i]));
00730 k++;
00731 }
00732
00733 for(int i = 0; i< totalF2; i++)
00734 {
00735 features[k] = double(currGaPyr[n][2].getVal(
00736 r2.left()+xF2[i], r2.top()+yF2[i]));
00737 k++;
00738 }
00739 }
00740 }
00741
00742
00743
00744 void getMouthFeature(Rectangle r, Image<double> features)
00745 {
00746
00747
00748 int k = 0;
00749 Rectangle r2 =
00750 Rectangle::tlbrI(r.top()/2 , r.left()/2 ,
00751 r.top()/2+r.height()/2-1, r.left()/2+r.width()/2-1 );
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 int totalF1 = 32;
00771 int xF1[32] = { 2, 7, 8, 9,10,11,12,17, 2, 9,10,17, 2, 9,10,17,
00772 2, 9,10,17, 2, 9,10,17, 2, 7, 8, 9,10,11,12,17 };
00773 int yF1[32] = { 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
00774 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7 };
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784 int totalF2 = 16;
00785 int xF2[16] = { 1, 3, 4, 5, 6, 8, 1, 4, 5, 8, 1, 3, 4, 5, 6, 8 };
00786 int yF2[16] = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3 };
00787
00788
00789 for(int n = 0; n < NUM_DIR; n++)
00790 {
00791 for(int i = 0; i< totalF1; i++)
00792 {
00793 features[k] = double(currGaPyr[n][1].getVal(
00794 r.left()+xF1[i], r.top()+yF1[i]));
00795 k++;
00796 }
00797
00798 for(int i = 0; i< totalF2; i++)
00799 {
00800 features[k] = double(currGaPyr[n][2].getVal(
00801 r2.left()+xF2[i], r2.top()+yF2[i]));
00802 k++;
00803 }
00804 }
00805 }
00806
00807
00808 Rectangle getPartRect(char* iName, char* dName, FacePart part, int opp)
00809 {
00810 Image<float> img = Raster::ReadGray(iName);
00811 return getPartRect(img, dName, part, opp);
00812 }
00813
00814
00815 Rectangle getPartRect(Image <float> img, char* dName, FacePart part, int opp)
00816 {
00817 int top = 0, bot = 0, left = 0, right = 0, width = 0, height = 0;
00818
00819 switch(part)
00820 {
00821 case EYE:
00822 top = NUM_HEADER_LINE + RE_TOP;
00823 bot = NUM_HEADER_LINE + RE_BOTTOM;
00824 left = NUM_HEADER_LINE + RE_LEFT;
00825 right = NUM_HEADER_LINE + RE_RIGHT;
00826 width = MODEL_EYE_WIDTH;
00827 height = MODEL_EYE_HEIGHT;
00828 break;
00829 case NOSE:
00830 top = NUM_HEADER_LINE + N_TOP;
00831 bot = NUM_HEADER_LINE + N_BOTTOM;
00832 left = NUM_HEADER_LINE + N_LEFT;
00833 right = NUM_HEADER_LINE + N_RIGHT;
00834 width = MODEL_NOSE_WIDTH;
00835 height = MODEL_NOSE_HEIGHT;
00836 break;
00837 case MOUTH:
00838 top = NUM_HEADER_LINE + M_TOP;
00839 bot = NUM_HEADER_LINE + M_BOTTOM;
00840 left = NUM_HEADER_LINE + M_LEFT;
00841 right = NUM_HEADER_LINE + M_RIGHT;
00842 width = MODEL_MOUTH_WIDTH;
00843 height = MODEL_MOUTH_HEIGHT;
00844 break;
00845 case L_EYE:
00846 top = NUM_HEADER_LINE + LE_TOP;
00847 bot = NUM_HEADER_LINE + LE_BOTTOM;
00848 left = NUM_HEADER_LINE + LE_LEFT;
00849 right = NUM_HEADER_LINE + LE_RIGHT;
00850 width = MODEL_EYE_WIDTH;
00851 height = MODEL_EYE_HEIGHT;
00852 break;
00853 case R_EYE:
00854 top = NUM_HEADER_LINE + RE_TOP;
00855 bot = NUM_HEADER_LINE + RE_BOTTOM;
00856 left = NUM_HEADER_LINE + RE_LEFT;
00857 right = NUM_HEADER_LINE + RE_RIGHT;
00858 width = MODEL_EYE_WIDTH;
00859 height = MODEL_EYE_HEIGHT;
00860 break;
00861 default:
00862 LFATAL("Unknown face part");
00863 }
00864
00865
00866 if(img.getWidth() == 0)
00867 LFATAL("Image not found");
00868 int w = img.getWidth(), h = img.getHeight();
00869
00870
00871 FILE *fp; char input[100];
00872
00873
00874
00875 if((fp = fopen(dName,"rb")) == NULL)
00876 LFATAL("data file not found");
00877
00878 int temp, temp2, xT, yT; int xL, yL; int xB, yB; int xR, yR;
00879
00880
00881 fseek (fp, 0, SEEK_SET);
00882 for(int i = 0; i<= top; i++) if (fgets(input, 1000, fp) == NULL) LFATAL("fgets failed");
00883 sscanf(input, "point %d = [ %d, %d], index = %d", &temp, &xT, &yT, &temp2);
00884
00885
00886 fseek (fp, 0, SEEK_SET);
00887 for(int i = 0; i<= left; i++) if (fgets(input, 1000, fp) == NULL) LFATAL("fgets failed");
00888 sscanf(input, "point %d = [ %d, %d], index = %d", &temp, &xL, &yL, &temp2);
00889
00890
00891 fseek (fp, 0, SEEK_SET);
00892 for(int i = 0; i<= bot; i++) if (fgets(input, 1000, fp) == NULL) LFATAL("fgets failed");
00893 sscanf(input, "point %d = [ %d, %d], index = %d", &temp, &xB, &yB, &temp2);
00894
00895
00896 fseek (fp, 0, SEEK_SET);
00897 for(int i = 0; i<= right; i++) if (fgets(input, 1000, fp) == NULL) LFATAL("fgets failed");
00898 sscanf(input, "point %d = [ %d, %d], index = %d", &temp, &xR, &yR, &temp2);
00899
00900 fclose(fp);
00901
00902
00903 switch(part)
00904 {
00905 case EYE: case MOUTH: case L_EYE: case R_EYE:break;
00906 case NOSE:
00907 if(xB > xL) xL = xB;
00908 if(xB < xR) xR = xB;
00909 if(yB > std::min(yL,yR)) yB = std::min(yL,yR);
00910 break;
00911 default:
00912 LFATAL("Unknown face part");
00913 }
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924 int t = 0, b = 0, l = 0, r = 0;
00925 t = (h - yT + h - yB)/4 - height/2 ;
00926 l = (xL + xR)/4 - width/2 ;
00927 b = (h - yT + h - yB)/4 + height/2 - 1;
00928 r = (xL + xR)/4 + width/2 - 1;
00929
00930
00931 if(opp)
00932 {
00933 Rectangle box =
00934 Rectangle::tlbrI(t - height/2, l - width/2, b + height/2, r + width/2);
00935
00936
00937
00938
00939
00940 int xRand, yRand;
00941 xRand = int(rand()/(RAND_MAX + 1.0) * (w/2 - width - 1));
00942 yRand = int(rand()/(RAND_MAX + 1.0) * (h/2 - height - 1));
00943
00944 Rectangle lFace =
00945 Rectangle::tlbrI(0,0 ,h/2,w/5/2);
00946 Rectangle rFace =
00947 Rectangle::tlbrI(0,4*w/5/2,h/2,w/2 );
00948
00949 while(within(box , xRand, yRand)||
00950 within(lFace, xRand, yRand)||
00951 within(rFace, xRand, yRand) )
00952 {
00953 xRand = int(rand()/(RAND_MAX + 1.0) * (w/2 - width - 1));
00954 yRand = int(rand()/(RAND_MAX + 1.0) * (h/2 - height - 1));
00955
00956 }
00957
00958 Rectangle res =
00959 Rectangle::tlbrI(yRand, xRand, yRand+height - 1, xRand+width - 1);
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969 return res;
00970 }
00971
00972 Rectangle res = Rectangle::tlbrI(t,l,b,r);
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983 return res;
00984
00985 }
00986
00987
00988 bool within(Rectangle r, int x, int y)
00989 {
00990
00991
00992 return (x >= r.left() && x <= r.rightI() &&
00993 y >= r.top() && y <= r.bottomI() );
00994 }
00995
00996
00997 Image<float> getPartImage(char* iName, Rectangle pr)
00998 {
00999 Image<float> img = Raster::ReadGray(iName);
01000 return getPartImage(img,pr);
01001 }
01002
01003
01004
01005
01006 XWinManaged *iWin;
01007 XWinManaged *gaWin[NUM_DIR][3];
01008 int start_win = 1;
01009 Image<float> getPartImage(Image<float> img, Rectangle pr)
01010 {
01011 int w = img.getWidth(), h = img.getHeight();
01012 ImageSet<float> gPyr = buildPyrGaussian(img, 0, 9, 3);
01013 Image<float> resMap;
01014 resMap = crop(gPyr[1],pr);
01015
01016
01017
01018 if(start_win == 1)
01019 {
01020 iWin = new XWinManaged(Dims(w*2,h),700,700,"Image"); wList.add(*iWin);
01021
01022 }
01023
01024 float min, max;
01025 getMinMax(gPyr[1], min,max);
01026 drawRect(gPyr[1], pr, max, 1);
01027 iWin->drawImage(zoomXY(gPyr[1], 2,-1),0,0);
01028 iWin->drawImage(zoomXY(resMap,8,-1),w,0);
01029
01030
01031
01032 Image<float> temp;
01033 for(int i = 0; i < NUM_DIR; i++)
01034 for(int j = 1; j < 4; j++)
01035 {
01036 if(start_win == 1)
01037 gaWin[i][j-1] = new XWinManaged(img.getDims(),i*w,j*h,"imgL");
01038 temp = zoomXY(currGaPyr[i][j],int(pow(2.0,j-1)),-1);
01039 temp = crop(temp,pr);
01040
01041 gaWin[i][j-1]->drawImage(zoomXY(temp,8,-1),0,0);
01042 }
01043 start_win = 0;
01044 Raster::waitForKey();
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075 return resMap;
01076 }
01077
01078
01079
01080 void printRegion(Image<float> img,int sX,int eX,int dX, int sY,int eY, int dY)
01081 {
01082 for(int j = sY; j<=eY; j+=dY)
01083 {
01084 for(int i = sX; i<=eX; i+=dX)
01085 printf("%8.3f ", img.getVal(i,j));
01086 printf(" \n");
01087 }
01088 printf("\n");
01089 }
01090
01091
01092
01093
01094
01095