|
|
#include "common.h"
#include "glyph.h"
#include "score.h"
#include "fugu.h"
#include "volcanop.h"
#include "nnet.h"
#define FUGU_SEG_MAX_SPACES 32
static int g_cSpaces; static FUGU_INTEGER_WEIGHTS g_aCharDetNet[FUGU_SEG_MAX_SPACES];
POINT *DupPoints(POINT *pOldPoints, int nPoints); GLYPH *GlyphFromStrokes(UINT cStrokes, STROKE *pStrokes);
// prepare net from pointer
BOOL PrepareCharDetNet (BYTE *pb, FUGU_INTEGER_WEIGHTS *pCharDetNet) { pCharDetNet->pHeader = (FUGU_INTEGER_WEIGHTS_HEADER *) pb; pCharDetNet->pfdchMapping = (WCHAR *) (pb + sizeof(FUGU_INTEGER_WEIGHTS_HEADER)); pCharDetNet->pbWeights = pb + sizeof(FUGU_INTEGER_WEIGHTS_HEADER) + sizeof(WCHAR) * pCharDetNet->pHeader->arch.nOutputs;
return TRUE; }
// validates the header of the brknet
int CheckCharDetHeader (void *pData) { NNET_HEADER *pHeader = (NNET_HEADER *)pData;
// wrong magic number
ASSERT (pHeader->dwFileType == CHARDET_FILE_TYPE);
if (pHeader->dwFileType != CHARDET_FILE_TYPE) { return FALSE; }
// check version
ASSERT(pHeader->iFileVer >= CHARDET_OLD_FILE_VERSION); ASSERT(pHeader->iMinCodeVer <= CHARDET_CUR_FILE_VERSION);
ASSERT ( !memcmp ( pHeader->adwSignature, g_locRunInfo.adwSignature, sizeof (pHeader->adwSignature) ) );
ASSERT (pHeader->cSpace <= FUGU_SEG_MAX_SPACES);
if ( pHeader->iFileVer >= CHARDET_OLD_FILE_VERSION && pHeader->iMinCodeVer <= CHARDET_CUR_FILE_VERSION && !memcmp ( pHeader->adwSignature, g_locRunInfo.adwSignature, sizeof (pHeader->adwSignature) ) && pHeader->cSpace <= FUGU_SEG_MAX_SPACES ) { return pHeader->cSpace; } else { return 0; } }
// does the necessary preparations for a net to be used later
static BOOL CharDetLoadFromPointer (BYTE *pData) { int iSpc, cSpc, iSpaceID; NNET_SPACE_HEADER *pSpaceHeader; BYTE *pPtr;
if (!pData) { return FALSE; }
// check the header info
cSpc = CheckCharDetHeader (pData); g_cSpaces = cSpc; if (cSpc <= 0) { return FALSE; } pPtr = pData + sizeof (NNET_HEADER);
for (iSpc = 0; iSpc < cSpc; iSpc++) { // point to the one and only space that we have
pSpaceHeader = (NNET_SPACE_HEADER *)pPtr; pPtr += sizeof (NNET_SPACE_HEADER);
// point to the actual data
iSpaceID = pSpaceHeader->iSpace;
ASSERT (iSpaceID >= 1 && iSpaceID <= FUGU_SEG_MAX_SPACES);
if (!PrepareCharDetNet ( pData + pSpaceHeader->iDataOffset, g_aCharDetNet + iSpaceID - 1 ) ) { return FALSE; } }
return TRUE; }
BOOL LoadCharDetFromFile(wchar_t *wszPath, LOAD_INFO *pLoadInfo) { wchar_t awszFileName[MAX_PATH]; // memory map the file
wsprintf (awszFileName, L"%s\\chardet.bin", wszPath);
if (!DoOpenFile(pLoadInfo, awszFileName)) { return FALSE; }
return CharDetLoadFromPointer (pLoadInfo->pbMapping); }
BOOL LoadCharDetFromResource (HINSTANCE hInst, int nResID, int nType) { LOAD_INFO LoadInfo;
if (!DoLoadResource (&LoadInfo, hInst, nResID, nType)) { return FALSE; }
return CharDetLoadFromPointer (LoadInfo.pbMapping); }
BOOL CharDetUnloadFile(LOAD_INFO *pInfo) { return DoCloseFile(pInfo); }
int *ApplyFuguInteger(FUGU_INTEGER_WEIGHTS *pFugu, int aiInput[FUGU_INPUT_WIDTH][FUGU_INPUT_HEIGHT]);
float FuguSegScore(int cStrokes, STROKE *pStrokes, LOCRUN_INFO *pLocRunInfo) { GLYPH *pGlyph = GlyphFromStrokes(cStrokes, pStrokes); int i; int aiInput[FUGU_INPUT_WIDTH][FUGU_INPUT_HEIGHT]; int *piOutput = NULL; float flOutput = 0;
if (cStrokes >= 1 && cStrokes <= g_cSpaces) { // First convert the ink to 29x29 input region
if (!FuguRender(pGlyph, NULL, aiInput)) { return -1; }
// Apply the recognizer
piOutput = ApplyFuguInteger(g_aCharDetNet + cStrokes - 1, aiInput); if (piOutput == NULL) { return -1; }
for (i = 0; i < g_aCharDetNet[cStrokes - 1].pHeader->arch.nOutputs; i++) { wchar_t wch = g_aCharDetNet[cStrokes - 1].pfdchMapping[i]; // I'm assuming every space will have "not a char" samples. Note that
// there are two possible mappings for "not a char", the old one L'0'
// and the new one which is simply 0.
if (wch == 0 || wch == L'0') { int cRight = FUGU_ACTIVATION_SCALE - piOutput[i]; if (cRight == 0) { cRight = 1; }
flOutput = (float) cRight / (float) FUGU_ACTIVATION_SCALE; } } } DestroyFramesGLYPH(pGlyph); DestroyGLYPH(pGlyph); ExternFree(piOutput); return flOutput; }
|