簡體   English   中英

使用OpenCV,Boost線程和多個攝像頭

[英]Using OpenCV, Boost threading and multiple cameras

我正在嘗試編寫一個能夠從兩個不同線程中的兩個不同攝像頭捕獲圖像的程序。 我想這樣做是因為當我在同一個線程中執行此操作時,我必須繼續等待cvQueryFrame兩倍的時間,因此我無法以30 fps的速度抓取圖像(我從每個攝像頭獲得15 FPS)。

我看過這篇SO帖子,但這只適用於一台攝像機。 一起使用cvQueryFrame和boost :: thread

我當前的程序給出了不同的結果,有時它會給內存泄漏,通常我只是看不到任何事情發生,有時候它會花費幾秒鍾,但圖像會再次凍結。 奇怪的是,早些時候我沒有調用cvShowImage,但是我的imageProcessing函數做了一些有用的東西,我可以看到我從兩個攝像頭得到實時結果。 我認為這意味着可以使這項工作成功,但我在某處犯了一個愚蠢的錯誤。 我的操作系統是LINUX,我使用的是OpenCV 2.4

我的代碼:

#include <iostream>
#include <cstdio>
#include <cv.h>
#include <ml.h>
#include <cvaux.h>
#include <highgui.h>
#include <vector>
#include <stdio.h>
#include "producer_consumer_queue.hpp"



//Camera settings
int cameraWidth = 1280;
int cameraHeight = 720;
int waitKeyValue = 5;
bool threads_should_exit = false;

CvCapture * capture;
CvCapture * capture2;

using namespace std;
using namespace cv;

void grabFrame(concurrent_queue<IplImage* > * frame_queue, int camNumber) {
    try {
        //Load first frames
        cout << "grabFrame: " << camNumber << " init with " << cameraWidth << " x " << cameraHeight << endl;

        IplImage* frame;
        if (camNumber == 0)frame = cvQueryFrame(capture);
        if (camNumber == 1)frame = cvQueryFrame(capture2);
        while (frame && !threads_should_exit) {
            if (camNumber == 0)frame = cvQueryFrame(capture);
            if (camNumber == 1)frame = cvQueryFrame(capture2);
            IplImage* frame_copy = NULL;
            frame_copy = cvCloneImage(frame);

            if (camNumber == 0)cvShowImage("NE", frame);
            cout << "grabFrame: " << camNumber << " pushing back to queue" << endl;
            frame_queue->push(frame_copy);

            int k = cvWaitKey(waitKeyValue);

            if (k == 1048603 || k == 27 || k == '\r') {

                cout << "grabFrame: Process killed" << endl;
                //release memory
                threads_should_exit = true;
            }

        }
    } catch (const concurrent_queue<IplImage* >::Canceled & e) {
        cout << "grabFrame: Show thread is canceled" << endl;
        return;
    }

}

void processFrames(concurrent_queue<IplImage* > * frame_queue0, concurrent_queue<IplImage* > * frame_queue1) {
    try {
        do {
            cout << "processFrames: Processing two frames" << endl;
            IplImage* frm = NULL;
            frame_queue0->wait_and_pop(frm);
            IplImage * frm2 = NULL;
            frame_queue1->wait_and_pop(frm2);
            cvReleaseImage(&frm);
            cvReleaseImage(&frm2);
        } while (!threads_should_exit);
    } catch (const concurrent_queue<IplImage* >::Canceled & e) {
        cout << "processFrames: Processing thread is canceled" << endl;
        return;
    }
}

int main() {
    capture = cvCreateCameraCapture(0);
    capture2 = cvCreateCameraCapture(1);
    cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, cameraWidth);
    cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, cameraHeight);
    cvSetCaptureProperty(capture2, CV_CAP_PROP_FRAME_WIDTH, cameraWidth);
    cvSetCaptureProperty(capture2, CV_CAP_PROP_FRAME_HEIGHT, cameraHeight);

    boost::thread_group frame_workers;
    boost::thread_group frame_workers2;
    concurrent_queue<IplImage* > frame_queue(&frame_workers);
    concurrent_queue<IplImage* > frame_queue2(&frame_workers2);

    boost::thread * query_thread = new boost::thread(processFrames, &frame_queue, &frame_queue2);
    boost::thread * cam0_thread = new boost::thread(grabFrame, &frame_queue, 0);
    usleep(10000);
    boost::thread * cam1_thread = new boost::thread(grabFrame, &frame_queue2, 1);

    frame_workers.add_thread(query_thread);
    frame_workers.add_thread(cam0_thread);

    frame_workers2.add_thread(query_thread);
    frame_workers2.add_thread(cam1_thread);
    while (true) {
        if (threads_should_exit) {
            cout << "Main: threads should be killed" << endl;
            while (!frame_queue.empty()) {
                usleep(10000);
            }
            frame_workers.remove_thread(query_thread);
            frame_workers2.remove_thread(query_thread);
            frame_workers.remove_thread(cam0_thread);
            frame_workers2.remove_thread(cam1_thread);

            frame_workers.join_all();
            break;
        }
        usleep(10000);
    }

    return 0;

}

編輯:

我添加了一個簡單的函數來檢測一張紙,看看當我不調用cvShowImage()時一切正常。 如果我不調用cvShowImage()我的程序可以檢測到一張紙。 如果我這樣做該程序再次有奇怪的行為並凍結等。

應該只有一個線程來操縱GUI(對於任何GUI框架都是如此)。 您應該組織代碼,以便cvShowImage主“GUI線程”調用cvShowImage

似乎在query_thread中完成的工作可以在主線程內輕松完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM