mardi 19 mars 2019

What is the best way to run multiple threads that must loop 25 times per second without over loading the CPU

Hi I am trying to capture multiple frames from different IP camera via openCV I have an i7 12 core CPU and currently I can stream 4 HD IP cameras and display each camera in a 2 x 2 matrix overlay window but my issue is streaming these 4 camera is using 20% of my CPU unless I use sleep in each thread which then slows the display from there true frame rate. I am using timers to fire each thread that calls opencv to read each frame resize the image to the size of each matrix frame and passes each Mat buffer to Directx 11 overlay. If I set the cameras to stream at 25 FPS my timers to fire each thread event are set to 40 milliseconds which is 25 events every second but this is pulling my CPU down here is some of the code im using for my threads

 void mCam1(void * p)
        {
            COpenCVROIDlg* pThis = (COpenCVROIDlg*)p;
            v_Mat[pThis->m_MatrixView].copyTo(v_MatPre[pThis->m_MatrixView]);
            cv::Point pt;
            cv::Mat m_img, imgResized, m_matrix;
            if (!pThis->camera0.isOpened()) {
                // Send not connected to list control
            }else{
                pThis->camera0.read(m_img);
                if (m_img.empty()) {
                    //send no signal to list control
                }
                else {
                    cv::resize(m_img, imgResized, cv::Size(v_Cams[pThis->m_MatrixView][0].mPT.rc.right, v_Cams[pThis->m_MatrixView][0].mPT.rc.bottom), 0, 0, INTER_LINEAR_EXACT);
                    Rect roi(v_Cams[pThis->m_MatrixView][0].mPT.pt.x, v_Cams[pThis->m_MatrixView][0].mPT.pt.y, imgResized.cols, imgResized.rows);
                    v_Mat[pThis->m_MatrixView].copyTo(m_matrix);
                    imgResized.copyTo(m_matrix(roi));
                    m_matrix.copyTo(v_Mat[pThis->m_MatrixView]);
                    cv::waitKey(1);
                }
            }
            cv::waitKey(84);// 12 frames per second
        }

      void CreateThreads(){
            m_hEventStream0 = CreateEvent(NULL, FALSE, FALSE, 0);`
            ghOnvifThread[2] = CreateThread(
                NULL,              // default security
                0,                 // default stack size
                (LPTHREAD_START_ROUTINE)ThreadCamera1,        // name of the thread function
                LPVOID(this),              // no thread parameters
                THREAD_TERMINATE | THREAD_SET_CONTEXT,                  // default startup flags
                &dwThreadID[2]);
 SetTimer(TM_CAMERA0, 10, NULL);
         }

        static LPTHREAD_START_ROUTINE ThreadCamera1(LPVOID _pParam)
        {
            COpenCVROIDlg* pThis = (COpenCVROIDlg*)_pParam;
            HANDLE      hEvent;
            hEvent = m_hEventStream0;
            DWORD dwEventObject;
            __try
            {
                while (dwThreadID[2])
                {
                    dwEventObject = WaitForSingleObject(hEvent, INFINITE);
                    if (dwEventObject == (WAIT_OBJECT_0))
                    {
                        mCam1(pThis);
                    }
                }
            }
            __except (EXCEPTION_EXECUTE_HANDLER)
            {
            //  ExitThread(0x2222E000);
                return 0;
            }
            ExitThread(0x22220000);
            return 0;
        }

Can anyone show me an example or point me to a way where I can run multiple threads without causing excessive CPU over head. It seems with opencv I cant get each videocapture to tell me if theres a new image ready I have to keep probing it via the thread and read each frame that way. Thanks

Aucun commentaire:

Enregistrer un commentaire