Video Capture : Frame always empty - opencv - c++

I am working with openCV Version 2.4.9, and on Mac OSX.
I have written this code for loading and displaying a video on my desktop. But it never seems to work. I always get the output as "frame empty". Thus it does not complain about reading the video using VideoCapture.It is NOT able to capture any frames, and thus 'frame' is always EMPTY. Any idea what the problem might be?
Note: I have tried both ways to capture a frame - commented as try 1 and try2.
int main(int argc, const char * argv[])
{
Mat frame;
VideoCapture capture_ir("/Users/shreyatandon/Desktop/resize_ir.avi");
if ( !capture_ir.isOpened() ) // if not success, exit program
{
cout << "Cannot open the video file" << endl;
return -1;
}
for (;;){
// capture_ir.read(frame); //try1
capture_ir>>frame; //try2
if(frame.empty()){
std::cerr<<"frame is empty"<<std::endl;
break;
}
imshow("", frame);
waitKey(10);
break;
}
return 0;
}

Just made it work.
Mat current_frame;
VideoCapture video("video.avi");
while(true)
{
video.read(current_frame);
imshow("Image",current_frame);
}
If you keep having problems using avi format have a look at your links to the ffmpeg libraries and it dependencies. I tried to install it from scratch using homebrew and it is working without problems. Cheers

Related

OpenCV trying to read or write to video file causes VIDEOIO exception "Can't find starting number" (icvExtractPattern)

So for a school project, I am trying to use cv::VideoCapture to open a .avi file to perform some image processing on it. Also, I am trying to record the video from my (Laptop) camera and save it to a file out.avi. Both times I encountered more or less the same exception.
I am using OpenCV 4.1.2 and CLion on Linux Mint.
Trying to use cv::VideoCapture vid(0); works perfectly fine, it shows the output from the Laptop's camera. However, when specifying a path to a video file to open, I get the following error:
VIDIOC_REQBUFS: Inappropriate ioctl for device
[ERROR:0] global /home/aris/dev/opencv/modules/videoio/src/cap.cpp (116) open VIDEOIO(CV_IMAGES): raised OpenCV exception:
OpenCV(4.1.2-dev) /home/aris/dev/opencv/modules/videoio/src/cap_images.cpp:253: error: (-5:Bad argument) CAP_IMAGES: can't find starting number (in the name of file): ../example_depth.avi in function 'icvExtractPattern'
When trying to create a cv::VideoWriter object (to save the camera video ouput to a file) using:
cv::VideoWriter vidWrit("out.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 10, cv::Size(width, height), true);
I am encountering this error:
[ERROR:0] global /home/aris/dev/opencv/modules/videoio/src/cap.cpp (392) open VIDEOIO(CV_IMAGES): raised OpenCV exception:
OpenCV(4.1.2-dev) /home/aris/dev/opencv/modules/videoio/src/cap_images.cpp:253: error: (-5:Bad argument) CAP_IMAGES: can't find starting number (in the name of file): out.avi in function 'icvExtractPattern'
Which looks kind of similar to the other one.
Here is a minimal example (note that the program still shows the camera output in task == "write"):
#include <opencv2/opencv.hpp>
int main ()
{
std::string task = "write";
if(task == "read") { // Read from .avi file
system("pwd"); // Print current path
cv::VideoCapture vid("../example_depth.avi"); // Throws first exception "Inappropriate ioctl for device"
int key = 0;
cv::Mat frame;
while (key != 27) {
vid >> frame;
if (frame.empty())
break;
cv::imshow("Video", frame);
key = cv::waitKey(25);
}
} else if (task == "write") { // Write Laptop video to file
cv::VideoCapture vid(0); // Video from camera
int width = vid.get(cv::VideoCaptureProperties::CAP_PROP_FRAME_WIDTH);
int height = vid.get(cv::VideoCaptureProperties::CAP_PROP_FRAME_HEIGHT);
cv::VideoWriter vidWriter("out.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 10, cv::Size(width, height), true); // Throws second exception
int key = 0;
cv::Mat frame;
while (key != 27) {
vid >> frame;
if (frame.empty())
break;
vidWriter.write(frame);
cv::imshow("Video", frame);
key = cv::waitKey(25);
}
}
return 0;
}
I've been looking for a solution for two days now. Maybe I am missing some library or OpenCV didn't get installed correctly, I don't know about that (yes, I've tried 'recompiling' OpenCV). I used this tutorial to make all the OpenCV files.
Did the file you want to write to (out.avi) already exist?
I got this error with opencv-python==4.1.2.30 and changing the output to a filepath that did not exist solved it for me.
I've seen this issue a couple of times. First check if the path to the video is correct. In your case, "out.avi" should exist. So this is probably is a dependency or conflict issue. My speculation is that this error occurs when a backend video encoder library conflicts with OpenCV. Try reinstalling the libraries. I suggest you follow the instructions from the official documentation, and open an issue if you keep experiencing problems.

OpenCV VideoCapture works inconsistently

I have been trying to get my application using OpenCV to work for a while now and a longstanding error which I cannot seem to fix is this one:
PROBLEM:
OpenCV's VideoCapture is inconsistent in splitting video into frames for different file formats and codecs.
Specifics:
My errors are in one part of the application: splitting videos into frames. There are three current scenarios when I choose a valid directory for VideoCapture and open it. It either:
Opens and works perfectly.
Is able to open the VideoCapture (cap.isOpened() = true) but receives an empty frame or two during the frame split which causes app to throw error.
Does not open at all.
A given video will only do one of those three things. AVI File formats seem to have most of the errors, though.
Fixes tried:
Installing K-Lite Codec Pack Full
Putting OpenCV_FFMPEG.dll and OpenCV_FFMPEG_64.dll in project directory and in PATH
The only explanation I can think of is this is an error with the way I installed OpenCV and FFmpeg.
Any help would be greatly appreciated! Thanks.
By the way, I am running Qt 5.8.0 and OpenCV 3.2.0 and this is my FrameSplit code.
vector<int> mainFrame::frameSplit(string filename, string location)
{
//Extract + Save Frames
string vidDir = filename;
string locationDir = location + "/frames/";
VideoCapture cap(vidDir);
if (!cap.isOpened())
{
qDebug() << "OO";
return {};
}
else
{
Mat firstFrame;
Mat nextFrame;
Mat frame;
int count = 1;
QProgressDialog progress("Extracting files...", "Abort", 0, cap.get(CV_CAP_PROP_FRAME_COUNT));
progress.setWindowModality(Qt::WindowModal);
progress.setAttribute(Qt::WA_DeleteOnClose, true);
progress.setFixedSize(500, 100);
progress.show();
vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
compression_params.push_back(100);
qDebug() << cap.get(CV_CAP_PROP_FRAME_COUNT);
bool failure = false;
for (count = 1; count < cap.get(CV_CAP_PROP_FRAME_COUNT); count++)
{
cap >> frame;
if(frame.empty()) {
QMessageBox messageBox;
messageBox.critical(this, "Error", "There was an error in analyzing the video. Please try and install the appropriate codecs and try again.");
messageBox.setFixedSize(600,400);
vector<int> empty;
return empty;
}
string filePath = locationDir + to_string(count) + ".jpg";
imwrite(filePath,frame,compression_params);
progress.setValue(count);
}
progress.setValue(count);
progress.close();
vector<int> props;
props.push_back(cap.get(CV_CAP_PROP_FRAME_COUNT));
props.push_back(round(cap.get(CV_CAP_PROP_FPS)));
props.push_back(cap.get(CV_CAP_PROP_FRAME_WIDTH));
props.push_back(cap.get(CV_CAP_PROP_FRAME_HEIGHT));
qDebug() << props[0];
return props;
}
}

A bug in CV::VideoCapture::open()?

I am using CV::VideoCapture to capture frames from an IP camera. It works most of time, however, sometimes it reports the error:
[mjpeg # 0x233aea0] overread 8
And when this error occurred, my program just stuck there. This might explain why. But how can I solve it in C++ code? Can OpenCV handle this error without terminate the program?
p.s. I found that if I didn't call CV::VideoCapture::read() immediately, but wait for a while, like 60 seconds, after CV::VideoCapture::open(), this error occurred everytime! Is it a bug of OpenCV?
#include <unistd.h>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
int main(int argc, char* argv[]) {
// argv[1] is a valid url, like "http://xxxx/mjpg/video.mjpg"
cv::VideoCapture cap(argv[1]);
if (!cap.isOpened()) {
std::cout << "Cannot Open Camera!" << std::endl;
return -1;
}
// The error occures if I pause for a while.
// But it is okay when I capture frames from video files intead of IP camera.
sleep(60);
while (static_cast<char>(cv::waitKey(1)) != 'q') {
cv::Mat frame;
cap >> frame;
if (frame.empty()) break;
cv::imshow("frame", frame);
}
}
I can't explain why but using the address http://xxxx/axis-cgi/mjpg/video.cgi instead of http://xxxx/mjpg/video.mjpg solved it! Can anyone provide some nice explanation here, or some links? Thanks!

opencv mp3 header missing

Hi i'm new to the openCV library. Just really installed in today and i was trying to do some basic stuff like show a picture in a window and show a video in a window.
I got both of these to work but when i try and show the video it plays without sound and i get the following
[mp3 # 0x107808800] Header missing
in the console. How do i add the mp3 header so it plays with sound?
here is my code
int main(int argc, const char * argv[])
{
if (argc<2) {
printf("not enough arguments");
return -1;
}
//create a window
namedWindow(windowName,WINDOW_AUTOSIZE);
Mat frame;
//capture video from file
VideoCapture capture;
capture.open(argv[1]);
int run=1;
while (1) {
//make play and pause feature
if (run !=0) {
capture>>frame;
imshow(windowName, frame);
}
char c=waitKey(33);
if (c=='p') {
run=1;
}
if (c=='s') {
run=0;
}
if (c ==27 || c=='q') {
break;
}
}
return 0;
}
you can't .
audio gets discarded (that's the message you get), and there's no way to retrieve it again.

Unable to read frames from VideoCapture from secondary webcam with OpenCV

Code:
Simple example that works perfectly with primary webcam (device 0):
VideoCapture cap(0);
if (!cap.isOpened()) {
std::cout << "Unable to read stream from specified device." << std::endl;
return;
}
while (true)
{
// retrieve the frame:
Mat frame;
if (!cap.read(frame)) {
std::cout << "Unable to retrieve frame from video stream." << std::endl;
break;
}
// display it:
imshow("MyVideo", frame);
// check if Esc has been pressed:
if (waitKey(1) == 27) {
break;
}
// else continue:
}
cap.release();
Problem:
I have a second webcam, which I'd like to use. However, when I replace VideoCapture cap(0); with VideoCapture cap(1);, the stream is being opened correctly (or at least cap.isOpened() returns true) but the cap.read(frame) call returns false and I'm unable to find out why.
What I've tried:
I've been trying to play with VideoCapture's settings a bit like calling:
cap.set(CV_CAP_PROP_FORMAT, CV_8UC3);
and random stuff like that, but nothing seems to help.
I've also found this: VideoCapture::read fails on uncompressed video (Bug #2281), which seems to be solved on version 2.4.7.. but I've just updated OpenCV to 2.4.8 and it still doesn't work...
I've tried to use the AMCap to capture the raw video from this camera, save it as aaa.avi file and constructed VideoCapture by calling:
VideoCapture cap("aaa.avi");
and it works (while being read from file)... what I need is real-time processing with live view though.
HW, OS, SW details:
My HW: HP ProBook 4510s with built-in webcam that always works perfectly
+ external webcam CANYON CNR-FWCII3, refered by OS as "USB Video Device" (the troublesome one)
OS, SW: Windows 8.1 Pro x86, Visual Studio 2012 Pro, OpenCV 2.4.8 ~ using vc11 build
Questions:
Am I missing something?
Is there anything else that I could do?
Is there at least any way how to retrieve some additional information about what the problem might actually be?
... OpenCV's API seems quite poor in this case and everywhere where people seemed to be facing the similar issue, there was someone claiming it to be "OS / HW depnendant" as an excuse.
Any help will be appreciated.
After some time I've found out that it is always only the first call of read that fails and skipping the first frame started to work fine although the true reason of this behavior remained unknown.
Later James Barnett (see comments above) has pointed out that the reason might be that it takes a while till the camera gets ready for capturing and my current solution looks the following way (C++11's sleep):
#include <chrono>
#include <thread>
...
VideoCapture cap(1);
// give camera some extra time to get ready:
std::this_thread::sleep_for(std::chrono::milliseconds(200));
if (!cap.isOpened()) {
std::cout << "Unable to read stream from specified device." << std::endl;
return;
}
while (true)
{
// retrieve the frame:
Mat frame;
if (!cap.read(frame)) {
std::cout << "Unable to retrieve frame from video stream." << std::endl;
continue;
}
// display it:
imshow("LiveStream", frame);
// stop if Esc has been pressed:
if (waitKey(1) == 27) {
break;
}
}
cap.release();
Hopefully some future visitors will find it helpful :)
easiest way to solve is to read once before checking for success. This code snippet works for me.
//
cap.read(frame);
if(!cap.read(frame)){
//
...
the fix in my case is disconect any camera conected to a sub hub! even if is only one! use your pc's usb port directly.