📄 marki.cpp
字号:
RECT RectWorkArea;SystemParametersInfo(SPI_GETWORKAREA, 0, &RectWorkArea, 0);if (xPos < RectWorkArea.left) xPos = RectWorkArea.left;if (yPos < RectWorkArea.top) yPos = RectWorkArea.top;if (xSize > RectWorkArea.right - RectWorkArea.left) xSize = RectWorkArea.right - RectWorkArea.left;if (ySize > RectWorkArea.bottom - RectWorkArea.top) ySize = RectWorkArea.bottom - RectWorkArea.top;if (xDlg < RectWorkArea.left) xDlg = RectWorkArea.left;if (yDlg < RectWorkArea.top) yDlg = RectWorkArea.top+50;*pxPos = xPos;*pyPos = yPos;*pxSize = xSize;*pySize = ySize;*pxDlg = xDlg;*pyDlg = yDlg;}//-----------------------------------------------------------------------------static void SaveStateToRegistry (HWND hMainWnd, HWND hDlgWnd){RECT rectMain, rectDlg;HKEY hKey;DWORD dwDispo;char sRegValue[SLEN];GetWindowRect(hMainWnd, &rectMain);GetWindowRect(hDlgWnd, &rectDlg);sprintf(sRegValue, "%ld %ld %ld %ld %d %d %d %d %d %d", rectMain.left, rectMain.top, rectMain.right-rectMain.left, rectMain.bottom-rectMain.top, igCrop, fgAutoNext, fgEqualize, fgConnectDots, rectDlg.left, rectDlg.top);lprintf("Saving state to registry: HKEY_CURRENT_USER Key \"%s\" Name \"%s\"\n", sgRegistryKey, sgRegistryName);// no point in checking return values in func calls belowRegCreateKeyEx(HKEY_CURRENT_USER, sgRegistryKey, 0, "", 0, KEY_ALL_ACCESS, NULL, &hKey, &dwDispo);RegSetValueEx(hKey, sgRegistryName, 0, REG_SZ, (CONST BYTE *)sRegValue, strlen(sRegValue)+1);RegCloseKey(hKey);}//-----------------------------------------------------------------------------static void WmSize (HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam){ngMaiwidth = LOWORD(lParam);ngMaiheight = HIWORD(lParam);SendMessage(hgToolbar, TB_AUTOSIZE, 0, 0L);}//-----------------------------------------------------------------------------// display a tooltip TODO not workingstatic void WmNotify (HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam){LPNMHDR pnmh = (LPNMHDR)lParam;if (pnmh->code == TTN_NEEDTEXT) { LPTOOLTIPTEXT pToolTipText = (LPTOOLTIPTEXT)lParam; int iButton = pToolTipText->hdr.idFrom - IDM_FirstInToolbar; LPSTR pDest = pToolTipText->lpszText; strcpy(pDest, sgTooltips[iButton]); }}//-----------------------------------------------------------------------------static bool fPointMarked (int iImage, int iPoint){return gShapesOrg[iImage](iPoint, VX) != gShapes[iImage](iPoint, VX) || gShapesOrg[iImage](iPoint, VX) != gShapes[iImage](iPoint, VX);}//-----------------------------------------------------------------------------static void __cdecl Msg (char *pArgs, ...){va_list pArg;char sMsg[1000]; // big enough for my stringsva_start(pArg, pArgs);vsprintf(sMsg, pArgs, pArg);va_end(pArg);lprintf("Msg: %s\n", sMsg);MessageBox(hgMainWnd, sMsg, sgProgramName, MB_OK);}//-----------------------------------------------------------------------------#define MA_NO_SHOW_ERR 0 // values for fShowErr#define MA_SHOW_ERR 1static char *sLoadCurrentImage (bool fShowErr){int ix, iy;char *sErrMsg = NULL;sErrMsg = sLoadImageGivenDirs(gImg, sgImageDirs, &gTagStrings[igImage].c_str()[FNAME_OFFSET], QUIET, NO_EXIT_ON_ERR);int width = gImg.width, height = gImg.height;if (sErrMsg) { Err(sErrMsg); PostQuitMessage(0); // calling this here is not quite right but does the job }else if (width % 4) //TODO may not need this, cropping below takes care of it, need to test { Err("Width of image is not divisible by 4 (limitation of this program, sorry)"); PostQuitMessage(0); }else { if (fgEqualize) QuickEqualizeRgbImage(gImg);#if USE_SHAPE_FILE ASSERT(igLandmark >= 0 && igLandmark < ngPoints); if (!fPointUsed(gShapesOrg[igImage], igLandmark)) { // landmark is unused#if 1 // Just print a message // The user will see the face centered on 0,0 on the screen so should be alerted by that lprintf("Current landmark %d unused in %s\n", igLandmark, &gTagStrings[igImage].c_str()[FNAME_OFFSET]);#else // search for a good landmark to use instead TODO is this really what we want to do? int iOldLandmark = igLandmark; for (int i = 0; i < gShapesOrg[igImage].nrows(); i++) { if (++igLandmark == gShapesOrg[igImage].nrows()) igLandmark = 0; if (fPointUsed(gShapesOrg[igImage], igLandmark)) break; } ASSERT(fPointUsed(gShapesOrg[igImage], igLandmark)); Msg("Current landmark %d unused in %s\nChanging to landmark %d instead", iOldLandmark, &gTagStrings[igImage].c_str()[FNAME_OFFSET], igLandmark);#endif } DrawShape(gImg, gShapes[igImage], C_DRED, 1.0, fgConnectDots, IM_NO_ANNOTATE, IM_NO_WHISKERS, 0, IM_NO_TRANSPARENT, NULL, NULL, IM_NO_DRAW_CIRCLES, C_YELLOW); // draw old mark in bright red ix = int(gShapesOrg[igImage](igLandmark, VX) + 0.5); // matches code in DrawShape() iy = int(gShapesOrg[igImage](igLandmark, VY) + 0.5); if (gShapes[igImage](igLandmark, VX) == 0 && gShapes[igImage](igLandmark, VY) == 0) // point deleted? SetImagePoint(gImg, 0xc0, 0x80, 0, ix, iy); // point deleted, 0xc0 0x80 0 is orange else SetImagePoint(gImg, 0xff, 0, 0, ix, iy); // 0xff 0 0 is red // draw new mark in cyan for (int iPoint = 0; iPoint < ngPoints; iPoint++) if (fPointMarked(igImage, iPoint)) { ix = int(gShapes[igImage](iPoint, VX) + 0.5); // matches code in DrawShape() iy = int(gShapes[igImage](iPoint, VY) + 0.5); if (ix != 0 || iy != 0) SetImagePoint(gImg, 0x00, 0xff, 0xff, ix, iy); // 0x00 0xff 0xff is cyan }#endif // Possibly crop the image, depending on user setting of igCrop SHAPE *pShape = &gShapes[igImage]; switch (igCrop) { case 0: // don't crop igTopCrop = igBottomCrop = igRightCrop = igLeftCrop = 0; break; case 1: {#if USE_SHAPE_FILE // put igLandmark in the center of the window // DASSERT(fPointUsed(gShapesOrg[igImage], igLandmark)); ix = (*pShape)(igLandmark, VX) + width/2; // change shape coords to window coords iy = height/2 + (*pShape)(igLandmark, VY); igTopCrop = __max(0, height - iy - height/6); igBottomCrop = __max(0, iy - height/6); igLeftCrop = __max(0, ix - width/6); igRightCrop = __max(0, width - ix - width/6);#else // crop top and sides: for working on lower half of image if (width > 400) { igTopCrop = height/2; igBottomCrop = height/4; igRightCrop = width/3; igLeftCrop = width/3; } else { igTopCrop = height/3; igBottomCrop = 0 igRightCrop = 0; igLeftCrop = 0; }#endif } break; case 2: {#if USE_SHAPE_FILE // expand whole face to fit window // iPupilDist gives an estimate of how much extra space to leave horizontally int iPupilDist = (*pShape)(MREye, VX) - (*pShape)(MLEye, VX); igTopCrop = __max(height/2 - (*pShape)(MLInnerTopEyeBrow, VY) - 25, 0); // a bit extra for toolbar igBottomCrop = __max(height/2 + (*pShape)(MTipOfChin, VY) - 5, 0); igLeftCrop = __max(width/2 + (*pShape)(MLEyeOuter, VX) - iPupilDist/2, 0); igRightCrop = __max(width/2 - (*pShape)(MREyeOuter, VX) - iPupilDist/2, 0);#else // crop bottom and sides: for working on upper half of image // magic numbers below optimized for M3 files and images already cropped by masm -fw if (width > 400) { igTopCrop = height/4; igBottomCrop = height/4; igRightCrop = width/4; igLeftCrop = width/4; } else { igTopCrop = 0; igBottomCrop = height/4; igRightCrop = 0; igLeftCrop = 0; }#endif break; } default: SysErr("LoadCurrentImage %d", igCrop); break; } CropRgbImage(gImg, igTopCrop, igBottomCrop, igLeftCrop, igRightCrop, QUIET, IM_WIDTH_DIVISIBLE_BY_4); }return sErrMsg;}//-----------------------------------------------------------------------------// YesNoMsg returns true for YESstatic BOOL __cdecl fYesNoMsg (bool fDefaultYes, char *pArgs, ...){va_list pArg;char sMsg[1000]; // big enough for my stringsva_start(pArg, pArgs);vsprintf(sMsg, pArgs, pArg);va_end(pArg);char sFirstLineOfMsg[SLEN];char *pDest = strchr(sMsg, '\n');if (pDest) strncpy(sFirstLineOfMsg, sMsg, pDest - sMsg); //TODO can print garbage?else strcpy(sFirstLineOfMsg, sMsg);lprintf("YesNoMsg: %s ", sFirstLineOfMsg);// use NULL for hwnd and not hgMainWnd because this may be called after hgMainWnd is closedint iAnswer = MessageBox(NULL, sMsg, sgProgramName, MB_YESNO|MB_ICONQUESTION|(fDefaultYes? 0: MB_DEFBUTTON2));lprintf("%s\n", (iAnswer == IDYES? "YES": "NO"));return IDYES == iAnswer;}//-----------------------------------------------------------------------------static void DisplayImageNbr (void){char s[SLEN];sprintf(s, "%d", igImage);SetDlgItemText(hgDlgWnd, IDC_IMAGE_NBR, s);}//-----------------------------------------------------------------------------static void IdmNext (void){if (++igImage > ngImages - 1) { if (fgChug) fgChug = false; else Msg("Looped to first shape"); igImage = 0; }DisplayImageNbr();}//-----------------------------------------------------------------------------static void IdmPrev (void){if (--igImage < 0) { if (fgChug) fgChug = false; else Msg("Looped to last shape"); igImage = ngImages-1; }DisplayImageNbr();}//-----------------------------------------------------------------------------static bool fDidUserMarkAnyImages (void){for (int iImage = 0; iImage < ngImages; iImage++) for (int iPoint = 0; iPoint < ngPoints; iPoint++) if (fPointMarked(iImage, iPoint)) return true;return false;}//-----------------------------------------------------------------------------static bool fDidUserTagAnyImages (void){for (int iImage = 0; iImage < ngImages; iImage++) if (gImageStatus[iImage] != ST_NONE) return true;return false;}//-----------------------------------------------------------------------------static void CreateMarkedFile (void){if (fDidUserMarkAnyImages()) { int nMarked = 0; lprintf("Creating \"%s\" ", sgMarkedFile); FILE *pOut = Fopen(sgMarkedFile, "w"); for (int iImage = 0; iImage < ngImages; iImage++) for (int iPoint = 0; iPoint < ngPoints; iPoint++) if (fPointMarked(iImage, iPoint)) { char sDrive[_MAX_DRIVE], sDir[_MAX_DIR], sFname[_MAX_FNAME], sExt[_MAX_EXT]; _splitpath(&gTagStrings[iImage].c_str()[FNAME_OFFSET], sDrive, sDir, sFname, sExt); fprintf(pOut, "%s %g %g\n", sFname, gShapes[iImage](iPoint, VX), gShapes[iImage](iPoint, VY)); nMarked++; } fclose(pOut); lprintf("%d points marked\n", nMarked); lprintf("\n"); }}//-----------------------------------------------------------------------------static void CreateTaggedFile (void){if (fDidUserTagAnyImages()) { lprintf("Creating \"%s\" ", sgTagged); FILE *pOut = Fopen(sgTagged, "w"); for (int iImage = 0; iImage < ngImages; iImage++) { eImageStatus eStat = gImageStatus[iImage]; if (eStat != ST_NONE) { const char *sFile = &gTagStrings[iImage].c_str()[FNAME_OFFSET]; fprintf(pOut, "%c %s\n", sgImageStatus[eStat][0], sFile); } } fclose(pOut); lprintf("\nCreating \"%s\" ", sgUmSed); pOut = Fopen(sgUmSed, "w"); for (iImage = 0; iImage < ngImages; iImage++) { eImageStatus eStat = gImageStatus[iImage]; const char *sFile = &gTagStrings[iImage].c_str()[FNAME_OFFSET]; // need to get just the base name because want to ignore .pgm versus .bmp suffix char sDrive[_MAX_DRIVE], sDir[_MAX_DIR], sFname[_MAX_FNAME], sExt[_MAX_EXT]; _splitpath(sFile, sDrive, sDir, sFname, sExt); if (eStat != ST_NONE) fprintf(pOut, "s/ADJUST .*%s/ %c \\0/\n", sFname, sgImageStatus[eStat][0]); } fclose(pOut); lprintf("\n"); }}//-----------------------------------------------------------------------------static int iGetWantedPoints (const ShapeVec &Shapes, const StringVec &TagStrings, unsigned Mask1, unsigned Mask2){int iRefShape = iGetRefShapeIndex(Shapes, TagStrings, Mask1, Mask2);int nrows = Shapes[iRefShape].nrows();DASSERT(nrows > 4); // not strictly necessary, helps catch user errorsif (nrows != 20 && nrows != 68 && nrows != 76 && nrows != 84) Warn("Strange number of landmarks %d", nrows);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -