Ask Your Question

Revision history [back]

Why can't I get 3 webcam to run in parallel with pthreads?

Hey all, I need some help with OpenCV with threading using C++. I am using a raspberry pi 3B. Which is a quad core. There are 4 USB 2.0 devices, 3 USB 2.0 webcam and USB 2.0 Arduino. The webcam’s cable has been spliced out to provide voltage on its own, so only data wires are going into the pi. The Arduino is being powered by the pi. Now to the issue. I have 4 threads going, 3 for the webcams and 1 for the Arduino. The webcams wait for the Arduino to send a signal to the webcams in parallel. The issue is, I cannot get the 3 cameras to work simultaneously. I can get any combination of 2 cameras to work but not 3. When I try 3 webcams, I get an error of empty frames.

Link To Webcam Used

[ WARN:2] global /home/pi/opencv/modules/videoio/src/cap_v4l.cpp (1004) tryIoctl VIDEOIO(V4L2:/dev/video0): select() timeout. Empty Frame terminate called after throwing an instance of 'cv::Exception' what(): OpenCV(4.3.0) /home/pi/opencv/modules/imgcodecs/src/loadsave.cpp:738: error: (-215:Assertion failed) !_img.empty() in function 'imwrite'

Aborted   #include<stdio.h> #include<stdlib.h> #include<thread> #include<iostream> #include<fstream>

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include"pthread.h"
#include<stdlib.h>
#include<string>
#include<boost/date_time/posix_time/posix_time.hpp>

#include<mutex>
#include<condition_variable>
#include<atomic>


std::mutex m;
std::condition_variable suspend_cv;
std::atomic<bool> enabled (false);

struct args {
    int camNum;
    char* camName;
    int x;
    int y;
    };


void* camSetup(void *inputs){
cv::VideoCapture stream(((struct args*)inputs)->camNum);
cv::Mat Frame;
//cv::Mat resizeFrame;
if(!stream.isOpened()){
    std::cout << "Cannot Open Camera: " + ((struct args*) inputs)->camNum + '\n';
}
else{
    std::cout << "Camera Open: " << ((struct args*) inputs)->camNum + '\n';
}
std::unique_lock<std::mutex> lock(m);
while (true){
    stream >> Frame;
    //cv::resize(Frame, resizeFrame, cv::Size(25, 25));
    while (enabled){
        // Get current time from the clock, using microseconds resolution
        const boost::posix_time::ptime now = 
            boost::posix_time::microsec_clock::local_time();

        // Get the time offset in current day
        const boost::posix_time::time_duration td = now.time_of_day();
        const long year         = now.date().year();
        const long month        = now.date().month();
        const long day          = now.date().day();
        const long hours        = td.hours();
        const long minutes      = td.minutes();
        const long seconds      = td.seconds();
        const long milliseconds = td.total_milliseconds() -
                                  ((hours * 3600 + minutes * 60 + seconds) * 1000);

        char buf[80];
        sprintf(buf, "%02ld%02ld%02ld_%02ld%02ld%02ld__%03ld", 
            year, month, day, hours, minutes, seconds, milliseconds);
            std::string sBuf = buf;
            std::string PATH = std::string("/home/pi/Desktop/") +
                            ((struct args*)inputs)->camName + 
                                '/' +
                                std::string(((struct args*)inputs)->camName) +
                                '_' +
                                sBuf +
                                ".jpeg";
        if (Frame.empty())
        {
            std::cout << "Empty Frame" <<std::endl;
            stream >> Frame;
            //cv::resize(Frame, resizeFrame, cv::Size(25, 25));

        }
        cv::imwrite(PATH, Frame);
        if (cv::waitKey(30) >= 0){
            break;
        }
        suspend_cv.wait(lock);
    }
}
return NULL;
}


void* ardReader(void*){
ARDUINO STUFF HAPPENS…
}

int main(){
struct args *cameraA = (struct args *)malloc(sizeof(struct args));
struct args *cameraB = (struct args *)malloc(sizeof(struct args));
struct args *cameraC = (struct args *)malloc(sizeof(struct args));

cameraA->camNum = 0;
char camA[] = "camA";
cameraA->camName = camA;
cameraA->x = 100;
cameraA->y =100;

cameraB->camNum = 2;
char camB[] = "camB";
cameraB->camName = camB;
cameraB->x = 100;
cameraB->y = 300;

cameraC->camNum = 4;
char camC[] = "camC";
cameraC->camName = camC;
cameraC->x = 100;
cameraC->y = 500;

pthread_t t1, t2, t3, t4;

pthread_create(&t1, NULL, camSetup, (void *) cameraA);
pthread_create(&t2, NULL, camSetup, (void *) cameraB);
pthread_create(&t3, NULL, camSetup, (void *) cameraC);
pthread_create(&t4, NULL, ardReader, NULL);

pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
pthread_join(t4, NULL);
return 0;
}

Why can't I get 3 webcam to run in parallel with pthreads?

Hey all, I need some help with OpenCV with threading using C++. I am using a raspberry pi 3B. Which is a quad core. There are 4 USB 2.0 devices, 3 USB 2.0 webcam and USB 2.0 Arduino. The webcam’s cable has been spliced out to provide voltage on its own, so only data wires are going into the pi. The Arduino is being powered by the pi. Now to the issue. I have 4 threads going, 3 for the webcams and 1 for the Arduino. The webcams wait for the Arduino to send a signal to the webcams in parallel. The issue is, I cannot get the 3 cameras to work simultaneously. I can get any combination of 2 cameras to work but not 3. When I try 3 webcams, I get an error of empty frames.

Link To Webcam Used

Error:

[ WARN:2] global /home/pi/opencv/modules/videoio/src/cap_v4l.cpp (1004) tryIoctl VIDEOIO(V4L2:/dev/video0): select() timeout.
Empty Frame
terminate called after throwing an instance of 'cv::Exception'
  what():  OpenCV(4.3.0) /home/pi/opencv/modules/imgcodecs/src/loadsave.cpp:738: error: (-215:Assertion failed) !_img.empty() in function 'imwrite'

'imwrite' Aborted

Aborted   #include<stdio.h> #include<stdlib.h> #include<thread> #include<iostream> #include<fstream>

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include"pthread.h"
#include<stdlib.h>
#include<string>
#include<boost/date_time/posix_time/posix_time.hpp>

#include<mutex>
#include<condition_variable>
#include<atomic>


std::mutex m;
std::condition_variable suspend_cv;
std::atomic<bool> enabled (false);

struct args {
    int camNum;
    char* camName;
    int x;
    int y;
    };


void* camSetup(void *inputs){
cv::VideoCapture stream(((struct args*)inputs)->camNum);
cv::Mat Frame;
//cv::Mat resizeFrame;
if(!stream.isOpened()){
    std::cout << "Cannot Open Camera: " + ((struct args*) inputs)->camNum + '\n';
}
else{
    std::cout << "Camera Open: " << ((struct args*) inputs)->camNum + '\n';
}
std::unique_lock<std::mutex> lock(m);
while (true){
    stream >> Frame;
    //cv::resize(Frame, resizeFrame, cv::Size(25, 25));
    while (enabled){
        // Get current time from the clock, using microseconds resolution
        const boost::posix_time::ptime now = 
            boost::posix_time::microsec_clock::local_time();

        // Get the time offset in current day
        const boost::posix_time::time_duration td = now.time_of_day();
        const long year         = now.date().year();
        const long month        = now.date().month();
        const long day          = now.date().day();
        const long hours        = td.hours();
        const long minutes      = td.minutes();
        const long seconds      = td.seconds();
        const long milliseconds = td.total_milliseconds() -
                                  ((hours * 3600 + minutes * 60 + seconds) * 1000);

        char buf[80];
        sprintf(buf, "%02ld%02ld%02ld_%02ld%02ld%02ld__%03ld", 
            year, month, day, hours, minutes, seconds, milliseconds);
            std::string sBuf = buf;
            std::string PATH = std::string("/home/pi/Desktop/") +
                            ((struct args*)inputs)->camName + 
                                '/' +
                                std::string(((struct args*)inputs)->camName) +
                                '_' +
                                sBuf +
                                ".jpeg";
        if (Frame.empty())
        {
            std::cout << "Empty Frame" <<std::endl;
            stream >> Frame;
            //cv::resize(Frame, resizeFrame, cv::Size(25, 25));

        }
        cv::imwrite(PATH, Frame);
        if (cv::waitKey(30) >= 0){
            break;
        }
        suspend_cv.wait(lock);
    }
}
return NULL;
}


void* ardReader(void*){
ARDUINO STUFF HAPPENS…
}

int main(){
struct args *cameraA = (struct args *)malloc(sizeof(struct args));
struct args *cameraB = (struct args *)malloc(sizeof(struct args));
struct args *cameraC = (struct args *)malloc(sizeof(struct args));

cameraA->camNum = 0;
char camA[] = "camA";
cameraA->camName = camA;
cameraA->x = 100;
cameraA->y =100;

cameraB->camNum = 2;
char camB[] = "camB";
cameraB->camName = camB;
cameraB->x = 100;
cameraB->y = 300;

cameraC->camNum = 4;
char camC[] = "camC";
cameraC->camName = camC;
cameraC->x = 100;
cameraC->y = 500;

pthread_t t1, t2, t3, t4;

pthread_create(&t1, NULL, camSetup, (void *) cameraA);
pthread_create(&t2, NULL, camSetup, (void *) cameraB);
pthread_create(&t3, NULL, camSetup, (void *) cameraC);
pthread_create(&t4, NULL, ardReader, NULL);

pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
pthread_join(t4, NULL);
return 0;
}

Why can't I get 3 webcam to run in parallel with pthreads?

Hey all, I need some help with OpenCV with threading using C++. I am using a raspberry pi 3B. Which is a quad core. There are 4 USB 2.0 devices, 3 USB 2.0 webcam and USB 2.0 Arduino. The webcam’s cable has been spliced out to provide voltage on its own, so only data wires are going into the pi. The Arduino is being powered by the pi. Now to the issue. I have 4 threads going, 3 for the webcams and 1 for the Arduino. The webcams wait for the Arduino to send a signal to the webcams in parallel. The issue is, I cannot get the 3 cameras to work simultaneously. I can get any combination of 2 cameras to work but not 3. When I try 3 webcams, I get an error of empty frames.

Link To Webcam Used

Error:

[ WARN:2] global /home/pi/opencv/modules/videoio/src/cap_v4l.cpp (1004) tryIoctl VIDEOIO(V4L2:/dev/video0): select() timeout.
Empty Frame
terminate called after throwing an instance of 'cv::Exception'
  what():  OpenCV(4.3.0) /home/pi/opencv/modules/imgcodecs/src/loadsave.cpp:738: error: (-215:Assertion failed) !_img.empty() in function 'imwrite'

Aborted

  #include<stdio.h> #include<stdlib.h> #include<thread> #include<iostream> #include<fstream>Code: 

#include<stdio.h>
#include<stdlib.h>
#include<thread>
#include<iostream>
#include<fstream>

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include"pthread.h"
#include<stdlib.h>
#include<string>
#include<boost/date_time/posix_time/posix_time.hpp>

#include<mutex>
#include<condition_variable>
#include<atomic>


std::mutex m;
std::condition_variable suspend_cv;
std::atomic<bool> enabled (false);

struct args {
    int camNum;
    char* camName;
    int x;
    int y;
    };


void* camSetup(void *inputs){
 cv::VideoCapture stream(((struct args*)inputs)->camNum);
 cv::Mat Frame;
 //cv::Mat resizeFrame;
 if(!stream.isOpened()){
     std::cout << "Cannot Open Camera: " + ((struct args*) inputs)->camNum + '\n';
 }
 else{
     std::cout << "Camera Open: " << ((struct args*) inputs)->camNum + '\n';
 }
 std::unique_lock<std::mutex> lock(m);
 while (true){
     stream >> Frame;
     //cv::resize(Frame, resizeFrame, cv::Size(25, 25));
     while (enabled){
         // Get current time from the clock, using microseconds resolution
         const boost::posix_time::ptime now = 
             boost::posix_time::microsec_clock::local_time();

         // Get the time offset in current day
         const boost::posix_time::time_duration td = now.time_of_day();
         const long year         = now.date().year();
         const long month        = now.date().month();
         const long day          = now.date().day();
         const long hours        = td.hours();
         const long minutes      = td.minutes();
         const long seconds      = td.seconds();
         const long milliseconds = td.total_milliseconds() -
                                   ((hours * 3600 + minutes * 60 + seconds) * 1000);

         char buf[80];
         sprintf(buf, "%02ld%02ld%02ld_%02ld%02ld%02ld__%03ld", 
             year, month, day, hours, minutes, seconds, milliseconds);
             std::string sBuf = buf;
             std::string PATH = std::string("/home/pi/Desktop/") +
                             ((struct args*)inputs)->camName + 
                                 '/' +
                                 std::string(((struct args*)inputs)->camName) +
                                 '_' +
                                 sBuf +
                                 ".jpeg";
         if (Frame.empty())
         {
             std::cout << "Empty Frame" <<std::endl;
             stream >> Frame;
             //cv::resize(Frame, resizeFrame, cv::Size(25, 25));

         }
         cv::imwrite(PATH, Frame);
         if (cv::waitKey(30) >= 0){
             break;
         }
         suspend_cv.wait(lock);
     }
 }
 return NULL;
 }


void* ardReader(void*){
 ARDUINO STUFF HAPPENS…
}

int main(){
 struct args *cameraA = (struct args *)malloc(sizeof(struct args));
 struct args *cameraB = (struct args *)malloc(sizeof(struct args));
 struct args *cameraC = (struct args *)malloc(sizeof(struct args));

 cameraA->camNum = 0;
 char camA[] = "camA";
 cameraA->camName = camA;
 cameraA->x = 100;
 cameraA->y =100;

 cameraB->camNum = 2;
 char camB[] = "camB";
 cameraB->camName = camB;
 cameraB->x = 100;
 cameraB->y = 300;

 cameraC->camNum = 4;
 char camC[] = "camC";
 cameraC->camName = camC;
 cameraC->x = 100;
 cameraC->y = 500;

 pthread_t t1, t2, t3, t4;

 pthread_create(&t1, NULL, camSetup, (void *) cameraA);
 pthread_create(&t2, NULL, camSetup, (void *) cameraB);
 pthread_create(&t3, NULL, camSetup, (void *) cameraC);
 pthread_create(&t4, NULL, ardReader, NULL);

 pthread_join(t1, NULL);
 pthread_join(t2, NULL);
 pthread_join(t3, NULL);
 pthread_join(t4, NULL);
 return 0;
 }