简体   繁体   English

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

[英]OpenCV display and processing webcam stream

I was looking for process a stream with opencv coming from webcam. 我正在寻找使用来自摄像头的opencv处理流。 My goal is to detect rectangles for each frames. 我的目标是为每个帧检测矩形。 I'm able to display the result but the framerate is really slow, ~1 fps. 我可以显示结果,但是帧速率确实很慢,约为1 fps。

Here is an overview of my source code: 这是我的源代码的概述:

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;
}

I would like to know if it's possible to make it threaded to gain at least 30fps ? 我想知道是否有可能使其线程至少获得30fps?

I'm working on windows 8.1, Visual 2010, c++ & OpenCV 2.4.10 我正在Windows 8.1,Visual 2010,C ++和OpenCV 2.4.10上工作

You could use threads before while(true) loop. 您可以在while(true)循环之前使用线程。 Of course, reading frames from the camera and displaying them would have to be serialized. 当然,必须从相机读取帧并将其显示出来。

I see you're using C++ std::vector, so I would suggest you use C++11 threads and mutex. 我看到您使用的是C ++ std :: vector,因此建议您使用C ++ 11线程和互斥量。 The most performatic way I can think of is openning all threads at startup (before the while(true) loop) and make then receive the frames captured by the main thread. 我能想到的最有效的方法是在启动时打开所有线程(在while(true)循环之前),然后使它们接收由主线程捕获的帧。 All threads would be locked on the same mutex for reading the frame queue and on a second mutex for displaying it. 所有线程将锁定在同一互斥锁上以读取帧队列,并锁定在另一个互斥锁上以显示帧队列。 The frame queue may be implemented as: 帧队列可以实现为:

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

Depending on the size of your project and side effects, it may even be declared global. 根据项目的大小和副作用,它甚至可能被声明为全局的。

I fixed this issue using another solution found on stackoverflow. 我使用在stackoverflow上找到的另一个解决方案解决了此问题。 Here is my complete code: 这是我完整的代码:

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());
        }
    }
}

Here is my reference: OpenCV C++/Obj-C: Detecting a sheet of paper / Square Detection 这是我的参考: OpenCV C ++ / Obj-C:检测一张纸/正方形检测

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM