protected override void DisposeObject() { base.DisposeObject(); _segMask?.Dispose(); _forgroundMask?.Dispose(); _motionHistory?.Dispose(); _foregroundDetector?.Dispose(); }
protected override MotionDetectorOutput DoProcess(MotionDetectorInput input) { var output = new MotionDetectorOutput(); var subtractorConfig = input.Settings.SubtractorConfig; if (_foregroundDetector == null || !_currentSubtractorConfig.Equals(subtractorConfig)) { if (_foregroundDetector != null) { _foregroundDetector.Dispose(); } _foregroundDetector = new BackgroundSubtractorMOG2( subtractorConfig.History , subtractorConfig.Threshold , subtractorConfig.ShadowDetection); _currentSubtractorConfig = subtractorConfig; } _foregroundDetector.Apply(input.Captured, _forgroundMask); _motionHistory.Update(_forgroundMask); #region get a copy of the motion mask and enhance its color double[] minValues, maxValues; Point[] minLoc, maxLoc; _motionHistory.Mask.MinMax(out minValues, out maxValues, out minLoc, out maxLoc); var motionMask = new Mat(); using (var sa = new ScalarArray(255.0 / maxValues[0])) { CvInvoke.Multiply(_motionHistory.Mask, sa, motionMask, 1, DepthType.Cv8U); } #endregion if (input.SetCapturedImage) { output.ForegroundImage = _forgroundMask.ToImage <Bgr, byte>(); output.MotionImage = new Image <Bgr, byte>(motionMask.Size); CvInvoke.InsertChannel(motionMask, output.MotionImage, 0); } Rectangle[] motionComponents; using (var boundingRect = new VectorOfRect()) { _motionHistory.GetMotionComponents(_segMask, boundingRect); motionComponents = boundingRect.ToArray(); } foreach (Rectangle motionComponent in motionComponents) { int area = motionComponent.Area(); //reject the components that have small area; if (area < input.Settings.MinimumArea || area > input.Settings.MaximumArea) { continue; } // find the angle and motion pixel count of the specific area double angle, motionPixelCountDouble; _motionHistory.MotionInfo(_forgroundMask, motionComponent, out angle, out motionPixelCountDouble); int motionPixelCount = (int)motionPixelCountDouble; //reject the area that contains too few motion if (motionPixelCount < area * input.Settings.MinimumPercentMotionInArea) { continue; } var motionSection = new MotionSection(); motionSection.Area = area; motionSection.Region = motionComponent; motionSection.Angle = angle; motionSection.PixelsInMotionCount = motionPixelCount; output.MotionSections.Add(motionSection); } if (output.IsDetected) { switch (input.Settings.BiggestMotionType) { case BiggestMotionType.Unspecified: break; case BiggestMotionType.Area: output.MotionSections.Sort((x, y) => y.Area.CompareTo(x.Area)); break; case BiggestMotionType.Pixels: output.MotionSections.Sort((x, y) => y.PixelsInMotionCount.CompareTo(x.PixelsInMotionCount)); break; } output.BiggestMotion = output.MotionSections.FirstOrDefault(); } double overallAngle, overallMotionPixelCount; _motionHistory.MotionInfo(_forgroundMask, new Rectangle(Point.Empty, motionMask.Size), out overallAngle, out overallMotionPixelCount); output.OverallAngle = overallAngle; output.OverallMotionPixelCount = Convert.ToInt32(overallMotionPixelCount); return(output); }