#include<cv.h>
#include<highgui.h>
#include<cxcore.h>
#include<math.h>
#include<stdio.h>
int main()
{
IplImage *frame,*pimg,*pimg1;
CvCapture *capture;
int i,j,t1,t2,t3,n=0,count=0,k1,k2,flag[4]={0},k=0,x1,x2,y1,y2,m,d[4]={70,110,150,185},N=0,sum1=0,sum2=0,sum3=0;
int c[8][2]={{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}};//寻址坐标
int e[8]={1,0,1,0,1,0,1,0};
char *a,**b,*a1,**b1;
CvScalar color=cvScalar(255,255,255);
capture=cvCreateFileCapture("highwayII_raw.AVI");
pimg=cvLoadImage("backgroud1.bmp",1);//读入背景图像
a=pimg->imageData;
b=new char*[pimg->height];
for(i=0;i<pimg->height;i++)
{
b[i]=&a[i*pimg->widthStep];
//b1[i]=&a1[i*pimg->widthStep];
}
cvNamedWindow("test1",CV_WINDOW_AUTOSIZE);
cvNamedWindow("test2",CV_WINDOW_AUTOSIZE);
while(1)//每次循环完成对一帧图像的处理
{N++;
frame=cvQueryFrame(capture);
if(!frame)break;
cvSaveImage("test2.bmp",frame);
pimg1=cvLoadImage("test2.bmp",1);
//printf("%d %d %d %d\n",frame->height,frame->widthStep,pimg->height,pimg->widthStep);
a1=pimg1->imageData;
b1=new char*[pimg1->height];
for(i=0;i<pimg->height;i++)
{
//b[i]=&a[i*pimg->widthStep];
b1[i]=&a1[i*pimg->widthStep];
}
//for(i=0;i<pimg->width;i++)
//printf("%d %d %d %d %d %d\n",b[0][3*i],b1[0][3*i],b[0][3*i+1],b1[0][3*i+1],b[0][3*i+2],b1[0][3*i+2]);
//领域平均滤波,对图像进行预处理
for(i=1;i<pimg->height-1;i++)
{
for(j=1;j<pimg->width-1;j++)
{ sum1=0;sum2=0;sum3=0;
for(k=0;k<8;k++)//读入领域像素
{
sum1+=unsigned char(b1[i+c[k][0]][3*(j+c[k][1])]*e[k]);
sum2+=unsigned char(b1[i+c[k][0]][3*(j+c[k][1])+1]*e[k]);
sum3+=unsigned char(b1[i+c[k][0]][3*(j+c[k][1])+2]*e[k]);
}
b1[i][3*j]=(sum1+unsigned char(b1[i][3*j]))/5;
b1[i][3*j+1]=(sum2+unsigned char(b1[i][3*j+1]))/5;
b1[i][3*j+2]=(sum2+unsigned char(b1[i][3*j+2]))/5;
}
}
//得到差值图像并用大津法得到的阈值进行运动目标的检测
for(i=0;i<pimg->height;i++)
for(j=0;j<pimg->width;j++)
{
/*t1=(unsigned char)b[i][3*j]-(unsigned char)b1[i][3*j];
t2=(unsigned char)b[i][3*j+1]-(unsigned char)b1[i][3*j+1];
t3=(unsigned char)b[i][3*j+2]-(unsigned char)b1[i][3*j+2];*/
t1=unsigned char(b[i][3*j])-unsigned char(b1[i][3*j]);
t2=unsigned char(b[i][3*j+1])-unsigned char(b1[i][3*j+1]);
t3=unsigned char(b[i][3*j+2])-unsigned char(b1[i][3*j+2]);
//if(i==0)
//printf("%d %d %d\n",t1,t2,t3);
if(abs(t1)>40&&abs(t2)>40&&abs(t3)>40)//二值化
{ b1[i][3*j]=255;
b1[i][3*j+1]=255;
b1[i][3*j+2]=255;
}
else {
b1[i][3*j]=0;
b1[i][3*j+1]=0;
b1[i][3*j+2]=0;
}
}
/*for(i=0;i<pimg->height;i++)
for(j=0;j<pimg->width;j++)
printf("%d,%d,%d\n",b1[i][3*j],b1[i][3*j+1],b1[i][3*j+2]);
/*for(i=0;i<pimg->height;i+=40)
for(j=0;j<pimg->width;j+=30)
{
for(k1=0;k1<40;k1++)
for(k2=0;k2<30;k2++)
if(b1[i+k1][j+3*k2]&&b1[i+k1][j+3*k2+1]&&b1[i+k1][j+3*k2+2])
n++;
if(n>210)
{
x1=i;y1=j;
x2=i+40;y2=j+30;
CvPoint pt1=cvPoint(x1,y1);
CvPoint pt2=cvPoint(x2,y2);
cvRectangle(frame,pt1,pt2,color);
}
n=0;
}*/
//车辆计数
m=0;k=0;
while(m<4)//对四个检测窗口分别进行检测
{i=d[m];
for(k1=0;k1<10;k1++)//选取窗口的大小为10*30
for(j=0;j<30;j++)
{
if(b1[50+k1][3*(i+j)]&&b1[50+k1][3*(i+j)+1]&&b1[50+k1][3*(i+j)+2])//像素值不为0说明是目标点
{n++;//printf("%d,%d,%d\n",b1[50][3*(i+j)],b1[50][3*(i+j)+1],b1[50][3*(i+j)+2]);
}
}
//printf("%d\n",n);
if(n>35)//如果大于阈值
{
if(flag[k]==0)//如果之前没有车进入检测窗口
flag[k]=1;//有车进入检测窗口的标志
}else
{
if(n<35&&flag[k]==1)
{
count++;flag[k]=0;printf("%d\n",count);//有车要离开,记录车辆数
}
}
n=0;m++;k++;
}
//为了更好的观察实验结果,将四个检测窗口画到图像上对应的位置
CvPoint pt1=cvPoint(70,50);
CvPoint pt2=cvPoint(100,60);
CvScalar color=cvScalar(255,255,255);
cvRectangle(pimg1,pt1,pt2,color);
pt1=cvPoint(110,50);
pt2=cvPoint(140,60);
cvRectangle(pimg1,pt1,pt2,color);
pt1=cvPoint(150,50);
pt2=cvPoint(180,60);
cvRectangle(pimg1,pt1,pt2,color);
pt1=cvPoint(185,50);
pt2=cvPoint(230,60);
cvRectangle(pimg1,pt1,pt2,color);
cvShowImage("test2",pimg1);
cvShowImage("test1",frame);
cvWaitKey(33);
cvSaveImage("test1.bmp",pimg1);
cvReleaseImage(&pimg1);
}
cvDestroyWindow("test1");
cvDestroyWindow("test2");
cvReleaseImage(&pimg);
return 0;
}
评论2