如何使用c ++提取视频帧并将其另存为图像

时间:2015-11-03 15:37:19

标签: c++ opencv

我现在正试图将视频文件的帧保存到我的电脑上的图像中。我正在使用Visual Studio 2010和opencv 2.3.1。在此代码中(如下所示),它可以保存图像序列的帧,但对于视频文件,我无法保存帧。 这个问题似乎特别在这里: 在vidoeprocessing()

的功能
   string imageToSave =("output_MOG_" +  frameNumberString + ".png");
  bool saved = imwrite( imageToSave,fgMaskMOG);
  if(!saved) {
   cerr << "Unable to save " << imageToSave << endl;
      } 

任何人都可以帮忙解决这个问题吗? 提前谢谢。

我的代码是:

    //opencv
 #include < opencv2/opencv.hpp>
 #include < opencv2/core/core.hpp>
 #include < opencv2/highgui/highgui.hpp>
 #include < opencv2/video/background_segm.hpp>
 //#include <opencv2/imgcodecs.hpp>
 #include <opencv2/imgproc/imgproc.hpp>
 //#include "opencv2/videoio.hpp"
  #include <opencv2/video/video.hpp>
 //C
 #include <stdio.h>
//C++
#include <iostream>
#include <sstream>

using namespace cv;
using namespace std;

      // Global variables
  Mat frame; //current frame
 Mat fgMaskMOG; //fg mask fg mask generated by MOG method
 Ptr<BackgroundSubtractor> pMOG; //MOG Background subtractor
 int keyboard; //input from keyboard

 /** Function Headers */
void 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;
 }

/**
 * @function main
 */
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 ");

//create Background Subtractor objects
pMOG = new BackgroundSubtractorMOG();
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;
}

 //function processVideo

 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->operator()(frame, fgMaskMOG,0.9);
    //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(CV_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);
    //get the input from the keyboard
    keyboard = waitKey( 30 );
}

/*
string imageToSave =("output_MOG_" +  frameNumberString + ".bmp");
    bool saved = imwrite( imageToSave,fgMaskMOG);
    if(!saved) {
    cerr << "Unable to save " << imageToSave << endl;
       } 
      */


//delete capture object
 capture.release();
 }

/**
 * @function processImages
 */
void processImages(char* fistFrameFilename) {
  //read the first file of the sequence
  frame = imread(fistFrameFilename);
  if(frame.empty()){
    //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->operator()(frame, fgMaskMOG,0.9);
    //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);
    //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.empty()){
        //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);

    // save subtracted images
    string imageToSave =("output_MOG_" +  frameNumberString + ".png");
    bool saved = imwrite( imageToSave,fgMaskMOG);
    if(!saved) {
    cerr << "Unable to save " << imageToSave << endl;
       }
}
}

1 个答案:

答案 0 :(得分:2)

这是使用网络摄像头的小样本。您可以轻松地对其进行调整以使用视频:

#include "opencv2/opencv.hpp"
using namespace cv;

int main(int, char**)
{
    VideoCapture cap(0); // open the default camera
    if (!cap.isOpened())  // check if we succeeded
        return -1;

    Ptr<BackgroundSubtractor> pMOG = new BackgroundSubtractorMOG2();

    Mat fg_mask;
    Mat frame;
    int count = -1;

    for (;;)
    {
        // Get frame
        cap >> frame; // get a new frame from camera

        // Update counter
        ++count;

        // Background subtraction
        pMOG->operator()(frame, fg_mask);

        imshow("frame", frame);
        imshow("fg_mask", fg_mask);

        // Save foreground mask
        string name = "mask_" + std::to_string(count) + ".png";
        imwrite("D:\\SO\\temp\\" + name, fg_mask);

        if (waitKey(1) >= 0) break;
    }
    // the camera will be deinitialized automatically in VideoCapture destructor
    return 0;
}