OpenCV显示和处理网络摄像头流

时间:2015-01-21 15:49:12

标签: c++ windows multithreading opencv image-processing

我正在寻找一个来自网络摄像头的opencv流程。我的目标是检测每个帧的矩形。我能够显示结果,但帧速率非常慢,~1 fps。

以下是我的源代码概述:

int main( int argc, char** argv ) {

CvCapture* cap=cvCreateCameraCapture(0);
cvNamedWindow("LiveFeed",CV_WINDOW_AUTOSIZE);

    while(true) {
    frame=cvQueryFrame(cap);
    if(!frame) 
        printf("\n no");
    else {
        Mat mat_img(frame);
        std::vector<std::vector<cv::Point>> rectangle = findSquaresInImage(mat_img);
        rectangle=filterRectangleSimilaire(rectangle,20.0);
        Mat res=debugSquares(rectangle,mat_img);

        cvShowImage("LiveFeed",new IplImage(res));//new IplImage(res));
    }
    char c=cvWaitKey(33);
    if(c==27)
        break;
}

cvReleaseCapture(&cap);
cvDestroyAllWindows();
return 0;
}

我想知道是否有可能使其获得至少30fps的线程?

我正在使用Windows 8.1,Visual 2010,c ++&amp; OpenCV 2.4.10

2 个答案:

答案 0 :(得分:3)

您可以在while(true)循环之前使用线程。当然,从相机读取帧并显示它们必须序列化。

我看到你正在使用C ++ std :: vector,所以我建议你使用C ++ 11线程和互斥锁。我能想到的最有效的方法是在启动时打开所有线程(在while(true)循环之前),然后生成接收主线程捕获的帧。所有线程都将锁定在同一个互斥锁上以读取帧队列,并锁定在第二个互斥锁上以显示它。帧队列可以实现为:

struct frameQueue{
    std::vector<Mat> frames;
    std::mutex mtx;
};

根据项目的大小和副作用,它甚至可能被声明为全局。

答案 1 :(得分:2)

我使用stackoverflow上的另一个解决方案解决了这个问题。 这是我的完整代码:

Mat mat_img(frame);
Mat gray_mat_img, threshold_mat_img, detected_edges;
std::vector<std::vector<cv::Point>> contours;
vector<Vec4i> hierarchy;

cvtColor(mat_img, gray_mat_img, CV_BGR2GRAY);
blur(gray_mat_img, gray_mat_img, Size(10,10));
cv::threshold(gray_mat_img, threshold_mat_img, 140, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
Canny(threshold_mat_img, detected_edges, 100, 100, 3);
cv::findContours(detected_edges, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

RNG rng(12345);
//contours = filterRectangleSimilaire(contours, 10);
//if (contours.size() < 5) {
vector<Rect> boundRect( contours.size() );
vector<Point> approx;


for (size_t i = 0; i < contours.size(); i++) {
    approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
    if (approx.size() == 4 && fabs(contourArea(Mat(approx))) > 100 && isContourConvex(Mat(approx))) {
        double maxCosine = 0;
        for (int j = 2; j < 5; j++) {
            double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
            maxCosine = MAX(maxCosine, cosine);
        }
        if (maxCosine < 0.3) {
            Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255));
            boundRect[i] = boundingRect( Mat(approx) );
            rectangle( mat_img, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
            drawContours(mat_img, contours, i, color, 2, 8, hierarchy, 0, Point());
        }
    }
}

以下是我的参考:OpenCV C++/Obj-C: Detecting a sheet of paper / Square Detection