2010-03-10 6 views
2

저는 OpenCV가있는 학교 프로젝트에 참여하고 있습니다. 이 프로그램의 주요 부분은 히스토그램 비교입니다. 히스토그램 데이터베이스가 생기고 라이브 비디오 피드에서 새 히스토그램을 만들고 데이터베이스의 히스토그램과 비교합니다. 지금은 비디오 피드에서 올바르게 생성 된 히스토그램을 얻으려고합니다. 제 문제는 프로그램이 비정상적으로 충돌하거나 속도가 크게 느려지는 것입니다. 그래서 내 질문은 어떻게 충돌이나 속도 저하에서 프로그램을 방지 할 수 있습니까? OpenCV는 항상 저에게 희한종 이었기 때문에 제 코드에 문제가 있는지 또는 OpenCV의 본질인지 확실하지 않습니다. 내 코드와 관련이 있다면이 문제는 프레임 속도 (추측/내장 느낌)와 관련이 있다고 생각합니다. "cvWaitKey"를 사용하여 프레임의 로딩 속도를 조정하지만 "Learning OpenCV"책에서 "cvWaitKey"에 대해 말할 내용이 있습니다.OpenCV 프레임 속도 문제

c = cvWaitKey (33); if (c == 27) break; 프레임이 표시되면 33ms를 기다립니다. 사용자가 키를 누르는 경우 c 은 해당 키의 ASCII 값으로 설정됩니다. 그렇지 않은 경우 -1로 설정됩니다. 사용자가 Esc 키 (ASCII 27)를 누르면 읽기 루프가 종료됩니다. 그렇지 않으면 33ms가 지나고 루프가 다시 실행됩니다. 이 간단한 예에서 지능적인 방식으로 비디오의 속도를 명시 적으로 제어하지는 않습니다. cvWaitKey()의 타이머 만 사용하여 프레임로드 속도를 조절합니다. 보다 정교한 응용 프로그램에서이 합니다 (AVI에서)을 CvCapture 구조의 실제 프레임 속도를 읽고 따라 행동하는 것이 현명 할 것입니다!

내 루프에서 다음 실행을 시작하기 전에 10ms를 기다리는 루프가 표시됩니다 (here에서 수정 됨). 종종 프로그램이 아무런 문제없이 실행되지만, 때로는 1 분 안에 5 분 이내에 충돌 할 수 있습니다. 실제로는 발견 할 수있는 패턴이 없습니다. 이 충돌 (또는 속도 저하)을 방지 할 수있는 방법에 대한 제안은 환영받을 것입니다. 내가 할, 즉, 또한 나는 내가 (지금 바로 작업을 OpenCV 2.0을 얻을 수 없다)을 OpenCV 1.1을 사용하고, 나는 비주얼 스튜디오 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는 PS3 Eye를 항상 좋아하지 않습니다. 때로는 위대하지 않고 다른 때는 훌륭하게 작동합니다. 저는 세 대의 컴퓨터에서 이것을 검증했습니다.이 모든 것은 표준 웹캠으로 코드를 실행하지만 PS3 아이를 사용할 때 무작위로 고정됩니다. 그래도 GMan 제안에 감사드립니다!

1

만 몇 가지 내가 볼 또는 추천 :

빌드를 고려하면, 당신이 릴리스에서 구축하고 있는지 확인하십시오. 또한 사용중인 OpenCV 빌드가 OpenMP를 사용하여 빌드되었는지 확인하십시오. 이는 큰 차이를 만듭니다.

루프 외부에서 할당을 옮겨보십시오. gray 및 기타 이미지를 다시 작성해야하는 모든 루프는 재사용해야합니다.

다른 것은

어려운 쉽게 좋은 권장 사항을 제공 할 수 있습니다 당신의 스타일입니다. 변수를 미리 선언하는 것은 좋지 않습니다. C 스타일입니다. 사용하기 직전에 변수를 선언하면 코드를 더 쉽게 읽을 수 있습니다.

+1

나는 지금 당장 가야하지만, 그런 것들을 찾아야 만한다. 끊임없이 동적 인 할당을 피하고 루프 외부로 이동하십시오. – GManNickG

+0

자세히 설명해 주시겠습니까? OpenMP 버전이 덜 버그가있는 것 같은 의미입니까? origianlly 2.0 (sourceforge에서) 사용하려고했지만 Visual Studio 2008에서 올바르게 링크 할 수 없었습니다. 이전 버전의 내 책 (sourceforge 버전 1.1)을 사용하여 끝났습니다. 나는 내 스타일을 향상 시키려고 노력할 것이다. C++과 그 모든 프로그래밍에 익숙하지 않다. 그래서 내 "스타일"이 시간이 흐를 것이라고 확신한다. – ubiquibacon

+0

OpenMP는 멀티 스레딩 확장이다. 이 기능을 사용하면 OpenCV의 성능이 크게 향상 될 수 있습니다. – GManNickG