📄 ms.cpp
字号:
//-----------------------------------------------------------------------------// Return the name of the next input file// Returns NULL when no more filesstatic const char *sNextInputFile (int &argc, const char **pArgv[], // io const int nWantedImages, // in const char sTagRegExp[], // in unsigned Mask1, unsigned Mask2, // in: only read matrices where Attr&Mask1 == Mask2 (Attr is hex part of tag string) int nSeed, // in: 0 means no random selection; any other val select randomly with rand seed=nSeed const char sShapeFile[]) // in{const char *sFile = NULL;// process files specified directly on the command lineif (argc) { sFile = (**pArgv); (*pArgv)++; argc--; }// process files in sRefShapeFile matching sTagRegExpelse if (sTagRegExp[0]) { static int iFile = -1; static StringVec TagStrings; static char sDirs[SLEN]; if (iFile == -1) // need to read shapes file? { int nShapes = TagStrings.size(); ReadSelectedShapes(NULL, TagStrings, sDirs, nWantedImages, sTagRegExp, Mask1, Mask2, nSeed, NULL, sShapeFile, QUIET); logprintf(" [%.2f secs]", (double)(clock() - gTime) / CLOCKS_PER_SEC); lprintf("\n"); iFile = 0; } if (iFile < TagStrings.size()) { const char *sBase = &(TagStrings[iFile].c_str()[FNAME_OFFSET]); sFile = sGetFilenameGivenDirs(sDirs, sBase); if (sFile == NULL) Err("Can't open %s (searched in directories %s)", sBase, sDirs); iFile++; } }return sFile;}//-----------------------------------------------------------------------------static bool fGetStartShape1 (SHAPE &StartShape, // out int iModel, // in bool fBrief, // in bool fViolaJones, // in bool fViolaJonesEyes, // in bool fUseRefShapeIfNoDetFace,// in Image &Img, // in const char sImageFile[], // in const char sImageBase[], // in const SHAPE &ModelMeanShape, // in const SHAPE &CombinedShapeFromPreviousSearch, // in const char sDataDir[], // in const char *sRefShapeFile, // in const SHAPE *pRefShape) // in{bool fSuccess = true;if (iModel == 0) { clock_t Time = clock(); SHAPE DetShape; // shape returned by Viola Jones or Rowley global detector fSuccess = fGetStartShape(StartShape, DetShape, fgBrief, fViolaJones, fViolaJonesEyes, fUseRefShapeIfNoDetFace, Img, sImageFile, sImageBase, ModelMeanShape, sDataDir, sRefShapeFile, pRefShape); if (fSuccess) { bprintf(fgBrief, "Got start shape [%.2f secs]\n", (double)(clock() - Time) / CLOCKS_PER_SEC); if ((gImageBits & IM_FaceDetShape) != 0) // show images and shapes for debugging? { RgbImage RgbImg(Img); DrawShape(RgbImg, StartShape, C_RED, 1.0, CONF_fConnectDots, IM_NO_ANNOTATE, IM_NO_WHISKERS, 0, IM_TRANSPARENT); DrawShape(RgbImg, DetShape, C_YELLOW, 1.0, CONF_fConnectDots, IM_NO_ANNOTATE, IM_NO_WHISKERS, 0, IM_TRANSPARENT); if (pRefShape) DrawShape(RgbImg, *pRefShape, C_YELLOW, 1.0, IM_NO_CONNECT_DOTS, IM_NO_ANNOTATE, IM_NO_WHISKERS, 0, IM_TRANSPARENT); char sPath[SLEN]; sprintf(sPath, "%s/Init_%s.bmp", CONF_sOutDir, sImageBase); WriteBmp(RgbImg, sPath); } } }else // iModel>0, use previous model's result { if (ModelMeanShape.nrows() == CombinedShapeFromPreviousSearch.nrows()) StartShape = CombinedShapeFromPreviousSearch; else if (ModelMeanShape.nrows() < CombinedShapeFromPreviousSearch.nrows()) { StartShape = CombinedShapeFromPreviousSearch; StartShape.dimKeep(ModelMeanShape.nrows(), 2); } else // ModelMeanShape.nrows() > CombinedShapeFromPreviousSearch.nrows() { // The following method is found to give good results and is what is coded below: // Use points from CombinedShapeFromPreviousSearch where possible. // Where a point is unused in CombinedShapeFromPreviousSearch use the point from the aligned ModelMeanShape instead. StartShape = ModelMeanShape; SHAPE Combined1(CombinedShapeFromPreviousSearch); Combined1.dimKeep(ModelMeanShape.nrows(), 2); AlignShape(StartShape, Combined1); for (int iRow = 0; iRow < CombinedShapeFromPreviousSearch.nrows(); iRow++) if (fPointUsed(StartShape, iRow)) StartShape.row(iRow) = CombinedShapeFromPreviousSearch.row(iRow); } SetUnusedPointsToZero(StartShape, ModelMeanShape); }return fSuccess;}//-----------------------------------------------------------------------------int __cdecl main (int argc, const char *argv[]){char sUseMsMinusQForHelp[] = "Use ms -? for help.";char sRefShapeFile[PLEN]; sRefShapeFile[0] = 0;char sModel[SLEN]; sModel[0] = 0;bool fAppendToLog = false;bool fViolaJones = false; // -v flagbool fViolaJonesEyes = false; // -ve flagbool fGenFeatsFlag = false;bool fSkipIfGlobalDetectorFails = false;char sTagRegExp[SLEN]; sTagRegExp[0] = 0;unsigned AttrMask1=0, AttrMask2=0;int nWantedImages = 0;int nSeed = 1; // -nr N command line flag: 0 means no random selection; any other val select randomly with rand seed=nSeedgTime = clock();int nModels = 0; // will increment for each use of the -m flagtAsmModel Model[CONF_nMaxModels];InitMallocDebug();// read the arguments: ms [FLAGS] IMAGEwhile (--argc > 0 && (*++argv)[0] == '-') switch (*(*argv + 1)) { case 'n': GetOptInt(&argc, &argv, 'n', "ir", &nWantedImages, 1, 0, 10000, // -ni &nSeed, 1, 0, 1000); // -nr break; case 'f': GetOptBool(&argc, &argv, 'f', "ab", &fAppendToLog, // -a &fgBrief); // -b break; case 'x': GetOptHex(&argc, &argv, 'x', "i", &gImageBits, 1, 0, 0x3ff); // -xi, see defs for IM_ in header of this file break; case 'm': // -a asm file argv++; argc--; if (argc < 1) Err("-m needs an argument. %s", sUseMsMinusQForHelp); if (nModels >= CONF_nMaxModels) Err("You can specify up to %d models with -m. %s", CONF_nMaxModels, sUseMsMinusQForHelp); strcpy(Model[nModels++].sFile, *argv); break; case 'p': // shape pattern filter argv++; argc--; if (argc < 1) Err("-p needs an argument. %s", sUseMsMinusQForHelp); strcpy(sTagRegExp, *argv); break; case 'P': // shape mask filter argv++; argc--; if (argc < 1 || 1 != sscanf(*argv, "%x", &AttrMask1)) Err("-P needs two hex number arguments. %s", sUseMsMinusQForHelp); argv++; argc--; if (argc < 1 || 1 != sscanf(*argv, "%x", &AttrMask2)) Err("-P needs two hex number arguments. %s", sUseMsMinusQForHelp); break; case 'r': // -r reference file argv++; argc--; if (argc < 1) Err("-r needs an argument. %s", sUseMsMinusQForHelp); strcpy(sRefShapeFile, *argv); break; case 's': // -s suffix/prefix argv++; argc--; if (argc < 1) Err("-s needs an argument. %s", sUseMsMinusQForHelp); strcpy(sModel, *argv); break; case 'v': // -v use viola jones global face detector fViolaJones = true; if (*(*argv + 2) == 'e') // -ve ... with Rowley eyes fViolaJonesEyes = true; break; case 'G': // -G generate feature data for post analysis fGenFeatsFlag = true; break; case 'S': fSkipIfGlobalDetectorFails = true; break; case '?': Err(sgUsage, CONF_MsLogFilename); break; default: Err("Unrecognized option %s. %s", *argv, sUseMsMinusQForHelp); break; }if (argc < 1 && sTagRegExp[0] == 0) // need at least one image file Err("No image file. Use ms -? for help.");if (nModels == 0) Err("No -m flag specifying model file. Use ms -? for help.");if (sTagRegExp[0] && (sRefShapeFile[0] == 0)) Err("You can't use -p without specifying a reference file (use -r)");if (gImageBits) fCreateDirectory(CONF_sOutDir);if (gImageBits & IM_AllImages) { gImageBits &= ~IM_FinalImageOnly; // IM_AllImages supercedes IM_FinalImageOnly gImageBits |= IM_FaceDetShape; // ...and includes IM_FaceDetShape }if (gImageBits & IM_DoubleScale) gImageBits &= ~IM_FullScale; // IM_DoubleScale supercedes IM_FullScaleInit(VERBOSE, fAppendToLog, CONF_MsLogFilename); // open log file etc.lprintf("ms version 1.5\n");InitAsmsForSearch(Model, nModels, gImageBits);#if 0GenerateCFileFromAsmModel(Model[1]); // generate a C file of asm model#endifif (fViolaJones) Model[0].StartMethod = SM_UseViolaJones;ngModels = nModels;if (sRefShapeFile[0]) lprintf("RefShapeFile %s", sRefShapeFile);lprintf("\n");if (sModel[0]) // -s flag used? OpenDatFile(sRefShapeFile, sModel);InitGenFeat(fGenFeatsFlag, Model[0], sRefShapeFile, nModels);int nInFiles = 0;clock_t StartTime = clock();const char *sInFile;while (sInFile = sNextInputFile(argc, &argv, nWantedImages, sTagRegExp, AttrMask1, AttrMask2, nSeed, sRefShapeFile)) { sprintf(sgModel, "%s ", sModel); gTime = clock(); nInFiles++; char sImageOut[SLEN], sImagePath[PLEN], sImageBase[SLEN]; GenFileNames(sImageOut, sImagePath, sImageBase, sInFile, sModel); // read the image Image Img; if (sModel[0]) bprintf(fgBrief, "%s ", sgModel); sLoadImage(Img, sImagePath, !fgBrief); pgCurImageName = sImageBase; // for debugging // get RefShape, if user specified sRefShapeFile on command line with -r SHAPE RefShape(Model[0].nPoints, 2); // for comparing results against a known shape SHAPE *pRefShape = NULL; if (sRefShapeFile[0]) { GetRefShape(RefShape, sRefShapeFile, sImageBase, Model[0].nPoints); // this also inits igLandmarks and gLandTab pRefShape = &RefShape;#if CONF_fPrintFaceWidth lprintf("\nFaceWidth %.2f ", (*pRefShape)(MRJaw2, VX) - (*pRefShape)(MLJaw2, VX));#endif } else InitLandTabs(Model[0].nPoints, Model[0].nPoints); // init igLandmarks and gLandTab TODO tidy this up const tLand *pLands = pSelectLand(Model[0].nPoints); // landmark information SHAPE CombinedShape; // Best shape, created by combining shapes from each model search // CombinedShape size is size of Model[0].FileMeanShape, so // if Model[1] has extra points they are discarded in CombineModelSearchResults() for (int iModel = 0; iModel < nModels; iModel++) { int nStartLev; char sImageBase1[SLEN]; if (iModel == 0) { strcpy(sImageBase1, sImageBase); strcpy(sgImageOut, sImageOut); } else // append model number to names { sprintf(sImageBase1, "%s%d", sImageBase, iModel); sprintf(sgImageOut, "%s%d", sImageOut, iModel); } if (nModels > 0) sprintf(sgModel, "%s-mod%d", sModel, iModel); fgExplicitPrevNext = Model[iModel].fExplicitPrevNext; gNormalizedProfLen = Model[iModel].NormalizedProfLen; // init Shape to a good starting point for the search SHAPE Shape; bool fGotStartShape = fGetStartShape1(Shape, iModel, fgBrief, fViolaJones, fViolaJonesEyes, !fSkipIfGlobalDetectorFails, Img, sImagePath, sImageBase, Model[iModel].FileMeanShape, CombinedShape, "../../stasm/stasm/data", sRefShapeFile, pRefShape); if (!fGotStartShape) if (fSkipIfGlobalDetectorFails) { lprintf("Warning: can't get start shape from global face detector, skipping %s\n", sImageBase); nInFiles--; break; } else Err("Can't get start shape from global face detector"); double OrgFaceWidth; if (iModel == 0) OrgFaceWidth = Shape(MRJaw2, VX) - Shape(MLJaw2, VX); Image Img1; SHAPE Shape1, RefShape1; // rescale Img--->Img1 Shape--->Shape1 *pRefShape--->RefShape1, and set the global gImagePreScale PrescaleImageBaseRefShapes(Img1, Shape1, RefShape1, Img, Shape, pRefShape, OrgFaceWidth, Model[iModel].FileMeanShape, Model[iModel].nScaledFaceWidth, Model[iModel].fBilinearRescale); if (CONF_fEqualizeImages) //TODO should only do if iModel==0? EqualizeImageForSearch(Img1, Shape1, sImageBase1); Shape1.dimKeep(Model[iModel].nPoints, 2); // needed if iModel has a different number of landmarks to previous iModel SetUnusedPointsToZero(Shape1, Model[iModel].AsmLevs[0].MeanShape); if (pRefShape) { SetUnusedPointsToZero(RefShape1, Model[iModel].AsmLevs[0].MeanShape); PrintStartShapeStats(Shape1, RefShape1); #if CONF_fMeasureRefAgainstModel MeasureRefAgainstModel(RefShape1, Model[iModel], sImageBase, Img1); #endif LogInterEyeDist(sImageBase, &RefShape1); } if (fGenFeats() || CONF_fDebug1dProfs || CONF_fDebug2dProfs) { // lprintf("fGenFeats || CONF_fDebug1dProfs || CONF_fDebug2dProfs: forcing nStartLev=0\n"); nStartLev = 0; } else nStartLev = Model[iModel].nStartLev;#if CONF_fSelfEvaluate if (iModel == 0) ngStartLev = nStartLev;#endif ShapeSearchWrapper1(Shape1, Img1, Model[iModel], (pRefShape? &RefShape1: NULL), pLands, sImageBase1, nStartLev); PostSearch(CombinedShape, Model[iModel], iModel, nModels, Shape1, sImageBase, nInFiles, StartTime, (pRefShape? &RefShape1: NULL), Img1, sModel, sImageOut); CombinedShape = CombinedShape / gImagePreScale; // descale for next iteration } // end for iModel }FreeNetworks();CloseViolaJones();LogInterEyeDist();CloseDatFile();Shutdown();return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -