📄 testdlg.cpp
字号:
// TestDlg.cpp : implementation file
//
#include "stdafx.h"
//#include "CLjp.h"
//#include "TestDlg.h"
#include "vfw.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTestDlg dialog
//DEL
//DEL CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
//DEL : CDialog(CTestDlg::IDD, pParent)
//DEL {
AVIFileInit();
m_pbuff=NULL;
m_length=0;
m_nw=0;
m_nh=0;
m_state="没有车来";
m_timeinterval=100;
m_curframe=1;
//{{AFX_DATA_INIT(CTestDlg)
m_firstframe = 1;
m_curframe = 0;
m_length = 0;
m_state = _T("没有车来");
//}}AFX_DATA_INIT
}
void CTestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTestDlg)
DDX_Control(pDX, IDC_STOP, m_stop);
DDX_Control(pDX, IDC_START, m_start);
DDX_Control(pDX, IDC_PAUSE, m_pause);
DDX_Control(pDX, IDC_OPEN, m_open);
DDX_Text(pDX, IDC_EDIT1, m_firstframe);
DDX_Text(pDX, IDC_EDIT2, m_curframe);
DDX_Text(pDX, IDC_EDIT3, m_length);
DDX_Text(pDX, IDC_EDIT4, m_state);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
//{{AFX_MSG_MAP(CTestDlg)
ON_BN_CLICKED(IDC_OPEN, OnOpen)
ON_BN_CLICKED(IDC_START, OnStart)
ON_BN_CLICKED(IDC_PAUSE, OnPause)
ON_BN_CLICKED(IDC_STOP, OnStop)
ON_WM_PAINT()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTestDlg message handlers
void CTestDlg::OnOpen()
{
// TODO: Add your control notification handler code here
CFileDialog dlg(TRUE,"AVI文件(.avi)|*.avi||",NULL,OFN_HIDEREADONLY,
"AVI文件(.avi)|*.avi||",NULL);
CString filename;
if(dlg.DoModal()==IDOK)
{
filename=dlg.GetPathName();
//初始化
initiate(filename);
show();
//按钮使能,置灰
m_open.EnableWindow(FALSE);
m_start.EnableWindow(TRUE);
m_pause.EnableWindow(FALSE);
m_stop.EnableWindow(FALSE);
// m_confirmation.EnableWindow(TRUE);
m_bopen=true;
UpdateData(FALSE);
//Invalidate(1);
}
}
void CTestDlg::OnStart()
{
// TODO: Add your control notification handler code here
if(m_bopen!=true)
return;
m_curframe=0;
//初始化第一个背景
background1=new BYTE[m_nw*m_nh];
curground1=new BYTE[m_nw*m_nh];
m_pbuff=(BYTE *)AVIStreamGetFrame(m_pgf,m_firstframe);//提取单帧是packed DIB
m_pbuff+=40;
int i,j;
for(i=0;i<240;i++) //取位置140~150行;180~240列为背景范围
for( j=0;j<320;j++)
{
background1[i*240+j]=m_pbuff[i*3*m_nw+j*3]*0.11
+m_pbuff[i*3*m_nw+j*3+1]*0.59
+m_pbuff[i*3*m_nw+j*3+2]*0.3;
//m_bkmean+=background1[i*m_nh+j];
}
// m_bkmean=m_bkmean/(m_nh*m_nw);
// m_frontstate=false;
// m_nowstate=false;
// m_bkchange=0;
//按钮使能,置灰
m_pause.EnableWindow(TRUE);
m_stop.EnableWindow(TRUE);
m_open.EnableWindow(FALSE);
m_start.EnableWindow(FALSE);
// m_confirmation.EnableWindow(FALSE);
// m_number_car=0;
// SetTimer(1,m_timeinterval,NULL);
SetTimer(1,40,NULL);
}
void CTestDlg::OnPause()
{
// TODO: Add your control notification handler code here
KillTimer(1);
//按钮使能,置灰
m_open.EnableWindow(TRUE);
m_start.EnableWindow(TRUE);
m_pause.EnableWindow(FALSE);
m_stop.EnableWindow(FALSE);
}
void CTestDlg::OnStop()
{
// TODO: Add your control notification handler code here
KillTimer(1);
m_curframe=0;
//按钮使能,置灰
m_open.EnableWindow(TRUE);
m_start.EnableWindow(TRUE);
m_pause.EnableWindow(FALSE);
m_stop.EnableWindow(FALSE);
}
void CTestDlg::show()
{
//显示图像和线圈
CDC *pDC=GetDC();
pDC->SetStretchBltMode(COLORONCOLOR); //设置伸缩拷贝模式
StretchDIBits(pDC->GetSafeHdc(), //DC的句柄
45,//nLeft, //目标矩形左上角的X坐标
10,//nTop, //目标矩形左上角的Y坐标
320,//nRight, //目标矩形的宽度
240,//nBottom, //目标矩形的高度
0, //源矩形左上角的X坐标
0, //源矩形左上角的Y坐标
320,//GetDIBWidth(), //源矩形的宽度
240,//GetDIBHeight(), //源矩形的高度
m_pbuff,//pDIBData, //位图图象数据的地址
m_pbmi,//pBMI, //位图信息结构地址
DIB_RGB_COLORS, //标志选项
SRCCOPY);
//画坐标
pDC->MoveTo(44,251);
pDC->LineTo(44,5);
pDC->MoveTo(44,251);
pDC->LineTo(370,251);
CString tt="0";
pDC->TextOut(10,260,tt);
int x,y;
for(int k=0;k<8;k++)
{
if(k%2==0)
{
pDC->MoveTo(42,251-(k+1)*30); //Y
pDC->LineTo(44,251-(k+1)*30);
pDC->MoveTo(44+(k+1)*40,251); //X
pDC->LineTo(44+(k+1)*40,253);
}
else
{
pDC->MoveTo(40,251-(k+1)*30); //Y
pDC->LineTo(44,251-(k+1)*30);
CString t;
t.Format("%d",(k+1)*30);
pDC->TextOut(10,251-(k+1)*30-5,t);
pDC->MoveTo(44+(k+1)*40,251); //X
pDC->LineTo(44+(k+1)*40,255);
t.Format("%d",(k+1)*40);
pDC->TextOut(44+(k+1)*40-10,260,t);
}
}
}
void CTestDlg::initiate(CString filename)
{
//初始化,以及提取信息
AVIFileOpen(&m_pfile,filename,OF_READ,NULL);
AVIFileInfo(m_pfile,&m_pfi,sizeof(AVIFILEINFO));
//DWORD t;
//t=m_pfi.dwScale;
//DWORD W=m_pfi. dwRate ;
AVIFileGetStream(m_pfile,&m_pavi,streamtypeVIDEO,0);
m_length=AVIStreamLength(m_pavi);
m_pgf = AVIStreamGetFrameOpen(m_pavi, NULL);
LPBITMAPINFOHEADER bmp1;
bmp1= (LPBITMAPINFOHEADER)AVIStreamGetFrame(m_pgf, 1);
CClientDC dc(this);
//定义信息头和文件头
memset(&m_bmih,0,sizeof(BITMAPINFOHEADER));
m_bmih.biBitCount=bmp1->biBitCount;
m_bmih.biSize = sizeof(BITMAPINFOHEADER);
m_bmih.biWidth = m_pfi.dwWidth;
m_bmih.biHeight = m_pfi.dwHeight;
m_bmih.biPlanes =bmp1->biPlanes;
m_bmih.biCompression =BI_RGB;
m_bmih.biXPelsPerMeter = 0;
m_bmih.biYPelsPerMeter = 0;
m_bf.bfSize = sizeof(m_bf);
m_bf.bfOffBits = sizeof(m_bf) + sizeof(m_bmih);
m_bf.bfType = (int)'M' * 256 + 'B';
m_bf.bfReserved1 = 0;
m_bf.bfReserved2 = 0;
m_nw=m_bmih.biWidth;
m_nh=m_bmih.biHeight;
m_step=0;
while((m_nw*3+m_step)%4!=0) m_step++;
m_pbuff=(BYTE *)AVIStreamGetFrame(m_pgf,m_firstframe);//提取单帧是packed DIB
m_pbuff+=40;
m_pbmi=(BITMAPINFO*)new BYTE[sizeof(BITMAPINFO)];
memcpy(m_pbmi,&m_bmih,sizeof(BITMAPINFO));
/* m_frontstate=false;
m_nowstate=false;
m_number_car=0;*/
}
void CTestDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
if(m_bopen==true)
{
show();
}
// Do not call CDialog::OnPaint() for painting messages
}
void CTestDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
m_curframe++;
if(m_curframe>m_length-5)
{
OnStop();
return;
}
m_pbuff=(BYTE *)AVIStreamGetFrame(m_pgf,m_curframe);//提取单帧是packed DIB
m_pbuff+=40;
detect(m_pbuff);
UpdateBackground();
show();
// showcurve(m_result);
UpdateData(FALSE);
CDialog::OnTimer(nIDEvent);
}
//
void CTestDlg::detect(BYTE *buff)
{
//检测是否有车
// int t=m_number_car;
int i,j;
BYTE *Temp=new BYTE[m_nw*m_nh];
for( i=0;i<240;i++) //取位置140~150行;180~240列为背景范围
for(j=0;j<320;j++)
curground1[i*m_nw+j]=buff[i*3*m_nw+j*3]*0.11
+buff[i*3*m_nw+j*3+1]*0.59
+buff[i*3*m_nw+j*3+2]*0.3;
//求取自适应阈值
int nx,ny;
int ni,nj;
int l_p1;
int n_partw=10,n_parth=10;//小块的宽和长
for(ni=0;ni<m_nw;ni=ni+n_partw) //各小块的"原点"的横坐标
for(nj=0;nj<m_nh;nj=nj+n_parth) //各小块的"原点"的纵坐标
{ l_p1=0;
for(nx=0;nx<n_partw;nx++) //各小块中像素点的横坐标
for(ny=0;ny<n_parth;ny++)//各小块中像素点的纵坐标
{
l_p1=buff[(nx+ni)+(ny+nj)*m_nw]+l_p1;//得到小块中各像素点的灰度和
}
}
c_threshold=(unsigned char) (l_p1/(n_partw*n_parth));//自适应阈值
for( i=0;i<240;i++)
for(j=0;j<320;j++)
if(abs(curground1[i*m_nw+j]-background1[i*m_nw+j])>c_threshold)
Temp[i*m_nw+j]=255;
else
Temp[i*m_nw+j]=0;
// Action(Temp);
UpdateData(false);
}
//对背景进行更新
void CTestDlg::UpdateBackground()
{
BYTE *Temp;
BYTE *background2;
Temp=new BYTE[m_nw*m_nh];
background2=new BYTE[m_nw*m_nh];
long SumDiff=0;
int i,j;
for( i=0;i<240;i++) //取位置140~150行;180~240列为背景范围
for(j=0;j<320;j++)
curground1[i*m_nw+j]=m_pbuff[i*3*m_nw+j*3]*0.11
+m_pbuff[i*3*m_nw+j*3+1]*0.59
+m_pbuff[i*3*m_nw+j*3+2]*0.3;
for( i=0;i<240;i++)
for(j=0;j<320;j++)
if(abs(curground1[i*m_nw+j]-background1[i*m_nw+j])>20)
{
Temp[i*m_nw+j]=1;
m_pbuff[i*3*m_nw+j*3]=0;
m_pbuff[i*3*m_nw+j*3+1]=0;
m_pbuff[i*3*m_nw+j*3+2]=0;
}
else
{
Temp[i*m_nw+j]=0;
/* m_pbuff[i*3*m_nw+j*3]=255;
m_pbuff[i*3*m_nw+j*3+1]=255;
m_pbuff[i*3*m_nw+j*3+2]=255;*/
}
for( i=0;i<240;i++)
for(j=0;j<320;j++)
SumDiff+=Temp[i*m_nw+j];
if(abs(SumDiff)>100)
{
for( i=0;i<240;i++)
for(j=0;j<320;j++)
background2[i*m_nw+j]=0.1*background1[i*m_nw+j]+0.9*curground1[i*m_nw+j];
}
else
{
for( i=0;i<240;i++)
for(j=0;j<320;j++)
background2[i*m_nw+j]=background1[i*m_nw+j];
}
for( i=0;i<240;i++)
for(j=0;j<320;j++)
background1[i*m_nw+j]=background2[i*m_nw+j];
}
/*void CTestDlg::Action(BYTE *buff)
{
//unsigned char* lpSrc;//指向源图像的指针
unsigned char* lpDst;//指向要复制区域的指针
BYTE* lpImage; //指向目标图像的指针
int i,j,k;
lpImage=new BYTE[m_nw*m_nh];//暂时分配内存,以保存新图像
unsigned char pix;//像素值
lpDst=(unsigned char *)lpImage;
//使用1*5的结构元素进行腐蚀,为防止越界,所以不处理最左边和最右边的2列像素
for(j=0;j<m_nh;j++)
for(i=2;i<m_nw-2;i++)
{
lpSrc=(unsigned char *)Temp+m_nw*j+i;
lpDst=(unsigned char *)lpImage+m_nw*j+i;
pix=(unsigned char *)Temp;
for(k=0;k<5;k++)
{
pix=*(lpSrc+k-2);
if(pix==255)
{
*lpDst=(unsigned char)255;
break;
}
}
}
memcpy(buff,lpImage,m_nw*m_nh);
delete[] lpImage;
//使用1*5的结构元素进行膨胀,为防止越界,所以不处理最左边和最右边的2列像素
for(j=0;j<m_nh;j++)
for(i=2;i<m_nw-2;i++)
{
lpSrc=(unsigned char *)buff+m_nw*j+i;
lpDst=(unsigned char *)lpImage+m_nw*j+i;
pix=(unsigned char *)lpSrc;
*lpDst=(unsigned char)255;
for(k=0;k<5;k++)
{
pix=*(lpSrc+k-2);
if(pix==255)
{
*lpDst=(unsigned char)0;
break;
}
}
}
memcpy(buff,lpImage,m_nw*m_nh);
}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -