Writing Video to File with OpenCV - c++

Hi im trying to write a video from my webcam to my computer but I keep getting the error that my writer isnt opened. Im using windows 8 64 bit, VS 2013 & OpenCV 2.4.10. Here is the code that I am using:
#include <opencv\highgui.h>
#include <opencv\cv.h>
#include <iostream>
using namespace cv;
using namespace std;
string intToString(int number){
std::stringstream ss;
ss << number;
return ss.str();
}
int main(int argc, char* argv[])
{
VideoCapture cap(0); // open the video camera no. 0
VideoWriter writer;
if (!cap.isOpened()) // if not success, exit program
{
cout << "ERROR INITIALIZING VIDEO CAPTURE" << endl;
return -1;
}
char* windowName = "Webcam Feed";
namedWindow(windowName, CV_WINDOW_AUTOSIZE); //create a window to display our webcam feed
string filename = "C:\\thevideo.avi";
int fcc = CV_FOURCC('D', 'I', 'V', '3');
double fps = 20;
cv::Size frameSize(cap.get(CV_CAP_PROP_FRAME_WIDTH), cap.get(CV_CAP_PROP_FRAME_HEIGHT));
writer = VideoWriter(filename, fcc, fps, frameSize);
if (!writer.isOpened())
{
cout << "the writer isnt opened" << endl;
getchar();
return -1;
}
while (1) {
Mat frame;
bool bSuccess = cap.read(frame); // read a new frame from camera feed
if (!bSuccess) //test if frame successfully read
{
cout << "ERROR READING FRAME FROM CAMERA FEED" << endl;
break;
}
writer.write(frame);
imshow(windowName, frame); //show the frame in "MyVideo" window
//listen for 10ms for a key to be pressed
switch (waitKey(10)){
case 27:
//'esc' has been pressed (ASCII value for 'esc' is 27)
//exit program.
return 0;
}
}
return 0;
}
Can anyone help me?

I find the use a bit confusing. You do:
VideoWriter writer;
and then
writer = VideoWriter(filename, fcc, fps, frameSize);
Either do:
VideoWriter writer = VideoWriter(filename, fcc, fps, frameSize);
or
VideoWriter writer;
writer.open(filename, 0, fps, frameSize, 1);
Perhaps that is the issue?
Also, in writer.open(), the last parameter sis the colour setting. Set it accordingly. I have assumed you have colour input.
Also, a more complicated thing could be codec issue. I read that OPENCV can only write AVI files. So, I am not sure if it can use the DIV3 codec for writing. Call the writer with:
writer = VideoWriter(filename, -1, fps, frameSize);
and see what codecs can be used.

Try this codec:
int fcc = CV_FOURCC('M', 'J', 'P', 'G')
instead of:
int fcc = CV_FOURCC('D', 'I', 'V', '3');

Related

Record multiple videos from webcam stream in OpenCV C++

I want to record selected frames as multiple videos from webcam. I tried the following code to start recording a video on a key press and stop recording that video with a different key press. I want to record multiple such videos. But the recorded video files are empty. I can run its equivalent Python code successfully, but I want the same in C++. Can you please help me to correct my mistake?
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
int main(){
// Create a VideoCapture object and use camera to capture the video
VideoCapture cap(0);
// Check if camera opened successfully
if(!cap.isOpened()){
cout << "Error opening video stream" << endl;
return -1;
}
// Default resolutions of the frame are obtained.
int frame_width = cap.get(cv::CAP_PROP_FRAME_WIDTH);
int frame_height = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
bool recording = false;
int videono = 1;
VideoWriter video("dummy.avi", cv::VideoWriter::fourcc('M','J','P','G'), 10, Size(frame_width,frame_height));
video.release();
while(1)
{
Mat frame;
// Capture frame-by-frame
cap >> frame;
// If the frame is empty, break immediately
if (frame.empty())
break;
// Display the resulting frame
imshow( "Frame", frame );
// Press ESC on keyboard to exit
char c = (char)waitKey(1);
if( c == 27 )
break;
// Press s on keyboard to start recording
if( c == 115 and !recording)
{
char path[100];
sprintf(path, "%d.avi", videono);
std::cout << "recording started for " << path << "\n";
videono += 1;
VideoWriter video(path, cv::VideoWriter::fourcc('M','J','P','G'), 10, Size(frame_width,frame_height));
recording = true;
}
if( recording )
video.write(frame);
// Press x on keyboard to stop recording
if( c == 120)
{
std::cout << "recording finished.\n";
recording = false;
video.release();
}
}
// release the video capture and write object
cap.release();
// Closes all the frames
destroyAllWindows();
return 0;
}
Instead of re-creating a new VideoWriter every time and deleting it immediately like this
{
VideoWriter video(path, cv::VideoWriter::fourcc('M','J','P','G'), 10, Size(frame_width,frame_height));
} // <-- deleted here, because it's going out of scope
You should just use the 'open' function on the existing VideoWriter.
So something like this:
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
int main(){
// Create a VideoCapture object and use camera to capture the video
VideoCapture cap(0);
// Check if camera opened successfully
if(!cap.isOpened()){
cout << "Error opening video stream" << endl;
return -1;
}
// Default resolutions of the frame are obtained.
int frame_width = cap.get(cv::CAP_PROP_FRAME_WIDTH);
int frame_height = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
bool recording = false;
int videono = 1;
VideoWriter video;
while(1)
{
Mat frame;
// Capture frame-by-frame
cap >> frame;
// If the frame is empty, break immediately
if (frame.empty())
break;
// Display the resulting frame
imshow( "Frame", frame );
char c = (char)waitKey(1);
if( c == 27 ) // Press ESC on keyboard to exit
break;
if( c == 115 and !recording) // Press s on keyboard to start recording
{
char path[100];
sprintf(path, "%d.avi", videono);
std::cout << "recording started for " << path << "\n";
videono += 1;
video.open(path, cv::VideoWriter::fourcc('M','J','P','G'), 10, Size(frame_width,frame_height));
recording = true;
}
if( recording )
video.write(frame);
if( c == 'x') // Press x on keyboard to stop recording
{
std::cout << "recording finished.\n";
recording = false;
video.release();
}
}
cap.release();// release the video capture and write object
destroyAllWindows(); // Closes all the frames
return 0;
}

How to write *.mp4 video with OpenCV-C++?

My name is Toan. Currently, I'm using OpenCV-C++ to write video *.mp4 type. I can write video .avi type but It's take a lot of storage. About 1Mb/1s with 640x480 resolution and 15 FPS. I'm using iMX6UL-EVK board(Linux).
I built without error but no output .mp4 file. And in python code (OpenCV-Python), this board can write .mp4 video with "mp4v".
I tried with "mp4v", "xvid", "divx", "h264", "x264" but not working. So what can I do now? Or may you show me others type of video which not take much of storage ?
This is my code:
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
cout << "Built with OpenCV " << CV_VERSION << endl;
Mat image;
Mat src;
VideoCapture capture;
capture.open(2);
capture >> src;
bool isColor = (src.type() == CV_8UC3);
VideoWriter writer;
int codec = VideoWriter::fourcc('M', 'P', '4', 'V');
double fps = 15.0;
string filename = "live.mp4";
Size sizeFrame(640,480);
writer.open(filename, codec, fps, sizeFrame, isColor);
cout << "Started writing video... " << endl;
for (int i = 0 ; i < 60 ; i ++)
{
capture >> image;
Mat xframe;
resize(image,xframe,sizeFrame);
writer.write(xframe);
// imshow("Sample", image);
// char c = (char)waitKey(1);
// if(c == 27) break;
}
cout << "Write complete !" << endl;
capture.release();
writer.release();
return 0;
}
Thank you so much,
Toan
VideoWriter::fourcc('a', 'v', 'c', '1')
work fine for me to write mp4 file.

Videowriter function for greyscale image using OpenCV function

I have a GigaE camera and which gives me a greyscale image and I want to record it as a video and process it later.
So as initial step I tried recording video using my webcam it worked and if i convert it into greyscale before writing it into video. I am not getting any video.
My code is below
int main(int argc, char* argv[])
{
VideoCapture cap(0);
VideoWriter writer;
if (!cap.isOpened())
{
cout << "not opened" << endl;
return -1;
}
char* windowName = "Webcam Feed";
namedWindow(windowName, CV_WINDOW_AUTOSIZE);
string filename = "D:\myVideo_greyscale.avi";
int fcc = CV_FOURCC('8', 'B', 'P', 'S');
int fps = 30;
Size frameSize(cap.get(CV_CAP_PROP_FRAME_WIDTH),cap.get(CV_CAP_PROP_FRAME_HEIGHT));
writer = VideoWriter(filename,-1,fps,frameSize);
if(!writer.isOpened())
{
cout<<"Error not opened"<<endl;
getchar();
return -1;
}
while (1)
{
Mat frame;
bool bSuccess = cap.read(frame);
if (!bSuccess)
{
cout << "ERROR READING FRAME FROM CAMERA FEED" << endl;
break;
}
cvtColor(frame, frame, CV_BGR2GRAY);
writer.write(frame);
imshow(windowName, frame);
}
return 0;
}`
I used fcc has -1 tried all the possibilities none of them are able to record video.
I also tried creating a grayscale video using opencv for fcc has CV_FOURCC('8','B','P','S') but it did not help me.
I get this error in debug after using the breakpoint
VideoWriter has an optional parameter which tells whether the video is grayscale or color. Default ist color = true. Try
bool isColor = false;
writer = VideoWriter(filename,-1,fps,frameSize, isColor);

videowriter function doesnt save the file with opencv-3.0.0

I am working with GigaE Camera and it is a grayscale image and I want to record the videos. So I have tried initially with webcam and below is my code:
#include "opencv2\highgui\highgui.hpp"
#include "iostream"
#include "opencv2/opencv.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"
#include "opencv2/videoio/videoio.hpp"
#include<string>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
VideoCapture cap(0);
VideoWriter writer;
if (!cap.isOpened())
{
cout << "not opened" << endl;
return -1;
}
char* windowName = "Webcam Feed";
namedWindow(windowName, CV_WINDOW_AUTOSIZE);
string filename = "D:\videos\myVideo12.avi";
int fcc = CV_FOURCC('M', 'J', 'P', 'J');
int fps = 30;
Size frameSize(cap.get(CV_CAP_PROP_FRAME_WIDTH), cap.get(CV_CAP_PROP_FRAME_HEIGHT));
bool isColor = false;
writer = VideoWriter(filename, fcc, fps, frameSize, isColor);
if (!writer.isOpened())
{
cout << "Error not opened" << endl;
getchar();
return -1;
}
while (1)
{
Mat frame;
bool bSuccess = cap.read(frame);
if (!bSuccess)
{
cout << "ERROR READING FRAME FROM CAMERA FEED" << endl;
break;
}
cvtColor(frame, frame, CV_BGR2GRAY);
writer.write(frame);
imshow(windowName, frame);
return 0;
}
There is no video created and I don't get any error too. But it works fine with OpenCV-2.4.10.
Most likely, the video is not written because of the codec. OpenCV tends to stay silent in case of encoding (and many other) problems. Try setting fcc to -1 to choose from a list of available codecs.
Solved! The error is in the giving the filename path where I used '\' instead of '/'. The codecs are MPEG or DIV3 for grayscale images.

Converting Live Video Frames to Grayscale (OpenCV)

First and foremost, I should say that I'm a beginner to OpenCV. I'm trying to convert a live video stream from my webcam from RGB to Grayscale.
I have the following code in my function:
VideoCapture cap(0);
while (true)
{
Mat frame;
Mat grayscale;
cvtColor(frame, grayscale, CV_RGB2GRAY);
imshow("Debug Window", grayscale);
if (waitKey(30) >=0)
{
cout << "End of Stream";
break;
}
}
I know it isn't complete. I'm trying to find a way to take a frame of the video and send it to frame, manipulate it using cvtColor, then output it back to grayscale so I can display it on my screen.
If anyone could help, it would be much appreciated.
Please see this example, here the complete code exists, hope this will work for you:
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
VideoCapture cap(0); // open the video camera no. 0
if (!cap.isOpened()) // if not success, exit program
{
cout << "Cannot open the video cam" << endl;
return -1;
}
namedWindow("MyVideo",CV_WINDOW_AUTOSIZE);
while (1)
{
Mat frame;
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess)
{
cout << "Cannot read a frame from video stream" << endl;
break;
}
Mat grayscale;
cvtColor(frame, grayscale, CV_RGB2GRAY);
imshow("MyVideo", grayscale);
if (waitKey(30) == 27)
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}
You just initialized the variable "frame" and forgot to assign an image to it. Since the variable "frame" is empty you won't get output. Grab a image and copy to frame from the video sequence "cap". This piece of code will do the job for you.
Mat frame;
bool bSuccess = cap.read(frame); // read a frame from the video
if (!bSuccess)
{
cout << "Cannot read a frame from video stream" << endl;
break;
}