[英]OpenCV insufficient memory
我在Visual C ++ 2008和OpenCV 2.1上运行以下代码。 它会工作一段时间(例如3分钟),然后中止并显示错误消息
“未知函数中的内存不足(无法分配92610字节),文件......... \\ ocv \\ opencv \\ src \\ cxcore \\ cxalloc.cpp,第52行”
某处一定有内存泄漏(可能是图像创建),但是我似乎无法掌握它。
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <iostream>
#include <math.h>
using namespace std;
void main()
{
int i, j;
int **arr = new int*[480], blob[6][8]={0};
int max, maxi=-10, maxj=-10, div=80;
int xmax=480, ymax=640;
int frameH, frameW, fps, numFrames;
double hue, sat, lum;
int maxcolor, mincolor, maxcolval, mincolval;
char key='a';
CvScalar pix, destpix, destpix2, destpix3;
IplImage *img, *dest, *hsv;
for(i=0; i<480; i++)
arr[i] = new int[640];
CvCapture *capture = cvCaptureFromCAM(0);
if(!capture)
{
cout<<"Cannot read video!!!!";
exit(0);
}
frameH = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
frameW = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
fps = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
numFrames = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
printf("Width=%d Height=%d FPS=%d Count=%d\n", frameH, frameW, fps, numFrames);
cvNamedWindow("win1", CV_WINDOW_AUTOSIZE);
cvMoveWindow("win1", 10, 10);
cvNamedWindow("win2", CV_WINDOW_AUTOSIZE);
cvMoveWindow("win2", 600, 300);
destpix.val[0]=0;
destpix.val[1]=255;
destpix.val[2]=0;
destpix2.val[0]=0;
destpix2.val[1]=0;
destpix2.val[2]=0;
destpix3.val[0]=255;
destpix3.val[1]=255;
destpix3.val[2]=255;
while(key != 'q')
{
max=0;
maxi=-10;
maxj=-10;
img = cvQueryFrame(capture);
if(img == 0)break;
dest = cvCloneImage(img);
hsv = cvCloneImage(img);
cvCvtColor(img, hsv, CV_BGR2HSV);
for(i=0; i<xmax; i++)
for(j=0; j<ymax; j++)
{
arr[i][j]=0;
blob[i/div][j/div]=0;
}
cout<<endl<<cvGet2D(hsv, 5, 5).val[0];
//Looping through each pixel
for(i=0; i<xmax; i++)
{
for(j=0; j<ymax; j++)
{
//Getting the current pixel (i, j)
pix = cvGet2D(hsv, i, j);
//Setting all pixels to black
cvSet2D(dest, i, j, destpix2);
hue = pix.val[0];
sat = pix.val[1];
lum = pix.val[2];
//Looking for color red
if((hue<5 || hue>177) && sat>120 && lum>60)
{
arr[i][j] = 1;
cvSet2D(dest, i, j, destpix);
}
/*//Looking for color green
if((hue>90 && hue<100) && sat>120 && lum>60)
{
arr[i][j] = 1;
cvSet2D(dest, i, j, destpix);
}*/
/*//Looking for color blue
if((hue>100 && hue<110) && sat>120 && lum>60)
{
arr[i][j] = 1;
cvSet2D(dest, i, j, destpix);
}*/
/*//Looking for color yellow
if((hue>30 && hue<40) && sat>120 && lum>60)
{
arr[i][j] = 1;
cvSet2D(dest, i, j, destpix);
}*/
}
}
//Counting the blobs in each grid
for(i=0; i<xmax; i++)
{
for(j=0; j<ymax; j++)
{
if(arr[i][j])
{
blob[i/div][j/div]++;
}
}
}
//Finding the grid with the largest blob
for(i=0; i<xmax/div; i++)
for(j=0; j<ymax/div; j++)
if(blob[i][j]>max)
{
max=blob[i][j];
maxi=i;
maxj=j;
}
if(max>200)
{
//Borders
for(i=maxi*div; i<maxi*div+2; i++)
for(j=maxj*div; j<maxj*div+div; j++)
cvSet2D(dest, i, j, destpix3);
for(i=maxi*div+div-2; i<maxi*div+div; i++)
for(j=maxj*div; j<maxj*div+div; j++)
cvSet2D(dest, i, j, destpix3);
for(i=maxi*div; i<maxi*div+div; i++)
for(j=maxj*div; j<maxj*div+2; j++)
cvSet2D(dest, i, j, destpix3);
for(i=maxi*div; i<maxi*div+div; i++)
for(j=maxj*div+div-2; j<maxj*div+div; j++)
cvSet2D(dest, i, j, destpix3);
//Center
for(i=maxi*div+(div/2)-5; i<maxi*div+(div/2)+5; i++)
for(j=maxj*div+(div/2)-5; j<maxj*div+(div/2)+5; j++)
cvSet2D(dest, i, j, destpix3);
}
//Creating Windows
//cvCvtColor(fin, dest, CV_HSV2BGR);
key = cvWaitKey(20);
cvShowImage("win1", dest);
cvShowImage("win2", img);
}
cvWaitKey(0);
cvReleaseCapture(&capture);
cvReleaseImage(&dest);
cvDestroyWindow("win1");
cvDestroyWindow("win2");
}
“内存不足”实际上意味着“尝试分配内存时出现错误”。
您很有可能实际上已经损坏了某处的某些内容,而不是实际上耗尽了内存,尤其是使用这种类型的代码时。
CloneImage的文档说:
制作图像的完整副本
IplImage * cvCloneImage(const IplImage * image);
图像原始图像。
函数cvCloneImage制作图像的完整副本,包括标题,ROI和数据
您将在每个循环中创建一个深层副本,并使用相同的指针进行保存。 每个循环都会释放previos分配的内存,而不会释放内存。
编辑
此功能可以帮助您:
发行图片
释放标题和图像数据
void cvReleaseImage(IplImage ** image);
image双重指针,指向已释放图像的标题。
函数cvReleaseImage释放标题和图像数据。 此呼叫是的缩写形式
if( *image ) { cvReleaseData( *image ); cvReleaseImageHeader( image ); }
尝试在while循环结束时释放内存。
旧帖子,但是肯定这个问题最近让我头疼...
我完全有同样的问题,我只是在使用普通绘图功能。 您在这里基本上是想在每次迭代中复制一个图像。 当前情况是:
dest = cvCloneImage(img)
将分配内存,将整个图像克隆到其中,然后将指针返回到该新内存,这样您将丢失dest
之前的指针值。 因此,如果那时您还没有使用cvReleaseImage(img)
释放内存,则会发生内存泄漏。
必须有一种更简单的方法,实际上是:
/* Copies source array to destination array */
CVAPI(void) cvCopy( const CvArr* src, CvArr* dst,
const CvArr* mask CV_DEFAULT(NULL) );
所以你只需要使用cvCopy(img, dest);
目标中的内容将被覆盖=>没有内存泄漏
IplImage * img,* dest,* hsv;
在将它们分配给新值之前,请查看文档并查看是否有责任释放上述指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.