0

I am getting an out of memory exception, but am only using about .3GB of RAM. I know Visual Studio allocates 2GB of RAM for 32-bit machines, and I am running in 32-bit mode.

Here is how you can replicate it:

1) Install Emgu CV (can just use NuGet)

2) Use it in Visual Studio (I'm using 2013, not sure if that matters)

3) Add a button that executes this algorithm OnClick:

Note 1: "YourLargeFilename" should be larger than 9,000 by 7,000... too large for me to upload here

Note 2: Use any x, y, and width/height values as your template size (obviously they should be significantly smaller than the size of the source, and should be within the source's bounds)

public void OnClick() {
    CroppedBitmap cbmp = getCroppedImage(new Int32Rect(x, y, width, height));
    System.Drawing.Bitmap bitmap = BitmapSourceToBitmap((BitmapSource)cbmp));

    Image<Gray, byte> source = new Image<Gray, byte>("YourLargeFilename");
    Image<Gray, byte> template = new Image<Gray, byte>(bitmap);
    Image<Gray, float> result = source.MatchTemplate(template, TemplateMatchingType.CcoeffNormed);
}

public CroppedBitmap getCroppedImage(Int32Rect rectangle) {
    sourceBitmapImage = new BitmapImage(new Uri(ofd.FileName));
    return new CroppedBitmap((BitmapoSource)sourceBitmapImage, rectangle);
}

private System.Drawing.Bitmap BitmapSourceToBitmap(BitmapSource bitmapSource)
{
    System.Drawing.Bitmap bitmap;
    using (var outStream = new MemoryStream())
    {
        BitmapEncoder enc = new BmpBitmapEncoder();
        enc.Frames.Add(BitmapFrame.Create(bitmapSource));
        enc.Save(outStream);
        bitmap = new System.Drawing.Bitmap(outStream);
    }
    return bitmap;
}

The error message looks like this:

Exception of type 'System.OutOfMemoryException' was thrown. at Emgu.CV.Image2.AllocateData(Int32 rows, Int32 cols, Int32 numberOfChannels) at Emgu.CV.Image2..ctor(Int32 width, Int32 height) at Emgu.CV.Image2.MatchTemplate(Image2 template, TemplateMatchingType method)

What other information should I provide?

  • Try to split the load that you send to the external lib as it just can't cope. – XAMlMAX Aug 02 '17 at 15:01
  • 1
    You need to dispose the Bitmap - either explicitly by calling Dispose or put in in a using statement. Make sure all other objects are correctly disposed too. I have occasionally encountered problems when allocating large amounts of memory (& correctly disposing) in quick succession that are resolved by calling GC.Collect() either straight after the dispose or prior to the next memory allocation. NOTE you need to dispose the Bitmap in the OnClick method NOT the BitmapSourceToBitmap method. – PaulF Aug 02 '17 at 15:19
  • It's going to be a combination of factors. There are other things taking up the address space than the few variables you seem to be taking into account. I'd expect the .net runtime to take a sizable chunk, and so will other used libraries. Then you need to consider that `matchTemplate` needs *some* temporary space... actually a fair amount. There's [one step](https://github.com/opencv/opencv/blob/master/modules/imgproc/src/templmatch.cpp#L869) calling `cv::integral` which allocates 2 CV_64FC1 matrices of the size of your input. At image size of 9000x7000 that's almost 500 MiB each. ...cont – Dan Mašek Aug 02 '17 at 16:40
  • And address space fragmentation will do the rest, since you're probably already near the limit, if not past it. I'd say if you want to work with images of this size, switch to 64bit. If you can't for some serious technical reason, expect to have to be quite creative and sink a lot of time and effort into it. – Dan Mašek Aug 02 '17 at 16:42

0 Answers0