📄 staticdetect.cpp
字号:
/*******************************************************************
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -