2

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

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

您将在下面的代码(从此处修改)中看到,我的循环在开始下一次执行之前等待了 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();

}
4

2 回答 2

1

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

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

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

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

于 2010-03-10T00:33:44.450 回答
1

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

于 2010-03-12T11:48:19.280 回答