2010-03-10 2 views
2

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

c = cvWaitKey (33); if (c == 27) break; Как только мы отобразили фрейм, мы ожидаем 33 мс. Если пользователь нажимает клавишу, то c будет установлено значение ASCII этого ключа; если нет, то он будет установлен в -1. Если пользователь нажимает ключ Esc (ASCII 27), мы выйдем из цикла чтения. В противном случае пройдет 33 мс, и мы просто выполним цикл снова. Стоит отметить, что в этом простом примере мы явно не контролируем скорость видео в любом разумном ключе. Мы полагаемся исключительно на таймер в 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(); 

} 

ответ

1

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

1

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

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

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

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

+1

Я должен идти, но все, что вам нужно искать. Избегайте постоянного динамического выделения, попробуйте переместить его за пределы цикла. – GManNickG

+0

Не могли бы вы рассказать? Вы просто имеете в виду, что версия OpenMP менее глючна или что-то в этом роде? Я origianlly пытался использовать 2.0 (из sourceforge), но я никогда не смог правильно его связать в Visual Studio 2008. В итоге я использовал более старую версию, используемую моей книгой (версия 1.1, ранее на sourceforge). Я также попытаюсь улучшить свой стиль, как вы сказали, я новичок в C++ (и все программирование в этом отношении), поэтому я уверен, что мой «стиль» будет развиваться со временем :) – ubiquibacon

+0

OpenMP - это многопоточное расширение. С его поддержкой производительность OpenCV может резко возрасти. – GManNickG