public override IObservable <RegionActivityCollection> Process(IObservable <IplImage> source) { return(Observable.Defer(() => { var roi = default(IplImage); var mask = default(IplImage); var currentRegions = default(Point[][]); var boundingRegions = default(Rect[]); return source.Select(input => { var operation = Operation; var output = new RegionActivityCollection(); mask = IplImageHelper.EnsureImageFormat(mask, input.Size, IplDepth.U8, 1); if (operation != ReduceOperation.Sum) { roi = null; } else { roi = IplImageHelper.EnsureImageFormat(roi, input.Size, input.Depth, input.Channels); } if (Regions != currentRegions) { currentRegions = Regions; if (currentRegions != null) { mask.SetZero(); CV.FillPoly(mask, currentRegions, Scalar.All(255)); boundingRegions = currentRegions.Select(polygon => { var points = polygon.SelectMany(point => new[] { point.X, point.Y }).ToArray(); using (var mat = new Mat(1, polygon.Length, Depth.S32, 2)) { Marshal.Copy(points, 0, mat.Data, points.Length); return CV.BoundingRect(mat); } }).ToArray(); } } if (currentRegions != null) { var activeMask = mask; if (roi != null) { roi.SetZero(); CV.Copy(input, roi, mask); activeMask = roi; } var activation = ActivationFunction(operation); for (int i = 0; i < boundingRegions.Length; i++) { var rect = boundingRegions[i]; var polygon = currentRegions[i]; using (var region = input.GetSubRect(rect)) using (var regionMask = activeMask.GetSubRect(rect)) { output.Add(new RegionActivity { Roi = polygon, Rect = rect, Activity = activation(region, regionMask) }); } } } return output; }); })); }
public override IObservable <IplImage> Process(IObservable <IplImage> source) { return(Observable.Defer(() => { var mask = default(IplImage); var boundingBox = default(Rect); var currentRegions = default(Point[][]); return source.Select(input => { if (Regions != currentRegions) { currentRegions = Regions; boundingBox = default(Rect); if (currentRegions != null) { mask = new IplImage(input.Size, IplDepth.U8, 1); mask.SetZero(); var points = currentRegions .SelectMany(region => region) .SelectMany(point => new[] { point.X, point.Y }) .ToArray(); if (points.Length > 0) { using (var mat = new Mat(1, points.Length / 2, Depth.S32, 2)) { Marshal.Copy(points, 0, mat.Data, points.Length); boundingBox = CV.BoundingRect(mat); boundingBox = ClipRectangle(boundingBox, input.Size); } CV.FillPoly(mask, currentRegions, Scalar.All(255)); if (cropOutput) { mask = mask.GetSubRect(boundingBox); } } } else { mask = null; } } var selectionType = MaskType; if (selectionType <= ThresholdTypes.BinaryInv) { var size = mask != null ? mask.Size : input.Size; var output = new IplImage(size, IplDepth.U8, 1); switch (selectionType) { case ThresholdTypes.Binary: if (mask == null) { output.SetZero(); } else { CV.Copy(mask, output); } break; case ThresholdTypes.BinaryInv: if (mask == null) { output.Set(Scalar.All(255)); } else { CV.Not(mask, output); } break; default: throw new InvalidOperationException("Selection operation is not supported."); } return output; } if (currentRegions != null && boundingBox.Width > 0 && boundingBox.Height > 0) { var output = new IplImage(mask.Size, input.Depth, input.Channels); var inputRoi = cropOutput ? input.GetSubRect(boundingBox) : input; try { switch (selectionType) { case ThresholdTypes.ToZeroInv: var fillRoi = cropOutput ? inputRoi : input; CV.Copy(fillRoi, output); output.Set(FillValue, mask); break; case ThresholdTypes.ToZero: output.Set(FillValue); CV.Copy(inputRoi, output, mask); break; default: throw new InvalidOperationException("Selection operation is not supported."); } } finally { if (inputRoi != input) { inputRoi.Close(); } } return output; } return input; }); })); }