2011-11-24 33 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