视频模块 视频分析

来源:互联网 发布:网络配资平台 编辑:程序博客网 时间:2024/04/27 15:21

opencv_video模块:运动估计、特征跟踪及前景提取函数和类;(视频分析组件,该模块包括运动估计,背景分离,对象跟踪等视频处理相关内容)

从这个单元,可以找到可用于您的视频流的算法,如:运动提取,特征跟踪和前景提取。

标题:如何使用背景减法方法

兼容性:> OpenCV 2.4.6

作者:Domenico Daniele Bloisi

我们将学习如何从两个视频和图像序列中提取前景蒙版并显示它们。

背景减法(BS)是通过使用静态摄像机产生前景掩码(即,包含属于场景中的移动物体的像素的二进制图像)的常用和广泛使用的技术。

顾名思义,BS计算当前帧和背景模型之间的减法的前景掩码,该背景模型包含场景的静态部分,或者更一般地,考虑到观察到的场景的特征可以被视为背景的所有内容。

背景建模包括两个主要步骤:

背景初始化;
背景更新

在第一步中,计算背景的初始模型,而在第二步中,更新模型以适应场景中的可能变化。

在本教程中,我们将学习如何使用OpenCV执行BS。 作为输入,我们将使用来自公开可用数据集背景模型挑战(BMC)的数据。

目标:

在本教程中,您将学习如何:
通过使用VideoCapture或图像序列通过使用imread从视频中读取数据;
使用BackgroundSubtractor类创建和更新背景模型;
使用imshow获取并显示前景蒙板;
使用imwrite保存输出以定量评估结果。

源代码;

在下面你可以找到源代码。 我们将让用户选择处理视频文件或一系列图像。

两种不同的方法用于生成两个前景蒙版:

  1. MOG
  2. MOG2

结果以及输入数据显示在屏幕上。

//opencv-bg_sub.cpp#include <opencv2/highgui/highgui.hpp>#include <opencv2/video/background_segm.hpp>//C#include <stdio.h>//C++#include <iostream>#include <sstream>using namespace cv;using namespace std;//global variablesMat frame; //current frameMat fgMaskMOG; //fg mask generated by MOG methodMat fgMaskMOG2; //fg mask fg mask generated by MOG2 methodPtr<BackgroundSubtractor> pMOG; //MOG Background subtractorPtr<BackgroundSubtractor> pMOG2; //MOG2 Background subtractorint keyboard;//function declarationsvoid help();void processVideo(char* videoFilename);void processImages(char* firstFrameFilename);void help(){  cout  << "--------------------------------------------------------------------------"  << endl  << "This program shows how to use background subtraction methods provided by "   << endl  << " OpenCV. You can process both videos (-vid) and images (-img)."              << endl                                                                                   << endl  << "Usage:"                                                                      << endl  << "./bs {-vid <video filename>|-img <image filename>}"                          << endl  << "for example: ./bs -vid video.avi"                                            << endl  << "or: ./bs -img /data/images/1.png"                                            << endl  << "--------------------------------------------------------------------------"  << endl  << endl;}int main(int argc, char* argv[]){  //print help information  help();  //check for the input parameter correctness  if(argc != 3) {    cerr <<"Incorret input list" << endl;    cerr <<"exiting..." << endl;    return EXIT_FAILURE;  }  //create GUI windows  namedWindow("Frame");  namedWindow("FG Mask MOG");  namedWindow("FG Mask MOG 2");  //create Background Subtractor objects  pMOG = createBackgroundSubtractorMOG(); //MOG approach  pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach  if(strcmp(argv[1], "-vid") == 0) {    //input data coming from a video    processVideo(argv[2]);  }  else if(strcmp(argv[1], "-img") == 0) {    //input data coming from a sequence of images    processImages(argv[2]);  }  else {    //error in reading input parameters    cerr <<"Please, check the input parameters." << endl;    cerr <<"Exiting..." << endl;    return EXIT_FAILURE;  }  //destroy GUI windows  destroyAllWindows();  return EXIT_SUCCESS;}void processVideo(char* videoFilename) {  //create the capture object  VideoCapture capture(videoFilename);  if(!capture.isOpened()){    //error in opening the video input    cerr << "Unable to open video file: " << videoFilename << endl;    exit(EXIT_FAILURE);  }  //read input data. ESC or 'q' for quitting  while( (char)keyboard != 'q' && (char)keyboard != 27 ){    //read the current frame    if(!capture.read(frame)) {      cerr << "Unable to read next frame." << endl;      cerr << "Exiting..." << endl;      exit(EXIT_FAILURE);    }    //update the background model    pMOG->apply(frame, fgMaskMOG);    pMOG2->apply(frame, fgMaskMOG2);    //get the frame number and write it on the current frame    stringstream ss;    rectangle(frame, cv::Point(10, 2), cv::Point(100,20),              cv::Scalar(255,255,255), -1);    ss << capture.get(CAP_PROP_POS_FRAMES);    string frameNumberString = ss.str();    putText(frame, frameNumberString.c_str(), cv::Point(15, 15),            FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));    //show the current frame and the fg masks    imshow("Frame", frame);    imshow("FG Mask MOG", fgMaskMOG);    imshow("FG Mask MOG 2", fgMaskMOG2);    //get the input from the keyboard    keyboard = waitKey( 30 );  }  //delete capture object  capture.release();}void processImages(char* fistFrameFilename) {  //read the first file of the sequence  frame = imread(fistFrameFilename);  if(!frame.data){    //error in opening the first image    cerr << "Unable to open first image frame: " << fistFrameFilename << endl;    exit(EXIT_FAILURE);  }  //current image filename  string fn(fistFrameFilename);  //read input data. ESC or 'q' for quitting  while( (char)keyboard != 'q' && (char)keyboard != 27 ){    //update the background model    pMOG->apply(frame, fgMaskMOG);    pMOG2->apply(frame, fgMaskMOG2);    //get the frame number and write it on the current frame    size_t index = fn.find_last_of("/");    if(index == string::npos) {      index = fn.find_last_of("\\");    }    size_t index2 = fn.find_last_of(".");    string prefix = fn.substr(0,index+1);    string suffix = fn.substr(index2);    string frameNumberString = fn.substr(index+1, index2-index-1);    istringstream iss(frameNumberString);    int frameNumber = 0;    iss >> frameNumber;    rectangle(frame, cv::Point(10, 2), cv::Point(100,20),              cv::Scalar(255,255,255), -1);    putText(frame, frameNumberString.c_str(), cv::Point(15, 15),            FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));    //show the current frame and the fg masks    imshow("Frame", frame);    imshow("FG Mask MOG", fgMaskMOG);    imshow("FG Mask MOG 2", fgMaskMOG2);    //get the input from the keyboard    keyboard = waitKey( 30 );    //search for the next image in the sequence    ostringstream oss;    oss << (frameNumber + 1);    string nextFrameNumberString = oss.str();    string nextFrameFilename = prefix + nextFrameNumberString + suffix;    //read the next frame    frame = imread(nextFrameFilename);    if(!frame.data){      //error in opening the next image in the sequence      cerr << "Unable to open image frame: " << nextFrameFilename << endl;      exit(EXIT_FAILURE);    }    //update the path of the current frame    fn.assign(nextFrameFilename);  }}

使用drawContours来清理背景分割结果的示例 :segment_objects.cpp

#include "opencv2/imgproc.hpp"#include "opencv2/videoio.hpp"#include "opencv2/highgui.hpp"#include "opencv2/video/background_segm.hpp"#include <stdio.h>#include <string>using namespace std;using namespace cv;static void help(){    printf("\n"            "This program demonstrated a simple method of connected components clean up of background subtraction\n"            "When the program starts, it begins learning the background.\n"            "You can toggle background learning on and off by hitting the space bar.\n"            "Call\n"            "./segment_objects [video file, else it reads camera 0]\n\n");}static void refineSegments(const Mat& img, Mat& mask, Mat& dst){    int niters = 3;    vector<vector<Point> > contours;    vector<Vec4i> hierarchy;    Mat temp;    dilate(mask, temp, Mat(), Point(-1,-1), niters);    erode(temp, temp, Mat(), Point(-1,-1), niters*2);    dilate(temp, temp, Mat(), Point(-1,-1), niters);    findContours( temp, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE );    dst = Mat::zeros(img.size(), CV_8UC3);    if( contours.size() == 0 )        return;    // iterate through all the top-level contours,    // draw each connected component with its own random color    int idx = 0, largestComp = 0;    double maxArea = 0;    for( ; idx >= 0; idx = hierarchy[idx][0] )    {        const vector<Point>& c = contours[idx];        double area = fabs(contourArea(Mat(c)));        if( area > maxArea )        {            maxArea = area;            largestComp = idx;        }    }    Scalar color( 0, 0, 255 );    drawContours( dst, contours, largestComp, color, FILLED, LINE_8, hierarchy );}int main(int argc, char** argv){    VideoCapture cap;    bool update_bg_model = true;    CommandLineParser parser(argc, argv, "{help h||}{@input||}");    if (parser.has("help"))    {        help();        return 0;    }    string input = parser.get<std::string>("@input");    if (input.empty())        cap.open(0);    else        cap.open(input);    if( !cap.isOpened() )    {        printf("\nCan not open camera or video file\n");        return -1;    }    Mat tmp_frame, bgmask, out_frame;    cap >> tmp_frame;    if(tmp_frame.empty())    {        printf("can not read data from the video source\n");        return -1;    }    namedWindow("video", 1);    namedWindow("segmented", 1);    Ptr<BackgroundSubtractorMOG2> bgsubtractor=createBackgroundSubtractorMOG2();    bgsubtractor->setVarThreshold(10);    for(;;)    {        cap >> tmp_frame;        if( tmp_frame.empty() )            break;        bgsubtractor->apply(tmp_frame, bgmask, update_bg_model ? -1 : 0);        refineSegments(tmp_frame, bgmask, out_frame);        imshow("video", tmp_frame);        imshow("segmented", out_frame);        char keycode = (char)waitKey(30);        if( keycode == 27 )            break;        if( keycode == ' ' )        {            update_bg_model = !update_bg_model;            printf("Learn background is in state = %d\n",update_bg_model);        }    }    return 0;}





0 0
原创粉丝点击