计算机视觉
图像处理

三帧差分算法

本文给出参考代码,注意,这里的代码仅仅有参考意义,并没有考虑工程实际中的效率,内存耗费等问题,望谅解。

  1. int CallTime = 0;//定义调用次数计数器
  2. IplImage* BackGroundImage;//上一帧灰度图
  3. IplImage* DiffImage_1;//上一帧差分图的二值化图
  4. void ThreeFrmDiff(IplImage* pColorIn)
  5. {
  6.     CallTime++;
  7.     if(CallTime > 10)//防止溢出
  8.     {
  9.         CallTime = 10;
  10.     }
  11.     CvSize ImageSize = cvSize(pColorIn->width,pColorIn->height);
  12.     IplImage* GrayImage = cvCreateImage(ImageSize,IPL_DEPTH_8U,1);//当前帧的灰度图
  13.     IplImage* GxImage = cvCreateImage(ImageSize,IPL_DEPTH_8U,1);//当前帧的X方向梯度图
  14.     IplImage* GyImage = cvCreateImage(ImageSize,IPL_DEPTH_8U,1);//当前帧的Y方向梯度图
  15.     IplImage* DiffImage = cvCreateImage(ImageSize,IPL_DEPTH_8U,1);//当前帧的差分图
  16.     IplImage* DiffImage_2 = cvCreateImage(ImageSize,IPL_DEPTH_8U,1);//前一帧差分图
  17.     IplImage* pyr = cvCreateImage(cvSize((ImageSize.width&-2)/2,(ImageSize.height&-2)/2),8,1); //进行腐蚀去除噪声的中间临时图片
  18.     uchar* DiffImageData_2;
  19.     DiffImageData_2 = (uchar*)DiffImage_2->imageData;//得到前一帧差分图的数据
  20.     int height,width,step;//定义图像的高,宽,步长
  21.     int SumInRect = 0;//指定矩形内图像数据之和
  22.     int y1, y2, x1, x2;//对运动目标画框时的四个坐标点位置
  23.     y1 = 0;
  24.     y2 = 0;
  25.     x1 = 0;
  26.     x2 = 0;
  27.     char Kx[9] = {1,0,-1,2,0,-2,1,0,-1};//X方向掩模,用于得到X方向梯度图
  28.     char Ky[9] = {1,2,1,0,0,0,-1,-2,-1};//Y方向掩模,用于得到Y方向梯度图
  29.     CvMat KX,KY;
  30.     KX = cvMat(3,3,CV_8S,Kx);//构建掩模内核
  31.     KY = cvMat(3,3,CV_8S,Ky);//构建掩模内核
  32.     cvCvtColor(pColorIn,GrayImage,CV_BGR2GRAY);//将当前帧转化为灰度图
  33.     cvSmooth(GrayImage,GrayImage,CV_GAUSSIAN,7,7);//进行平滑处理
  34.     cvFilter2D(GrayImage,GxImage,&KX,cvPoint(-1,-1));//得到X方向的梯度图
  35.     cvFilter2D(GrayImage,GyImage,&KY,cvPoint(-1,-1));//得到Y方向的梯度图
  36.     cvAdd(GxImage,GyImage,GrayImage,NULL);//得到梯度图
  37.     height = GrayImage->height;
  38.     width = GrayImage->width;
  39.     step = GrayImage->widthStep;
  40.     CvRect rect;//定义矩形框
  41.     if(CallTime == 1)//如果是第一帧
  42.     {
  43.         //对Image_1,BackGroundImage,DiffImage_1进行内存申请
  44.         BackGroundImage = cvCreateImage(ImageSize,IPL_DEPTH_8U,1);
  45.         DiffImage_1 = cvCreateImage(ImageSize,IPL_DEPTH_8U,1);
  46.         cvCopy(GrayImage,BackGroundImage,NULL);//如果是第一帧,设置为背景
  47.     }
  48.     else
  49.     {
  50.         cvAbsDiff(GrayImage,BackGroundImage,DiffImage);//得到当前帧的差分图
  51.         cvCopy(GrayImage,BackGroundImage,NULL);//将当前帧的梯度图作为下一帧的背景
  52.         cvThreshold(DiffImage,DiffImage,15,255,CV_THRESH_BINARY);//二值化当前差分图
  53.         if(CallTime > 2)//如果大于等于第三帧
  54.         {
  55.             cvAnd(DiffImage,DiffImage_1,DiffImage_2);//进行“与”运算,得到前一帧灰度图的“准确”运动目标
  56.             char str[256];
  57.             memset(str, ‘’, 256*sizeof(char));
  58.             static int iCount = 0;
  59.             sprintf(str, “./img/%d.jpg”, iCount++);
  60.             cvSaveImage(str, DiffImage_2);
  61.         }
  62.         cvPyrDown(DiffImage_2,pyr,7);//向下采样
  63.         cvErode(pyr,pyr,0,1);//腐蚀,消除小的噪声
  64.         cvPyrUp(pyr,DiffImage_2,7);
  65.         cvCopy(DiffImage,DiffImage_1,NULL);//备份当前差分图的二值化图
  66.     }
  67.     cvReleaseImage(&GxImage);
  68.     cvReleaseImage(&GyImage);
  69.     cvReleaseImage(&GrayImage);
  70.     cvReleaseImage(&DiffImage);
  71.     cvReleaseImage(&DiffImage_2);
  72.     cvReleaseImage(&pyr);
  73. }

转载注明来源:CV视觉网 » 三帧差分算法

分享到:更多 ()
扫描二维码,给作者 打赏
pay_weixinpay_weixin

请选择你看完该文章的感受:

0不错 1超赞 0无聊 0扯淡 0不解 0路过

评论 6

评论前必须登录!