//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <stdio.h>
#include <math.h>
#include <windef.h>
#include <stdlib.h>
#include "Unit1.h"
#include "main.h"
#include <vfw.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
HDC hdccap;
CAPSTATUS capfrmstatus; //定义捕获窗当前的状态
CAPDRIVERCAPS capdrvcapcity; //定义捕获设备的能力
CAPTUREPARMS capparm; //视频流捕获过程的有关参数
BYTE *Ptr;
int mark;
int nHeight=capfrmstatus.uiImageHeight;
int nWidth=capfrmstatus.uiImageWidth;
BYTE *Str;
BYTE a[1200000]={0}; //存i-1帧像素值
BYTE *ImgData;//帧数据首地址
int RowBytes=nWidth*3; //每行字节数
void FrameCallback(HDC hwnd,LPVIDEOHDR lpVHDR); //帧回调函数
void GrayConvert(Byte *Img);//灰度变换
void Binarization(Byte *Img);//二值化
void motiondetect(Byte *Img);//运动检测
void Filtering(Byte *Img); //形态学滤波
void location(BYTE *Img); //目标定位
BYTE thresholdValue;//阈值
LRESULT CALLBACK StatusCallbackProc(HDC hwnd,int nID,LPSTR lpstatusText) //状态回调函数
{if(! hwnd) return false;
capGetStatus(hwnd,&capfrmstatus,sizeof(capfrmstatus));
SetWindowPos(hwnd,NULL,0,0,capfrmstatus.uiImageWidth,capfrmstatus.uiImageHeight,SWP_NOZORDER|SWP_NOMOVE);
return true;
}
LRESULT CALLBACK ErrorCallbackProc(HDC hwnd,int nErrID,LPSTR lpErrorText) //错误回调函数
{if(! hwnd) return false;
if(nErrID==0) return true; //清除旧的错误
MessageBox(NULL,lpErrorText,"Error",MB_OK|MB_ICONEXCLAMATION);
return true;
}
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
hwndParent=Form2->Handle; //获取主窗口的句柄
hdccap=capCreateCaptureWindow("My Own Capture Window",WS_CHILD|WS_VISIBLE,0,0,Panel1->Width,Panel1->Height,Panel1->Handle,0);//生成捕获窗
capSetCallbackOnError(hdccap,(FARPROC)ErrorCallbackProc); //登记回调函数
capSetCallbackOnStatus(hdccap,(FARPROC)StatusCallbackProc);
capSetCallbackOnFrame(hdccap,(FARPROC)FrameCallback); //帧回调
capfrmlink=capDriverConnect(hdccap,0); //将创建的视频捕获窗与视频器件连接起来,并初始化成员变量capfrmlink
if(! capfrmlink) //返回错误信息
{ShowMessage("不能与摄像头连接,请检查后再进去系统");
capSetCallbackOnStatus(hdccap,NULL); //取消登记的回调函数
capSetCallbackOnError(hdccap,NULL);
Close();
return;
}
capDriverGetCaps(hdccap,&capdrvcapcity,sizeof(capdrvcapcity));
//获得驱动器的能力,相关的信息放在结构体capdrvcapcity中
}
//----------------------------------------------------------------------------
void FrameCallback(HDC hwnd,LPVIDEOHDR lpVHDR) //帧回调函数
{
BYTE *Img=lpVHDR->lpData;
switch(mark)
{
case 0:break;
case 1:GrayConvert(Img);break; //灰度变换
case 2:Binarization(Img);break; //二值化
case 3:motiondetect(Img);break; //帧差分运动检测
case 4:Filtering(Img);break; //形态学滤波
case 5:location(Img);break; //目标定位
}
}
//---------------------------------------------------------------------------
void GrayConvert(Byte *Img) //灰度变换
{
BYTE *ImgData=Img;
BYTE *Ptr;
double gray;
int nHeight=capfrmstatus.uiImageHeight;
int nWidth=capfrmstatus.uiImageWidth;
int RowBytes=nWidth*3; //每行字节数
int x,y;
for(y=0;y<nHeight;y++) //每行
{for(x=0;x<nWidth;x++)
{Ptr=ImgData+y*RowBytes+x*3;
gray=(*Ptr)*0.114+(*(Ptr+1))*0.587+(*(Ptr+2))*0.299;
*Ptr=(BYTE)gray;
*(Ptr+1)=(BYTE)gray;
*(Ptr+2)=(BYTE)gray;
}
}
}
//----------------------------------------------------------------------
void Binarization(Byte *Img) //二值化
{
BYTE *ImgData=Img;
BYTE *Ptr;
BYTE gray;
int nHeight=capfrmstatus.uiImageHeight;
int nWidth=capfrmstatus.uiImageWidth;
int RowBytes=nWidth*3; //每行字节数
int x,y;
for(y=0;y<nHeight;y++) //每行
{for(x=0;x<nWidth;x++)
{Ptr=ImgData+y*RowBytes+x*3;
gray=(*Ptr)*0.114+(*(Ptr+1))*0.587+(*(Ptr+2))*0.299;
*Ptr=(BYTE)gray;
*(Ptr+1)=(BYTE)gray;
*(Ptr+2)=(BYTE)gray;
}
}
int i,j; //最大方差的双阈值选择
int GrayMatrix[256];
int bn,an;
int k1,k2;//双阈值
int a1,b1,c1,a2,b2,c2,a3,b3;
int tt1,tt2;
int u=0;//总均值
int variance,maxvalue=0;
memset(GrayMatrix,0,1024); //初始化GrayMatrix为0
an=nHeight*nWidth; //整幅图像的像素的个数
bn=0;
maxvalue=0;//计算灰度直方图
for(y=0;y<nHeight;y++) //计算类方差,求阈值p
{
for(x=0;x<nWidth;x++)
{
Ptr=ImgData+y*RowBytes+x*3;
gray=*(Ptr+x*3);//兰绿红依次循环
GrayMatrix[gray]+=1;//用来存放灰度值=K的点的总个数
bn+=gray;//计算总灰度
}
}
u=bn/an; //计算阈值 整个图像灰度平均值
a1=0;b1=0;
for(k1=0;k1<256;k1++)
{
a1+=GrayMatrix[k1]; //一类像素总数
b1+=GrayMatrix[k1]*k1; //总灰度值
if(a1) c1=b1/a1; //C1组平均值
else c1=0;
a2=an-a1;
b2=bn-b1;
if(a2) c2=b2/a2;
else c2=0;
variance=1.0*a1/an*(c1-u)*(c1-u)+1.0*a2/an*(c2-u)*(c2-u);//两组间的方差
if(variance>maxvalue)
{
maxvalue=variance;
tt1=k1;
}
}
thresholdValue=tt1; //thresholdValue是最佳阈值
for(y=0;y<nHeight;y++)
{
for (x=0;x<nWidth;x++)
{ Ptr=ImgData+y*RowBytes+x*3;
if (*Ptr>=thresholdValue)
{
*Ptr=255;
*(Ptr+1)=255;
*(Ptr+2)=255;
}
else
{
*Ptr=0;
*(Ptr+1)=0;
*(Ptr+2)=0;
}
}
}
}
//----------------------------------------------------------------------------
void motiondetect(Byte *Img)
{
BYTE *ImgData=Img;
BYTE *Ptr;
BYTE *Str;
int gray;
int nHeight=capfrmstatus.uiImageHeight;
int nWidth=capfrmstatus.uiImageWidth;
int RowBytes=nWidth*3; //每行字节数
int x,y;
for(y=0;y<nHeight;y++) //每行
{for(x=0;x<nWidth;x++)
{
Ptr=ImgData+y*RowBytes+x*3;
Str=a+y*RowBytes+x*3;
gray=(*Ptr)*0.114+(*(Ptr+1))*0.587+(*(Ptr+2))*0.299;
*Ptr=(BYTE)gray;
*(Ptr+1)=(BYTE)gray;
*(Ptr+2)=(BYTE)gray;
int diff=abs(*Ptr-*Str); //当前帧减前一帧
*Str=(BYTE)gray;
*(Str+1)=(BYTE)gray;
*(Str+2)=(BYTE)gray;
*Ptr=(BYTE)diff;
*(Ptr+1)=(BYTE)diff;
*(Ptr+2)=(BYTE)diff;
}
}
int GrayMatrix[256];
double bn,an;
//int gray;
int k1,k2;//双阈值
double a1,b1,c1,a2,b2,c2,a3,b3;
int tt1,tt2;
int u=0;//总均值
int variance,maxvalue=0;
memset(GrayMatrix,0,1024);
an=nHeight*nWidth; //整幅图像的像素的个数
bn=0;
maxvalue=0;//计算灰度直方图
for(y=0;y<nHeight;y++) //计算类方差,求阈值 p
{
for(x=0;x<nWidth;x++)
{
Ptr=ImgData+y*RowBytes+x*3;
gray=*(Ptr+x*3);//兰绿红依次循环
GrayMatrix[gray]+=1;//用来存放灰度值=K的点的总个数
bn+=gray;//计算总灰度
}
}
u=bn/an; //计算阈值
a1=0;b1=0;
for(k1=0;k1<256;k1++)
{
a1+=GrayMatrix[k1]; //一类像素总数
b1+=GrayMatrix[k1]*k1; //一类像素总灰度值
if(a1) c1=b1/a1; //一类像素概率
else c1=0;
a2=an-a1;
b2=bn-b1;
if(a2) c2=b2/a2;
else c2=0;
variance=1.0*a1/an*(c1-u)*(c1-u)+1.0*a2/an*(c2-u)*(c2-u