OpenCV_基于自适应背景更新的运动目标检测

下面这段代码利用OpenCV实现了最为简单的基于自适应背景更新的运动目标检测算法。

即:
运动前景提取——背景减除
foreground = |frame - background| > threshold
更新背景模型——滑动平均滤波
background = background + (frame - background) *  alpha  = background * (1 - alpha) + frame * alpha

//运动前景检测——基于自适应背景更新
//Author: http://blog.csdn.net/icvpr
#include <iostream>
#include <string>

#include <opencv2/opencv.hpp>

int main(int argc, char** argv)
{
 std::string videoFileName = "../test.avi";

 int threshold = 25 ;    // 二值化阈值
 float alpha = 0.01;    // 更新速度 [0, 1]

 cv::VideoCapture capture;
 capture.open(videoFileName);
 if (!capture.isOpened())
 {
  std::cout<<"cannot open video"<<std::endl;
  return -1;
 }


 cv::Mat foregroundImg;
 cv::Mat foregroundMat;

 cv::Mat backgroundImg;
 cv::Mat backgroundMat;

 cv::Mat frame;
 cv::Mat grayImg;
 cv::Mat grayMat;
 
 while (capture.read(frame))
 {
  cv::cvtColor(frame, grayImg, CV_BGR2GRAY);
  grayImg.convertTo(grayMat, CV_32FC1);

  if (backgroundMat.empty())
  {
   grayImg.copyTo(backgroundImg);
   grayImg.convertTo(backgroundMat, CV_32FC1); 
  }
 
  // 背景减除
  cv::absdiff(grayMat, backgroundMat, foregroundMat);
 
  // 自适应背景更新
  cv::addWeighted(backgroundMat, alpha, foregroundMat, 1-alpha, 0, backgroundMat);

  // 二值化,获取前景像素点
  cv::threshold(foregroundMat, foregroundMat, threshold, 255, CV_THRESH_BINARY);


  // 为了显示用,将CV_32FC1转换为CV_8U
  cv::convertScaleAbs(foregroundMat, foregroundImg);
  cv::convertScaleAbs(backgroundMat, backgroundImg);

  cv::imshow("frame", frame);
  cv::imshow("foreground", foregroundImg);
  cv::imshow("background", backgroundImg);

  if (cv::waitKey(25) > 0)
  {
   break;
  }
 }

 return 0;
}

相关推荐