DigitClass.cpp
上传用户:cdscwht
上传日期:2022-07-27
资源大小:264k
文件大小:13k
源码类别:

图形/文字识别

开发平台:

Visual Basic

  1. // DigitClass.cpp: implementation of the CDigitClass class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "DigitClass.h"
  6. #include "Thinner.h"
  7. //#include "dib.h"
  8. #include "math.h"
  9. #ifdef _DEBUG
  10. #undef THIS_FILE
  11. static char THIS_FILE[]=__FILE__;
  12. #define new DEBUG_NEW
  13. #endif
  14. //////////////////////////////////////////////////////////////////////
  15. // Construction/Destruction
  16. //////////////////////////////////////////////////////////////////////
  17. CDigitClass::CDigitClass()
  18. {
  19. }
  20. CDigitClass::~CDigitClass()
  21. {
  22. }
  23. /*void CDigitClass::CopyArToBitmap(void)
  24. {
  25. LONG x, y;
  26. digitWidth = digitdib.GetWidth();
  27. digitHeight = digitdib.GetHeight();
  28. for(x=0; x<digitWidth; x++)
  29. {
  30. for(y=0; y<digitHeight; y++)
  31. {
  32. digitdib.SetPixel8(x, y, digitarray[x][y]);
  33. //digitdib.SetPixel8(x, y, 0);
  34. }
  35. }
  36. }
  37. void CDigitClass::CopyBitmapToAr(void)
  38. {
  39. LONG x, y;
  40. digitWidth = digitdib.GetWidth();
  41. digitHeight = digitdib.GetHeight();
  42. for(x=0; x<digitWidth; x++)
  43. {
  44. for(y=0; y<digitHeight; y++)
  45. {
  46. digitarray[x][y] = digitdib.GetPixel8(x, y);
  47. TRACE("%d ",digitdib.GetPixel8(x, y));
  48. }
  49. }
  50. }*/
  51. void CDigitClass::BinaryDigit(BYTE thre)
  52. {
  53. // digitWidth = digitdib.GetWidth();
  54. // digitHeight = digitdib.GetHeight();
  55. LONG x, y;
  56. for(x=0; x<digitWidth; x++)
  57. {
  58. for(y=0; y<digitHeight; y++)
  59. {
  60. if(digitarray[x][y] >= thre)
  61. digitarray[x][y]=(BYTE)1;
  62. else
  63. digitarray[x][y]=(BYTE)0;
  64. }
  65. }
  66. }
  67. void CDigitClass::BinaryDigit()
  68. {
  69.     int x,y;
  70. int k=0;
  71. long double total=0;
  72. float aver=0;
  73. for(x=0;x<digitWidth;x++)
  74. {
  75. for(y=0;y<digitHeight;y++)
  76. {
  77. total+=digitarray[x][y];
  78. }
  79. }
  80. aver=(BYTE)(total/(float)(digitWidth*digitHeight));
  81. float delt; 
  82. float sub=0; 
  83. for(x=0;x<digitWidth;x++)
  84. {
  85. for(y=0;y<digitHeight;y++)
  86. {
  87. sub+=(digitarray[x][y]-aver)*(digitarray[x][y]-aver);  
  88. }
  89. }
  90. delt=(float)(sqrt(sub/(float)(digitWidth*digitHeight)));
  91. BYTE judge;
  92. judge=(BYTE)(delt+aver);
  93. for(x=0;x<digitWidth;x++)
  94. {
  95. for(y=0;y<digitHeight;y++)
  96. {
  97. if(digitarray[x][y]>=judge)
  98. {
  99. digitarray[x][y]=1;
  100. }
  101. else
  102. {
  103. digitarray[x][y]=0;
  104. }
  105. }
  106. }
  107. }
  108. void CDigitClass::ThinDigit_1()
  109. {
  110. LONG x,y,k;
  111. k=0;
  112. // digitWidth = digitdib.GetWidth();
  113. // digitHeight = digitdib.GetHeight();
  114. for(x=0; x<digitWidth; x++)
  115. {
  116. digitarray[x][0] = (BYTE)0;
  117. digitarray[x][digitHeight-1] = (BYTE)0;
  118. }
  119. for(y=0; y<digitHeight; y++)
  120. {
  121. digitarray[0][y] = (BYTE)0;
  122. digitarray[digitWidth-1][y] = (BYTE)0;
  123. }
  124. for(x=0; x<digitWidth; x++)
  125. {
  126. for(y=0; y<digitHeight; y++)
  127. {
  128. digitarray1[k] = digitarray[x][y];
  129. if(digitarray1[k] != 0)
  130. digitarray1[k] = (BYTE)1;
  131. k++;
  132. }
  133. }
  134. ThinnerHilditch((void *)digitarray1, digitWidth, digitHeight);
  135. k=0;
  136. for(x=0; x<digitWidth; x++)
  137. {
  138. for(y=0; y<digitHeight; y++)
  139. {
  140. digitarray[x][y] = digitarray1[k];
  141. if(digitarray[x][y]!=0)
  142. digitarray[x][y] = (BYTE)1;
  143. k++;
  144. }
  145. }
  146. }
  147. void CDigitClass::ThinDigit_2()
  148. {
  149. LONG x,y,k;
  150. k=0;
  151. // digitWidth = digitdib.GetWidth();
  152. // digitHeight = digitdib.GetHeight();
  153. for(x=0; x<digitWidth; x++)
  154. {
  155. digitarray[x][0] = (BYTE)0;
  156. digitarray[x][digitHeight-1] = (BYTE)0;
  157. }
  158. for(y=0; y<digitHeight; y++)
  159. {
  160. digitarray[0][y] = (BYTE)0;
  161. digitarray[digitWidth-1][y] = (BYTE)0;
  162. }
  163. for(x=0; x<digitWidth; x++)
  164. {
  165. for(y=0; y<digitHeight; y++)
  166. {
  167. digitarray1[k] = digitarray[x][y];
  168. if(digitarray1[k] != 0)
  169. digitarray1[k] = (BYTE)1;
  170. k++;
  171. }
  172. }
  173. ThinnerPavlidis((void *)digitarray1, digitWidth, digitHeight);
  174. k=0;
  175. for(x=0; x<digitWidth; x++)
  176. {
  177. for(y=0; y<digitHeight; y++)
  178. {
  179. digitarray[x][y] = digitarray1[k];
  180. if(digitarray[x][y]!=0)
  181. digitarray[x][y] = (BYTE)1;
  182. k++;
  183. }
  184. }
  185. }
  186. void CDigitClass::ThinDigit_3()
  187. {
  188. LONG x,y,k;
  189. k=0;
  190. // digitWidth = digitdib.GetWidth();
  191. // digitHeight = digitdib.GetHeight();
  192. for(x=0; x<digitWidth; x++)
  193. {
  194. digitarray[x][0] = (BYTE)0;
  195. digitarray[x][digitHeight-1] = (BYTE)0;
  196. }
  197. for(y=0; y<digitHeight; y++)
  198. {
  199. digitarray[0][y] = (BYTE)0;
  200. digitarray[digitWidth-1][y] = (BYTE)0;
  201. }
  202. for(x=0; x<digitWidth; x++)
  203. {
  204. for(y=0; y<digitHeight; y++)
  205. {
  206. digitarray1[k] = digitarray[x][y];
  207. if(digitarray1[k] != 0)
  208. digitarray1[k] = (BYTE)1;
  209. k++;
  210. }
  211. }
  212. ThinnerHilditch((void *)digitarray1, digitWidth, digitHeight);
  213. k=0;
  214. for(x=0; x<digitWidth; x++)
  215. {
  216. for(y=0; y<digitHeight; y++)
  217. {
  218. digitarray[x][y] = digitarray1[k];
  219. if(digitarray[x][y]!=0)
  220. digitarray[x][y] = (BYTE)1;
  221. k++;
  222. }
  223. }
  224. }
  225. void CDigitClass::ThinDigit_4()
  226. {
  227. LONG x,y,k;
  228. k=0;
  229. // digitWidth = digitdib.GetWidth();
  230. // digitHeight = digitdib.GetHeight();
  231. for(x=0; x<digitWidth; x++)
  232. {
  233. digitarray[x][0] = (BYTE)0;
  234. digitarray[x][digitHeight-1] = (BYTE)0;
  235. }
  236. for(y=0; y<digitHeight; y++)
  237. {
  238. digitarray[0][y] = (BYTE)0;
  239. digitarray[digitWidth-1][y] = (BYTE)0;
  240. }
  241. for(x=0; x<digitWidth; x++)
  242. {
  243. for(y=0; y<digitHeight; y++)
  244. {
  245. digitarray1[k] = digitarray[x][y];
  246. if(digitarray1[k] != 0)
  247. digitarray1[k] = (BYTE)1;
  248. k++;
  249. }
  250. }
  251. ThiningDIBSkeleton((LPSTR)digitarray1, digitHeight, digitWidth);
  252. k=0;
  253. for(x=0; x<digitWidth; x++)
  254. {
  255. for(y=0; y<digitHeight; y++)
  256. {
  257. digitarray[x][y] = digitarray1[k];
  258. if(digitarray[x][y]!=0)
  259. digitarray[x][y] = (BYTE)1;
  260. k++;
  261. }
  262. }
  263. }
  264. void CDigitClass::GetFeature()
  265. {
  266. int i,j;
  267. for(i=0; i<13; i++)
  268. feature[i] = 0;
  269. //图象是20×36大小的,分成9块
  270. //第一块
  271. for(i=0; i<7; i++)
  272. {
  273. for(j=0; j<12; j++)
  274. {
  275. if(digitarray[i][j]==1)
  276. feature[0]+=1.0;
  277. }
  278. }
  279. //第二块
  280. for(i=0; i<7; i++)
  281. {
  282. for(j=12; j<24; j++)
  283. {
  284. if(digitarray[i][j]==1)
  285. feature[1]+=1.0;
  286. }
  287. }
  288. //第三块
  289. for(i=0; i<7; i++)
  290. {
  291. for(j=24; j<36; j++)
  292. {
  293. if(digitarray[i][j]==1)
  294. feature[2]+=1.0;
  295. }
  296. }
  297. //第四块
  298. for(i=7; i<13; i++)
  299. {
  300. for(j=0; j<12; j++)
  301. {
  302. if(digitarray[i][j]==1)
  303. feature[3]+=1.0;
  304. }
  305. }
  306. //第五块
  307. for(i=7; i<13; i++)
  308. {
  309. for(j=12; j<24; j++)
  310. {
  311. if(digitarray[i][j]==1)
  312. feature[4]+=1.0;
  313. }
  314. }
  315. //第六块
  316. for(i=7; i<13; i++)
  317. {
  318. for(j=24; j<36; j++)
  319. {
  320. if(digitarray[i][j]==1)
  321. feature[5]+=1.0;
  322. }
  323. }
  324. //第七块
  325. for(i=13; i<20; i++)
  326. {
  327. for(j=0; j<12; j++)
  328. {
  329. if(digitarray[i][j]==1)
  330. feature[6]+=1.0;
  331. }
  332. }
  333. //第八块
  334. for(i=13; i<20; i++)
  335. {
  336. for(j=12; j<24; j++)
  337. {
  338. if(digitarray[i][j]==1)
  339. feature[7]+=1.0;
  340. }
  341. }
  342. //第九块
  343. for(i=13; i<20; i++)
  344. {
  345. for(j=24; j<36; j++)
  346. {
  347. if(digitarray[i][j]==1)
  348. feature[8]+=1.0;
  349. }
  350. }
  351. //下面统计方向交点特征
  352. for(j=0; j<36; j++)
  353. {
  354. if(digitarray[7][j]==1)
  355. feature[9]+=1.0;
  356. }
  357. for(j=0; j<36; j++)
  358. {
  359. if(digitarray[13][j]==1)
  360. feature[10]+=1.0;
  361. }
  362. for(i=0; i<20; i++)
  363. {
  364. if(digitarray[i][12]==1)
  365. feature[11]+=1.0;
  366. }
  367. for(i=0; i<20; i++)
  368. {
  369. if(digitarray[i][24]==1)
  370. feature[12]+=1.0;
  371. }
  372. }
  373. void CDigitClass::FixSize()
  374. {
  375. if(digitWidth==20&&digitHeight==36)
  376. return;
  377. LONG lWidth=digitWidth;
  378. // 源图像的宽度和高度
  379. LONG lHeight=digitHeight;
  380. BYTE *temp_img=new BYTE[lWidth*lHeight];
  381. // 循环变量
  382. LONG i;
  383. LONG j;
  384. //memcpy(temp_img,digitarray,lWidth*lHeight);
  385. for(i = 0; i < digitHeight; i++)
  386. {
  387. for(j = 0; j < digitWidth; j++)
  388. {
  389. temp_img[i*digitWidth+j]=digitarray[j][i];
  390. }
  391. }
  392. // 缩放后图像的宽度和高度
  393. LONG lNewWidth;
  394. LONG lNewHeight;
  395. float XZRatio=(float) 20/digitWidth;
  396. float YZRatio=(float) 36/digitHeight;
  397. // float XZRatio=(float) digitWidth/20;
  398. // float YZRatio=(float) digitHeight/36;
  399. // lNewWidth = (LONG) (lWidth * XZRatio + 0.5);
  400. // lNewHeight = (LONG) (lHeight * YZRatio + 0.5);
  401. // 象素在源坐标
  402. LONG i0;
  403. LONG j0;
  404. //归一后的大小
  405. lNewWidth = 20;
  406. lNewHeight = 36;
  407. digitHeight=lNewHeight;
  408. digitWidth=lNewWidth;
  409. for(i = 0; i < lNewHeight; i++)
  410. {
  411. for(j = 0; j < lNewWidth; j++)
  412. {
  413. i0 = (LONG) (i / YZRatio + 0.5);
  414. j0 = (LONG) (j / XZRatio + 0.5);
  415. digitarray[j][i]=Interpolation(temp_img,lWidth,lHeight,j0,i0);
  416. /*
  417.   
  418. // 判断是否在源图范围内
  419. if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight))
  420. {
  421. // 复制象素
  422. digitarray[j][i] = temp_img[lHeight * j0 + i0];
  423. }
  424. else
  425. {
  426. // 对于源图中没有的象素,直接赋值为255
  427. //digitarray[j][i] = 255;
  428. digitarray[j][i] = 0;
  429. }*/
  430. }
  431. }
  432. delete [] temp_img;
  433. }
  434. void CDigitClass::FixSize1()
  435. {
  436. if(digitWidth==20&&digitHeight==36)
  437. return;
  438. // 源图像的宽度和高度
  439. LONG lWidth=digitWidth;
  440. LONG lHeight=digitHeight;
  441. BYTE *temp_img=new BYTE[lWidth*lHeight];
  442. // 循环变量
  443. LONG i;
  444. LONG j;
  445. //memcpy(temp_img,digitarray,lWidth*lHeight);
  446. for(i = 0; i < digitHeight; i++)
  447. {
  448. for(j = 0; j < digitWidth; j++)
  449. {
  450. temp_img[j*digitHeight+i]=digitarray[j][i];
  451. }
  452. }
  453. // 缩放后图像的宽度和高度
  454. LONG lNewWidth;
  455. LONG lNewHeight;
  456. float XZRatio=(float) 20/digitWidth;
  457. float YZRatio=(float) 36/digitHeight;
  458. // 象素在源坐标
  459. LONG i0;
  460. LONG j0;
  461. // 计算缩放后的图像实际宽度
  462. // 此处直接加0.5是由于强制类型转换时不四舍五入,而是直接截去小数部分
  463. lNewWidth = (LONG) (lWidth * XZRatio + 0.5);
  464. // 计算缩放后的图像高度
  465. lNewHeight = (LONG) (lHeight * YZRatio + 0.5);
  466. for(i = 0; i < lNewHeight; i++)
  467. {
  468. for(j = 0; j < lNewWidth; j++)
  469. {
  470. i0 = (LONG) (i / YZRatio + 0.5);
  471. j0 = (LONG) (j / XZRatio + 0.5);
  472. // 判断是否在源图范围内
  473. if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 <lHeight ))
  474. {
  475. // 复制象素
  476. digitarray[j][i] = temp_img[lHeight * j0 + i0];
  477. }
  478. else
  479. {
  480. // 对于源图中没有的象素,直接赋值为255
  481. digitarray[j][i] = 255;
  482. }
  483. }
  484. }
  485. digitHeight=lNewHeight;
  486. digitWidth=lNewWidth;
  487. delete [] temp_img;
  488. }
  489. float CDigitClass::Marroperator(float dr, int x, int y)
  490. {
  491. double a=(float) (-2.0/3.1415926/dr/dr/dr/dr);
  492. a=a*(1-(x*x+y*y)/2.0/dr/dr);
  493. double b=-(double)((x*x+y*y)/2.0/dr/dr);
  494. b=(double)(exp(b));
  495. a=a*b;
  496. return (float)(12.0*a);
  497. }
  498. void CDigitClass::MarrBinary()
  499. {
  500. float *temp=NULL;
  501. float *Temp=NULL;
  502. int i,j;
  503. temp=new float[digitWidth*digitHeight];
  504. memset(temp,255,digitWidth*digitHeight*sizeof(float));
  505. Temp=temp;
  506. float dr=(float) 1.6;
  507. float Marr[9][9];
  508. for(int x=-4;x<=4;x++)
  509. {
  510. for(int y=-4;y<=4;y++)
  511. {
  512. float result=(float)(-Marroperator(dr,x,y));
  513. Marr[x+4][y+4]=result;
  514. }
  515. }
  516. for(i=4;i<digitHeight-4;i++)
  517. {
  518. for(j=4;j<digitWidth-4;j++)
  519. {
  520. Temp[i*digitWidth+j]=0;
  521. for(int di=-4;di<4;di++)
  522. {
  523. for(int dj=-4;dj<4;dj++)
  524. {
  525. Temp[i*digitWidth+j]+=
  526. Marr[4+di][4+dj]*(float)digitarray[j+dj][i+di];
  527. }
  528. }
  529. }
  530. }
  531. for(i=0;i<digitHeight;i++)
  532. {
  533. for(j=0;j<digitWidth;j++)
  534. {
  535. digitarray[j][i]=Temp[i*digitWidth+j]>0?1:0;
  536. }
  537. }
  538. delete [] temp;
  539. }
  540. BYTE CDigitClass::Interpolation(BYTE *image, LONG lWidth, LONG lHeight, FLOAT x, FLOAT y)
  541. {
  542. // 四个最临近象素的坐标(i1, j1), (i2, j1), (i1, j2), (i2, j2)
  543. LONG i1, i2;
  544. LONG j1, j2;
  545. // 四个最临近象素值
  546. BYTE f1, f2, f3, f4;
  547. // 二个插值中间值
  548. BYTE f12, f34;
  549. // 定义一个值,当象素坐标相差小于改值时认为坐标相同
  550. FLOAT EXP;
  551. // 赋值
  552. EXP = (FLOAT) 0.0001;
  553. // 计算四个最临近象素的坐标
  554. i1 = (LONG) x;
  555. i2 = i1 + 1;
  556. j1 = (LONG) y;
  557. j2 = j1 + 1;
  558. // 根据不同情况分别处理
  559. if( (x < 0) || (x > lWidth - 1) || (y < 0) || (y > lHeight - 1))
  560. {
  561. // 要计算的点不在源图范围内,直接返回255。
  562. return 255;
  563. }
  564. else
  565. {
  566. if (fabs(x - lWidth + 1) <= EXP)
  567. {
  568. // 要计算的点在图像右边缘上
  569. if (fabs(y - lHeight + 1) <= EXP)
  570. {
  571. // 要计算的点正好是图像最右下角那一个象素,直接返回该点象素值
  572. f1 = (BYTE) image[lWidth * j1 + i1];
  573. return f1;
  574. }
  575. else
  576. {
  577. // 在图像右边缘上且不是最后一点,直接一次插值即可
  578. f1 = (BYTE)image[lWidth * j1 + i1];
  579. f3 = (BYTE)image[lWidth * j1 + i2];
  580. // 返回插值结果
  581. return ((BYTE) (f1 + (y -j1) * (f3 - f1)));
  582. }
  583. }
  584. else if (fabs(y - lHeight + 1) <= EXP)
  585. {
  586. // 要计算的点在图像下边缘上且不是最后一点,直接一次插值即可
  587. f1 = (BYTE)image[lWidth * j1 + i1];
  588. f2 = (BYTE)image[lWidth * j2 + i1];
  589. // 返回插值结果
  590. return ((BYTE) (f1 + (x -i1) * (f2 - f1)));
  591. }
  592. else
  593. {
  594. // 计算四个最临近象素值
  595. f1 = (BYTE) image[lWidth * j1 + i1];
  596. f2 = (BYTE) image[lWidth * j2 + i1];
  597. f3 = (BYTE) image[lWidth * j1 + i2];
  598. f4 = (BYTE) image[lWidth * j2 + i2];
  599. // 插值1
  600. f12 = (BYTE) (f1 + (x - i1) * (f2 - f1));
  601. // 插值2
  602. f34 = (BYTE) (f3 + (x - i1) * (f4 - f3));
  603. // 插值3
  604. return ((BYTE) (f12 + (y -j1) * (f34 - f12)));
  605. }
  606. }
  607. }
  608.