Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

500 lines
16 KiB

  1. //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation. All rights reserved.
  4. //
  5. // Module:
  6. // fugu.h
  7. //
  8. // Description:
  9. // Declarations for the Fugu recognizer
  10. //
  11. // Author:
  12. // hrowley
  13. //
  14. //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  15. #pragma once
  16. #include <limits.h>
  17. #include "common.h"
  18. // How many strokes Fugu processes
  19. #define FUGU_MIN_STROKES 1
  20. #define FUGU_MAX_STROKES 2
  21. // How wide the pen is when rendering the characters to a bitmap
  22. #define FUGU_PEN_WIDTH 5
  23. // Dimensions of the input
  24. #define FUGU_INPUT_WIDTH 29
  25. #define FUGU_INPUT_HEIGHT 29
  26. // Dimensions of the first layer of convolution kernels
  27. #define FUGU_KERNEL_WIDTH1 5
  28. #define FUGU_KERNEL_HEIGHT1 5
  29. #define FUGU_KERNELS1 5
  30. #define FUGU_KERNEL_SUBSAMPLE1 2
  31. // Dimensions of the image after the first convolutional layer
  32. #define FUGU_HIDDEN_WIDTH1 13
  33. #define FUGU_HIDDEN_HEIGHT1 13
  34. // Dimensions of the second layer of convolution kernels
  35. #define FUGU_KERNEL_WIDTH2 5
  36. #define FUGU_KERNEL_HEIGHT2 5
  37. #define FUGU_KERNELS2 50
  38. #define FUGU_KERNEL_SUBSAMPLE2 2
  39. // Dimensions of the image after the second convolutional layer
  40. #define FUGU_HIDDEN_WIDTH2 5
  41. #define FUGU_HIDDEN_HEIGHT2 5
  42. // For the fixed point math used at runtime, this specifies how much
  43. // the activation values are shifted to the left.
  44. #define FUGU_ACTIVATION_SHIFT 11
  45. // Similarly, this is the multiplicative factor
  46. #define FUGU_ACTIVATION_SCALE (1 << FUGU_ACTIVATION_SHIFT)
  47. // Given the scaling of the activations above, this is the largest number
  48. // which can be multiplied by an activation (between -1 and 1) and still
  49. // have the result fit in a 32 bit signed integer.
  50. #define FUGU_WEIGHT_SCALE (INT_MAX >> FUGU_ACTIVATION_SHIFT)
  51. // The structure is used to specify the architecture of the Fugu network.
  52. // Currently it only has the number of fully connected hidden and output
  53. // nodes, but it may eventually be generalized.
  54. typedef struct FUGU_ARCHITECTURE_HEADER
  55. {
  56. INT nHiddens; // Number of hidden units
  57. INT nOutputs; // Number of output units
  58. } FUGU_ARCHITECTURE_HEADER;
  59. // The integer version of the fugu database requires some extra fields.
  60. typedef struct FUGU_INTEGER_WEIGHTS_HEADER
  61. {
  62. FUGU_ARCHITECTURE_HEADER arch; // Architecture
  63. INT iScale; // Scale factor applied to weights to make them be integers
  64. INT aiWeightLookup[256]; // Lookup table to map bytes to weights
  65. } FUGU_INTEGER_WEIGHTS_HEADER;
  66. // This structure represents the fugu database
  67. typedef struct FUGU_INTEGER_WEIGHTS
  68. {
  69. FUGU_INTEGER_WEIGHTS_HEADER *pHeader; // Pointer to the above header
  70. WCHAR *pfdchMapping; // Pointer to the mapping from outputs to code points
  71. BYTE *pbWeights; // Pointer to the weights
  72. } FUGU_INTEGER_WEIGHTS;
  73. // This structure is used to represent a fugu databased mapped from a file or resource.
  74. typedef struct FUGU_LOAD_INFO
  75. {
  76. FUGU_INTEGER_WEIGHTS fugu;
  77. LOAD_INFO info;
  78. } FUGU_LOAD_INFO;
  79. // Magic key the identifies the fugu NN bin file
  80. #define FUGU_FILE_TYPE 0xF040F040
  81. // Version information for file.
  82. #define FUGU_MIN_FILE_VERSION 0 // First version of code that can read this file
  83. #define FUGU_OLD_FILE_VERSION 0 // Oldest file version this code can read.
  84. #define FUGU_CUR_FILE_VERSION 0 // Current version of code.
  85. // Magic key the identifies the fugu NN bin file
  86. #define CHARDET_FILE_TYPE 0xC3A8DE7C
  87. // Version information for file.
  88. #define CHARDET_MIN_FILE_VERSION 0 // First version of code that can read this file
  89. #define CHARDET_OLD_FILE_VERSION 0 // Oldest file version this code can read.
  90. #define CHARDET_CUR_FILE_VERSION 0 // Current version of code.
  91. ///////////////////////////////////////
  92. //
  93. // FuguNumberWeights
  94. //
  95. // Calculate the number of weights in a Fugu net given its architecture
  96. //
  97. // Parameters:
  98. // pArch: [in] Pointer to the architecture description header
  99. //
  100. // Return values:
  101. // Number of weights in the Fugu network
  102. //
  103. //////////////////////////////////////
  104. int FuguNumberWeights(FUGU_ARCHITECTURE_HEADER *pArch);
  105. ///////////////////////////////////////
  106. //
  107. // FuguRender
  108. //
  109. // Renders a glyph to an image, each pixel has a value from 0 to FUGU_ACTIVATION_SCALE
  110. //
  111. // Parameters:
  112. // pGlyph: [in] Pointer to the ink to render
  113. // pGuide: [in] Guide to scale ink to, or NULL to use the ink bounds
  114. // aiInput: [out] Array that will be used as input to Fugu
  115. //
  116. // Return values:
  117. // TRUE: Finished without errors
  118. // FALSE: An error occured
  119. //
  120. //////////////////////////////////////
  121. BOOL FuguRender(GLYPH *pGlyph, RECT *pGuide, int aiInput[FUGU_INPUT_WIDTH][FUGU_INPUT_HEIGHT]);
  122. ///////////////////////////////////////
  123. //
  124. // ApplyFuguInteger
  125. //
  126. // Apply the integer version of the Fugu network to an input image (fixed point format),
  127. // and return an array of outputs (also in fixed point). Return NULL if there is an
  128. // error in allocating memory for the output.
  129. //
  130. // Parameters:
  131. // pFugu: [in] Pointer to the fugu database to use
  132. // aiInput: [in] Input image to process, in fixed point format
  133. //
  134. // Return values:
  135. // An array of output activations in fixed point format, or NULL on error
  136. //
  137. //////////////////////////////////////
  138. int *ApplyFuguInteger(FUGU_INTEGER_WEIGHTS *pFugu, int aiInput[FUGU_INPUT_WIDTH][FUGU_INPUT_HEIGHT]);
  139. ///////////////////////////////////////
  140. //
  141. // FuguLoadPointer
  142. //
  143. // Set up the Fugu database using a pointer to the data itself
  144. //
  145. // Parameters:
  146. // pInfo: [in] Structure with mapping information.
  147. // [out] Returns with the pointers to the fugu database set
  148. // pLocRunInfo: [in] Locale database to check header on file
  149. // iSize: [in] Size of database in bytes
  150. //
  151. // Return values:
  152. // TRUE: Finished without errors
  153. // FALSE: An error occured
  154. //
  155. //////////////////////////////////////
  156. BOOL FuguLoadPointer(FUGU_LOAD_INFO *pInfo, LOCRUN_INFO *pLocRunInfo, int iSize);
  157. ///////////////////////////////////////
  158. //
  159. // FuguLoadRes
  160. //
  161. // Load an integer Fugu database from a resource
  162. //
  163. // Parameters:
  164. // pInfo: [out] Structure where information for unloading is stored
  165. // hInst: [in] Handle to the DLL containing the recognizer
  166. // iResNumber: [in] Number of the resource (ex RESID_FUGU)
  167. // iResType: [in] Number of the recognizer (ex VOLCANO_RES)
  168. // pLocRunInfo: [in] Locale database to check header on file
  169. //
  170. // Return values:
  171. // TRUE: Finished without errors
  172. // FALSE: An error occured
  173. //
  174. //////////////////////////////////////
  175. BOOL FuguLoadRes(FUGU_LOAD_INFO *pFugu, HINSTANCE hInst, int iResNumber, int iResType, LOCRUN_INFO *pLocRunInfo);
  176. ///////////////////////////////////////
  177. //
  178. // FuguLoadFile
  179. //
  180. // Load an integer Fugu database from a file
  181. //
  182. // Parameters:
  183. // pInfo: [out] Structure where information for unloading is stored
  184. // wszPath: [in] Path to load the database from
  185. // pLocRunInfo: [in] Locale database to check header on file
  186. //
  187. // Return values:
  188. // TRUE: Finished without errors
  189. // FALSE: An error occured
  190. //
  191. //////////////////////////////////////
  192. BOOL FuguLoadFile(FUGU_LOAD_INFO *pInfo, wchar_t *wszPath, LOCRUN_INFO *pLocRunInfo);
  193. ///////////////////////////////////////
  194. //
  195. // FuguUnLoadFile
  196. //
  197. // Unload a Fugu database loaded from a file
  198. //
  199. // Parameters:
  200. // pInfo: [in] Load information for unloading
  201. //
  202. // Return values:
  203. // TRUE: Finished without errors
  204. // FALSE: An error occured
  205. //
  206. //////////////////////////////////////
  207. BOOL FuguUnLoadFile(FUGU_LOAD_INFO *pInfo);
  208. ///////////////////////////////////////
  209. //
  210. // FuguMatch
  211. //
  212. // Invoke Fugu on a character
  213. //
  214. // Parameters:
  215. // pFugu: [in] Fugu database to use
  216. // pAltList: [out] Alt list
  217. // cAlt: [in] The maximum number of alternates to return
  218. // pGlyph: [in] The ink to recognize
  219. // pGuide: [in] Guide to scale ink to, or NULL to use the ink bounds
  220. // pCharSet: [in] Filter for the characters to be returned
  221. // pLocRunInfo: [in] Pointer to the locale database
  222. //
  223. // Return values:
  224. // Returned the number of items in the alt list, or -1 if there is an error
  225. //
  226. //////////////////////////////////////
  227. int FuguMatch(FUGU_INTEGER_WEIGHTS *pFugu, // Fugu database
  228. ALT_LIST *pAltList, // Alt list where the results are returned
  229. int cAlt, // Maximum number of results requested
  230. GLYPH *pGlyph, // Pointer to the strokes
  231. RECT *pGuide, // Guide to scale ink to
  232. CHARSET *pCharSet, // Filters to apply to the results
  233. LOCRUN_INFO *pLocRunInfo); // Locale database
  234. ///////////////////////////////////////
  235. //
  236. // FuguMatchRescore
  237. //
  238. // Invoke Fugu on a character. Returns the top 1 result, and
  239. // also rewrites the scores for the topN alternates returned by
  240. // another recognizer (say Otter).
  241. //
  242. // Parameters:
  243. // pFugu: [in] Fugu database to use
  244. // pwchTop1: [out] Top one result
  245. // pflTop1: [out] Top one score
  246. // pAltList: [in/out] Alt list to rewrite the scores of
  247. // cAlt: [in] The maximum number of alternates to return
  248. // pGlyph: [in] The ink to recognize
  249. // pGuide: [in] Guide to scale ink to, or NULL to use the ink bounds
  250. // pCharSet: [in] Filter for the characters to be returned
  251. // pLocRunInfo: [in] Pointer to the locale database
  252. //
  253. // Return values:
  254. // Returned the number of items in the alt list, or -1 if there is an error
  255. //
  256. //////////////////////////////////////
  257. int FuguMatchRescore(
  258. FUGU_INTEGER_WEIGHTS *pFugu, // Fugu recognizer
  259. wchar_t *pwchTop1, // Top one result
  260. float *pflTop1, // Top one score
  261. ALT_LIST *pAltList, // Alt list where the results are returned
  262. int cAlt, // Maximum number of results requested
  263. GLYPH *pGlyph, // Pointer to the strokes
  264. RECT *pGuide, // Guide to scale ink to
  265. CHARSET *pCharSet, // Filters to apply to the results
  266. LOCRUN_INFO *pLocRunInfo); // Locale database
  267. // The following declarations are used at training time
  268. #ifndef HWX_PRODUCT
  269. // An entry in the index file used during training
  270. typedef struct FUGU_INDEX
  271. {
  272. SHORT fdch; // Folded dense code
  273. USHORT usFile; // The file number which this sample is in
  274. union
  275. {
  276. UINT uiOffset; // Offset of stroke data in file.
  277. BYTE *pbData; // The offset gets converted to a pointer to the
  278. // stroke data in the training program
  279. };
  280. } FUGU_INDEX;
  281. // Data structure to access floating point weight database
  282. typedef struct FUGU_FLOAT_WEIGHTS {
  283. FUGU_ARCHITECTURE_HEADER *pArch; // Pointer to the architecture description
  284. WCHAR *pfdchMapping; // Pointer to the mapping from outputs to folded dense codes
  285. FLOAT *pflWeights; // Pointer to the array of weights
  286. } FUGU_FLOAT_WEIGHTS;
  287. ///////////////////////////////////////
  288. //
  289. // FuguForwardPassFloat
  290. //
  291. // Run a forward pass of the floating point network
  292. //
  293. // Parameters:
  294. // pFugu: [in] Fugu network
  295. // aflInput: [in] Input image to work from
  296. //
  297. // Return values:
  298. // Array of output activations, or NULL if an error occurs
  299. //
  300. //////////////////////////////////////
  301. float *FuguForwardPassFloat(
  302. FUGU_FLOAT_WEIGHTS *pFugu,
  303. float aflInput[FUGU_INPUT_WIDTH][FUGU_INPUT_HEIGHT]);
  304. ///////////////////////////////////////
  305. //
  306. // FuguForwardBackwardFloat
  307. //
  308. // Run a training pass of the floating point network
  309. //
  310. // Parameters:
  311. // pFugu: [in/out] Fugu network, which is updated for this sample
  312. // aflInput: [in] Input image to train on
  313. // iDesiredOutput: [in] The training output
  314. // pflPrevUpdate: [in] Pointer to an array of previous weight updates
  315. // for momentum, or NULL if there was no previous update.
  316. // flRate: [in] Learning rate
  317. // flMomentum: [in] Momentum
  318. //
  319. // Return values:
  320. // Returns NULL if there was an error.
  321. // Otherwise, if pflPrevUpdate was non-NULL, it is returned with the
  322. // updates for this sample. If
  323. // pflPrevUpdate was NULL, an array of updates is allocated and
  324. // returned, and it should be passed in on the next call.
  325. //
  326. //////////////////////////////////////
  327. float *FuguForwardBackwardFloat(
  328. FUGU_FLOAT_WEIGHTS *pFugu,
  329. float aflInput[FUGU_INPUT_WIDTH][FUGU_INPUT_HEIGHT],
  330. int iDesiredOutput,
  331. float *pflPrevUpdate,
  332. float flRate,
  333. float flMomentum);
  334. ///////////////////////////////////////
  335. //
  336. // FuguSaveIntegerWeights
  337. //
  338. // Write out an integer weights database
  339. //
  340. // Parameters:
  341. // wszFileName: [in] File name to write to
  342. // pFugu: [in] Pointer to Fugu data structure which is written
  343. //
  344. // Return values:
  345. // TRUE: Finished without errors
  346. // FALSE: An error occured
  347. //
  348. //////////////////////////////////////
  349. BOOL FuguSaveIntegerWeights(wchar_t *wszFileName, FUGU_INTEGER_WEIGHTS *pFugu);
  350. ///////////////////////////////////////
  351. //
  352. // FuguSaveFloatWeights
  353. //
  354. // Write out a floating point weights database
  355. //
  356. // Parameters:
  357. // wszFileName: [in] File name to write to
  358. // pFugu: [in] Pointer to Fugu data structure which is written
  359. //
  360. // Return values:
  361. // TRUE: Finished without errors
  362. // FALSE: An error occured
  363. //
  364. //////////////////////////////////////
  365. BOOL FuguSaveFloatWeights(wchar_t *wszFileName, FUGU_FLOAT_WEIGHTS *pFugu);
  366. ///////////////////////////////////////
  367. //
  368. // FuguLoadFloatWeights
  369. //
  370. // Read in a floating point weights database
  371. //
  372. // Parameters:
  373. // wszFileName: [in] File name to read from
  374. // pFugu: [in] Pointer to structure which gets filled in
  375. //
  376. // Return values:
  377. // TRUE: Finished without errors
  378. // FALSE: An error occured
  379. //
  380. //////////////////////////////////////
  381. BOOL FuguLoadFloatWeights(wchar_t *wszFileName, FUGU_FLOAT_WEIGHTS *pFugu);
  382. ///////////////////////////////////////
  383. //
  384. // FuguSaveBitmap
  385. //
  386. // Write out an image to a .bmp file, for debugging
  387. //
  388. // Parameters:
  389. // wszFileName: [in] File to write to
  390. // pBitmap: [in] Pointer to the bitmap header structure
  391. // pvBitBuf: [in] Pointer to the actual bits
  392. //
  393. // Return values:
  394. //
  395. //////////////////////////////////////
  396. void FuguSaveBitmap(wchar_t *wszFileName, BITMAPINFOHEADER *pBitmap, void *pvBitBuf);
  397. ///////////////////////////////////////
  398. //
  399. // FuguSaveNetworkInput
  400. //
  401. // Write out the network's input image to a .pgm file, for debugging
  402. //
  403. // Parameters:
  404. // wszFileName: [in] File to write to
  405. // aiInput: [in] Image to write out, in fixed point format
  406. //
  407. // Return values:
  408. //
  409. //////////////////////////////////////
  410. void FuguSaveNetworkInput(wchar_t *wszFileName, int aiInput[FUGU_INPUT_WIDTH][FUGU_INPUT_HEIGHT]);
  411. ///////////////////////////////////////
  412. //
  413. // FuguScaleGlyph
  414. //
  415. // Scales the coordinate values in the glyph to fit in a 256x256 range.
  416. //
  417. // Parameters:
  418. // pGlyph: [in] Ink to be scaled
  419. // [out] Scaled version of Ink
  420. // pGuide: [in] Guide to scale ink to, or NULL to use the ink bounds
  421. //
  422. // Return values:
  423. //
  424. //////////////////////////////////////
  425. void FuguScaleGlyph(GLYPH *pGlyph, RECT *pGuide);
  426. ///////////////////////////////////////
  427. //
  428. // FuguRenderNoScale
  429. //
  430. // Renders a glyph to an image, each pixel has a value from 0 to FUGU_ACTIVATION_SCALE.
  431. // Unlike FuguRender, this function does not scale the ink to the image, but rather
  432. // assumes the ink is already in scaled form as produced by FuguScaleGlyph().
  433. //
  434. // Parameters:
  435. // pGlyph: [in] Pointer to the ink to render
  436. // aiInput: [out] Array that will be used as input to Fugu
  437. //
  438. // Return values:
  439. // TRUE: Finished without errors
  440. // FALSE: An error occured
  441. //
  442. //////////////////////////////////////
  443. BOOL FuguRenderNoScale(GLYPH *pGlyph, int aiInput[FUGU_INPUT_WIDTH][FUGU_INPUT_HEIGHT]);
  444. // This was the structure used to read the weights from Dave's trainer
  445. /*
  446. typedef struct tagFuguFloatWeights {
  447. float _weights1[FuguKernels1][FuguKernelWidth1][FuguKernelHeight1];
  448. float _tweights1[FuguKernels1];
  449. float _weights2[FuguKernels2][FuguKernels1][FuguKernelWidth2][FuguKernelHeight2];
  450. float _tweights2[FuguKernels2];
  451. float _weights_fc[200][FuguKernels2][FuguHiddenWidth2][FuguHiddenHeight2];
  452. float _tweights_fc[200];
  453. float _weights_out[462][200];
  454. float _tweights_out[462];
  455. wchar_t mapping[462];
  456. } FuguFloatWeights;
  457. */
  458. #endif // !defined(HWX_PRODUCT)