打开CV内存堆叠(未正确释放)

时间:2017-02-17 08:48:37

标签: objective-c opencv uiimage

我正在使用第三方库进行图像处理,这种方法似乎是每次执行时大量内存使用(+ 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)

1 个答案:

答案 0 :(得分:0)

猜想这是一个很难的话题,因为没有多少人对OpenCV有足够的了解。我发现,针对类似问题的大多数答案都涉及将@autoreleasepool放置在使用此方法的位置。但是似乎也不释放内存。

作为临时解决方案,我将提供给此方法的图像调整为一半大小。至少应用会持续更长的时间,直到它最终崩溃。就是这样。