получение нескольких ошибок v4l с использованием opencv с несколькими веб-камерами на малине для съемки таймлапса

Я публикую это, потому что я уже искал в Интернете, пытаясь найти какое-то объяснение возникшим ошибкам, но не нашел.

Итак, я пытаюсь снять таймлапс растущего растения с 4 разных ракурсов. У меня есть 4 веб-камеры (Logitech B525), подключенные к моему Raspberry Pi 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;
                                }
                            }
                        }
                    }       
                }

person eALduderino    schedule 25.10.2018    source источник
comment
У меня такая же проблема ... вы ее решили?   -  person Steven    schedule 07.11.2018
comment
Привет, Стивен, к сожалению, нет. У меня было решение, добавив больше времени сна между каждым кадром во время периода захвата. Это было раньше, когда я использовал Python. Однако увеличение времени между кадрами для меня не вариант. Мне нужно, чтобы кадры были как можно ближе друг к другу.   -  person eALduderino    schedule 08.11.2018
comment
Спасибо за ваш отзыв. В моем случае я использую библиотеку C ++ openCV. Я понял, что проблема возникает не всегда. Работает примерно 1 раз больше 5. Вы пробовали играть с v4l2-ctl --set-fmt-video, чтобы попробовать другие форматы видео?   -  person Steven    schedule 08.11.2018
comment
на самом деле я пробовал, но все те же ошибки. ошибки также возникают при попытке imshow сразу нескольких камер. Я предполагаю, что это связано с пропускной способностью USB и, возможно, с временем отклика, а это означает, что камерам нужно больше времени для начала и завершения захвата, прежде чем другая камера начнет захват: /:?   -  person eALduderino    schedule 08.11.2018
comment
Перед использованием OpenCV я попробовал Qt с QCamera, и у меня не было проблем с открытием устройства. Если вам просто нужно делать одновременные снимки, это, вероятно, поможет вам.   -  person Steven    schedule 09.11.2018


Ответы (2)


Только что нашел этот пост: https://stackoverflow.com/a/53472812/3643138 Попробуйте открыть свое устройство с файлом имя вместо индекса! Это помогло мне!

person Steven    schedule 02.12.2018

Итак, ребята, поздно обновляйтесь. В прошлом году я узнал, что все это связано с Raspberry Pi. USB Bandwith и Raspberry pi 3B + просто недостаточны. Я запускал те же коды, что и на Raspberry, и на своем компьютере, и у меня не было проблем. Мне даже удалось запустить поток с 4 камер одновременно, выполняя задачи в многопоточном режиме. Pi может одновременно обрабатывать одну веб-камеру с низким разрешением, но как только будет использоваться другая, одновременная потоковая передача или даже захват одного изображения не будут работать.

person eALduderino    schedule 12.03.2020