LikelyHood.cpp
上传用户:sdsuchuang
上传日期:2013-01-12
资源大小:2228k
文件大小:10k
源码类别:

图形图像处理

开发平台:

Visual C++

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