StaticDetect.cpp
上传用户:smdfuse
上传日期:2015-11-06
资源大小:98k
文件大小:12k
源码类别:

图形图象

开发平台:

Visual C++

  1. /*******************************************************************
  2. Motion target detection methods in video
  3. Author: jianglong
  4. date: 2006.06
  5. Compiler: Microsoft Visual C++ 6.0 
  6. ********************************************************************/
  7. #include "stdafx.h"
  8. //#include "Motiontrack.h"
  9. #include "StaticDetect.h"
  10. #ifdef _DEBUG
  11. #undef THIS_FILE
  12. static char THIS_FILE[]=__FILE__;
  13. #define new DEBUG_NEW
  14. #endif
  15. //////////////////////////////////////////////////////////////////////
  16. // Construction/Destruction
  17. //////////////////////////////////////////////////////////////////////
  18. CStatsticDetect::CStatsticDetect(int nwidth, int nheight)
  19. {
  20. m_nFrame = 0;
  21. count = 0;
  22. WIDTH = nwidth;
  23. HEIGHT = nheight;
  24. IMAGESIZE = WIDTH*HEIGHT;
  25. m_pCurImage = new BYTE[IMAGESIZE*3];
  26. memset(m_pCurImage,0,IMAGESIZE*3);
  27. m_pGrayImage = new BYTE[IMAGESIZE];
  28. memset(m_pGrayImage,0,IMAGESIZE);
  29. m_pBackground = new BYTE[IMAGESIZE];
  30. memset(m_pBackground,0,IMAGESIZE);
  31. m_pBgImage = new BYTE[IMAGESIZE*3];
  32. memset(m_pBgImage,0,IMAGESIZE*3);
  33.     m_pDiffImage = new BYTE[IMAGESIZE]; 
  34. memset(m_pDiffImage,0,IMAGESIZE);
  35. m_pDetectImage = new BYTE[IMAGESIZE*3];
  36. memset(m_pDetectImage,0,IMAGESIZE*3);
  37. m_pBackHistgram = new short int[IMAGESIZE*256];
  38. memset(m_pBackHistgram,0,IMAGESIZE*256*sizeof(short int));
  39. m_pTemplate = new UINT[IMAGESIZE];
  40. memset(m_pTemplate,0,IMAGESIZE*sizeof(UINT));
  41. m_pPreGrayImage = new BYTE[IMAGESIZE];
  42. memset(m_pPreGrayImage,0,IMAGESIZE);
  43. image1 = new BYTE[IMAGESIZE];
  44. memset(image1,0,IMAGESIZE);
  45. image2 = new BYTE[IMAGESIZE];
  46. memset(image2,0,IMAGESIZE);
  47. image3 = new BYTE[IMAGESIZE];
  48. memset(image3,0,IMAGESIZE);
  49. image4 = new BYTE[IMAGESIZE];
  50. memset(image4,0,IMAGESIZE);
  51. }
  52. CStatsticDetect::~CStatsticDetect()
  53. {
  54. delete []m_pBackHistgram;
  55. delete []m_pDiffImage;
  56. delete []m_pBgImage;
  57. delete []m_pGrayImage;
  58. delete []m_pBackground;
  59. delete []m_pDetectImage;
  60. delete []m_pCurImage;
  61. delete []m_pTemplate;
  62. delete []image1;
  63. delete []image2;
  64. delete []image3;
  65. delete []image4;
  66. }
  67. void CStatsticDetect::ReceiveFrame(int index,BYTE* sBuf, DETECT_METHOD sMethod)
  68. {
  69. m_nFrame = index;
  70. memcpy(m_pCurImage,sBuf,WIDTH*HEIGHT*3);
  71. RGBToYUV(m_pCurImage,m_pGrayImage,WIDTH,HEIGHT);
  72. // if(index==1256)
  73. // SaveBmp(m_pGrayImage,WIDTH,HEIGHT,8,index);
  74. switch(sMethod)
  75. {
  76. case D_MULDIFFER:
  77. // ImageCopy(m_pGrayImage, m_nFrame);
  78. // if(m_nFrame>2)
  79. // {
  80. // MDiffImage(m_pDiffImage,WIDTH,HEIGHT,15);
  81. // DeNoise(m_pDiffImage,WIDTH,HEIGHT);
  82. //// SaveBmp(m_pDiffImage,WIDTH,HEIGHT,8,index);
  83. // }
  84. if(m_nFrame>0)
  85. {
  86. DiffImage(m_pGrayImage,m_pPreGrayImage,WIDTH,HEIGHT,20);
  87. DeNoise(m_pDiffImage,WIDTH,HEIGHT);
  88. }
  89. memcpy(m_pPreGrayImage,m_pGrayImage,IMAGESIZE);
  90. break;
  91. case D_MULMEAN:
  92. GetMultiData(m_pGrayImage,WIDTH,HEIGHT);
  93. if(m_nFrame>BACK_ALL_NUM)
  94. {
  95. if(m_nFrame==(BACK_ALL_NUM+1))
  96. {
  97. GetBgImage();
  98. memset(m_pTemplate,0,IMAGESIZE*sizeof(UINT));
  99. count = 0;
  100. SaveBmp(m_pBackground,WIDTH,HEIGHT,8,index);
  101. }
  102. else if(m_nFrame%(2*BACK_ALL_NUM)==1) //更新背景图像
  103. {
  104. GetBgImage();
  105. memset(m_pTemplate,0,IMAGESIZE*sizeof(UINT));
  106. count = 0;
  107. SaveBmp(m_pBackground,WIDTH,HEIGHT,8,index);
  108. }
  109. DiffImage(m_pGrayImage,m_pBackground,WIDTH,HEIGHT,THRESHOLD);
  110. DeNoise(m_pDiffImage,WIDTH,HEIGHT);
  111. }
  112. break;
  113. case D_STATISTIC:
  114. if(m_nFrame%BACK_SEQ_NUM==1)
  115. SetBgHistgram(m_pBackHistgram,m_pGrayImage,WIDTH,HEIGHT);
  116. if(m_nFrame>BACK_ALL_NUM)
  117. {
  118. if(m_nFrame==(BACK_ALL_NUM+1))
  119. {
  120. GetBgByHistgram(m_pBackHistgram,m_pBackground,WIDTH,HEIGHT);
  121. memset(m_pBackHistgram,0,WIDTH*HEIGHT*256*sizeof(short int));
  122. // SaveBmp(m_pBackground,WIDTH,HEIGHT,8,index);
  123. }
  124. else if(m_nFrame%(3*BACK_ALL_NUM)==1) //更新背景图像
  125. {
  126. GetBgByHistgram(m_pBackHistgram,m_pBackground,WIDTH,HEIGHT);
  127. memset(m_pBackHistgram,0,WIDTH*HEIGHT*256*sizeof(short int));
  128. // SaveBmp(m_pBackground,WIDTH,HEIGHT,8,index);
  129. }
  130. DiffImage(m_pGrayImage,m_pBackground,WIDTH,HEIGHT,THRESHOLD);
  131. DeNoise(m_pDiffImage,WIDTH,HEIGHT);
  132. if(index==1257)
  133. SaveBmp(m_pDiffImage,WIDTH,HEIGHT,8,index);
  134. }
  135. break;
  136. default:
  137. break;
  138. }
  139. }
  140. void CStatsticDetect::RGBToYUV(BYTE *sRGB,BYTE *sGray,int nWidth, int nHeight)
  141. {
  142. int i,j;
  143. for(j=0;j<nHeight;j++)
  144. {
  145. for(i=0;i<nWidth;i++)
  146. {
  147. sGray[nWidth*j+i]=(11*sRGB[3*(nWidth*j+i)]+59*sRGB[3*(nWidth*j+i)+1]+30*sRGB[3*(nWidth*j+i)+2])/100;
  148. }
  149. }
  150. }
  151. void CStatsticDetect::SetBgHistgram(short int *pHistgram, BYTE *sGray,int nWidth, int nHeight)
  152. {
  153. for(int j=0;j<nHeight;j++)
  154. {
  155. for(int i=0;i<nWidth;i++)
  156. {
  157. int p=*(sGray+j*nWidth+i)+256*(j*nWidth+i);
  158. *(pHistgram+p)=*(pHistgram+p)+1;
  159. }
  160. }
  161. }
  162. BOOL CStatsticDetect::GetBgByHistgram(short int *pHistgram,BYTE *sBg,int nWidth,int nHeight)
  163. {
  164. int j,i,k;
  165. for(j=0;j<nHeight;j++)
  166. {
  167. for(i=0;i<nWidth;i++)
  168. {
  169. int c=0; 
  170. int color=0;
  171. for(k=0;k<256;k++)
  172. {
  173. if(*(pHistgram+256*(j*nWidth+i)+k)>c)
  174. {
  175. c=*(pHistgram+256*(j*nWidth+i)+k);
  176. color=k;
  177. }
  178. }
  179. *(sBg+j*nWidth+i)=color;
  180. }
  181. }
  182. for(j=0;j<nHeight;j++)
  183. {
  184. for( i=0;i<nWidth;i++)
  185. {
  186. memset(m_pBgImage+(nWidth*j+i)*3,*(sBg+j*nWidth+i),3);
  187. }
  188. }
  189. return TRUE;
  190. }
  191. void CStatsticDetect::DiffImage(BYTE *sGray,BYTE *pGray,int nWidth, int nHeight,int nThreshold)
  192. {
  193. int i,j;
  194. for(j=0;j<nHeight;j++)
  195. {
  196. for(i=0;i<nWidth;i++)
  197. {
  198. int diff=sGray[j*nWidth+i]-pGray[nWidth*j+i];
  199. // m_pDiffImage[j*nWidth+i] = BYTE(abs(diff));
  200. if(diff>nThreshold||diff<-nThreshold)
  201. {
  202. m_pDiffImage[j*nWidth+i]=255;
  203. }
  204. else
  205. {
  206. m_pDiffImage[j*nWidth+i]=0;
  207. }
  208. }
  209. }
  210. }
  211. void CStatsticDetect::DeNoise(BYTE *sGray,int nWidth, int nHeight)
  212. {
  213. int mode[3][3] = {-1,0,-1,-1,0,-1,-1,0,-1};
  214. Erosion(sGray,nWidth,nHeight,mode);
  215. // Dilation(sGray,nWidth,nHeight,mode);
  216. Medianfilter_3x3(sGray,nWidth,nHeight);
  217. for(int j=0;j<nHeight;j++)
  218. {
  219. for(int i=0;i<nWidth;i++)
  220. {
  221. memset(m_pDetectImage+(nWidth*j+i)*3, *(m_pDiffImage+j*nWidth+i), 3);
  222. }
  223. }
  224. }
  225. void CStatsticDetect::Medianfilter_3x3(BYTE *sGray, int nWidth, int nHeight)
  226. {
  227. int i,j,k,l,count;
  228. int ii,mid;
  229. BYTE mean[9];
  230. int ImageWidth, ImageHeight;
  231. ImageWidth = nWidth;
  232. ImageHeight = nHeight;
  233. BYTE* pBuf=new BYTE[ImageWidth*ImageHeight]; 
  234. for(i=1;i<ImageHeight-1;i++)
  235. {
  236. for(j=1;j<ImageWidth-1;j++)
  237. {
  238. count = 0;
  239. for(k=-1;k<=1;k++)
  240. {
  241. for(l=-1;l<=1;l++)
  242. {
  243. mean[count]=sGray[(k+i)*ImageWidth+l+j];
  244. count++;
  245. }
  246. }
  247. for(k=0;k<9;k++)
  248. {
  249. mid=mean[k];
  250. ii=k;
  251. for(l=k+1;l<9;l++)
  252. {
  253. if(mid>mean[l])
  254. {
  255. mid=mean[l];
  256. ii=l;
  257. }
  258. }
  259. mean[ii]=mean[k];
  260. mean[k]=mid;
  261. }
  262. pBuf[i*ImageWidth+j]= mean[4];
  263. }
  264. }
  265. memcpy(sGray,pBuf,sizeof(BYTE)*ImageWidth*ImageHeight);
  266. delete []pBuf;
  267. }
  268. void CStatsticDetect::Dilation(BYTE *sGray,int nWidth, int nHeight,int structure[3][3])
  269. {
  270. BYTE* t_gray = new BYTE[nWidth*nHeight];
  271. BYTE pixel;
  272. int i,j,m,n;
  273. for(j=1;j<nHeight-1;j++)
  274. {
  275. for(i=1;i<nWidth-1;i++)
  276. {
  277. t_gray[j*nWidth+i] = (BYTE)0;
  278. for (m = 0;m < 3;m++ )
  279. {
  280. for (n = 0;n < 3;n++)
  281. {
  282. if( structure[m][n] == -1)
  283. continue;
  284. pixel = sGray[(j+(m-2)+1)*nWidth + i + (n-1)];
  285. if (pixel == 255 )
  286. {
  287. t_gray[j*nWidth+i] = (BYTE)255;
  288. break;
  289. }
  290. }
  291. }
  292. }
  293. }
  294. memcpy(sGray,t_gray,nWidth*nHeight);
  295. delete []t_gray;
  296. }
  297. void CStatsticDetect::Erosion(BYTE *sGray,int nWidth, int nHeight,int structure[3][3])
  298. {
  299. BYTE* t_gray = new BYTE[nWidth*nHeight];
  300. BYTE pixel;
  301. int i,j,m,n;
  302. for(j=1;j<nHeight-1;j++)
  303. {
  304. for(i=1;i<nWidth-1;i++)
  305. {
  306. t_gray[j*nWidth+i] = (BYTE)255;
  307. for (m = 0;m < 3;m++ )
  308. {
  309. for (n = 0;n < 3;n++)
  310. {
  311. if( structure[m][n] == -1)
  312. continue;
  313. pixel = sGray[(j+(m-2)+1)*nWidth + i + (n-1)];
  314. if (pixel == 0 )
  315. {
  316. t_gray[j*nWidth+i] = (BYTE)0;
  317. break;
  318. }
  319. }
  320. }
  321. }
  322. }
  323. memcpy(sGray,t_gray,nWidth*nHeight);
  324. delete []t_gray;
  325. }
  326. void CStatsticDetect::GetMultiData(BYTE *sGray,int nWidth, int nHeight)
  327. {
  328.     count++;
  329. for(int j=0;j<nHeight;j++)
  330. for(int i=0;i<nWidth;i++)
  331. m_pTemplate[j*nWidth+i]+=sGray[j*nWidth+i];
  332. }
  333. void CStatsticDetect::GetBgImage()
  334. {
  335. int i,j,t,pixel;
  336. for(j=0;j<HEIGHT;j++)
  337. {
  338. for(i=0;i<WIDTH;i++)
  339. {
  340. t = j*WIDTH+i;
  341. pixel = UINT(m_pTemplate[t]/count+0.5);
  342. if(pixel>255)
  343. m_pBackground[t] = BYTE(255);
  344. else if(pixel<0)
  345. m_pBackground[t] = BYTE(0);
  346. else
  347. m_pBackground[t] = BYTE(pixel);
  348. }
  349. }
  350. }
  351. void CStatsticDetect::SaveBmp(BYTE* buffer,int nwidth, int nheight, int bit, int index) 
  352. {
  353. //write bmp
  354. BITMAPFILEHEADER bfh; 
  355. bfh.bfType=0X4D42;
  356. bfh.bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256 + nheight*nwidth);
  357. bfh.bfReserved1=0;
  358. bfh.bfReserved2=0;
  359. bfh.bfOffBits=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256);
  360. BITMAPINFOHEADER bih;
  361. bih.biSize=sizeof(BITMAPINFOHEADER);
  362. bih.biWidth=nwidth;
  363. bih.biHeight=nheight;
  364. bih.biPlanes=1;
  365. bih.biBitCount=bit;
  366. bih.biCompression=BI_RGB;
  367. bih.biSizeImage=nheight*nwidth;
  368. bih.biXPelsPerMeter = 0;
  369. bih.biYPelsPerMeter = 0;
  370. bih.biClrUsed = 0;
  371. bih.biClrImportant = 0;
  372. RGBQUAD palate[256];
  373. for(int t=0;t<256;t++)
  374. {
  375. palate[t].rgbBlue=(BYTE)t;
  376. palate[t].rgbGreen=(BYTE)t;
  377. palate[t].rgbRed=(BYTE)t;
  378. palate[t].rgbReserved=0;
  379. }
  380. int bpl = (nwidth*8+31)/32*4;
  381. int imageSize = nheight*bpl;
  382. BYTE* imgData = NULL;
  383. if(bit == 8)
  384. {
  385. imgData = new BYTE[imageSize];
  386. memcpy(imgData, buffer, imageSize);
  387. }
  388. if(bit == 24)
  389. {
  390. imgData = new BYTE[imageSize*3];
  391. memcpy(imgData, buffer, imageSize*3);
  392. }
  393. CFile fp;
  394. CString path ;
  395. path.Format("Frame%03d.bmp",index);
  396. TRY
  397. {
  398. fp.Open("F:\"+path,CFile::modeCreate | CFile::modeWrite);
  399. fp.Write((LPSTR)&bfh,sizeof(BITMAPFILEHEADER)); //写文件头
  400. fp.Write((LPSTR)&bih,sizeof(BITMAPINFOHEADER)); //写信息头
  401. if(bit==8)
  402. fp.Write((LPSTR)palate,sizeof(RGBQUAD)*256); //写调色板
  403. fp.Write(imgData,nheight*nwidth);//写数据
  404. }
  405. CATCH(CFileException,e)
  406. {
  407. THROW_LAST();
  408. }
  409. END_CATCH
  410. delete []imgData;
  411. imgData = NULL;
  412. fp.Close();
  413. }
  414. void CStatsticDetect::ImageCopy(BYTE *sGray, int m_num)
  415. {
  416. if(m_num==0) 
  417. {
  418. memcpy(image1,sGray,IMAGESIZE);
  419. }
  420. else if(m_num==1)
  421. {
  422. memcpy(image2,sGray,IMAGESIZE);
  423. }
  424. else if(m_num==2)
  425. {
  426. memcpy(image3,sGray,IMAGESIZE);
  427. }
  428. else if(m_num==4)
  429. {
  430. memcpy(image4,sGray,IMAGESIZE);
  431. }
  432. else
  433. {
  434. memcpy(image1,image2,IMAGESIZE);
  435. memcpy(image2,image3,IMAGESIZE);
  436. memcpy(image3,image4,IMAGESIZE);
  437. memcpy(image4,sGray,IMAGESIZE);
  438. }
  439. }
  440. void CStatsticDetect::Subtract(BYTE *nImage, BYTE *nImage1, BYTE *nImage2, int nWidth, int nHeight, int nThresh)
  441. {
  442. int i,j;
  443. for(j=0;j<nHeight;j++)
  444. {
  445. for(i=0;i<nWidth;i++)
  446. {
  447. int t = j*nWidth+i;
  448. nImage[t] = nImage1[t]-nImage2[t];
  449. if(abs(nImage[t])>nThresh) 
  450. nImage[t] = 1;
  451. else
  452. nImage[t] = 0;
  453. }
  454. }
  455. }
  456. void CStatsticDetect::MDiffImage(BYTE *sGray,int nWidth, int nHeight, int nthresh)
  457. {
  458. BYTE *temp1 = new BYTE[nWidth*nHeight];
  459. BYTE *temp2 = new BYTE[nWidth*nHeight];
  460. Subtract(temp1, image1, image3, nWidth, nHeight, nthresh);
  461. Subtract(temp2, image2, image4, nWidth, nHeight, nthresh);
  462. int i,j;
  463. // for(j=0;j<nHeight;j++)
  464. // {
  465. // for(i=0;i<nWidth;i++)
  466. // {
  467. // int t=j*nWidth+i;
  468. // if(temp1[t]==1)
  469. // temp1[t] = 255;
  470. // else
  471. // temp1[t] = 0;
  472. //
  473. // if(temp2[t]==1)
  474. // temp2[t] = 255;
  475. // else
  476. // temp2[t] = 0;
  477. //
  478. // }
  479. // }
  480. //
  481. //    DeNoise(temp1,WIDTH,HEIGHT);
  482. // SaveBmp(temp1,WIDTH,HEIGHT,8,7000);
  483. //    DeNoise(temp2,WIDTH,HEIGHT);
  484. // SaveBmp(temp2,WIDTH,HEIGHT,8,7001);
  485.     bool p;
  486. for(j=0;j<nHeight;j++)
  487. {
  488. for(i=0;i<nWidth;i++)
  489. {
  490. int t=j*nWidth+i;
  491. p = temp1[t] && temp2[t];
  492. if(p)
  493. sGray[t] = 255;
  494. else
  495. sGray[t] = 0;
  496. }
  497. }
  498. delete []temp1;
  499. delete []temp2;
  500. }