protected virtual void Dispose(bool disposing) { if (_bgModel != null) { _bgModel.Dispose(); _bgModel = null; } if (_calc != null) { _calc.Dispose(); _calc = null; } if (_foreground != null) { _foreground.Dispose(); _foreground = null; } if (_markerBuffer != null) { Marshal.FreeHGlobal((IntPtr)_markerBuffer); _markerBuffer = null; } if (_momentState != null) { ip.ippiMomentFree_64s(_momentState); _momentState = null; } }
private void Dispose(bool disposing) { if (_bgModel != null) { _bgModel.Dispose(); _bgModel = null; } if (_calc != null) { _calc.Dispose(); _calc = null; } if (_foreground != null) { _foreground.Dispose(); _foreground = null; } if (_bgSubtracted != null) { _bgSubtracted.Dispose(); _bgSubtracted = null; } if (_markerBuffer != null) { Marshal.FreeHGlobal((IntPtr)_markerBuffer); _markerBuffer = null; } if (_momentState != null) { Marshal.FreeHGlobal((IntPtr)_momentState); _momentState = null; } if (_strel3x3 != null) { _strel3x3.Dispose(); _strel3x3 = null; } }
/// <summary> /// Tracks fish on a multiwell plate /// </summary> /// <param name="image">The current image to track and update the background with</param> /// <param name="updateBackground">If true the current image will be used to update the background</param> /// <param name="forceFullFrame">If set to true background updates won't exclude fish locations</param> /// <returns>A list of fish-blobs, one for each well or null if no fish was detected</returns> public BlobWithMoments[] TrackMultiWell(Image8 image, bool updateBackground = true, bool forceFullFrame = false) { if (_frame == 0) { ip.ippiSet_8u_C1R(0, Foreground.Image, Foreground.Stride, Foreground.Size); ip.ippiSet_8u_C1R(0, _calc.Image, _calc.Stride, _calc.Size); } BlobWithMoments[] currentFish = new BlobWithMoments[_wellnumber]; if (_frame > FramesInitialBackground && !forceFullFrame) { //do global stuff (everything except labelMarkers if we don't do parallel tracking otherwise only the inherently parallel background subtraction) //cache 8-bit representation of the background Image8 bg = _bgModel.Background; //Perform background subtraction if (DoMedianFiltering) { IppHelper.IppCheckCall(cv.ippiAbsDiff_8u_C1R(image.Image, image.Stride, bg.Image, bg.Stride, _calc.Image, _calc.Stride, image.Size)); } else { IppHelper.IppCheckCall(cv.ippiAbsDiff_8u_C1R(image.Image, image.Stride, bg.Image, bg.Stride, _foreground.Image, _foreground.Stride, image.Size)); } if (_trackMethod == TrackMethods.Parallel && _parallelChunks > 1) { if (!Parallel.For(0, _parallelChunks, TrackChunk).IsCompleted) { System.Diagnostics.Debug.WriteLine("Error in parallel tracking. Not all regions completed"); } //copy our result into currentFish for (int i = 0; i < _wellnumber; i++) { currentFish[i] = _parallelTrackResults[i]; } } else { if (DoMedianFiltering) { //remove noise via median filtering IppHelper.IppCheckCall(ip.ippiFilterMedianWeightedCenter3x3_8u_C1R(_calc[1, 1], _calc.Stride, _foreground[1, 1], _foreground.Stride, new IppiSize(image.Width - 2, image.Height - 2), 1)); } //Threshold and close Im2Bw(_foreground, new IppiROI(new IppiPoint(0, 0), image.Size)); Close3x3(_foreground, new IppiROI(new IppiPoint(0, 0), image.Size)); //label markers and extract - depending on the method selector //we label components on the whole image (new) or individual wells(old) if (_trackMethod == TrackMethods.OnWholeImage) { currentFish = ExtractAll(); } else { for (int i = 0; i < _wellnumber; i++) { currentFish[i] = ExtractFish(_wells[i]); } } } }//If We are past initial background frames //create/update background and advance frame counter if (_frame == 0) { _bgModel = new SelectiveUpdateBGModel(image, 1.0f / FramesInBackground); } else if (updateBackground || _frame <= FramesInitialBackground)//only allow reduction of background update rate AFTER initial background has been created { if (currentFish == null || forceFullFrame) { _bgModel.UpdateBackground(image); } else { _bgModel.UpdateBackground(image, currentFish); } } _frame++; return(currentFish); }
/// <summary> /// Given an image identifies a fish in it and returns /// it's properties such as position and heading /// </summary> /// <param name="image">The image to be tracked.</param> /// <returns>A blob representation of the fish</returns> public BlobWithMoments Track(Image8 image) { if (IsDisposed) { throw new ObjectDisposedException("Tracker90mmDish", "Can't track after disposal!"); } BlobWithMoments currentFish = null; if (RemoveCMOSISBrightLineArtefact) { //Do as two step to get information back into image _strel3x3.Erode(image, _calc, _imageROI); _strel3x3.Dilate(_calc, image, _imageROI); } if (_frame > FramesInitialBackground) { //if _previousFish is present we only check an area around it if (_previousFish != null) { //compute search region //top-left tl_x = _previousFish.Centroid.x - _searchRegionSize; tl_y = _previousFish.Centroid.y - _searchRegionSize; tl_x = tl_x < 0 ? 0 : tl_x; tl_y = tl_y < 0 ? 0 : tl_y; //bottom-right br_x = _previousFish.Centroid.x + _searchRegionSize; br_y = _previousFish.Centroid.y + _searchRegionSize; br_x = br_x >= image.Width ? image.Width - 1 : br_x; br_y = br_y >= image.Height ? image.Height - 1 : br_y; //update search region _searchRegion.X = tl_x; _searchRegion.Y = tl_y; _searchRegion.Width = br_x - tl_x + 1; _searchRegion.Height = br_y - tl_y + 1; //extract fish within region currentFish = ExtractFish(image, _searchRegion); } else { currentFish = ExtractFish(image, _imageROI); } }//If We are past initial background frames //create/update background and advance frame counter if (_frame == 0) { //Blank images - necessary specifically because of the median filter step //which otherwise will leave pixels in _bgSubtracted un-initialized ip.ippiSet_8u_C1R(0, Foreground.Image, Foreground.Stride, Foreground.Size); ip.ippiSet_8u_C1R(0, _calc.Image, _calc.Stride, _calc.Size); ip.ippiSet_8u_C1R(0, _bgSubtracted.Image, _bgSubtracted.Stride, _bgSubtracted.Size); _bgModel = new SelectiveUpdateBGModel(image, 1.0f / FramesInBackground); } else { //update background every nth frame only if (_frame % BGUpdateEvery == 0) { if (currentFish == null) { _bgModel.UpdateBackground(image); } else { _bgModel.UpdateBackground(image, currentFish); } } } //Update knowledge about previous fish //if current fish is trustworthy if (currentFish != null && currentFish.Area > FullTrustMinArea) { _previousFish = currentFish; } else { _previousFish = null; } _frame++; return(currentFish); }