我试着拍摄电影的第一帧。但VideoCapture(opencv)似乎不可能。 为了确保我无法获得第一个视频,我创建了一个所有帧编号。您可以检查保存的视频是否具有正确的编号。 无论我做什么,我都无法回到第一帧。 检查这个的代码:
如何获得电影的第一帧? 这是一个错误还是在检索代码中的框架时出错?
请编译代码并运行。没有参数,就会生成一部小电影。关于想要的标准输出评论。或者将电影名称指定为参数。
另见下两个图像的比较问题(“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;
}
}