LikelyHood.cpp
上传用户:yeung_1189
上传日期:2010-02-10
资源大小:3536k
文件大小:10k
源码类别:

图形/文字识别

开发平台:

Visual C++

  1. //////////////////////////////////////////////////////////////////////
  2. // LikelyHood.cpp: 类CLikelyHood的接口
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "FaceDetect.h"
  6. #include "LikelyHood.h"
  7. //////////////////////////////////////////////////////////////////////
  8. // 构造函数/析构函数
  9. //////////////////////////////////////////////////////////////////////
  10. CLikelyHood::CLikelyHood()
  11. {
  12. m_pLikeliHoodArray = NULL;
  13. m_pBinaryArray = NULL;
  14. bmean =  B_Mean;
  15. rmean =  R_Mean;
  16. brcov[0][0] =  Brcov00;
  17. brcov[0][1] =  Brcov01;
  18. brcov[1][0] =  Brcov10;
  19. brcov[1][1] =  Brcov11;
  20. }
  21. //////////////////////////////////////////////////////////////////////
  22. //构造函数:
  23. //参数:    source-输入图像数据
  24. //          width-图像宽度
  25. //          height-图像高度
  26. //////////////////////////////////////////////////////////////////////
  27. CLikelyHood::CLikelyHood(RGBQUAD ** source,int width,int height)
  28. {
  29. int i;
  30. bmean =  B_Mean;
  31. rmean =  R_Mean;
  32. brcov[0][0] =  Brcov00;
  33. brcov[0][1] =  Brcov01;
  34. brcov[1][0] =  Brcov10;
  35. brcov[1][1] =  Brcov11;
  36. m_nWidth = width;
  37. m_nHeight= height;
  38. m_bLikeliHoodReady = false;
  39. m_bBinaryReady = false;
  40. //初始化各数组
  41. m_pSourceData = source;
  42. m_pLikeliHoodArray = new  double*[height];
  43. for(i=0;i <height; i++)
  44. m_pLikeliHoodArray[i] = new double[width];
  45. m_pBinaryArray = new  BYTE*[height];
  46. for(i=0;i <height; i++)
  47. m_pBinaryArray[i] = new BYTE[width];
  48. }
  49. ////////////////////////////////////////////////////////////////////////
  50. //析构函数
  51. ////////////////////////////////////////////////////////////////////////
  52. CLikelyHood::~CLikelyHood()
  53. {
  54. if(m_pLikeliHoodArray!=NULL)
  55. {
  56. for(int i=0;i<m_nHeight;i++)
  57. if(m_pLikeliHoodArray[i]!=NULL) delete m_pLikeliHoodArray[i];
  58. delete m_pLikeliHoodArray;
  59. }
  60. if(m_pBinaryArray!=NULL)
  61. {
  62. for(int i=0;i<m_nHeight;i++)
  63. if(m_pBinaryArray[i]!=NULL) delete m_pBinaryArray[i];
  64. delete m_pBinaryArray;
  65. }
  66. }
  67. //////////////////////////////////////////////////////////////////////////
  68. //计算相似度
  69. //////////////////////////////////////////////////////////////////////////
  70. void CLikelyHood::CalLikeHood()
  71. {
  72. int i,j;
  73. for(i=0; i<m_nHeight; i++)
  74. {
  75. for(j=0; j<m_nWidth; j++)
  76. {
  77. double x1,x2;
  78. TCbCr temp = CalCbCr(m_pSourceData[i][j].rgbRed,m_pSourceData[i][j].rgbGreen,m_pSourceData[i][j].rgbBlue);
  79. x1 = temp.Cb-bmean;
  80. x2 = temp.Cr-rmean;
  81. double t;
  82. t = x1*(x1*brcov[1][1]-x2*brcov[1][0])+x2*(-x1*brcov[0][1]+x2*brcov[0][0]);
  83. t /= (brcov[0][0]*brcov[1][1]-brcov[0][1]*brcov[1][0]);
  84. t /= (-2);
  85. m_pLikeliHoodArray[i][j] = exp(t);
  86. }
  87. }
  88. filter(m_pLikeliHoodArray,m_nWidth,m_nHeight);
  89. double max = 0.0;
  90. for(i=0; i<m_nHeight; i++)
  91. for(j=0; j<m_nWidth; j++)
  92. if(m_pLikeliHoodArray[i][j] > max) 
  93. max = m_pLikeliHoodArray[i][j];
  94. for(i=0; i<m_nHeight; i++)
  95. {
  96. for(j=0; j<m_nWidth; j++)
  97. {
  98. m_pLikeliHoodArray[i][j] /= max;
  99. }
  100. }
  101. m_bLikeliHoodReady = true;
  102. }
  103. ///////////////////////////////////////////////////////////////////////////////
  104. //计算Cb,Cr
  105. ///////////////////////////////////////////////////////////////////////////////
  106. TCbCr CLikelyHood::CalCbCr(int R, int G, int B)
  107. {
  108. TCbCr res;
  109. res.Cb =( 128 - 37.797 * R/255 - 74.203 * G/255 +   112 * B/255);
  110. res.Cr =( 128 + 112    * R/255 - 93.786 * G/255 -18.214 * B/255);
  111. return res;
  112. }
  113. ///////////////////////////////////////////////////////////////////////////////
  114. //滤波
  115. ///////////////////////////////////////////////////////////////////////////////
  116. void CLikelyHood::filter(double** source,int m_nWidth,int m_nHeight)
  117. {
  118. int i,j;
  119. double **temp;
  120. //申请一个临时二维数组
  121. temp = new  double*[m_nHeight+2];
  122. for(i=0;i <=m_nHeight+1; i++)
  123. temp[i] = new double[m_nWidth+2];
  124. //边界均设为0
  125. for(i=0; i<=m_nHeight+1; i++)
  126. {
  127. temp[i][0] = 0;
  128. temp[i][m_nWidth+1] = 0;
  129. }
  130. for(j=0; j<=m_nWidth+1; j++)
  131. {
  132. temp[0][j] = 0;
  133. temp[m_nHeight+1][j] = 0;
  134. }
  135. //将原数组的值赋予临时数组
  136. for(i=0; i<m_nHeight; i++)
  137. for(j=0; j<m_nWidth; j++)
  138. temp[i+1][j+1] = source[i][j];
  139. //均值滤波
  140. for(i=0; i<m_nHeight; i++)
  141. {
  142. for(j=0; j<m_nWidth; j++)
  143. {
  144. source[i][j] = 0;
  145. for(int k=0;k<=2;k++)
  146. for(int l=0;l<=2;l++)
  147. source[i][j] += temp[i+k][j+l];
  148. source[i][j] /= 9;
  149. }
  150. }
  151. if(temp!=NULL)
  152. {
  153. for(int i=0;i<=m_nHeight+1;i++)
  154. if(temp[i]!=NULL) delete temp[i];
  155. delete temp;
  156. }
  157. }
  158. //////////////////////////////////////////////////////////////////////////
  159. //二值化图像
  160. //////////////////////////////////////////////////////////////////////////
  161. bool CLikelyHood::CalBinary()
  162. {
  163. if(!m_bLikeliHoodReady) 
  164. return false;
  165. int i,j;
  166. BYTE **temp;
  167. temp = new  BYTE*[m_nHeight];
  168. for(i=0;i <m_nHeight; i++)
  169. {
  170. temp[i] = new BYTE[m_nWidth];
  171. for(j=0; j<m_nWidth; j++) 
  172. temp[i][j] = 0;
  173. }
  174. double min = 10000000000000000.0;
  175. int index = -1;
  176. for(int k=5;k>=0;k--)
  177. {
  178. double sum = 0;
  179. for(i=0; i<m_nHeight; i++)
  180. for(j=0; j<m_nWidth; j++)
  181. {
  182. if(m_pLikeliHoodArray[i][j]>k*0.1+0.05)
  183. m_pBinaryArray[i][j] = 1;
  184. else
  185. m_pBinaryArray[i][j] = 0;
  186. sum += (m_pBinaryArray[i][j]-temp[i][j]);
  187. }
  188. if(sum < min)
  189. {
  190. min = sum;
  191. index = 6-k;
  192. }
  193.     for(i=0; i<m_nHeight; i++)
  194.     for(j=0; j<m_nWidth; j++)
  195. temp[i][j] = m_pBinaryArray[i][j];
  196. }
  197. double optimalThreshold = (7-index)*0.1;
  198. for(i=0; i<m_nHeight; i++)
  199. for(j=0; j<m_nWidth; j++)
  200. {
  201. if(m_pLikeliHoodArray[i][j]>optimalThreshold)
  202. m_pBinaryArray[i][j] = 1;
  203. else
  204. m_pBinaryArray[i][j] = 0;
  205. }
  206. if(temp!=NULL)
  207. {
  208. for(int i=0;i<=m_nHeight-1;i++)
  209. if(temp[i]!=NULL) delete temp[i];
  210. delete temp;
  211. }
  212. m_bBinaryReady = true;
  213. return true;
  214. }
  215. /////////////////////////////////////////////////////////////////////////
  216. //功能:训练参数
  217. //参数:DirectPath-Bmp文件路径
  218. /////////////////////////////////////////////////////////////////////////
  219. int CLikelyHood::CalParameter(CString DirectPath)
  220. {
  221. WIN32_FIND_DATA FindFileData;
  222. HANDLE hFind;
  223. BOOL  FINDOVER=TRUE;
  224. hFind = FindFirstFile(DirectPath+"\*.bmp", &FindFileData);
  225. if (hFind == INVALID_HANDLE_VALUE)
  226. {
  227. return 0;
  228. }
  229. int filenum = 0;
  230. while(FINDOVER)
  231. {
  232. CString m_sOpenFileName=DirectPath+FindFileData.cFileName;
  233. filenum ++;
  234. FINDOVER=FindNextFile(hFind,&FindFileData);
  235. }
  236. FindClose(hFind);
  237. double **CrList,**CbList;
  238. CrList = new double*[filenum];
  239. CbList = new double*[filenum];
  240. int* mapLength = new int[filenum];
  241. FINDOVER=TRUE;
  242. BOOL FileOK=true;
  243. int index = 0;
  244. hFind = FindFirstFile(DirectPath+"\*.bmp", &FindFileData);
  245. while(FINDOVER && FileOK)
  246. {
  247. CString m_sOpenFileName=DirectPath+"\"+FindFileData.cFileName;
  248. CDib * dib;
  249. dib = new CDib();
  250. if(!dib->Open(m_sOpenFileName))
  251. {
  252. AfxMessageBox(m_sOpenFileName+": Invalid File Format! It must be BMP File");
  253. FileOK = false;
  254. }
  255. if(FileOK)
  256. {
  257. int m_nBitMapWidth = dib->GetWidth();
  258. int m_nBitMapHeight= dib->GetHeight();
  259. CrList[index] = new double[m_nBitMapWidth*m_nBitMapHeight];
  260. CbList[index] = new double[m_nBitMapWidth*m_nBitMapHeight];
  261. mapLength[index] = m_nBitMapWidth*m_nBitMapHeight;
  262. BYTE *colorTable;
  263. colorTable = (BYTE *)dib->m_pDibBits;
  264. int byteBitCount  = dib->GetBiBitCount()/8;
  265. int count = 0;
  266. double **tempCr,**tempCb;
  267. tempCr = new  double*[m_nBitMapHeight];
  268. tempCb = new  double*[m_nBitMapHeight];
  269. for(int i=0;i <m_nBitMapHeight; i++)
  270. {
  271. tempCr[i] = new double[m_nBitMapWidth];
  272. tempCb[i] = new double[m_nBitMapWidth];
  273. }
  274. for(i=m_nBitMapHeight-1; i>=0; i--)
  275. {
  276. for(int j=0; j<m_nBitMapWidth; j++)
  277. {
  278. TCbCr temp = CalCbCr(colorTable[count+2],colorTable[count+1],colorTable[count]);
  279. tempCr[i][j] = temp.Cr;
  280. tempCb[i][j] = temp.Cb;
  281. //int q = m_nBitMapWidth*(m_nBitMapHeight-1-i)+j;
  282. //CrList[index][q]= temp.Cr;
  283. //CbList[index][q]= temp.Cb;
  284. count += byteBitCount;
  285. }
  286. count += (4-(m_nBitMapWidth*byteBitCount)%4)%4;
  287. }
  288. filter(tempCr,m_nBitMapWidth,m_nBitMapHeight);
  289. filter(tempCb,m_nBitMapWidth,m_nBitMapHeight);
  290. for(i=0 ; i<m_nBitMapHeight; i++)
  291. {
  292. for(int j=0; j<m_nBitMapWidth; j++)
  293. {
  294. int q = m_nBitMapWidth*i+j;
  295. CrList[index][q]= tempCr[i][j];
  296. CbList[index][q]= tempCb[i][j];
  297. }
  298. }
  299. for(i=0;i<m_nBitMapHeight;i++)
  300. {
  301. delete tempCr[i];
  302. delete tempCb[i];
  303. }
  304. delete tempCr;
  305. delete tempCb;
  306. index++;
  307. }
  308. delete dib;
  309. FINDOVER=FindNextFile(hFind,&FindFileData);
  310. }
  311. FindClose(hFind);
  312. double avgCr = 0;
  313. double avgCb = 0;
  314. double cov00,cov01,cov10,cov11;
  315. cov00 = cov01 = cov10 = cov11 = 0.0;
  316. int totallen = 0;
  317. if(FileOK)
  318. {
  319. for(int i=0;i<filenum;i++)
  320. {
  321. totallen+=mapLength[i];
  322. for(int j=0;j<mapLength[i];j++)
  323. {
  324. avgCr += CrList[i][j];
  325. avgCb += CbList[i][j];
  326. }
  327. }
  328. avgCr /= totallen;
  329. avgCb /= totallen;
  330. for(i=0;i<filenum;i++)
  331. {
  332. for(int j=0;j<mapLength[i];j++)
  333. {
  334. cov11 += (CrList[i][j]-avgCr)*(CrList[i][j]-avgCr);
  335. cov00 += (CbList[i][j]-avgCb)*(CbList[i][j]-avgCb);
  336. cov01 += (CrList[i][j]-avgCr)*(CbList[i][j]-avgCb);
  337. }
  338. }
  339. cov00 /= totallen;
  340. cov01 /= totallen;
  341. cov10 = cov01;
  342. cov11 /= totallen;
  343. }
  344. for(int i=0;i<filenum;i++)
  345. {
  346. if(CrList[i]!=NULL) delete CrList[i];
  347. if(CbList[i]!=NULL) delete CbList[i];
  348. }
  349. delete mapLength;
  350. if(!FileOK) return 1;
  351. if((cov00*cov11-cov01*cov01) == 0) return 2;
  352. bmean =  avgCb;
  353. rmean =  avgCr;
  354. brcov[0][0] =  cov00;
  355. brcov[0][1] =  cov01;
  356. brcov[1][0] =  cov10;
  357. brcov[1][1] =  cov11;
  358. return 3;
  359. }