Write to dummy video stream using OpenCV - c++

I'm using OpenCV and v4l2loopback library to emulate video devices:
modprobe v4l2loopback devices=2
Then I check what devices I have:
root#blah:~$ v4l2-ctl --list-devices
Dummy video device (0x0000) (platform:v4l2loopback-000):
/dev/video1
Dummy video device (0x0001) (platform:v4l2loopback-001):
/dev/video2
XI100DUSB-SDI (usb-0000:00:14.0-9):
/dev/video0
video0 is my actual camera where I grab frames from, then I plan to process them via OpenCV and write it to video2 (which is a sink I believe).
Here is how I attempt to do so:
int width = 320;
int height = 240;
Mat frame(height, width, CVX_8UC3, Scalar(0, 0, 255));
cvtColor(frame, frame, CVX_BGR2YUV);
int fourcc = CVX_FOURCC('Y', 'U', 'Y', '2');
cout << "Trying to open video for write: " << FLAGS_out_video << endl;
VideoWriter outputVideo = VideoWriter(
FLAGS_out_video, fourcc, 30, frame.size());
if (!outputVideo.isOpened()) {
cerr << "Could not open the output video for write: " << FLAGS_out_video
<< endl;
}
As far as I know video output format should be YUYV (which is equal to YUY2 in OpenCV). Please correct me if I'm wrong. In my code I'm not writing into outputVideo anything yet, just trying to open it for write, but I keep getting outputVideo.isOpened()==false for some reason, no additional errors/info in the output:
root#blah:~$ main --uid='' --in_video='0' --out_video='/dev/video2'
Trying to open video for write: /dev/video2
Could not open the output video for write: /dev/video2
I'd appreciate any advice or help on how to debug/resolve this issue. Thank you in advance!

Related

OpenCV c++ API VideoCapture not working with video files

I'm currently using OpenCV(4.5.1-dev) c++ api to try to read frames from a mp4 .video file. I keep getting error "can not open video file". I compile open cv with
-DWITH_FFMPEG=OFF
as suggested in OpenCV readme.txt. The minimum reproducible code is
cv::VideoCapture cap;
cap.open(video_path, cv::CAP_V4L);
if(!cap.isOpened())
{
std::cerr << "trying to open video file at: " << video_path << std::endl;
CV_Error(cv::Error::StsError, "Can not open Video file");
}
for(int frameNum = 0; frameNum < cap.get(cv::CAP_PROP_FRAME_COUNT); frameNum++)
{
cv::Mat frame;
cap >> frame; // get the next frame from video
frames.push_back(frame);
}
where for video_path, I tried both absolute and relative path. Neither works. Any suggestions?

Streaming Logitec C922 at 60fps with C++

I would like to capture images with a webcam (i.e. logitech C922) with C++. Does anyone succeed in capturing images with the webcam at 60fps and 720p? I read the code in the following thread and add "cap.set(CAP_PROP_FPS, 60)", but the frame rate was maintained at about 30fps.
How to set camera fps in opencv?
Then I posted the same question, but the forum is under maintenance.
http://answers.opencv.org/question/172992/streaming-logitec-c922-at-60fps-with-c/
I added the both proposed codes to mine.
As the result, the value of fps was 33.3... and FPS was 60.0 in the case that I used cap.set(CAP_PROP_EXPOSURE, -5) because I'm in office and at night here.
I tried to use lower value for CAP_PROP_EXPOSURE (e.g. -10), but the fps didn't change.
The image shown with imshow wasn't updated obviously at 60fps.
Is there anything I can do?
This is the code I used.
VideoCapture cap(0); //capture the video from web cam
if (!cap.isOpened()) // if not success, exit program
{
cout << "Cannot open the web cam" << endl;
return -1;
}
cap.set(CV_CAP_PROP_FOURCC, CV_FOURCC('M','J','P','G'));
cap.set(CAP_PROP_FPS, 60);
cap.set(CAP_PROP_EXPOSURE, -5);
cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 720);
cout << cap.get(CAP_PROP_FPS) << endl;
cvNamedWindow("img");
time_t cap_start, cap_end;
Mat frame;
double MAX_FRAME_NUM = 100;
time(&cap_start);
for (int n = 0; n < MAX_FRAME_NUM; n++) {
cap >> frame;
}
time(&cap_end);
double fps = MAX_FRAME_NUM / difftime(cap_end, cap_start);
cout << "fps:" << fps << endl;
cv::waitKey(0);
Environment Information OpenCv: 3.3.0 OS: Windows 10 Pro IDE: Visual Studio 2017 CPU: i7-7560U RAM 16GB USB: 3.0
Best regards, gellpro
I stumbled upon the same issue with this camera.
My environment is Ubuntu 18.04, python 3.6.5 and OpenCV 3.4.
I found this solution from your first link to be working:
cap.set(CV_CAP_PROP_FOURCC, CV_FOURCC('M', 'J', 'P', 'G'));
For python, the code I use is:
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M','J','P','G'))
cap.set(cv2.CAP_PROP_FPS, 60)

Stream video using OpenCV, GStreamer

I am developing a program that is capturing raspicam and streaming with GStreamer. The first course, capturing raspicam doesn't have problem. But, the next course is have a big problem. I was created a total of 2 of sources code (server, client). Streaming data is very slow. Can I have a way to improve it?
Please, help me.
Thank you.
----------- Server.cpp (Raspberry Pi, Raspbian) -----------
cap.set(CAP_PROP_FPS, 30);
cap.open(0);
// Movie Frame Setup
fps = cap.get(CAP_PROP_FPS);
width = cap.get(CAP_PROP_FRAME_WIDTH);
height = cap.get(CAP_PROP_FRAME_HEIGHT);
cout << "Capture camera with " << fps << " fps, " << width << "x" << height << " px" <<
writer.open("appsrc ! gdppay ! tcpserversink host=192.168.0.29 port=5000", 0, fps, cv::Size(width, height), true);
while(1){
printf("AA");
cap >> frame;
writer << frame;
}
----------- Client.cpp (PC, Ubuntu) -----------
Mat test;
String captureString = "tcpclientsrc host=192.168.0.29 port=5000 ! gdpdepay ! appsink";
VideoCapture cap(captureString);//0);
namedWindow("t");
while(1)
{
cap >> test;
imshow("t", test);
if( waitKey(10) > 0)
break;
}
}
You might benefit from using a udp stream instead of tcp. Check out this link for an example where a video was streamed from rpi to pc with only 100 ms lag.

Opening images one after the other

I have a series of images saved on my system according to their time stamps.
For example the images are named as:
20140305180348.jpg
20140305180349.jpg
I have 100 such images, I want to open them using OpenCV one after the other. I have tried using cvCapturefromFile() but using it I am able to open just a single image at a time. I want to stitch/join them so that I can make a video.
I am sorry I cannot post the code as I am not allowed to. How do I proceed?
In OpenCV, to write images to a video, you can use VideoWriter (and do it in a loop to read a sequence of images):
VideoWriter outputVideo; // Open the output
// ... set video properties like FPS
if (!outputVideo.isOpened())
{
cout << "Could not open the output video for write: " << source << endl;
return -1;
}
for(...)
{
// read your frame, e.g. to Mat img
// outputVideo.write(img); //save or
outputVideo << img;
}
cout << "Finished writing" << endl;
Check out here for more info.
In this tutorial is an example how to write a video. Just modify the for-loop in the end.
pseudocode:
open videocontainer
int i=0;
while(i<100){
Mat img = imread("path"+to_string(i)+".jpg");
outputvideo << img;
}
close videocontainer

Why this code doesn't write any data to output file to create movie using opencv

I am trying to create some video from a set of large raw images that I have.
The code is as follow:
int imageWidth=687;
int imageHeight=916;
int fps=3;
int ex=-1;
CvSize size = cvSize(imageWidth,imageHeight);
VideoWriter outputVideo;
outputVideo.open(MovieOutput, ex, fps, size, true);
if(outputVideo.isOpened())
{
cout << "error opening output video";
}
for(int frameNo=0;frameNo<58;frameNo++)
{
ostringstream outfilename;
outfilename << InputDir<< (frameNo+1)<<".jpg";
rawimages.Read(frameNo);
Mat image=rawimages.ToOpencvImage();
imwrite( outfilename.str(), image );
outputVideo <<image;
imshow("Image", image);
if(waitKey(30) >= 0) break;
}
I can see that images are shown on screen and also different jpg are saved on hard disk.
I can see that the output avi is created, but its size is zero.
What is the problem with this code?
some note:
The output size is very big. Can it generate movie with that size?
To summarize the comments: you pass the second parameter to the VideoWriter open command with a value of -1. This is supposed to open a codec selection dialogue in Windows, but as of OpenCV 2.4.5, the dialogue seems to be bugged - it appears, but I couldn't manage to write to a file afterwards.
Selecting a codec directly works fine and makes more sense in my opinion. More info about this command and available codecs can be found here.
outputVideo.open("example.avi", CV_FOURCC('M','J','P','G'), fps, size, true);