Opencv capture video from multiple cameras - c++

I am verifying multiple video captures by Opencv 3.4, there are 3 cameras in use, one built-in camera in the laptop and 2 USB cameras connected two separated USB ports. I can't make the video captures happen, it always throws exception as:
libv4l2: error setting pixformat: Device or resource busy
OpenCV Error: Unspecified error (GStreamer: unable to start pipeline) in cvCaptureFromCAM_GStreamer, file /opt/opencv/modules/videoio/src/cap_gstreamer.cpp, line 890
VIDEOIO(cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L2, reinterpret_cast<char *>(index))): raised OpenCV exception:
/opt/opencv/modules/videoio/src/cap_gstreamer.cpp:890: error: (-2) GStreamer: unable to start pipeline in function cvCaptureFromCAM_GStreamer
libv4l2: error setting pixformat: Device or resource busy
OpenCV Error: Unspecified error (GStreamer: unable to start pipeline) in cvCaptureFromCAM_GStreamer, file /opt/opencv/modules/videoio/src/cap_gstreamer.cpp, line 890
VIDEOIO(cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L2, reinterpret_cast<char *>(index))): raised OpenCV exception:
/opt/opencv/modules/videoio/src/cap_gstreamer.cpp:890: error: (-2) GStreamer: unable to start pipeline in function cvCaptureFromCAM_GStreamer
cap1 doesn't work
Source code is quite simple:
using namespace cv;
int main(int, char**)
{
VideoCapture cap0(0); // open the default camera
VideoCapture cap1(1);
VideoCapture cap2(2);
if(!cap0.isOpened()) {
std::cout << "cap0 doesn't work" << std::endl;
return -1;
}
if(!cap1.isOpened()) {
std::cout << "cap1 doesn't work" << std::endl;
return -1;
}
if(!cap2.isOpened()) {
std::cout << "cap2 doesn't work" << std::endl;
return -1;
}
Mat frame0;
Mat frame1;
Mat frame2;
for(;;)
{
cap0 >> frame0; // get a new frame from camera
cap1 >> frame1;
cap2 >> frame2;
imshow("Video0", frame0);
imshow("Video1", frame1);
imshow("Video2", frame2);
if(waitKey(30) >= 0) break;
}
return 0;
}
All cameras are recognized:
crw-rw----+ 1 root video 81, 0 1月 14 09:05 /dev/video0
crw-rw----+ 1 root video 81, 1 1月 14 09:30 /dev/video1
crw-rw----+ 1 root video 81, 2 1月 14 10:11 /dev/video2
I am using Ubuntu 14.04.
Any idea how to make multiple video captures happen?

The first thing with multiple USB cameras, and unrelated to OpenCV is the USB bandwidth, which rarely supports more than one camera bandwidth per USB port, for which it is recommended to connect each camera to a separate USB port, and NOT to a USB hub.
The second thing (my experience in Ubuntu 16.04 and 18.04; haven't tested in Windows) that some cameras will take two indexes, such that if there are two cameras, you can try opening camera index 0 for the first camera, and camera index 2 for the second:
VideoCapture camA(0);
VideoCapture camB(2);
And third, it is good practice to control the apiPreference for the camera stream. For example, to use Linux V4L2 and remove GStreamer from the video pipeline, instead of the above use this (OpenCV must have been built selecting WITH_CAP_V4L2):
VideoCapture camA(0, CAP_V4L2);
VideoCapture camB(2, CAP_V4L2);

Related

OpenCV: isOpened() always fails

I am taking my first steps with OpenCV and I am trying to run this piece of code. It is supposed to open the specified video in a new window and wait for the user to press ESC. I tried passing both the relative and absolute path to VideoCapture but VideoCapture::isOpened() always fails. Why is this happening?
If I pass 0 to VideoCapture and do NOT call isOpened(), then I get a nice little window.
Note that I am using VS15 and OpenCV 2.4 (with the x86 libs)
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(path_to_video); // open the video file
// VideoCapture cap(0);
if(!cap.isOpened()) // check if we succeeded
return -1;
namedWindow("Video",1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("Video", frame);
if(waitKey(30) >= 0) break;
}
return 0;
}
EDIT: I solved this by reinstalling OpenCV and creating a new Visual Studio project. The above code miraculously started working.
If I pass 0 to VideoCapture and do NOT call isOpened(), then I get a
nice little window. Why is this happening?
Because the VideoCapture class has two different constructors. The one that takes a string attempts to read from a file. The one that takes an integer attempts to read from a device. Passing 0 to the second version specifies the default device / camera.
VideoCapture::open¶ Open video file or a capturing device for video
capturing
C++: bool VideoCapture::open(const string& filename)
C++: bool VideoCapture::open(int device)
Parameters:
filename – name of the opened video file (eg. video.avi)
or image sequence (eg. img_%02d.jpg, which will read samples like
img_00.jpg, img_01.jpg, img_02.jpg, ...)
device – id of the opened video capturing device (i.e. a camera index).

I can't open 2 gige(basler) cameras at the same time with opencv

I'm using two GigE (basler aca2500-14gm) cameras on win10 opencv3.4, I connect the wires of the 2 cameras to the switch, and then connect it to my computer.but I can't open the camera and get the frames at the same time。
my code:
`
int main()
{
PylonInitialize();
VideoCapture cap(0);
VideoCapture cap1(2);
if (!cap.isOpened())
{
cout << "Camera 1 unsuccessfully opened" << endl;
}
if (!cap1.isOpened())
{
cout << "Camera 2 unsuccessfully opened" << endl;
}
bool stop = false;
while (!stop)
{
Mat frame;
Mat frame1;
cap >> frame;
cap1 >> frame1;
if (frame.empty() || frame1.empty())
{
break;
}
imshow("Open the camera 1", frame);
imshow("Open the camera 2", frame1);
if (waitKey(100) >= 0)
{
PylonTerminate();//
stop = true;
}
}
}`
by the way,when I tried to run the sample of basler SDK :Grab_MultipleCameras.cpp,
I can open the camera but the image in the window is grey.
is there anyone help me to solve this problem?
Thanks in advance.
When you run this sample of basler SDK it might happen that the second camera still could not be open but it just show you the window with defualt color (grey).
Another likely thing is that your are passing wrong device ID for VideoCapture to work, See this
OpenCv VideoCap documentation. Also from what I know if you are using GigE cameras it will be better to pass ip address of each camera to VideoCapture
So I would say only to try change one think in your code:
From
VideoCapture cap(0);
VideoCapture cap1(2);
To:
VideoCapture cap(/*camera Ip Address*/); //or try with different IDs
VideoCapture cap1(/*camera Ip Address*/);
Also take a look at this answer VideoCapture and GigE camera . It is stated there that when there is more than one camera you would be better with passing IP address.
Another thing to check will be if you can see both cameras in your device manager.
EDIT:
Hey I found nice documentation about working with Pylon SDK( from camera vendor) andOpenCV (it is probably older version of OpenCV but still can be useful)

Open USB camera with OpenCV and stream to rtsp server

I got a Logitech C920 camera connected via USB to a NVIDIA TX1. I am trying to both stream the camera feed over rtsp to a server while doing some computer vision in OpenCV. I managed to read H264 video from the usb camera in Opencv
#include <iostream>
#include "opencv/cv.h"
#include <opencv2/opencv.hpp>
#include "opencv/highgui.h"
using namespace cv;
using namespace std;
int main()
{
Mat img;
VideoCapture cap;
int heightCamera = 720;
int widthCamera = 1280;
// Start video capture port 0
cap.open(0);
// Check if we succeeded
if (!cap.isOpened())
{
cout << "Unable to open camera" << endl;
return -1;
}
// Set frame width and height
cap.set(CV_CAP_PROP_FRAME_WIDTH, widthCamera);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, heightCamera);
cap.set(CV_CAP_PROP_FOURCC, CV_FOURCC('X','2','6','4'));
// Set camera FPS
cap.set(CV_CAP_PROP_FPS, 30);
while (true)
{
// Copy the current frame to an image
cap >> img;
// Show video streams
imshow("Video stream", img);
waitKey(1);
}
// Release video stream
cap.release();
return 0;
}
I also have streamed the USB camera to a rtsp server by using ffmpeg:
ffmpeg -f v4l2 -input_format h264 -timestamps abs -video_size hd720 -i /dev/video0 -c:v copy -c:a none -f rtsp rtsp://10.52.9.104:45002/cameraTx1
I tried to google how to combine this two functions, i.e. open usb camera in openCV and use openCV to stream H264 rtsp video. However, all I can find is people trying to open rtsp stream in openCV.
Have anyone successfully stream H264 rtsp video using openCV with ffmpeg?
Best regards
Sondre

Select Timeout error in Ubuntu14.04 with camera Opencv

I am trying to use a webcam for my project. I use Opencv2.4.11 and the Logicool webcam C270.
I wrote a very simple code shown on below.
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include <stdio.h>
using namespace std;
using namespace cv;
int main()
{
Mat frame;
VideoCapture capture(0); // open the default camera
if (!capture.isOpened()) // check if we succeeded
return -1;
namedWindow("CVtest",1);
while (true) {
capture >> frame;
imshow("CVtest", frame);
waitKey(20);
}
return 0;
}
but this code is not work for me. I get this error messages.
jiehunt#ubuntu:~/work/test$ ./test.out
init done
opengl support available
select timeout
select timeout
I found this page Select Timeout error in Ubuntu - Opencv , and I followed the step
sudo rmmod uvcvideo
sudo modprobe uvcvideo nodrop=1 timeout=6000 quirks=0x80
It doesn't work for me.
When I turned on the trace of uvcvideo, I got this error message.
[13087.385542] uvcvideo: Marking buffer as bad (error bit set).
[13087.385545] uvcvideo: Frame complete (EOF found).
And now, I don't know what I should do.
My camera formats are shown bellow.
jiehunt#ubuntu:~/work/test$ v4l2-ctl --list-formats
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUV 4:2:2 (YUYV)
Index : 1
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : MJPEG

OpenCV C++ camera image not being saved to matrix

I am using openCV 2.4.10 on visual studios 2012 express for desktop on windows 7, 32 bit operating system.
I created a function that initializes a webcam, takes an image and stores it in a matrix, and then returns the image matrix.
Mat frameCapture ()
{
Mat srcCap;
//initializes structure type of cap
VideoCapture cap(0);
if(!cap.isOpened())
{
//check for camera
cout << "No camera detected" << endl;
waitKey(10);
}
//stores next frame into matrix
cap >> srcCap;
//check to see the camera took a picture
if( srcCap.empty())
{
cout << "no data in image\n";
}
//return the image matrix
cap.release();
return srcCap;
}
int main ()
{
Mat src;
src = frameCapture();
imshow (window1, src);
waitKey(0);
}
So when running the program, it will say "no data in image" meaning that srcCap.empty() returned true and then it will throw an assertion error for the imshow function. However, the program will sometimes run and return an image successfully. Furthermore, when I incorporate the function in a loop for image processing, it will sometimes take a few pictures and then randomly spit out "no data in image" and throw the same assertion error, or it won't take the first picture at all and spits out "no data in image", throwing the same assertion error. The camera is detected every time and cap is opened; the code never says "No camera detected"
My question is what is causing cap >> srcCap to not work, is it a hardware issue? The camera i'm using is a usb 2.0 plugable microscope.
I think you that your current program just reads the first frame only. Mostly when reading the camera frame, the first frame may not contain any data.
I would suggest that you use a loop in the main() and read latter frames.