StaticDetect.cpp
上传用户:smdfuse
上传日期:2015-11-06
资源大小:98k
文件大小:12k
- /*******************************************************************
- Motion target detection methods in video
- Author: jianglong
- date: 2006.06
- Compiler: Microsoft Visual C++ 6.0
- ********************************************************************/
- #include "stdafx.h"
- //#include "Motiontrack.h"
- #include "StaticDetect.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CStatsticDetect::CStatsticDetect(int nwidth, int nheight)
- {
- m_nFrame = 0;
- count = 0;
- WIDTH = nwidth;
- HEIGHT = nheight;
- IMAGESIZE = WIDTH*HEIGHT;
-
- m_pCurImage = new BYTE[IMAGESIZE*3];
- memset(m_pCurImage,0,IMAGESIZE*3);
- m_pGrayImage = new BYTE[IMAGESIZE];
- memset(m_pGrayImage,0,IMAGESIZE);
- m_pBackground = new BYTE[IMAGESIZE];
- memset(m_pBackground,0,IMAGESIZE);
- m_pBgImage = new BYTE[IMAGESIZE*3];
- memset(m_pBgImage,0,IMAGESIZE*3);
- m_pDiffImage = new BYTE[IMAGESIZE];
- memset(m_pDiffImage,0,IMAGESIZE);
- m_pDetectImage = new BYTE[IMAGESIZE*3];
- memset(m_pDetectImage,0,IMAGESIZE*3);
- m_pBackHistgram = new short int[IMAGESIZE*256];
- memset(m_pBackHistgram,0,IMAGESIZE*256*sizeof(short int));
- m_pTemplate = new UINT[IMAGESIZE];
- memset(m_pTemplate,0,IMAGESIZE*sizeof(UINT));
- m_pPreGrayImage = new BYTE[IMAGESIZE];
- memset(m_pPreGrayImage,0,IMAGESIZE);
- image1 = new BYTE[IMAGESIZE];
- memset(image1,0,IMAGESIZE);
- image2 = new BYTE[IMAGESIZE];
- memset(image2,0,IMAGESIZE);
- image3 = new BYTE[IMAGESIZE];
- memset(image3,0,IMAGESIZE);
- image4 = new BYTE[IMAGESIZE];
- memset(image4,0,IMAGESIZE);
- }
- CStatsticDetect::~CStatsticDetect()
- {
- delete []m_pBackHistgram;
- delete []m_pDiffImage;
- delete []m_pBgImage;
- delete []m_pGrayImage;
- delete []m_pBackground;
- delete []m_pDetectImage;
- delete []m_pCurImage;
- delete []m_pTemplate;
- delete []image1;
- delete []image2;
- delete []image3;
- delete []image4;
- }
- void CStatsticDetect::ReceiveFrame(int index,BYTE* sBuf, DETECT_METHOD sMethod)
- {
- m_nFrame = index;
- memcpy(m_pCurImage,sBuf,WIDTH*HEIGHT*3);
- RGBToYUV(m_pCurImage,m_pGrayImage,WIDTH,HEIGHT);
- // if(index==1256)
- // SaveBmp(m_pGrayImage,WIDTH,HEIGHT,8,index);
-
- switch(sMethod)
- {
- case D_MULDIFFER:
- // ImageCopy(m_pGrayImage, m_nFrame);
- // if(m_nFrame>2)
- // {
- // MDiffImage(m_pDiffImage,WIDTH,HEIGHT,15);
- // DeNoise(m_pDiffImage,WIDTH,HEIGHT);
- //// SaveBmp(m_pDiffImage,WIDTH,HEIGHT,8,index);
- // }
- if(m_nFrame>0)
- {
- DiffImage(m_pGrayImage,m_pPreGrayImage,WIDTH,HEIGHT,20);
- DeNoise(m_pDiffImage,WIDTH,HEIGHT);
- }
- memcpy(m_pPreGrayImage,m_pGrayImage,IMAGESIZE);
- break;
- case D_MULMEAN:
- GetMultiData(m_pGrayImage,WIDTH,HEIGHT);
-
- if(m_nFrame>BACK_ALL_NUM)
- {
- if(m_nFrame==(BACK_ALL_NUM+1))
- {
- GetBgImage();
- memset(m_pTemplate,0,IMAGESIZE*sizeof(UINT));
- count = 0;
- SaveBmp(m_pBackground,WIDTH,HEIGHT,8,index);
- }
- else if(m_nFrame%(2*BACK_ALL_NUM)==1) //更新背景图像
- {
- GetBgImage();
- memset(m_pTemplate,0,IMAGESIZE*sizeof(UINT));
- count = 0;
- SaveBmp(m_pBackground,WIDTH,HEIGHT,8,index);
- }
-
- DiffImage(m_pGrayImage,m_pBackground,WIDTH,HEIGHT,THRESHOLD);
- DeNoise(m_pDiffImage,WIDTH,HEIGHT);
- }
-
- break;
- case D_STATISTIC:
- if(m_nFrame%BACK_SEQ_NUM==1)
- SetBgHistgram(m_pBackHistgram,m_pGrayImage,WIDTH,HEIGHT);
-
- if(m_nFrame>BACK_ALL_NUM)
- {
- if(m_nFrame==(BACK_ALL_NUM+1))
- {
- GetBgByHistgram(m_pBackHistgram,m_pBackground,WIDTH,HEIGHT);
- memset(m_pBackHistgram,0,WIDTH*HEIGHT*256*sizeof(short int));
- // SaveBmp(m_pBackground,WIDTH,HEIGHT,8,index);
-
- }
- else if(m_nFrame%(3*BACK_ALL_NUM)==1) //更新背景图像
- {
- GetBgByHistgram(m_pBackHistgram,m_pBackground,WIDTH,HEIGHT);
- memset(m_pBackHistgram,0,WIDTH*HEIGHT*256*sizeof(short int));
- // SaveBmp(m_pBackground,WIDTH,HEIGHT,8,index);
-
- }
- DiffImage(m_pGrayImage,m_pBackground,WIDTH,HEIGHT,THRESHOLD);
- DeNoise(m_pDiffImage,WIDTH,HEIGHT);
- if(index==1257)
- SaveBmp(m_pDiffImage,WIDTH,HEIGHT,8,index);
- }
- break;
- default:
- break;
- }
-
- }
- void CStatsticDetect::RGBToYUV(BYTE *sRGB,BYTE *sGray,int nWidth, int nHeight)
- {
- int i,j;
- for(j=0;j<nHeight;j++)
- {
- for(i=0;i<nWidth;i++)
- {
- 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;
- }
- }
- }
- void CStatsticDetect::SetBgHistgram(short int *pHistgram, BYTE *sGray,int nWidth, int nHeight)
- {
- for(int j=0;j<nHeight;j++)
- {
- for(int i=0;i<nWidth;i++)
- {
- int p=*(sGray+j*nWidth+i)+256*(j*nWidth+i);
- *(pHistgram+p)=*(pHistgram+p)+1;
- }
- }
- }
- BOOL CStatsticDetect::GetBgByHistgram(short int *pHistgram,BYTE *sBg,int nWidth,int nHeight)
- {
- int j,i,k;
- for(j=0;j<nHeight;j++)
- {
- for(i=0;i<nWidth;i++)
- {
- int c=0;
- int color=0;
- for(k=0;k<256;k++)
- {
- if(*(pHistgram+256*(j*nWidth+i)+k)>c)
- {
- c=*(pHistgram+256*(j*nWidth+i)+k);
- color=k;
- }
- }
- *(sBg+j*nWidth+i)=color;
- }
- }
- for(j=0;j<nHeight;j++)
- {
- for( i=0;i<nWidth;i++)
- {
- memset(m_pBgImage+(nWidth*j+i)*3,*(sBg+j*nWidth+i),3);
- }
- }
- return TRUE;
- }
- void CStatsticDetect::DiffImage(BYTE *sGray,BYTE *pGray,int nWidth, int nHeight,int nThreshold)
- {
- int i,j;
- for(j=0;j<nHeight;j++)
- {
- for(i=0;i<nWidth;i++)
- {
- int diff=sGray[j*nWidth+i]-pGray[nWidth*j+i];
- // m_pDiffImage[j*nWidth+i] = BYTE(abs(diff));
-
- if(diff>nThreshold||diff<-nThreshold)
- {
- m_pDiffImage[j*nWidth+i]=255;
- }
- else
- {
- m_pDiffImage[j*nWidth+i]=0;
- }
- }
- }
- }
- void CStatsticDetect::DeNoise(BYTE *sGray,int nWidth, int nHeight)
- {
- int mode[3][3] = {-1,0,-1,-1,0,-1,-1,0,-1};
- Erosion(sGray,nWidth,nHeight,mode);
- // Dilation(sGray,nWidth,nHeight,mode);
- Medianfilter_3x3(sGray,nWidth,nHeight);
- for(int j=0;j<nHeight;j++)
- {
- for(int i=0;i<nWidth;i++)
- {
- memset(m_pDetectImage+(nWidth*j+i)*3, *(m_pDiffImage+j*nWidth+i), 3);
- }
- }
- }
- void CStatsticDetect::Medianfilter_3x3(BYTE *sGray, int nWidth, int nHeight)
- {
- int i,j,k,l,count;
- int ii,mid;
- BYTE mean[9];
- int ImageWidth, ImageHeight;
- ImageWidth = nWidth;
- ImageHeight = nHeight;
-
- BYTE* pBuf=new BYTE[ImageWidth*ImageHeight];
- for(i=1;i<ImageHeight-1;i++)
- {
- for(j=1;j<ImageWidth-1;j++)
- {
- count = 0;
- for(k=-1;k<=1;k++)
- {
- for(l=-1;l<=1;l++)
- {
- mean[count]=sGray[(k+i)*ImageWidth+l+j];
- count++;
- }
- }
- for(k=0;k<9;k++)
- {
- mid=mean[k];
- ii=k;
- for(l=k+1;l<9;l++)
- {
- if(mid>mean[l])
- {
- mid=mean[l];
- ii=l;
- }
- }
- mean[ii]=mean[k];
- mean[k]=mid;
- }
- pBuf[i*ImageWidth+j]= mean[4];
- }
- }
- memcpy(sGray,pBuf,sizeof(BYTE)*ImageWidth*ImageHeight);
- delete []pBuf;
- }
- void CStatsticDetect::Dilation(BYTE *sGray,int nWidth, int nHeight,int structure[3][3])
- {
- BYTE* t_gray = new BYTE[nWidth*nHeight];
- BYTE pixel;
- int i,j,m,n;
- for(j=1;j<nHeight-1;j++)
- {
- for(i=1;i<nWidth-1;i++)
- {
- t_gray[j*nWidth+i] = (BYTE)0;
- for (m = 0;m < 3;m++ )
- {
- for (n = 0;n < 3;n++)
- {
- if( structure[m][n] == -1)
- continue;
- pixel = sGray[(j+(m-2)+1)*nWidth + i + (n-1)];
- if (pixel == 255 )
- {
- t_gray[j*nWidth+i] = (BYTE)255;
- break;
- }
- }
- }
-
- }
- }
- memcpy(sGray,t_gray,nWidth*nHeight);
- delete []t_gray;
- }
- void CStatsticDetect::Erosion(BYTE *sGray,int nWidth, int nHeight,int structure[3][3])
- {
- BYTE* t_gray = new BYTE[nWidth*nHeight];
- BYTE pixel;
- int i,j,m,n;
- for(j=1;j<nHeight-1;j++)
- {
- for(i=1;i<nWidth-1;i++)
- {
- t_gray[j*nWidth+i] = (BYTE)255;
- for (m = 0;m < 3;m++ )
- {
- for (n = 0;n < 3;n++)
- {
- if( structure[m][n] == -1)
- continue;
- pixel = sGray[(j+(m-2)+1)*nWidth + i + (n-1)];
- if (pixel == 0 )
- {
- t_gray[j*nWidth+i] = (BYTE)0;
- break;
- }
- }
- }
-
- }
- }
- memcpy(sGray,t_gray,nWidth*nHeight);
- delete []t_gray;
- }
- void CStatsticDetect::GetMultiData(BYTE *sGray,int nWidth, int nHeight)
- {
- count++;
- for(int j=0;j<nHeight;j++)
- for(int i=0;i<nWidth;i++)
- m_pTemplate[j*nWidth+i]+=sGray[j*nWidth+i];
- }
- void CStatsticDetect::GetBgImage()
- {
- int i,j,t,pixel;
- for(j=0;j<HEIGHT;j++)
- {
- for(i=0;i<WIDTH;i++)
- {
- t = j*WIDTH+i;
- pixel = UINT(m_pTemplate[t]/count+0.5);
- if(pixel>255)
- m_pBackground[t] = BYTE(255);
- else if(pixel<0)
- m_pBackground[t] = BYTE(0);
- else
- m_pBackground[t] = BYTE(pixel);
- }
- }
- }
- void CStatsticDetect::SaveBmp(BYTE* buffer,int nwidth, int nheight, int bit, int index)
- {
- //write bmp
- BITMAPFILEHEADER bfh;
- bfh.bfType=0X4D42;
- bfh.bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256 + nheight*nwidth);
- bfh.bfReserved1=0;
- bfh.bfReserved2=0;
- bfh.bfOffBits=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256);
-
- BITMAPINFOHEADER bih;
- bih.biSize=sizeof(BITMAPINFOHEADER);
- bih.biWidth=nwidth;
- bih.biHeight=nheight;
- bih.biPlanes=1;
- bih.biBitCount=bit;
- bih.biCompression=BI_RGB;
- bih.biSizeImage=nheight*nwidth;
- bih.biXPelsPerMeter = 0;
- bih.biYPelsPerMeter = 0;
- bih.biClrUsed = 0;
- bih.biClrImportant = 0;
-
- RGBQUAD palate[256];
- for(int t=0;t<256;t++)
- {
- palate[t].rgbBlue=(BYTE)t;
- palate[t].rgbGreen=(BYTE)t;
- palate[t].rgbRed=(BYTE)t;
- palate[t].rgbReserved=0;
- }
- int bpl = (nwidth*8+31)/32*4;
- int imageSize = nheight*bpl;
- BYTE* imgData = NULL;
- if(bit == 8)
- {
- imgData = new BYTE[imageSize];
- memcpy(imgData, buffer, imageSize);
- }
- if(bit == 24)
- {
- imgData = new BYTE[imageSize*3];
- memcpy(imgData, buffer, imageSize*3);
- }
- CFile fp;
- CString path ;
- path.Format("Frame%03d.bmp",index);
-
- TRY
- {
- fp.Open("F:\"+path,CFile::modeCreate | CFile::modeWrite);
- fp.Write((LPSTR)&bfh,sizeof(BITMAPFILEHEADER)); //写文件头
- fp.Write((LPSTR)&bih,sizeof(BITMAPINFOHEADER)); //写信息头
- if(bit==8)
- fp.Write((LPSTR)palate,sizeof(RGBQUAD)*256); //写调色板
- fp.Write(imgData,nheight*nwidth);//写数据
- }
- CATCH(CFileException,e)
- {
- THROW_LAST();
- }
- END_CATCH
-
- delete []imgData;
- imgData = NULL;
- fp.Close();
- }
- void CStatsticDetect::ImageCopy(BYTE *sGray, int m_num)
- {
- if(m_num==0)
- {
- memcpy(image1,sGray,IMAGESIZE);
- }
- else if(m_num==1)
- {
- memcpy(image2,sGray,IMAGESIZE);
- }
- else if(m_num==2)
- {
- memcpy(image3,sGray,IMAGESIZE);
- }
- else if(m_num==4)
- {
- memcpy(image4,sGray,IMAGESIZE);
- }
- else
- {
- memcpy(image1,image2,IMAGESIZE);
- memcpy(image2,image3,IMAGESIZE);
- memcpy(image3,image4,IMAGESIZE);
- memcpy(image4,sGray,IMAGESIZE);
- }
- }
- void CStatsticDetect::Subtract(BYTE *nImage, BYTE *nImage1, BYTE *nImage2, int nWidth, int nHeight, int nThresh)
- {
- int i,j;
- for(j=0;j<nHeight;j++)
- {
- for(i=0;i<nWidth;i++)
- {
- int t = j*nWidth+i;
- nImage[t] = nImage1[t]-nImage2[t];
-
- if(abs(nImage[t])>nThresh)
- nImage[t] = 1;
- else
- nImage[t] = 0;
- }
- }
- }
- void CStatsticDetect::MDiffImage(BYTE *sGray,int nWidth, int nHeight, int nthresh)
- {
- BYTE *temp1 = new BYTE[nWidth*nHeight];
- BYTE *temp2 = new BYTE[nWidth*nHeight];
- Subtract(temp1, image1, image3, nWidth, nHeight, nthresh);
- Subtract(temp2, image2, image4, nWidth, nHeight, nthresh);
-
- int i,j;
- // for(j=0;j<nHeight;j++)
- // {
- // for(i=0;i<nWidth;i++)
- // {
- // int t=j*nWidth+i;
- // if(temp1[t]==1)
- // temp1[t] = 255;
- // else
- // temp1[t] = 0;
- //
- // if(temp2[t]==1)
- // temp2[t] = 255;
- // else
- // temp2[t] = 0;
- //
- // }
- // }
- //
- // DeNoise(temp1,WIDTH,HEIGHT);
- // SaveBmp(temp1,WIDTH,HEIGHT,8,7000);
- // DeNoise(temp2,WIDTH,HEIGHT);
- // SaveBmp(temp2,WIDTH,HEIGHT,8,7001);
- bool p;
- for(j=0;j<nHeight;j++)
- {
- for(i=0;i<nWidth;i++)
- {
- int t=j*nWidth+i;
- p = temp1[t] && temp2[t];
- if(p)
- sGray[t] = 255;
- else
- sGray[t] = 0;
- }
- }
- delete []temp1;
- delete []temp2;
- }