2011-11-24 57 views
2

我最近在OpenCV中做了一些循環檢測,並取得了一些成功。下面的代碼在32位平臺上用C++很好地工作。然而,我確實有一個小問題。隨着程序運行,我的RAM負載繼續加載。例如,當我啓動程序時,我在250MB,30秒後我在800MB左右。這繼續下去並最終溢出到硬盤。我試圖在while循環中移動cvReleaseCapture,但我只是得到舊的「內存位置的異常....」。任何想法如何我可以清理這件事?非常感謝。下面的代碼:Opencv Circle檢測 - RAM加載

#include "stdafx.h" 
#include <cv.h> 
#include <highgui.h> 
#include <math.h> 


int main(int argc, char **argv) 
{ 
    CvCapture *capture = 0; 
    IplImage *img = 0; 
    int  key = 0; 
CvFont font; 
cvInitFont(&font, CV_FONT_HERSHEY_PLAIN,1.0,1.0,0,1,CV_AA); 

capture = cvCaptureFromCAM(0); 

if (!capture) { 
    fprintf(stderr, "Cannot open initialize webcam!\n"); 
    return 1; 
} 

cvNamedWindow("result", CV_WINDOW_AUTOSIZE); 

while(key != 'q') { 
    img = cvQueryFrame(capture); 
    IplImage* gray = cvCreateImage(cvGetSize(img), 8, 1); 
    CvMemStorage* storage = cvCreateMemStorage(0); 
    cvCvtColor(img, gray, CV_BGR2GRAY); 
    cvSmooth(gray, gray, CV_GAUSSIAN, 9, 9); 
    CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 2, gray- >height/4, 200, 100, 20, 100); 
    int i; 
    for(i = 0; i < circles->total; i++) 
    { 
     float* p = (float*)cvGetSeqElem(circles, i); 
     //cvCircle(img, cvPoint(cvRound(p[0]),cvRound(p[1])), 2, CV_RGB(0,255,0), -1, 8, 0); 
     cvCircle(img, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(0,255,0), 2, 8, 0); 
     cvLine (img, cvPoint(cvRound(p[0]+40),cvRound(p[1])), cvPoint(cvRound(p[0]),cvRound(p[1])), CV_RGB(0,255,0), 1, CV_AA,0); 
     cvLine (img, cvPoint(cvRound(p[0]),cvRound(p[1]+40)), cvPoint(cvRound(p[0]),cvRound(p[1])), CV_RGB(0,255,0), 1, CV_AA,0); 
     cvLine (img, cvPoint(cvRound(p[0]-40),cvRound(p[1])), cvPoint(cvRound(p[0]),cvRound(p[1])), CV_RGB(0,255,0), 1, CV_AA,0); 
     cvLine (img, cvPoint(cvRound(p[0]),cvRound(p[1]-40)), cvPoint(cvRound(p[0]),cvRound(p[1])), CV_RGB(0,255,0), 1, CV_AA,0); 
     cvPutText(img, "Meow",cvPoint(cvRound(p[0]+45),cvRound(p[1]+45)), &font, CV_RGB(0,0,255)); 

    } 


    if(!img) break;  
    cvShowImage("result", img); 
    key = cvWaitKey(1); 
    cvReleaseCapture(&capture); 
} 

cvDestroyWindow("result"); 
cvReleaseCapture(&capture);  

return 0; 

}

回答

0

擺脫while循環中的cvReleaseCapture的。相反,你應該有

cvReleaseMemStorage(storage); 
cvReleaseImage(gray); 

而且你可能應該移動if (!img) break;排隊,所以它讀取:

img = cvQueryFrame(capture); 
if (!img) break; 

編輯

事實上,而不是不斷地創造,然後銷燬gray,你應該做一個初始捕獲(img = cvQueryFrame(capture);)外部eof while循環。然後以正常方式創建gray。然後,您不必在while循環中繼續創建它,這就是爲什麼內存不足(您每次迭代都會創建一個新圖像而不釋放它)。

所以

#include "stdafx.h" 
#include <cv.h> 
#include <highgui.h> 
#include <math.h> 


int main(int argc, char **argv) 
{ 
    CvCapture *capture = 0; 
    IplImage *img = 0; 
    int  key = 0; 
    CvFont font; 
    cvInitFont(&font, CV_FONT_HERSHEY_PLAIN,1.0,1.0,0,1,CV_AA); 

    capture = cvCaptureFromCAM(0); 

    if (!capture) { 
     fprintf(stderr, "Cannot open initialize webcam!\n"); 
     return 1; 
    } 

    cvNamedWindow("result", CV_WINDOW_AUTOSIZE); 

    img = cvQueryFrame(capture); 
    if (!img) 
     exit(1); 
    IplImage* gray = cvCreateImage(cvGetSize(img), 8, 1); 
    CvMemStorage* storage = cvCreateMemStorage(0); 

    while(key != 'q') { 
     img = cvQueryFrame(capture); 
     if(!img) break; 


     cvCvtColor(img, gray, CV_BGR2GRAY); 
     cvSmooth(gray, gray, CV_GAUSSIAN, 9, 9); 
     CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 2, gray-  >height/4, 200, 100, 20, 100); 
     int i; 
     for(i = 0; i < circles->total; i++) 
     { 
      float* p = (float*)cvGetSeqElem(circles, i); 
      //cvCircle(img, cvPoint(cvRound(p[0]),cvRound(p[1])), 2, CV_RGB(0,255,0), -1, 8, 0); 
      cvCircle(img, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(0,255,0), 2, 8, 0); 
      cvLine (img, cvPoint(cvRound(p[0]+40),cvRound(p[1])), cvPoint(cvRound(p[0]),cvRound(p[1])), CV_RGB(0,255,0), 1, CV_AA,0); 
      cvLine (img, cvPoint(cvRound(p[0]),cvRound(p[1]+40)), cvPoint(cvRound(p[0]),cvRound(p[1])), CV_RGB(0,255,0), 1, CV_AA,0); 
      cvLine (img, cvPoint(cvRound(p[0]-40),cvRound(p[1])), cvPoint(cvRound(p[0]),cvRound(p[1])), CV_RGB(0,255,0), 1, CV_AA,0); 
      cvLine (img, cvPoint(cvRound(p[0]),cvRound(p[1]-40)), cvPoint(cvRound(p[0]),cvRound(p[1])), CV_RGB(0,255,0), 1, CV_AA,0); 
      cvPutText(img, "Meow",cvPoint(cvRound(p[0]+45),cvRound(p[1]+45)), &font, CV_RGB(0,0,255)); 

     } 

     cvShowImage("result", img); 
     key = cvWaitKey(1); 

    } 
    cvReleaseMemStorage(storage); 
    cvReleaseImage(gray); 
    cvDestroyWindow("result"); 
    cvReleaseCapture(&capture);  

    return 0; 
} 
+0

完美。在此計劃一分鐘後,我的電腦非常感謝。 – Meozaa

+0

甜。你是新來的stackoverflow;下一步的行動是提高我的答案,並選擇它是正確的;) – Anthony