【问题标题】:OpenCV Frame Rate IssueOpenCV 帧率问题
【发布时间】:2011-01-25 16:47:39
【问题描述】:

我正在使用 OpenCV 进行学校项目。该程序的主要部分将是直方图的比较。将有一个直方图数据库,新的直方图将从实时视频馈送中创建,然后与数据库中的直方图进行比较。现在我只是想从视频源中正确创建直方图。 我的问题是程序在随机的时间间隔内崩溃或显着变慢。所以我的问题是如何防止程序崩溃或变慢? OpenCV 对我来说一直有点不稳定,所以我不确定这是我的代码有问题还是只是OpenCV 的本质。如果与我的代码有关,我认为该问题可能与帧速率有关(猜测/直觉)。我正在使用“cvWaitKey”来“调整”帧的加载速度,但“Learning OpenCV”一书中有关于“cvWaitKey”的说法

c = cvWaitKey(33); if( c == 27 ) 中断; 一旦我们显示了帧,我们就等待 33 毫秒。如果用户按下一个键,那么 c 将设置为该键的 ASCII 值;如果不是,则将其设置为 –1。如果用户点击 Esc 键(ASCII 27),然后我们将退出读取循环。否则,将经过 33 ms 并且 我们将再次执行循环。 值得注意的是,在这个简单的例子中,我们并没有明确控制 任何智能方式的视频速度。我们完全依赖于定时器 cvWaitKey() 来调整帧的加载速度。在更复杂的应用程序中,它会 明智地从 CvCapture 结构(来自 AVI)和 相应地行事!

您将在下面的代码(从here 修改)中看到,我的循环在开始下一次执行之前等待了 10 毫秒。通常程序运行时完全没有问题,但有时它会在不到一分钟或五分钟内崩溃,我真的无法检测到模式。 欢迎任何关于如何防止崩溃(或减速)的建议。 另外我应该补充一点,我正在使用 OpenCV 1.1(永远无法让 OpenCV 2.0 正常工作),我是使用 Visual Studio 2008,每次修改代码时都会创建一个 .MSI 安装程序包,也就是说,我不在 Visual Studio 中调试。依赖项是 cv110.dll、cxcore110.dll 和 highgui110.dll。我的代码如下:

// SLC (Histogram).cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include <cxcore.h>
#include <cv.h>
#include <cvaux.h>
#include <highgui.h>
#include <stdio.h>
#include <sstream>
#include <iostream>

using namespace std;

int main(){

    CvCapture* capture = cvCaptureFromCAM(0);

    if(!cvQueryFrame(capture)){
        cout<<"Video capture failed, please check the camera."<<endl;
    }

    else{
        cout<<"Video camera capture successful!"<<endl;
    };

    CvSize sz = cvGetSize(cvQueryFrame(capture));

    IplImage* image = cvCreateImage(sz, 8, 3);
    IplImage* imgHistogram = 0;
    IplImage* gray = 0;
    CvHistogram* hist;

    cvNamedWindow("Image Source",1);
    cvNamedWindow("Histogram",1);

    for(;;){

        image = cvQueryFrame(capture);

        //Size of the histogram -1D histogram
        int bins = 256;
        int hsize[] = {bins};

        //Max and min value of the histogram
        float max_value = 0, min_value = 0;

        //Value and normalized value
        float value;
        int normalized;

        //Ranges - grayscale 0 to 256
        float xranges[] = {0, 256};
        float* ranges[] = {xranges};

        //Create an 8 bit single channel image to hold a grayscale version of the original picture
        gray = cvCreateImage(cvGetSize(image), 8, 1);
        cvCvtColor(image, gray, CV_BGR2GRAY);

        //Planes to obtain the histogram, in this case just one
        IplImage* planes[] = {gray};

        //Get the histogram and some info about it
        hist = cvCreateHist(1, hsize, CV_HIST_ARRAY, ranges,1);
        cvCalcHist(planes, hist, 0, NULL);
        cvGetMinMaxHistValue(hist, &min_value, &max_value);
        printf("Minimum Histogram Value: %f, Maximum Histogram Value: %f\n", min_value, max_value);

        //Create an 8 bits single channel image to hold the histogram and paint it white
        imgHistogram = cvCreateImage(cvSize(bins, 50),8,3);
        cvRectangle(imgHistogram, cvPoint(0,0), cvPoint(256,50), CV_RGB(255,255,255),-1);

        //Draw the histogram
        for(int i=0; i < bins; i++){
            value = cvQueryHistValue_1D(hist, i);
            normalized = cvRound(value*50/max_value);
            cvLine(imgHistogram,cvPoint(i,50), cvPoint(i,50-normalized), CV_RGB(0,0,0));
        }

        cvFlip(image, NULL, 1);
        cvShowImage("Image Source", image);
        cvShowImage("Histogram", imgHistogram);

        //Page 19 paragraph 3 of "Learning OpenCV" tells us why we DO NOT use "cvReleaseImage(&image)" in this section
        cvReleaseImage(&imgHistogram);
        cvReleaseImage(&gray);
        cvReleaseHist(&hist);

        char c = cvWaitKey(10);

        //if ASCII key 27 (esc) is pressed then loop breaks
        if(c==27) break;

    }

    cvReleaseImage(&image);
    cvReleaseCapture(&capture);
    cvDestroyAllWindows();

}

【问题讨论】:

    标签: c++ crash opencv performance slowdown


    【解决方案1】:

    我只能看到或推荐几件事:

    考虑到构建,请确保您在 Release 中构建。此外,请确保您使用的 OpenCV 构建是在启用 OpenMP 的情况下构建的,这会产生巨大的差异。

    尝试将您的分配移出循环。您重新创建的每个循环 gray 和其他图像,它们应该被重新使用。

    另一件事是你的风格,这使得很难轻易给出好的建议。预先声明一堆变量是不好的风格,这是 C 风格。在使用之前声明你的变量,代码会更容易阅读。

    【讨论】:

    • 我现在必须走了,但你应该寻找类似的东西。避免不断动态分配,尝试将其移到循环之外。
    • 您能详细说明一下吗?你的意思是 OpenMP 版本的 bug 更少或类似的东西吗?我最初尝试使用 2.0(来自 sourceforge),但我永远无法在 Visual Studio 2008 中正确链接。我最终使用了我的书使用的旧版本(版本 1.1,之前在 sourceforge 上)。正如你所说,我也会尝试改进我的风格,我是 C++ 新手(以及所有相关的编程),所以我相信我的“风格”会随着时间的推移而发展 :)
    • OpenMP 是一个多线程扩展。启用它后,OpenCV 的性能可以显着提高。
    • 我已经玩了一段时间了,如果我错了,请纠正我,但是如果我将灰色移到循环之外,它不会随着循环的每次通过而更新,因此直方图不会更新。我想我必须在每次循环时重新创建灰色以使这段代码正常工作。
    • @typoking:你搬走了什么?您应该可以将其移出:gray = cvCreateImage(cvGetSize(image), 8, 1); 和匹配的版本。
    【解决方案2】:

    更新:我发现了问题,它实际上是我的硬件(我认为是驱动程序)。由于惊人的帧速率,我使用了 PS3 Eye,但出于某种原因,OpenCV 一直不喜欢 PS3 Eye。有时效果很好,有时效果不太好。我已经在三台计算机上验证了这一点,所有这些计算机都可以使用标准网络摄像头很好地运行我的代码,但在使用 PS3 Eye 时会随机锁定。不过,还是感谢 GMan 的建议!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-30
      • 1970-01-01
      • 2014-09-12
      • 2012-07-05
      • 2023-03-22
      相关资源
      最近更新 更多