Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reduce memory consumed by method that uses OpenCv on iOS

I am using OpenCV on iOS to do some image processing on a UIImage.

The method processImage is consuming too much memory. When I profile the App with allocations in Instruments. The Live Bytes peaks at 65MB to 70MB for about a second. This causes the application to crash.

It used to be higher i.e. ~90MB, changing int ddepth reduced this ( from CV_16S to CV_8U). While I do understand that reducing the 'desired depth of the destination image' may reduce the memory consumed, I do not understand it's inner workings to pick the best format.

The reduction in ddepth also seems to increase the execution time of the method.

I wish to greatly reduce the Live Bytes peak and reduce the execution time of the method as well .

Any insights in how to achieve this would be greatly appreciated.

- (void)processImage:(UIImage *)imageToProcess
{
cv::Mat imageMatrix;

double  sigmaX = 1.0;

int ddepth = CV_8U; //  ddepth – The desired depth of the destination image

cv::GaussianBlur( [self cvMatFromUIImage:imageToProcess], imageMatrix, cv::Size(3,3), sigmaX);

cv::Laplacian(imageMatrix, imageMatrix, ddepth, 1);

double minVal;
double maxVal;

cv::minMaxLoc(imageMatrix, &minVal, &maxVal);

std::cout << "min val : " << minVal << std::endl;
std::cout << "max val: " << maxVal << std::endl;

}

Edit Note : I am using cvMatFromUIImage from docs.opencv.org

Edit Update : I accepted @sansuiso 's answer as it reduced the Live Bytes by ~3MB. However, I am still looking for further reduction, any suggestions would be greatly appreciated. Thanks.

like image 568
Ríomhaire Avatar asked Apr 15 '13 13:04

Ríomhaire


2 Answers

The function cv::GaussianBlur can process an image in-place. You can assign the output of [self cvMatFromUIImage:imageToProcess] to your variable imageMatrix, which will avoid an extra image creation and reduce the peak value, i.e., proceed with:

cv::Mat imageMatrix = `[self cvMatFromUIImage:imageToProcess];
cv::GaussianBlur(imageMatrix, imageMatrix, cv::Size(3,3), sigmax);

You may also want to check the content of the cvMatFromUIImage method to ensure that everything is released correctly inside.

like image 71
sansuiso Avatar answered Nov 11 '22 03:11

sansuiso


It's either memory leak in the [self cvMatFromUIImage:] or often memory allocation problem.

To be sure there is no memory leak please show us cvMatFromUIImage listing.

Memory allocation

Try moving all your temporary images to class members. This eliminate unnecessary memory allocations and your code will be reusing allocated memory on each frame. No memory manager likes when user code does constant memory allocations of huge amounts of memory and frees it. You should try to avoid it because it cause spikes in memory consumptions and crashes because memory manager can hold a free memory in use for some time (after you deallocate cv::Mat).

like image 25
BloodAxe Avatar answered Nov 11 '22 02:11

BloodAxe