您的位置:首页 > 运维架构

OpenCV Error: Insufficient memory

2017-08-01 10:26 148 查看
在使用OpenCV从视频预处理人脸训练数据时,在正常运行一段时间后,程序报错 。



上述错误是典型的内存溢出错误,肯定是程序中存在使用后的指针没有释放,检查后发现使用是使用的IplImage* srcCopy参数在函数结束(或者已经不用了)的地方没有释放,只需要在相应的位置使用cvReleaseImage(&srcCopy)释放掉就可以。其他情况可类似排查,实例代码如下:

// 截取人脸,并保存
void CropFaceAndSave(const Mat& imgInput, bool isRight, const string& filename){

IplImage* src = &IplImage(imgInput);
IplImage* srcCopy;

int ratio = 3; // imgorl/imgdeal = 3 将图像缩小3倍处理

if (isRight)
{
srcCopy = cvCreateImage(cvSize(src->height, src->width), src->depth, src->nChannels);
cvTranspose(src, srcCopy);
cvFlip(srcCopy, NULL, 0);
}
else{
srcCopy = cvCreateImage(cvSize(src->width, src->height), src->depth, src->nChannels);
cvCopy(src, srcCopy, 0);
}

Mat imgOriginal(srcCopy), imgResult;

resize(imgOriginal, imgResult, Size(srcCopy->width / ratio, srcCopy->height / ratio));

// 对imgcopy检测人脸
Mat face_gray;

cvtColor(imgResult, face_gray, CV_BGR2GRAY);  //rgb类型转换为灰度类型
equalizeHist(face_gray, face_gray);   //直方图均衡化

face_cascade.detectMultiScale(face_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));

for (int i = 0; i < faces.size(); i++){

// 起始点
Point pointStart(faces[i].x, faces[i].y);
Point pointEnd(faces[i].x + faces[i].width, faces[i].y + faces[i].height);
Point center(int(faces[i].x + faces[i].width*0.5), int(faces[i].y + faces[i].height*0.5));

rectangle(imgResult, pointStart, pointEnd, Scalar(255, 0, 0), 2, 8, 0);

// 阈值选取,滤除小的干扰
if (ratio*faces[i].width < srcCopy->width / 3){
//cout << "滤除 x = " << ratio*faces[i].x << ", y = " << ratio*faces[i].y << endl;
continue;
}

// 计算原图上的截取区域,并截取
Point centerInOrignal(ratio*center.x, ratio*center.y);
// cout << "x = " << centerInOrignal.x << ", y = " << centerInOrignal.y << endl;

// 可以剪裁
if (centerInOrignal.y >= 360){

if (centerInOrignal.y > 720){
centerInOrignal.y = 720;
}

// 新建ROI大小的图片
cvSetImageROI(srcCopy, cvRect(0, centerInOrignal.y - 360, srcCopy->width, srcCopy->width));
IplImage* imgCrop = cvCreateImage(cvSize(srcCopy->width, srcCopy->width), srcCopy->depth, srcCopy->nChannels);
cvCopy(srcCopy, imgCrop, 0);
cvResetImageROI(srcCopy);

Mat imgCropResult(imgCrop);
imshow("Crop ROI", imgCropResult);

stringstream ss;
string indexStr;
ss << saveIndex;
ss >> indexStr;

imwrite(filename + "\\real" + indexStr + ".png", imgCropResult);

cvReleaseImage(&imgCrop); // 不用的指针一定要释放掉,不然内存会泄露
saveIndex++;
}

}

imshow("检测人脸", imgResult);
// 注意,这个指针不用释放,他不是我们新建出来的,只是指向了现有内存空间,而那块空间在栈中,系统会自动释放
//cvReleaseImage(&src);
// 只需要释放我们申请的内存
cvReleaseImage(&srcCopy);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: