Foundation.CreateDynamicThresholdImage related memory leak

Hi there,
I’m using the Foundation.CreateDynamicThesholdImage to pre-process an image before being passed through to the FBlob function.

Previously, I was doing simple thresholding all worked well. Since implementing Foundation.CreateDynamicThresholdImage, I see leaking memory issues. Removing the call removes the leak.

I’ve attached a simplified overview of the function that uses this method, below (hopefully the formatting will not go awry!);

if (Cvb.Image.IsImage((Cvb.Image.IMG)RawImage)) {
   // 1. Create temporary Image to run through dynamic thresholding before passing to FBlob...
   Image.IMG _imageForThresholding = new Image.IMG((Image.IMG)RawImage);               
   Foundation.CreateDynamicThresholdImage(_imageForThresholding, _maskSize, _threshold, out 
   Image.IMG _imageForBlobDetection);
   Foundation.FBLOB blob = Foundation.FBlobCreate(_imageForBlobDetection, 0);
   // 2.  Look for blobs within a specific area (the ROI)...
   Foundation.FBlobSetArea(blob, 0, ROI.Left, ROI.Top, ROI.Right, ROI.Bottom);
   // 3.  Look for black blobs on a white field, and with a specific black/white threshold...
   Foundation.FBlobSetObjectFeature(blob, _threshold, 
   // 4. Run blob detection...

   ...doing something useful with the blobs found...

This method is call continuously so that we can track objects within a live stream.

The garbage collector does not seem to handle the disposing of any resource associated with calls to CreateDynamicThresholdImage.

Is there a requirement for me to call something similar to the ReleaseObj used for the blob object? I can’t seem to find anything that does this job.

Any help would be much appreciated.


Hi @Foster,

first I would propose using the new Stemmer.Cvb and Stemmer.Cvb.Foundation wrappers which are shipped since :cvb: 2019 (13.02.000):

BlobResult[] FindBlobs(Image rawImage, Rect aoi, int maskSize, int threshold)
  if (rawImage == null)
    throw new ArgumentNullException(nameof(rawImage));

  using (var aoiImage = rawImage.Map(aoi))
    using (var binarized = Threshold.Dynamic(aoiImage, maskSize, threshold))
      return Blob.SearchAll(binarized);

For this code to work you need:

using Stemmer.Cvb;
using Stemmer.Cvb.Foundation;

Addendum: And if you want to find black blobs instead of white ones replace SearchAll with:

return Blob.BinarizeAndSearchAll(binarized.Planes[0], 0, 128);

The key issue with both source codes is the life-time management of the Images/IMGs. With the new wrappers the Image can be properly garbage collected as it is a ‘proper’ .Net object, but you will run out of memory nevertheless if the calls to this method happen to frequently. Thus I managed the life-time of the temporaries via using.

In your source code you also need to release the _imageForBlobDetection temporary via Image.ReleaseObj(_imageForBlobDetection);. IMGs are essentially just IntPtrs which point to a native IImageVpa object. And for these you must manually call ReleaseObj as otherwise you leak memory.

Hi @parsd,
Many thanks for your (very) quick response and snippet. I’m currently using 13.01.000 so will update to the suggested version to look at your suggested approach.

Best regards,

Hi @parsd,
Could you advise on where to access the download version 13.02.000? The website only appears to offer CVB 2018 v13.01.006.

Thanks in advance,

Sure, also here on the forum :wink::

Ah- missed that :slight_smile:


You are welcome. The forum is the place where you get the most up-to-date information about :cvb:. But I cannot promise that we are always able to answer that fast :smile:

Questions and feedback are always welcome :+1:

It’s a useful facility - and I don’t expect such a quick response all of the time :slight_smile:

Just a FYI; it seems that the forum download facility does not like Chrome very much (repeatedly comes up with a ‘might be temporarily down or it may have moved permanently to a new web address.’ error). However, MS Edge works a treat…:stuck_out_tongue: