我正在使用第三方库进行图像处理,这种方法似乎是每次执行时大量内存使用(+ 30MB)的原因,并且无法正常释放。反复使用它会导致应用程序崩溃(内存过载)。使用的图像直接来自我的iP6的相机。
+ (UIImage *)UIImageFromCVMat:(cv::Mat)cvMat
{
NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize() * cvMat.total()];
CGColorSpaceRef colorSpace;
if (cvMat.elemSize() == 1) {
colorSpace = CGColorSpaceCreateDeviceGray();
} else {
colorSpace = CGColorSpaceCreateDeviceRGB();
}
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
CGImageRef imageRef = CGImageCreate(cvMat.cols, // Width
cvMat.rows, // Height
8, // Bits per component
8 * cvMat.elemSize(), // Bits per pixel
cvMat.step[0], // Bytes per row
colorSpace, // Colorspace
kCGImageAlphaNone | kCGBitmapByteOrderDefault, // Bitmap info flags
provider, // CGDataProviderRef
NULL, // Decode
false, // Should interpolate
kCGRenderingIntentDefault); // Intent
// UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
UIImage *image = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return image;
}
我怀疑问题出在这里:(__bridge CFDataRef)data
。我不能使用CFRelease导致它崩溃。项目正在运行ARC。
修改
看来同样的代码也在openCV官方网站上: http://docs.opencv.org/2.4/doc/tutorials/ios/image_manipulation/image_manipulation.html
尔加!
编辑2 以下是我如何使用它的代码(实际上下面的代码也是第三方库的一部分,但我添加了一些行)。
cv::Mat undistorted = cv::Mat( cvSize(maxWidth,maxHeight), CV_8UC4); // here nothing
cv::Mat original = [MMOpenCVHelper cvMatFromUIImage:_adjustedImage]; // here +30MB
//NSLog(@"%f %f %f %f",ptBottomLeft.x,ptBottomRight.x,ptTopRight.x,ptTopLeft.x);
cv::warpPerspective(original, undistorted,
cv::getPerspectiveTransform(src, dst), cvSize(maxWidth, maxHeight)); // here +16MB
_cropRect.hidden=YES;
@autoreleasepool {
_sourceImageView.image=[MMOpenCVHelper UIImageFromCVMat:undistorted]; // here +15MB (PROBLEM)
}
original.release(); // here -30MB (THIS IS OK)
undistorted.release(); // here -16MB (ok)
答案 0 :(得分:0)
猜想这是一个很难的话题,因为没有多少人对OpenCV有足够的了解。我发现,针对类似问题的大多数答案都涉及将@autoreleasepool放置在使用此方法的位置。但是似乎也不释放内存。
作为临时解决方案,我将提供给此方法的图像调整为一半大小。至少应用会持续更长的时间,直到它最终崩溃。就是这样。