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 ミリ秒待機することがわかります。多くの場合、プログラムはまったく問題なく実行されますが、1 分以内または 5 分以内にクラッシュすることもあります。実際に検出できるパターンはありません。 このクラッシュ (またはスローダウン) を防止する方法についての提案を歓迎します。 また、私は 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

更新:問題を見つけました。それは実際には私のハードウェアでした(まあ、私が思うドライバーです)。フレームレートが素晴らしいのでPS3Eyeを使用していましたが、何らかの理由でOpenCVはPS3Eyeを常に気に入っていません。うまくいくこともあれば、それほどうまくいかないこともあります。私はこれを3台のコンピューターで検証しました。これらはすべて、標準のWebカメラでコードを適切に実行しますが、PS3Eyeを使用するとランダムにロックされます。それでも、GManの提案に感謝します!

于 2010-03-12T11:48:19.280 に答える
1

私が見たりお勧めしたりできることはほんのわずかです。

ビルドを考慮して、Release でビルドしていることを確認してください。また、使用している OpenCV のビルドが OpenMP を有効にしてビルドされていることを確認してください。これにより、大きな違いが生じます。

割り当てをループの外に移動してみてください。再作成するすべてのループgrayとその他の画像を再利用する必要がある場合。

もう 1 つはあなたのスタイルです。一連の変数を事前に宣言するのは不適切なスタイルです。これは C スタイルです。使用する直前に変数を宣言すると、コードが読みやすくなります。

于 2010-03-10T00:33:44.450 に答える