Частота кадров OpenCV - PullRequest
       12

Частота кадров OpenCV

2 голосов
/ 10 марта 2010

Я работаю над школьным проектом с OpenCV.Основной частью программы будет сравнение гистограмм.Будет создана база данных гистограмм, а новые гистограммы будут созданы из живого видеопотока, а затем будут сравниваться с гистограммами в базе данных.Сейчас я просто пытаюсь получить гистограммы, созданные правильно из видеопотока. Моя проблема в том, что программа зависает или резко замедляется через случайные интервалы.Поэтому мой вопрос заключается в том, как мне предотвратить сбой или замедление работы программы? OpenCV всегда был для меня немного странным, поэтому я не уверен, является ли это проблемой с моим кодом или это просто природаOpenCV.Если это связано с моим кодом, я думаю, что проблема может иметь какое-то отношение к частоте кадров (ощущение догадки / интуиции).Я использую «cvWaitKey», чтобы «ускорить» загрузку фреймов, но в книге «Изучение OpenCV» есть что сказать о «cvWaitKey»

c = cvWaitKey (33);если (с == 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();

}

Ответы [ 2 ]

1 голос
/ 12 марта 2010

Обновление: я обнаружил проблему, на самом деле это было мое оборудование (ну драйвер я думаю). Я использовал PS3 Eye из-за удивительной частоты кадров, но почему-то OpenCV не нравится PS3 Eye все время. Иногда это работает отлично, а иногда не так хорошо. Я проверил это на трех компьютерах, каждый из которых хорошо выполняет мой код со стандартной веб-камерой, но случайно блокируется при использовании PS3 Eye. Тем не менее, спасибо за ваши предложения GMan!

1 голос
/ 10 марта 2010

Только несколько вещей, которые я могу видеть или рекомендовать:

Учитывая сборку, убедитесь, что вы строите в Release. Кроме того, убедитесь, что сборка OpenCV, которую вы используете, была построена с включенным OpenMP, это имеет огромное значение.

Попробуйте переместить ваши выделения за пределы цикла. Каждый цикл, который вы воссоздаете gray и другие изображения, когда они должны быть повторно использованы.

Другая вещь - это ваш стиль, из-за которого сложно давать хорошие рекомендации. Это плохой стиль для предварительного объявления группы переменных, это C-стиль. Объявите ваши переменные непосредственно перед их использованием, и код будет легче читать.

...