Actually, I'm encountering this problem:
OpenCV Error: Insufficient memory (Failed to allocate 225792004 bytes) in OutOfMemoryError, file /build/buildd/opencv-2.4.8+dfsg1/modules/core/src/alloc.cpp, line 52
terminate called after throwing an instance of 'cv::Exception'
what(): /build/buildd/opencv-2.4.8+dfsg1/modules/core/src/alloc.cpp:52: error: (-4) Failed to allocate 225792004 bytes in function OutOfMemoryError
when I call the following method from the main
.. I'm working with 36 images in listOfImages
void MainHelper::startProcessingDataSampleForROCCurve(bool downSampleData)
{
/*Step 5: Load test data*/
vector <Mat> imagesToTest;
///Looping over the segmented to validate the method we did
Diagnostics diagnoLearningAndTesting;
WindowsDataSet windowsDataSetInstance;
map <int , vector < double > > areaCalculatedPerImageForEachK;
for (int indexImage = 0; indexImage < listOfImages.size(); indexImage++)
{
Mat imageTestForIteration = listOfImages[indexImage];
imagesToTest.push_back(imageTestForIteration);
Mat imageTestBinaryForIteration = listOfBinaryImages[indexImage];
//Prepare the learning image list by removing only the image for testing
vector<Mat> listOfLearningImages(listOfImages.begin(),listOfImages.end());
listOfLearningImages.erase(listOfLearningImages.begin() + indexImage);
vector<Mat> listOfBinaryLearningImages(listOfBinaryImages.begin(),listOfBinaryImages.end());
listOfBinaryLearningImages.erase(listOfBinaryLearningImages.begin() + indexImage);
/*Step 7: Processing the images by having a vector of descriptor for every window in the image*/
ImageProcessingManager imageManager;
map <int , vector< vector<double> > > dictWindowPerFeaturesPerTile;
// map <int , vector< vector<Mat> > > dictTilesPerLearningImage;
map <int , vector< int > > dictAnnotationPerTile;
diagnoLearningAndTesting.startMethod(StringUtils::stringFormat("Learning Part.. %d",(indexImage + 1)));
for (int indexWindowLength = 0; indexWindowLength < Constants::windowsSize.size(); indexWindowLength ++)
{
int windowLength = Constants::windowsSize[indexWindowLength];
vector < int > annotationPerTile;
//TODO: It won't be filled for now for memory reasons
vector < vector <Mat> > tilesPerLearningImage;
vector < vector <double> > featuresPerTile = imageManager.processImagesInWindowsWithFeatures(listOfLearningImages, listOfBinaryLearningImages, tilesPerLearningImage, annotationPerTile, windowLength, Constants::percentageOfWhiteToConsiderIntrumentWindow);
dictWindowPerFeaturesPerTile[windowLength] = featuresPerTile;
// dictTilesPerLearningImage[windowLength] = tilesPerLearningImage;
dictAnnotationPerTile[windowLength] = annotationPerTile;
}
diagnoLearningAndTesting.endMethod();
MemoryUtils::displayMemoryUsage();
diagnoLearningAndTesting.startMethod(StringUtils::stringFormat("Testing Part.. %d",(indexImage + 1)));
//TODO: Change the value of the param here..
for (int kNearestNeighbor = 2; kNearestNeighbor <= Constants::kNearestNeighbor; kNearestNeighbor ++)
{
Diagnostics::LogWithTime(StringUtils::stringFormat("*** Running annotations with K = %d", kNearestNeighbor));
if (Constants::hierarchyWindowLevel == Multiple)
{
for (int indexOfImage = 0; indexOfImage < imagesToTest.size(); indexOfImage ++)
{
Mat image = imagesToTest[indexOfImage];
vector <Mat> testImagesInVect = boost::assign::list_of(image);
Mat binaryResultOfImageTest(image.rows, image.cols, CV_8UC1, Scalar(0.));
vector <Mat> binaryTestImagesInVect = boost::assign::list_of(binaryResultOfImageTest);
for (int indexWindowLength = 0; indexWindowLength < Constants::windowsSize.size(); indexWindowLength ++)
{
int windowLength = Constants::windowsSize[indexWindowLength];
Diagnostics::LogWithTime(StringUtils::stringFormat("Running annotations with windowLength = %d", windowLength));
/*Step 7-1: Learning vectors already loaded */
vector < int > annotationPerTile = dictAnnotationPerTile[windowLength];
// vector < vector <Mat> > tilesPerLearningImage = dictTilesPerLearningImage[windowLength];
vector < vector <double> > featuresPerTile = dictWindowPerFeaturesPerTile[windowLength];
/*Step 8: Processing the samples on which we need to make our tests by having a vector of descriptor for every window in the image*/
//TODO: GET THE BINARY VERSION OF THE IMAGES******
vector< vector <int> > annotationPerImageForTiles;
vector < vector <Mat> > tilesPerTestImage;
vector < vector < vector <double> > > featuresPerTiles = imageManager.processSetOfImages(testImagesInVect, vector<Mat>(), tilesPerTestImage, windowLength, Constants::percentageOfWhiteToConsiderIntrumentWindow, annotationPerImageForTiles);
vector < vector <Mat> > binaryTiles = imageManager.divideBinaryImagesInTiles(binaryTestImagesInVect, windowLength);
/*Step 9: Knn Classifier train data */
Mat trainData = VectorUtility <double>::toMat(featuresPerTile);
Mat dataClasses = VectorUtility <int>::toMat(annotationPerTile);
ClassifierManager classifier(trainData, dataClasses, kNearestNeighbor);
/*Step 10: Annotation Step*/
vector < vector <int> > resultsForEachTilePerImage = classifier.annotateTheTilesInImages(featuresPerTiles);
/*Step 10-1: Annotation Step with window hierarchy: Extract tiles which have probability > 0*/
vector <Mat> instrumentTiles;
vector <Mat> instrumentBinaryTiles;
for (int resultIndex = 0; resultIndex < resultsForEachTilePerImage.size(); resultIndex ++)
{
vector <int> resultsForTilePerImage = resultsForEachTilePerImage[resultIndex];
vector <Mat> tilesPerImage = tilesPerTestImage[resultIndex];
vector <Mat> tilesPerBinaryImage = binaryTiles[resultIndex];
for (int resultIndex = 0; resultIndex < resultsForTilePerImage.size(); resultIndex ++)
{
int result = resultsForTilePerImage[resultIndex];
if (result > 0)
{
Mat tile = tilesPerImage[resultIndex];
instrumentTiles.push_back(tile);
Mat binaryTile = tilesPerBinaryImage[resultIndex];
instrumentBinaryTiles.push_back(binaryTile);
if (indexWindowLength == Constants::windowsSize.size() - 1)
{
int valueOfPixel = (result * 255) / 100;
//This region should be set to valueOfPixel..
binaryTile.setTo(valueOfPixel);
}
}
}
}
testImagesInVect = instrumentTiles;
binaryTestImagesInVect = instrumentBinaryTiles;
//Release objects for memory reasons..
resultsForEachTilePerImage.clear();
tilesPerTestImage.clear();binaryTiles.clear();
trainData.release();dataClasses.release();
featuresPerTiles.clear();
}
/*Step 11: Draw images with the regions of interest we want*/
string imagePrefix = StringUtils::stringFormat("%sM-ImageResult%d-k%d-WL", Constants::pathOfResultImages.c_str(), indexImage,kNearestNeighbor);
for (int indexWindowLength = 0; indexWindowLength < Constants::windowsSize.size(); indexWindowLength ++)
{
imagePrefix = StringUtils::concat(imagePrefix, numberToString(Constants::windowsSize[indexWindowLength]));
}
string imageName = StringUtils::stringFormat("%s.png", imagePrefix.c_str());
imwrite(imageName, binaryResultOfImageTest);
if (Constants::generateROCCurve)
{
/*Step 12: Validation steps by showing the percentage of accuracy of this method (ROC courbe)*/
double areaOfAZ = windowsDataSetInstance.ROCCurveFor(imageTestBinaryForIteration, binaryResultOfImageTest, image, Constants::pathOfResultImages, StringUtils::stringFormat("%d-k%d.txt",indexImage, kNearestNeighbor), kNearestNeighbor);
vector <double> listOfAreasCalculated = areaCalculatedPerImageForEachK[kNearestNeighbor];
listOfAreasCalculated.push_back(areaOfAZ);
areaCalculatedPerImageForEachK[kNearestNeighbor] = listOfAreasCalculated;
}
}
}
}
//Clear Objects for memory reasons
dictAnnotationPerTile.clear();dictWindowPerFeaturesPerTile.clear();
listOfLearningImages.clear();listOfBinaryLearningImages.clear();
diagnoLearningAndTesting.endMethod();
//Clear all elements of imagesToTest
imagesToTest.clear();
MemoryUtils::displayMemoryUsage();
}
//Step #12: Additional step to display the mean and standard variation of the list of Areas calculated for each value of K
for (std::map<int, vector <double> >::iterator it = areaCalculatedPerImageForEachK.begin(); it != areaCalculatedPerImageForEachK.end(); ++it)
{
vector < double> areas = it->second;
double mean = VectorUtility<double>::mean(areas);
double std = VectorUtility<double>::standardDeviation(areas, mean);
Diagnostics::LogWithTime(StringUtils::stringFormat("******* For K = %d : Mean(Az) = %f, Std(Az) = %f",it->first, mean, std));
}
}
I don't think we should go through the details of each method called here because what I'm looking for is a way to free up the memory at the end of each iteration of the first for
which means free up the vectors
/maps
allocated and their objects. I could not find any solution to do so, so my question: Do you have any idea on how to do it? Also, am I on the right track or I should go through to the details to find where exactly the problem is?