how to record a video in opencv without compression - c++

I'm trying to record a video with opencv the frame is 1920*180 with 25 frame/s, my Problem is that when I chose to write the frame unconpressed I don't get a video I get only one picture in avi format!! here my code :
using namespace cv;
int main (){
int key = 0;
Mat frame;
cv::VideoCapture cap(0);
cap>>frame;
cv::VideoWriter record("video.avi",-1, 25, frame.size(), true);
while(key!=27){
cap>>frame;
//cv::VideoWriter record("video.avi",-1, 25, frame.size(), true);
record<<frame;
imshow("",frame);
key=waitKey(1);
}
frame.release();
cv::destroyAllWindows();
return 0 ;
}
I'm use DeckLink SDI card to get the video, and when record the video with Media Express it works ? any Idea

Related

Reading h264 or h265 stream with ffmpeg/OpenCV: Which is faster?

I'm using OpenCV with ffmpeg support to read a RTSP stream coming from an IP camera and then to write the frames to a video. The problem is that the frame size is 2816x2816 at 20 fps i.e. there's a lot of data coming in.
I noticed that there was a significant delay in the stream, so I set the buffer size of the cv::VideoCapture object to 1, because I thought that the frames might just get stuck in the buffer instead of being grabbed and processed. This however just caused for frames to be dropped instead.
My next move was to experiment a bit with the frame size/fps and the encoding of the video that I'm writing. All of those things helped to improve the situation, but in the long run I still have to use a frame size of 2816x2816 and support up to 20 fps, so I can't set it lower sadly.
That's where my question comes in: given the fact that the camera stream is going to be either h264 or h265, which one would be read faster by the cv::VideoCapture object? And how should I encode the video I'm writing in order to minimize the time spent decoding/encoding frames?
That's the code I'm using for reference:
using namespace cv;
int main(int argc, char** argv)
{
VideoCapture cap;
cap.set(CAP_PROP_BUFFERSIZE, 1); // internal buffer will now store only 1 frames
if (!cap.open("rtsp://admin:admin#1.1.1.1:554/stream")) {
return -1;
}
VideoWriter videoWr;
Mat frame;
cap >> frame;
//int x264 = cv::VideoWriter::fourcc('x', '2', '6', '4'); //I was trying different options
int x264 = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
videoWr = cv::VideoWriter("test_video.avi", 0, 0, 20, frame.size(), true);
namedWindow("test", WINDOW_NORMAL);
cv::resizeWindow("test", 1024, 768);
for (;;)
{
cap >> frame;
if (frame.empty()) break; // end of video stream
imshow("test", frame);
if (waitKey(10) == 27) break;
videoWr << frame;
}
return 0;
}

OpenCV "stuck" frames with VideoCapture

I'm using OpenCV 3.1, I try to run a simple code as the following one (main function):
cv::VideoCapture cam;
cv::Mat matTestingNumbers;
cam.open(0);
if (!cam.isOpened()) { printf("--(!)Error opening video capture\n"); return -1; }
while (cam.read(matTestingNumbers))
{
cv::imshow("matTestingNumbers", matTestingNumbers);
cv::waitKey(5000);
}
When I move the camera it seems that the code does not capture and show the current frame but shows all the captured frames from the previous position and only then from the new one.
So when I capture the wall it shows the correct frames (the wall itself) in the correct delay, but, when I twist the camera to my computer, I first see about 3 frames of the wall and only then the computer, it seems that the frames are stuck.
I've tried to use videoCapture.set() functions and set the FPS to 1, and I tried to switch the method of capturing to cam >> matTestingNumbers (and the rest of the main function according to this change) but nothing helped, I still got "stuck" frames.
BTW, These are the solutions I found on web.
What can I do to fix this problem?
Thank you, Dan.
EDIT:
I tried to retrieve frames as the following:
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat frame;
namedWindow("edges",1);
for(;;)
{
cap.grab();
if (waitKey(11) >= 0)
{
cap.retrieve(frame);
imshow("edges", frame);
}
}
return 0;
}
But, it gave the result (when I pointed the camera on one spot and pressed a key it showed one more of the previous frames that were captured of the other point).
It is just like you're trying to picture one person then another but when you picture the second you get the photo of the first person what doesn't make sense.
Then, I tried the following:
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat frame;
namedWindow("edges",1);
for(;;)
{
cap >> frame;
if (waitKey(33) >= 0)
imshow("edges", frame);
}
return 0;
}
And it worked as expected.
One of the problems is that you are not calling cv::waitKey(X) to properly freeze the window for X amount of milliseconds. Get rid of usleep()!

opencv browser live streaming

Currently, I am using OpenCV to record a lifestream from my webcam. I now want to display that in a browser. I was thinking of using VideoWriter to write the video to a file, then somehow access that file from HTML5. Is this possible? Any other suggestions?
The following is the code I have.
int main(int argc, const char * argv[]) {
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) { // check if we succeeded
std::cout << "No camera found!\n";
}
namedWindow("Window",1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("Window", frame);
char keypress;
keypress = waitKey(30);
if(keypress==27) break;
}
return 0;
}
As can be seen, I am displaying the live stream in a window, but, as said, I want a browser lifestream. Thanks.

Playing video to correct speed with OpenCV

I have problem with plying video file, why it is slow motion ?
How can I make it normal speed?
#include"opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
VideoCapture cap("eye.mp4");
// open the default camera
if (!cap.isOpened())
// check if we succeeded
return -1;
namedWindow("Video", 1);
while (1)
{
Mat frame;
cap >> frame;
imshow("Video", frame);
if (waitKey(10) == 'c')
break;
}
return 0;
}
VideoCapture isn't built for playback, it's just a way to grab frames from video file or camera. Other libraries that supports playback, such as GStreamer or Directshow, they set a clock that control the playback, so that it can be configured to play as fastest as possible or use the original framerate.
In your snippet, the interval between frames comes from the time it takes to read a frame and the waitKey(10). Try using waitKey(0), it should at least play faster. Ideally, you could use waitKey(1/fps).

Gray screen being displayed during video capture - OpenCV

I am trying to run a program for video capture from the webcam in OpenCV. Everytime I run the program, a gray screen is being displayed. I initially tried programming in C API using the CvCapture Function and it worked perfectly fine. But now in the C++ API when I try running the following code which uses VideoCapture, a gray screen is getting displayed.
How do I resolve this problem? Please help. My OpenCV version is 2.4.6 and I am running the code in MS Visual Studio 2010 Professional.
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
int main(int argc, char** argv)
{
VideoCapture capture(0);
Mat frame;
if( !capture.isOpened() )
throw "Error when reading steam_avi";
namedWindow( "w", 1);
for( ; ; )
{
capture.read(frame);
if(frame.empty())
break;
imshow("w", frame);
waitKey(1);
}
waitKey(0);
}
Your code is running fine on my laptop. Make sure that your camera device is not blocked by another application, or you can try to comment out the namedWindow call (but it should not be a problem), actually you can use following loop to grab video frames from camera:
VideoCapture capture(0);
Mat frame;
if( !capture.isOpened() )
throw "Error when reading steam_avi";
namedWindow( "w", 1);
while(capture.read(frame))
{
imshow("w", frame);
waitKey(1);
}
waitKey(0);
According to documentation: "If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the methods return false and the functions return NULL pointer."