I'm using the following code to read a video from file, apply the canny edge algorithm and write the modified video to a file. The code compiles and runs perfectly. But, the video is not written! I'm utterly confused. Please tell me what the error is. The file is not created at all! OS: Ubuntu 12.10
Code for writing to the output file
Opening the output file
bool setOutput(const std::string &filename, int codec=0, double framerate=0.0, bool isColor=true) {
outputFile= filename;
extension.clear();
if (framerate==0.0)
framerate= getFrameRate(); // same as input
char c[4];
// use same codec as input
if (codec==0) {
codec= getCodec(c);
}
// Open output video
return writer.open(outputFile, // filename
codec, // codec to be used
framerate, // frame rate of the video
getFrameSize(), // frame size
isColor); // color video?
}
Writing the frame
void writeNextFrame (Mat& frame)
{
writer.write (frame);
}
And there's a separate run method which executes these
Whenever I encounter strange behaviors in my applications, I write a short, self contained, correct (compilable), example to help me understand what's going on.
I wrote the code below to illustrate what you should be doing. It's worth noting that it works perfectly on my Mac OS X:
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <string>
int main(int argc, char* argv[])
{
// Load input video
cv::VideoCapture input_cap("Wildlife.avi");
if (!input_cap.isOpened())
{
std::cout << "!!! Input video could not be opened" << std::endl;
return -1;
}
// Setup output video
cv::VideoWriter output_cap("output.avi",
input_cap.get(CV_CAP_PROP_FOURCC),
input_cap.get(CV_CAP_PROP_FPS),
cv::Size(input_cap.get(CV_CAP_PROP_FRAME_WIDTH), input_cap.get(CV_CAP_PROP_FRAME_HEIGHT)));
if (!output_cap.isOpened())
{
std::cout << "!!! Output video could not be opened" << std::endl;
return -1;
}
// Loop to read frames from the input capture and write it to the output capture
cv::Mat frame;
while (true)
{
if (!input_cap.read(frame))
break;
output_cap.write(frame);
}
// Release capture interfaces
input_cap.release();
output_cap.release();
return 0;
}
Inspecting the input file with FFmpeg reveals (ffmpeg -i Wildlife.avi
):
Input #0, avi, from 'Wildlife.avi':
Metadata:
ISFT : Lavf52.13.0
Duration: 00:00:07.13, start: 0.000000, bitrate: 2401 kb/s
Stream #0.0: Video: msmpeg4v2, yuv420p, 1280x720, PAR 1:1 DAR 16:9, 29.97 tbr, 29.97 tbn, 29.97 tbc
Stream #0.1: Audio: mp3, 44100 Hz, 2 channels, s16, 96 kb/s
and the output:
Input #0, avi, from 'output.avi':
Metadata:
ISFT : Lavf52.61.0
Duration: 00:00:07.10, start: 0.000000, bitrate: 3896 kb/s
Stream #0.0: Video: msmpeg4v2, yuv420p, 1280x720, 29.97 tbr, 29.97 tbn, 29.97 tbc
So the only significant change between the two files is that the output generated by OpenCV doesn't have an audio stream, which is the correct behavior since OpenCV doesn't deal with audio.
Make sure your user has the proper permission to read/write/execute in the directory you are running the application. Also, the debugs I added in the code will probably assist you to find problems related to input/output capture.
do you have FFMPEG library installed on your machine? On Linux FFMPEG is used to write videos; on Windows FFMPEG or VFW is used. check by command
ffmpeg -version
try to install additional libraries
sudo apt-get install libavformat-dev libswscale-dev
.
And by calling writer.open you only Initializes or reinitializes video writer.You have to call the void VideoWriter::write(const Mat& image) to write the next video frame to file. I hope this will work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With