/// <summary> /// Tries to find objects that are occluded. /// </summary> /// <param name="image"></param> /// <param name="updateTime"></param> /// <param name="outputImage"></param> /// <param name="objects"></param> private void UpdateOccludedObjects(Image<Rgb, byte> image, ref Image<Rgb, byte> outputImage, DateTime updateTime, RectangularObject[] objects) { var imageWidth = image.Width; var imageHeight = image.Height; var mask = new Image<Gray, byte>(imageWidth, imageHeight); var occludedObjects = objects.Where(o => !Equals(o.LastUpdate, updateTime)).ToArray(); // ignore if no objects are occluded but continue in case is render content set true to update debug view if (occludedObjects.Length < 1 && !IsRenderContent) return; foreach (var obj in occludedObjects) mask.Draw(obj.Shape, new Gray(1), -1); if (_depthImage == null) return; var occludedPartsImage = new Image<Gray, float>(imageWidth, imageHeight); var depthMapBinary = _depthImage.ThresholdBinaryInv(new Gray(255), new Gray(255)); var depthMap = depthMapBinary; if (depthMap.Width != imageWidth || depthMap.Height != imageHeight) { var resizedDepthMap = new Image<Gray, float>(imageWidth, imageHeight); CvInvoke.cvResize(depthMap.Ptr, resizedDepthMap.Ptr, INTER.CV_INTER_CUBIC); depthMap.Dispose(); depthMap = resizedDepthMap; } CvInvoke.cvCopy(depthMap.Ptr, occludedPartsImage.Ptr, mask); occludedPartsImage = occludedPartsImage.Erode(2).Dilate(2); var debugImage3 = occludedPartsImage.Convert<Rgb, byte>(); var fixedImage = image.Or(debugImage3); fixedImage = fixedImage.Dilate(2).Erode(2); var debugImage = fixedImage.Copy(); Task.Factory.StartNew(() => { var bitmapSource = debugImage.ToBitmapSource(true); debugImage.Dispose(); return bitmapSource; }).ContinueWith(t => DebugImageSource = t.Result); var outputImageEnclosed = outputImage; Parallel.ForEach(occludedObjects, obj => FindObjectByBlankingKnownObjects(true, fixedImage, ref outputImageEnclosed, updateTime, objects, obj)); }
/// <summary> /// Find an object by blanking out known objects except for the parameter object in the /// source image. If obj == null it will blank out all objects. /// </summary> /// <param name="occlusionTracking"></param> /// <param name="image"></param> /// <param name="outputImage"></param> /// <param name="objects"></param> /// <param name="obj"></param> /// <param name="updateTime"></param> private RectangularObject[] FindObjectByBlankingKnownObjects(bool occlusionTracking, Image<Rgb, byte> image, ref Image<Rgb, byte> outputImage, DateTime updateTime, RectangularObject[] objects, RectangularObject obj = null) { var objectsToBlank = obj != null ? objects.Where(o => o != obj) : objects; // Blank previous objects from previous frame var blankedImage = image.Copy(); foreach (var otherObject in objectsToBlank) { blankedImage.Draw(otherObject.Shape, Rgbs.Black, -1); } var blankedImageGray = blankedImage.Convert<Gray, Byte>(); var newObjects = FindRectangles(occlusionTracking, blankedImageGray, ref outputImage, updateTime, objects); blankedImageGray.Dispose(); return newObjects; }