IplImage *differenceLabImage = cvCreateImage( imageSize, IPL_DEPTH_32F, 3 ); //建立差分用图IplImage
IplImage *differenceLImage = cvCreateImage( imageSize, IPL_DEPTH_32F, 1 ); //建立L*值差分用图IplImage
IplImage *differenceAImage = cvCreateImage( imageSize, IPL_DEPTH_32F, 1 ); //建立a*值差分用图IplImage
IplImage *differenceBImage = cvCreateImage( imageSize, IPL_DEPTH_32F, 1 ); //建立b*值差分用图IplImage
IplImage *sqrDifferenceImage = cvCreateImage( imageSize, IPL_DEPTH_32F, 1 ); //建立距离计算差分用图IplImage
// currentImage和backgroundImage一起做CIE L*a*b*变换 cvConvertScale( currentImage, currentLabImage, SCALE ); cvConvertScale( backgroundImage, backgroundLabImage, SCALE ); cvCvtColor( currentLabImage, currentLabImage, CV_BGR2Lab ); cvCvtColor( backgroundLabImage, backgroundLabImage, CV_BGR2Lab ); //计算距离的平方
cvSub( currentLabImage, backgroundLabImage, differenceLabImage ); cvPow( differenceLabImage, differenceLabImage, 2 ); //将图像分割
cvSplit(differenceLabImage,differenceLImage,differenceAImage,differenceBImage, NULL );
cvCopy( differenceLImage, sqrDifferenceImage );
cvAdd( differenceAImage, sqrDifferenceImage, sqrDifferenceImage ); cvAdd( differenceBImage, sqrDifferenceImage, sqrDifferenceImage );
cvThreshold( sqrDifferenceImage, resultImage, THRESHOLD * THRESHOLD, THRESHOLD_MAX_VALUE, CV_THRESH_BINARY ); //进行阈值处理
cvReleaseImage( ¤tLabImage );//解放currentLabImage内存 cvReleaseImage( &backgroundLabImage );//解放backgroundLabImage内存 cvReleaseImage( &differenceLabImage );// 解放differenceLabImage内存 cvReleaseImage( &differenceLImage );//解放differenceLImage内存 cvReleaseImage( &differenceAImage );//解放differenceAImage内存 cvReleaseImage( &differenceBImage );//解放differenceBImage内存 cvReleaseImage( &sqrDifferenceImage );//解放sqrDifferenceImage内存 }
16
//灰度评价 // // // 解释:
// currentImage: 当前图像IplImage // backgroundImage: 背景图像用IplImage // resultImage: 结果图像用IplImage // void
colorDifference
(IplImage
*
currentImage
,
IplImage
*backgroundImage, // colorDifference模式 IplImage *resultImage ) { // 图像生成
IplImage *differenceImage = cvCreateImage( imageSize, IPL_DEPTH_8U, 3 ); // 建立差分用图IplImage
IplImage *differenceRImage = cvCreateImage( imageSize, IPL_DEPTH_8U, 1 ); //建立R通道值的差分用图IplImage *differenceRImage
IplImage *differenceGImage = cvCreateImage( imageSize, IPL_DEPTH_8U, 1 ); //建立G通道值的差分用图IplImage *differenceGImage
IplImage *differenceBImage = cvCreateImage( imageSize, IPL_DEPTH_8U, 1 ); //建立B通道值的差分用图IplImage *differenceGImage
cvAbsDiff( currentImage, backgroundImage, differenceImage );//对currentImage和backgroundImage取差分并求其绝对值
cvThreshold( differenceImage, differenceImage, THRESHOLD,
THRESHOLD_MAX_VALUE, CV_THRESH_BINARY ); // 进行阈值处理
cvSplit(differenceImage,differenceBImage,differenceGImage,differenceRImage, NULL );//将图像分割为R、G、B三个通道
cvOr( differenceRImage, differenceGImage, resultImage ); // R通道图像与G通道图像作或逻辑运算,结果存放在resultImage中
cvOr( differenceBImage, resultImage, resultImage ); // B通道图像与resultImage图像作或逻辑运算,结果存放在resultImage中 cvReleaseImage( &differenceImage ); // 解放图像存储器 cvReleaseImage( &differenceRImage ); // 解放R通道存储器 cvReleaseImage( &differenceGImage ); // 解放G通道存储器 cvReleaseImage( &differenceBImage ); // 解放B通道存储器 }
17
// // //
// 灰度估计 // 参数:
// currentImage : 当前图像用IplImage // backgroundImage : 背景图像用IplImage // resultImage : 结果图像用IplImage // // // void
int main( void ){ int key; // 输入所用变量
CvCapture *capture = NULL; // 照相机捕捉用的构造体
char windowNameCurrent[] = \表示当前的图像的窗的名字 char windowNameResult[] = \表示结果的图像的窗的名字
char windowNameBackground[] = \表示背景的图像的窗的名字 IplImage *frameImage = NULL; // IplImage 作为初始图片 IplImage *currentImage = NULL; // 当前的图像用IplImage IplImage *backgroundImage = NULL; // 背景的图像用plImage IplImage *resultImage = NULL; // 结果的图像用IplImage int captureOn = CAPTURE_ON; // 是否更新进行背景差分的图像 int differenceMode = COLOR_DIFFERENCE; // 差分计算模式 int noiseMode = NOISE_KEEP; // 噪声消除的模式 char *differenceMethod[3] ={ // 差分模式选择的模式 \对图像RGB成分分别评价\ \标准评价\ \灰度标准下进行评价\ };
char *noiseMethod[3] = {
\不用\ };
18
// 初始化摄像头
if ( ( capture = cvCreateCameraCapture( -1 ) ) == NULL ){ // 未发现摄像头
printf( \摄像头未被发现\\n\ return -1; }
cvNamedWindow (windowNameCurrent, CV_WINDOW_AUTOSIZE ); cvNamedWindow ( windowNameResult, CV_WINDOW_AUTOSIZE ); cvNamedWindow (windowNameBackground, CV_WINDOW_AUTOSIZE ); frameImage=cvQueryFrame (capture); // 拍摄一张背景图片 backgroundImage = cvCloneImage(frameImage);
currentImage = cvCloneImage(frameImage); // 将第一张背景图片复制为初始图片 imageSize=cvSize( frameImage->width,frameImage->height); // 保存图片尺寸 resultImage = cvCreateImage( imageSize,IPL_DEPTH_8U,1); // 创造二值化后的结果图片名为resultImage while( 1 ) // 开始计算 {
frameImage = cvQueryFrame( capture ); if( captureOn != 0) {
if( currentImage != NULL){ cvReleaseImage( ¤tImage ); }
currentImage = cvCloneImage( frameImage ); }
// 差分计算方法选择
if( differenceMode == COLOR_DIFFERENCE ){ //标准评价切换为RGB模式
colorDifference( currentImage, backgroundImage, resultImage ); }
else if( differenceMode == LAB_DIFFERENCE ){ // 标准评价切换为L*a*b* 模式
labDifference( currentImage , backgroundImage , resultImage ); }
else if( differenceMode == GRAY_DIFFERENCE ) // 灰度标准评价
19
{
grayScaleDifference ( currentImage, backgroundImage, resultImage ); }
if( noiseMode == NOISE_MORPHOLOGY ) // 消除噪音 {
cvErode ( resultImage, resultImage ); cvDilate ( resultImage, resultImage ); }
else if ( noiseMode == NOISE_MEDIAN ) {
cvSmooth( resultImage, resultImage, CV_MEDIAN ); }
if( resultImage->origin == 0 ) //左上角有原点的情况 {
cvFlip ( resultImage, resultImage, 0 ); }
cvShowImage ( windowNameCurrent, currentImage ); //显示图像currentImage cvShowImage ( windowNameResult, resultImage ); //显示图像resultImage
cvShowImage ( windowNameBackground, backgroundImage ); // 显示图像resultImage key = cvWaitKey ( 1 ); // 判断输入 if( key == 'q' ) // 'q'键退出循环 { break; }
else if( key == 'b' ) //键按下时刻的图像作为背景 {
if( backgroundImage != NULL ){ cvReleaseImage ( &backgroundImage ); }
backgroundImage = cvCloneImage( frameImage ); printf( \背景图像更新\\n\ }
else if( key == ' ' ) // 键变更图像保存的ON/OFF( 空格键 ) {
captureOn = 1 - captureOn;
20