在覆盆子上使用带有多个网络摄像头的 opencv 来拍摄延时摄影时出现多个 v4l 错误

Posted

技术标签:

【中文标题】在覆盆子上使用带有多个网络摄像头的 opencv 来拍摄延时摄影时出现多个 v4l 错误【英文标题】:getting multiple v4l errors using opencv with multiple webcams on a raspberry to shoot a timelapse 【发布时间】:2018-10-25 09:09:56 【问题描述】:

我发布此内容是因为我已经在网上搜索,试图为所导致的错误找到一些解释,但没有找到。

所以我试图从 4 个不同的角度拍摄正在生长的植物的延时摄影。 我有 4 个网络摄像头 (Logitech B525) 连接到我的树莓派 3。 每小时一次,所有 4 个摄像头都应拍摄尽可能窄且准确的时间同步帧。

在平稳运行后,有时几分钟有时几个小时,连接的摄像机不再被 V4L 发现或输出损坏的信息。 产生错误的相机是随机的,因此没有坏的 USB 端口,也没有损坏的电缆。 一段时间后,出现故障的摄像头再次开始工作,然后另一个摄像头出现故障,这种情况一直持续到所有摄像头都出现故障并且程序停止。

这里是错误输出的示例

我的储蓄期编程输出:

cam 1 attached
cam 2 attached
cam 3 attached
cam 4 attached
18-10-23_10-00-00
saving file of frame 4.. '../cam4/cam4_image_18-10-23_10-00-00.jpg'
18-10-23_10-00-01
saving file of frame 3.. '../cam3/cam3_image_18-10-23_10-00-01.jpg'
18-10-23_10-00-02
saving file of frame 2..'../cam2/cam2_image_18-10-23_10-00-02.jpg'
18-10-23_10-00-02
saving file of frame 1.. '../cam1/cam1_image_18-10-23_10-00-02.jpg'
waiting for next capture!

然后发生错误:

libv4l2: error setting pixformat: Input-/Output Error
VIDEOIO ERROR: libv4l unable to ioctl S_FMT
libv4l2: error setting pixformat: Input-/Output Error
libv4l1: error setting pixformat: Input-/Output Error
libv4l2: error setting pixformat: Input-/Output Error
libv4l1: error setting pixformat: Input-/Output Error
VIDEOIO ERROR: libv4l unable to ioctl VIDIOCSPICT

cam 1 not attached
cam 2 attached
VIDEOIO ERROR: V4L: device /dev/video2: Unable to query number of channels
cam 3 not attached
libv4l2: error setting pixformat: Input-/Output Error
VIDEOIO ERROR: libv4l unable to ioctl S_FMT
libv4l2: error setting pixformat: Input-/Output Error
libv4l1: error setting pixformat: Input-/Output Error
libv4l2: error setting pixformat: Input-/Output Error
libv4l1: error setting pixformat: Input-/Output Error
VIDEOIO ERROR: libv4l unable to ioctl VIDIOCSPICT

cam 4 not attached
sh: 1: reboot: not found
libv4l2: error setting pixformat: Input-/Output Error
VIDEOIO ERROR: libv4l unable to ioctl S_FMT
libv4l2: error setting pixformat: Input-/Output Error
libv4l1: error setting pixformat: Input-/Output Error
libv4l2: error setting pixformat: Input-/Output Error
libv4l1: error setting pixformat: Input-/Output Error
VIDEOIO ERROR: libv4l unable to ioctl VIDIOCSPICT


cam 1 attached
cam 2 attached
cam 3 attached
VIDEOIO ERROR: V4L: device /dev/video3: Unable to query number of channels
cam 4 not attached

摄像头永远不会断开连接,并且始终存在于设备文件夹 /dev/videoX 中,我想可以假设这不是电源问题。

导致错误的代码部分是开关部分一遍又一遍地重复,延迟 5 秒。 我的猜测是 USB 带宽问题,因为 raspberry 只有一个 USB 2.0 总线分成 4 个端口。 我尝试在关闭和再次打开捕获之间增加更多时间,但没有任何帮助。 我错过了什么吗?

这是我的代码:

                switch(4)
                
                    case 4:
                    
                        VideoCapture cap4(3);
                        if(!cap4.isOpened())
                        
                            cout<<"cam 4 not functional or attached!"<<endl;
                        
                        else
                        
                            //cap4.set(5, 30); //5=FPS settings
                            //cap4.set(38, 3); //38=Buffersize settings, Frames saved in Buffer
                            cap4.set(3,1280);//3=Width, Pixelcount
                            cap4.set(4,720); //4=Height, Pixelcount
                            Mat frame4;
                            cap4 >> frame4; // get a new frame from camera
                            waitKey(30); //wait for 2 Frames
                            cap4.release();
                            imshow("camera_4", frame4);                             

                            if(frame4.empty())
                            
                                cerr<<"Something is wrong with the camera 4, could not get frame 4!"<<endl;
                            
                            else
                            
                                try
                                
                                    if(save_next_file)
                                    
                                        string name4 = "../cam4/cam4_image_"+currentDateTime()+".jpg";
                                        cout<<"saving file of frame 4.. '"<<name4<<"'"<<endl;
                                        imwrite(name4.c_str(),frame4);
                                        waitKey(30);
                                        gettimeofday(&last_save, NULL); //reset the time interval
                                    
                                   
                                catch(cv::Exception e)
                                
                                    cout<<"error saving frame 4. >__<"<<endl;
                                
                            
                        
                    


                    case 3:
                    
                        VideoCapture cap3(2);
                        if(!cap3.isOpened())
                        
                            cout<<"cam 3 not functional or attached!"<<endl;
                        
                        else
                        
                            //cap3.set(5, 30); //5=FPS settings
                            //cap3.set(38, 3); //38=Buffersize settings, Frames saved in Buffer
                            cap3.set(3,1280);//3=Width, Pixelcount
                            cap3.set(4,720); //4=Height, Pixelcount
                            Mat frame3;
                            cap3 >> frame3; // get a new frame from camera
                            waitKey(30); //wait for 2 Frames
                            cap3.release();
                            imshow("camera_3", frame3);

                            if(frame3.empty())
                            
                                cerr<<"Something is wrong with the camrea 3, could not get frame 3. >__<"<<endl;
                            
                            else
                                               
                                try
                                
                                    if(save_next_file)
                                    
                                        string name3 = "../cam3/cam3_image_"+currentDateTime()+".jpg";
                                        cout<<"saving file of frame 3.. '"<<name3<<"'"<<endl;
                                        imwrite(name3.c_str(),frame3);
                                        waitKey(25);
                                        gettimeofday(&last_save, NULL); //reset the time interval
                                    
                                       
                                catch(cv::Exception e)
                                
                                    cout<<"error saving frame 3."<<endl;
                                
                            
                        
                    


                    case 2:
                    
                        VideoCapture cap2(1);
                        if(!cap2.isOpened())
                        
                            cout<<"cam 2 not functional or attached!"<<endl;
                        
                        else
                        
                            //cap2.set(5, 30); //5=FPS settings
                            //cap2.set(38, 3); //38=Buffersize settings, Frames saved in Buffer
                            cap2.set(3,1280);//3=Width, Pixelcount
                            cap2.set(4,720); //4=Height, Pixelcount
                            Mat frame2;
                            cap2 >> frame2; // get a new frame from camera
                            waitKey(30); //wait for 2 Frames
                            cap2.release();
                            imshow("camera_2", frame2);

                            if(frame2.empty())
                            
                                cerr << "Something is wrong with the camera 2, could not get frame 2!" << endl;
                            
                            else
                            
                                try
                                
                                    if(save_next_file)
                                    
                                        string name2 = "../cam2/cam2_image_"+currentDateTime()+".jpg";
                                        cout<<"saving file of frame 2..'"<<name2<<"'"<<endl;
                                        imwrite(name2.c_str(),frame2);
                                        waitKey(25);
                                        gettimeofday(&last_save, NULL); //reset the time interval
                                    
                                
                                catch(cv::Exception e)
                                
                                    cout<<"error saving frame 2. >__<"<<endl;
                                
                            
                        
                    


                    case 1:
                    
                        VideoCapture cap1(0);
                        if(cap1.isOpened())
                        if(!cap1.isOpened())
                        
                            cout<<"cam 1 not functional or attached!"<<endl;
                        
                        else
                        
                            //cap1.set(5, 30); //5=FPS settings
                            //cap1.set(38, 3); //38=Buffersize settings, Frames saved in Buffer
                            cap1.set(3,1280);//3=Width, Pixelcount
                            cap1.set(4,720); //4=Height, Pixelcount
                            Mat frame1;
                            cap1 >> frame1; // get a new frame from camera
                            waitKey(30); //wait for 2 Frames
                            cap1.release();
                            imshow("camera_1", frame1);

                            if(frame1.empty())
                            
                                cerr << "Something is wrong with camera 1, could not get frame 1!" << endl;
                            
                            else
                            
                                try
                                
                                    if(save_next_file)
                                    
                                        string name1 = "../cam1/cam1_image_"+currentDateTime()+".jpg";
                                        cout<<"saving file of frame 1.. '"<<name1<<"'"<<endl;
                                        imwrite(name1.c_str(),frame1);
                                        waitKey(25);
                                        gettimeofday(&last_save, NULL); //reset the time interval
                                    
                                
                                catch(cv::Exception e)
                                
                                    cout<<"error saving frame 1!"<<endl;
                                
                            
                        
                           
                

【问题讨论】:

我也有同样的问题...你解决了吗? 嘿,史蒂文,很遗憾没有。我有一个解决方案,即在拍摄期间在每次拍摄之间增加更多的睡眠时间。这是在我使用python之前。不过,在拍摄之间增加更多时间对我来说不是一个选择。我需要镜头尽可能靠近。 感谢您的反馈。就我而言,我使用的是 C++ openCV lib。我意识到问题并不总是发生。它大约工作 1 倍于 5。您是否尝试过使用 v4l2-ctl --set-fmt-video 来尝试其他视频格式? 其实我试过了,还是一样的错误。尝试直接显示多个相机时也会发生错误。我猜它与 USB 带宽有关,也可能与响应时间有关,这意味着在另一台相机开始捕捉之前,相机需要更多时间来开始和结束捕捉:/ :? 在使用 OpenCV 之前,我尝试了 Qt 和 QCamera 并且没有任何设备打开问题。如果您只需要同时拍摄照片,这可能会为您解决问题。 【参考方案1】:

刚刚发现这篇文章:https://***.com/a/53472812/3643138 尝试使用文件名而不是索引打开您的设备!这对我有用!

【讨论】:

【参考方案2】:

所以伙计们迟到了更新。 去年我发现这一切都与 Raspberry Pi 有关。 USB Bandwith 和 Raspberry pi 3B+ 功率不足。 我也在我的计算机上运行了我在树莓上使用的相同代码,并且没有任何问题。我什至能够在多线程任务时同时运行 4 个摄像头流。 Pi 可以同时处理一个低分辨率网络摄像头,但一旦要使用另一个,同时流式传输甚至单张图像捕获都将无法工作。

【讨论】:

以上是关于在覆盆子上使用带有多个网络摄像头的 opencv 来拍摄延时摄影时出现多个 v4l 错误的主要内容,如果未能解决你的问题,请参考以下文章

通过 USB 编程访问多个网络摄像头

OpenCV + OS X + 外部网络摄像头 = 非常慢

OpenCV 找不到我的 USB 网络摄像头

来自带有 Opencv C 程序的网络摄像头的灰色图像,但 C++ 程序完美运行

如何使用 opencv 获取网络摄像头设备列表?

在android上使用带有opencv的usb相机