Does anyone know how to get OpenCV to grab all the frames from a video file?
I've been trying to just grab frames from video files (.wmv files, in particular), but on most videos, I end up with "nan" as my framerate and it only gets a single frame from my video and doesn't think there are any more. However, on at least one video, it succeeds and gets the right framerate. I tried to manually set the frame rate, but this did not work.
One thing to note is that it seems like the videos where it doesn't work are very short (~5 seconds long). However, I have not thoroughly tested this theory as I don't have very many videos (only ~10 videos).
The minimum code necessary to reproduce this is below:
int main(int argc, char** argv)
{
VideoCapture capture;
char* video = argv[1];
int flag = arg_parse(argc, argv);
capture.open(video);
//capture.set(CV_CAP_PROP_FPS, 25); // Trying to set frame rate.
std::cout << "frame rate: " << capture.get(CV_CAP_PROP_FPS) << std::endl;
if(!capture.isOpened()) {
fprintf(stderr, "Could not initialize capturing..\n");
return -1;
}
while(true) {
Mat frame;
int i, j, c;
// get a new frame
capture >> frame;
std::cout << "GOT FRAME!" << std::endl;
if(frame.empty()) {
std::cout << "breaking..." << std::endl;
break;
}
}
return 0;
}
Thanks so much!
Related
I am currently trying to record a video from a webcam (Logitech StreamCam Pro - Full HD) and then writing the captured feed into an .mp4 file. However, when I open the file with VLC, I get no playback. Just the VLC logo, with video length being 00:00:00 / 00:00:00.
I have noticed that if I change the extension from .mp4 into .avi that it does actually play back in VLC, however, at a ludacris speed (fps), much higher than the 60 fps of the camera.
TLDR - I am unable to play the .mp4 file of my webcam feed 1920x1080 # 60 fps, and I am wondering if anyone can help me with the problem.
C++ code block below, containing the logic
int MediaCapture::RecordFeed(int cameraID)
{
std::cout << "Camera selected: " << cameraID << std::endl;
// Define total frames and start of a counter for FPS calculation
int totalFrames = 0;
cv::VideoCapture *capture;
capture = new cv::VideoCapture(2);
if(!capture->isOpened()){
std::cout << "Error opening video stream or file" << std::endl;
return -1;
}
int frameWidth = capture->get(cv::CAP_PROP_FRAME_WIDTH);
int frameHeight = capture->get(cv::CAP_PROP_FRAME_HEIGHT);
int cameraFPS = capture->get(cv::CAP_PROP_FPS);
cv::VideoWriter video(fs::current_path().string() + "/assets/videos/recording.mp4",video.fourcc('m','p','4','v'),cameraFPS,cv::Size(frameWidth,frameHeight));
int tf = 0;
time_t start, end;
time(&start);
cv::Mat frame;
cv::Mat resizedFrame;
while (capture->read(frame))
{
tf++;
cv::resize(frame,resizedFrame,cv::Size(1920,1080));
std::cout << "Height:" << resizedFrame.size().height << std::endl;
std::cout << "Width:" << resizedFrame.size().width << std::endl;
video.write(resizedFrame);
if (cv::waitKey(1) >= 0)
{
break;
}
}
// When everything done, release the video capture and write object
capture->release();
video.release();
// Closes all the windows
cv::destroyAllWindows();
return 0;
}
I have written a program to display a stored video file using opencv. I attached the code below. I am not getting any errors while building it but no output is displayed.
int main(int argc, char *argv[])
{
if (argc <= 1)
{
printf("Usage: %s video\n", argv[0]);
return -1;
}
VideoCapture capture(argv[1]);
namedWindow("display",cv::WINDOW_AUTOSIZE);
capture.set(cv::CAP_PROP_FRAME_WIDTH, 640);
capture.set(cv::CAP_PROP_FRAME_HEIGHT, 480);
if(!capture.isOpened())
{
printf("Failed to open the video\n");
return -1;
}
int i;
for(i=0;i<390;i++)
{
Mat frame;
capture >> frame; // get a new frame from camera
cout << "frame =" << endl << " " << frame << endl << endl;
imshow("display",frame);
}
}
I included the cout line at the end to check if the frame is getting any value or not. So a got a number of values in a matrix, but the video window is not appearing.
You have to add a very small delay after imshow by using waitKey.
imshow("display",frame);
waitKey(10); //Wait 10 milliseconds before showing next frame.
I am trying to read multiple image files named like 001.jpg, 002.jpg, 003.jpg and onwards by using OpenCV on Linux and displaying them in a window after some delay. Here is my code -
int main(int argc, char ** argv){
cv::VideoCapture cam("/home/bikz05/Desktop/dataset/%03d.jpg");
if (!cam.isOpened())
cout << "Capture is not opened";
cv::Mat image;
const string Window = "Image Number";
namedWindow(Window, CV_WINDOW_NORMAL);
while(true) {
cam >> image;
if (!image.data) {
std::cout << "Preview Ends" << std::endl;
break;
}
cv::imshow(Window, image);
waitKey(1000);
}
return 0;
}
In the first line of the main function, I even tried using
cv::VideoCapture cam("/home/bikz05/Desktop/dataset/001.jpg");
I even tried to place the images in the same folder as the binary, even that didn't help.
In both the cases, it displays only the first image and then the program exits. Note, it doesn't finish.
P.S. - The answers provided on Stack Exchange and opencv.org did not produce the intended result.
The code as you have written has several problems, but if you are going to read images from the disk, use cv::imread() instead of cv::VideoCapture:
std::string filename = "/home/bikz05/Desktop/dataset/001.jpg";
const std::string Window = "Image Number";
cv::namedWindow(Window, CV_WINDOW_NORMAL);
while (true)
{
cv::Mat image = cv::imread(filename.c_str());
if (!image.data)
{
std::cout << "!!! File not found: " << filename << std::endl;
break;
}
cv::imshow(Window, image);
cv::waitKey(1000);
// And before the loop ends, update filename with the next image:
// filename = ???;
}
I haven't tested this, but I'm sure you get the idea.
use glob as in glob(folderpath, vectorOfimages) then access each of the images as vectorOfimages[i].
vectorOfimages is
vector<String>
and folderpath is a String.
I had the same problem and videoCapture does not solve it.
I am trying to write the recording from my webcam into a file. For this purpose I am using the following code. I am getting an exit code of 2, all the time. Can someone help me figure out what is the problem?
I have previously used a similar function call to write frames from one video file into a new one, where it worked. Can't understand what is the problem in this case.
Code Snippet follows:
int main(int argc, char *argv[]){
cv::Mat frame;
cv::VideoCapture cap(0);
cv::BackgroundSubtractorGMG bg;
bg.numInitializationFrames=120;
bg.decisionThreshold = 0.95;
bg.maxFeatures = 10;
double fps = cap.get(CV_CAP_PROP_FPS);
CvSize frameSize;
frameSize.height = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
frameSize.width = cap.get(CV_CAP_PROP_FRAME_WIDTH);
VideoWriter VW1("resultbuff.avi",CV_FOURCC('M','P','E','G'), fps, frameSize, 1);
VideoWriter VW2("recordingbuff.avi",CV_FOURCC('M','P','E','G'), fps, frameSize, 1);
VideoWriter VW3("finalResult.avi",CV_FOURCC('M','P','E','G'), fps, frameSize, 1);
if (!VW1.isOpened())
{
std::cout << "!!! Output video could not be opened" << std::endl;
return 2;
}
if (!VW2.isOpened())
{
std::cout << "!!! Output video could not be opened" << std::endl;
return 3;
}
if (!VW3.isOpened())
{
std::cout << "!!! Output video could not be opened" << std::endl;
return 4;
}
As mentioned, the program exits with code 2.
Okay, I found the answer. It was an error with the dlls. I was running the program in debug mode and the openCV dlls linked were for the release mode.
I have written a program to display a stored video file using opencv. I attached the code below. I am not getting any errors while building it but no output is displayed.
int main(int argc, char *argv[])
{
if (argc <= 1)
{
printf("Usage: %s video\n", argv[0]);
return -1;
}
VideoCapture capture(argv[1]);
namedWindow("display",cv::WINDOW_AUTOSIZE);
capture.set(cv::CAP_PROP_FRAME_WIDTH, 640);
capture.set(cv::CAP_PROP_FRAME_HEIGHT, 480);
if(!capture.isOpened())
{
printf("Failed to open the video\n");
return -1;
}
int i;
for(i=0;i<390;i++)
{
Mat frame;
capture >> frame; // get a new frame from camera
cout << "frame =" << endl << " " << frame << endl << endl;
imshow("display",frame);
}
}
I included the cout line at the end to check if the frame is getting any value or not. So a got a number of values in a matrix, but the video window is not appearing.
You have to add a very small delay after imshow by using waitKey.
imshow("display",frame);
waitKey(10); //Wait 10 milliseconds before showing next frame.