mat 释放_cv :: Mat内存即使在调用release()后也不会释放?

在计算图像描述符如SIFT或VLFeat Dense SIFT后,作者发现即使调用了cv::Mat的release()方法,内存并未如预期释放。问题主要出现在VLFeat Dense SIFT的实现中,内存增长迅速。代码展示了如何计算和采样描述符,以及可能的内存泄漏原因。

我写了一个方法,其中图像描述符(如OpenCV SIFT或VLFeat Dense SI FT)计算一组图像的描述符(保存在std::vector<:string> files中)。通过ComputeDescriptors(image, descriptorMatrix)调用描述符,其中它填充descriptorMatrix,其描述符计算自。cv :: Mat内存即使在调用release()后也不会释放?

然后我随机选择samples(通常为50)描述符,并在返回的std::vector<:mat1f> descriptors中推送sampledDescriptors矩阵。

这是代码:

void SIFTDescriptor::ComputeDescriptorsRange(const std::vector<:string> &files, std::vector<:mat1f> &descriptors){

cv::Mat1f imgDescriptors;

cv::Mat img;

for(int i=0 ; i

std::cout<

img = cv::imread(files[i], cv::IMREAD_GRAYSCALE);

if(!img.data)

//throw error

//resoze dim is a class member

if(resizeDim>0)

ImgUtility::resize(img,resizeDim);

ComputeDescriptors(img,imgDescriptors);

if(samples > 0 && samples < imgDescriptors.rows){

std::cout<

cv::Mat1f sampledDescripotrs;

std::vector v(imgDescriptors.rows);

std::iota (std::begin(v), std::end(v), 0); //fill v with 0 ... imgDescriptors.rows

std::random_device rd;

std::mt19937 g(rd());

std::shuffle(v.begin(), v.end(), g);

for(int j=0 ; j

sampledDescripotrs.push_back(imgDescriptors.row(v[j]));

}

descriptors.push_back(sampledDescripotrs);

sampledDescripotrs.release();

}

else

descriptors.push_back(imgDescriptors); //copy of a smart pointer, not expensive

imgDescriptors.release();

std::cout<

std::cout<

}

这样做是为了可有效存储器,尤其是对密集的描述符,如VLFeat Dense SIFT成千上万描述符被提取。有了成千上万的图像,我们很快就会耗尽内存。相反,使用这种解决方案,我们每个图像只保留50个描述符(这对我的训练来说足够了)。

但是,出于某种奇怪的原因,使用OpenCV SIFT没有大的内存使用情况,但使用VLFeat Dense SIFT,内存增长得相当快,即使在两种情况下samples都是相等的!

我的唯一解释是,在每个回路中使用由imgDescriptors存储器不释放,即使使用imgDescriptors(这应该是没有必要的反正因为cv::Mat1f应该是有点智能指针等在循环结束时解除分配本身) ,但我不明白这可能如何。

这是VLFeat密集过筛ComputeDescriptor代码:

void DSIFTVLFeat::ComputeDescriptors(cv::Mat &img, cv::Mat1f &descriptors){

descriptors.release();

// transform image in cv::Mat to float vector

cv::Mat imgFloat;

img.convertTo(imgFloat, CV_32F, 1.0/255.0);

if(!imgFloat.isContinuous())

throw std::runtime_error("imgFloat is not continous");

for(int i=binSize; i<=maxBinSize; i+=2){

VlDsiftFilter *dsift = vl_dsift_new_basic (img.rows, img.cols, step, i);

vl_dsift_process (dsift, imgFloat.ptr());

cv::Mat scaleDescs(vl_dsift_get_keypoint_num(dsift), 128, CV_32F, (void*) vl_dsift_get_descriptors(dsift));

descriptors.push_back(scaleDescs);

scaleDescs.release();

free(dsift);

}

}

来源

2017-01-22

justHelloWorld

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值