无法检索电影opencv的第一帧

时间:2015-10-28 21:04:21

标签: opencv video-capture

我试着拍摄电影的第一帧。但VideoCapture(opencv)似乎不可能。 为了确保我无法获得第一个视频,我创建了一个所有帧编号。您可以检查保存的视频是否具有正确的编号。 无论我做什么,我都无法回到第一帧。 检查这个的代码:

  1. 读取电影(6帧)
  2. 使用每帧打印的索引写入6帧
  3. 读取新制作的电影
  4. 显示彼此相邻的2张图片
  5. 如何获得电影的第一帧? 这是一个错误还是在检索代码中的框架时出错?

    请编译代码并运行。没有参数,就会生成一部小电影。关于想要的标准输出评论。或者将电影名称指定为参数。

    另见下两个图像的比较问题(“VideoWrite和videoRead OpenCv之后的图像不一样”)。

       #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/imgcodecs.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    
    using namespace cv;
    using namespace std;
    
        std::vector<Mat> ReadImages(string  VideoName)
        {
        // read movie from disk
            VideoCapture capture( VideoName);
            cout << VideoName;
            if (!capture.isOpened())
                cout  << "Could not open the output video for write: " << VideoName << endl;
    
            int NumFrames = capture.get(CV_CAP_PROP_FRAME_COUNT);
            std::vector<Mat> FramesRead(NumFrames);
            //  int NumFrames = capture.get(CV_CAP_PROP_FRAME_COUNT);
    
            cout << endl;
            for(int fr = 0; fr < NumFrames; ++fr){
                // read frame in 3 different ways:
                cout << "Position of pointer in Movie: " << capture.get(CAP_PROP_POS_FRAMES) << endl;
    
                switch (3) {
                    case 1:
                        capture.grab();
                        capture.retrieve(FramesRead[fr]);// >> frame;       // get frame
                        break;
                    case 2:
                        capture.set ( CV_CAP_PROP_POS_FRAMES , fr);       // set position
                        capture.read(FramesRead[fr]);   // get frame
                        break;
                    default:
                        capture >> FramesRead[fr];       // get frame
                        break;
                }
                // show read frame
                imshow("Reader",FramesRead[fr]);
                cout << "Frame read should indicate a '" << fr << "'" << " and " << fr+1 << " Faces" << endl;
                cout << "if number in Image is not the same as written here: VideoReader does not retrieve first image! \n";
                        if(waitKey(-1)==1) break;
            }
            cout << "finished reading Movie\n";
            return FramesRead;
        }
    
        string WriteImages(std::vector<Mat> frames, string VideoName)
        {
            // write movie to disk and put number in every image according to frame number
            Size S = Size((int) frames[0].cols,    // get input size
                          (int) frames[0].rows);
    
            VideoWriter outputVideo;
            // use a uncompressed codec sheme
            string Codec = "raw ";//"tiff";//,  "mp4v", "MJPG"};
            // Open the output
            String VideoName2 = VideoName + "_" + Codec + "_" + "Write.avi";
            cout << VideoName2 << endl;
            outputVideo.open( VideoName2, VideoWriter::fourcc(Codec[0],Codec[1],Codec[2],Codec[3]),1, S, false);
            if (!outputVideo.isOpened())
            {
                cout  << "Could not open the output video for write: " << VideoName << endl;
                return "-1";
            }
            else
            {
             // write images and put frame number in images
                for(int fr=0;fr < frames.size() ; ++fr) //Show the image captured in the window and repeat
                {
                    imshow("writer",frames[fr]);
                    waitKey(1);
                    putText(frames[fr], to_string(fr), Point(200, 100), FONT_HERSHEY_SIMPLEX, 1, Scalar(255,255,255));
                    outputVideo << frames[fr].clone();
                }
                return VideoName2;
            }
        }
    
        std::vector<Mat> Face_Color_Movie(int NumFrames)
        {
            // create a movie with colored faces
            const int w = 450;
    
            std::vector<Mat> Frames(NumFrames);
            Mat tmp = Mat::zeros(w, w, CV_8UC3);
            for(int i=0;  i< NumFrames;i++)
                tmp.copyTo(Frames[i]);
            Scalar white = Scalar(0,0,255);
    
            for(int fr=0;fr < NumFrames; fr++)
            {
    
                for( int i = 0; i < fr+1; i++ )
                {
                    int dx = (i%2)*250 - 30;
                    int dy = (i/2)*150;
                    if (i == 0)
                        white = Scalar(0,0,255);
                    else if(i == 1)
                        white = Scalar(255,0,0);
                    else
                        white = Scalar(0,255,0);
    
    
                    const Scalar black = Scalar(0);
    
                    if( i == 0 )
                    {
                        for( int j = 0; j <= 10; j++ )
                        {
                            double angle = (j+5)*CV_PI/21;
                            line(Frames[fr], Point(cvRound(dx+100+j*10-80*cos(angle)),
                                                   cvRound(dy+100-90*sin(angle))),
                                 Point(cvRound(dx+100+j*10-30*cos(angle)),
                                       cvRound(dy+100-30*sin(angle))), white, 1, 8, 0);
                        }
                    }
                    //    imshow("Faces", Frames[fr]);waitKey(1);
                    ellipse( Frames[fr], Point(dx+150, dy+100), Size(100,70), 0, 0, 360, white, -1, 8, 0 );
                    //    imshow("Faces", Frames[fr]);waitKey(1);
                    ellipse( Frames[fr], Point(dx+115, dy+70), Size(30,20), 0, 0, 360, black, -1, 8, 0 );
                    ellipse( Frames[fr], Point(dx+185, dy+70), Size(30,20), 0, 0, 360, black, -1, 8, 0 );
                    ellipse( Frames[fr], Point(dx+115, dy+70), Size(15,15), 0, 0, 360, white, -1, 8, 0 );
                    ellipse( Frames[fr], Point(dx+185, dy+70), Size(15,15), 0, 0, 360, white, -1, 8, 0 );
                    ellipse( Frames[fr], Point(dx+115, dy+70), Size(5,5), 0, 0, 360, black, -1, 8, 0 );
                    ellipse( Frames[fr], Point(dx+185, dy+70), Size(5,5), 0, 0, 360, black, -1, 8, 0 );
                    ellipse( Frames[fr], Point(dx+150, dy+100), Size(10,5), 0, 0, 360, black, -1, 8, 0 );
                    ellipse( Frames[fr], Point(dx+150, dy+150), Size(40,10), 0, 0, 360, black, -1, 8, 0 );
                    ellipse( Frames[fr], Point(dx+27, dy+100), Size(20,35), 0, 0, 360, white, -1, 8, 0 );
                    ellipse( Frames[fr], Point(dx+273, dy+100), Size(20,35), 0, 0, 360, white, -1, 8, 0 );
                }
                imshow("Faces", Frames[fr]);
                waitKey(1);
            }
            return Frames;
        }
    
    
        std::vector<Mat> Load_Movie(int NumFrames,string VideoName)
        {
            // reads NUMFRAMES from a specified movie from disk
    
            VideoCapture capture(VideoName);
    
    
            if (!capture.isOpened())
                cout  << "Could not open the output video for write: " << VideoName << endl;
    
            int ex = static_cast<int>(capture.get(CV_CAP_PROP_FOURCC));
            cout << "Codec: "<< ex << endl;
    
            std::vector<Mat>  Frames(NumFrames);
    
            for(int fr = 0; fr < NumFrames; ++fr)
            {
                capture >> Frames[fr];       // get frame
                imshow("test",Frames[fr]);
                waitKey(30);
            }
            return Frames;
        }
    
        int main( int argc, char** argv )
        {
            int NumFrames = 6;
            std::vector<Mat> Frames;
    
            // create a movie
            if (argc < 2)
                // A movie with colored faces is generated
                Frames = Face_Color_Movie(NumFrames);
            //   Frames = Face_Movie(NumFrames);
            else{
                // use an existing movie
    
                string VideoName = "Megamind_bugy.avi";  // use your own movie here
                VideoName = argv[1];
                Frames = Load_Movie(NumFrames,VideoName);
            }
    
            //--------------------------------
            // write the frames to disk
            string VideoName2 =  WriteImages(Frames, "Video_Faces.avi");
            // read the frames from disk (again)
            std::vector<Mat> FramesRead =  ReadImages( VideoName2);
    
            // show the frames and subtract to see if they are really the same?
            for (int fr=0;fr <NumFrames; ++fr)
            {
                //-------------------------------
                // first frame of read movie is missing!!!
                // Original image;   fr+1 because VideoReader skips the first frame!!!
                imshow("Frame before writing to disk",Frames[fr]);
                // Image read from disk (first frame missing)
                imshow("Frame after reading from Disk",FramesRead[fr]);
                cout << "-------------------------------\n";
                cout << "Shows Frame before writing to disk and frames after reading from disk\n";
                cout << "Image windows may lay on top of each other\n";
    
                moveWindow("Frame after reading from Disk",505,46);
                if(waitKey(-1)==1) break;
            }
        }
    

0 个答案:

没有答案