protected override string ProcessInternal(Bitmap bitmap) { using (var grayScaleImage = GrayScaleImageHelper.ToGrayScale(bitmap)) { var bounds = new Rectangle(0, 0, grayScaleImage.Width, grayScaleImage.Height); BitmapData bitmapData = grayScaleImage.LockBits(bounds, ImageLockMode.ReadOnly, grayScaleImage.PixelFormat); var grayScaleHW = new byte[grayScaleImage.Height * bitmapData.Stride]; Marshal.Copy(bitmapData.Scan0, grayScaleHW, 0, grayScaleImage.Height * bitmapData.Stride); var stride = bitmapData.Stride; grayScaleImage.UnlockBits(bitmapData); if (!_backgroundModel.IsOperational()) { _backgroundModel.Train(grayScaleHW, grayScaleImage.Width, grayScaleImage.Height, stride); if (_backgroundModel.IsOperational()) { _interceptor.Intercept(MinIntensityBackgroundDebugView, GrayScaleImageHelper.FromData2(_backgroundModel._width, _backgroundModel._height, _backgroundModel._stride, _backgroundModel._minIntensity)); _interceptor.Intercept(MaxIntensityBackgroundDebugView, GrayScaleImageHelper.FromData2(_backgroundModel._width, _backgroundModel._height, _backgroundModel._stride, _backgroundModel._maxIntensity)); _interceptor.Intercept(MaxPerFrameDifferenceDebugView, GrayScaleImageHelper.FromData2(_backgroundModel._width, _backgroundModel._height, _backgroundModel._stride, _backgroundModel._maxPerFrameDifference)); } return(null); } var foreground = GetForefround(grayScaleHW, grayScaleImage.Width, grayScaleImage.Height, stride); //excluded, because does not work. //ExcludeShadows(grayScaleHW, foreground, grayScaleImage.Width, grayScaleImage.Height, stride); var temp = GrayScaleImageHelper.FromData( _backgroundModel._width, _backgroundModel._height, _backgroundModel._stride, foreground); int countDetected = 0; // create filter var diamondMask = CreateClosingOpeningFileter(); Closing filter = new Closing(diamondMask); Opening filter2 = new Opening(diamondMask); // apply the filter filter.ApplyInPlace(temp); filter2.ApplyInPlace(temp); _interceptor.Intercept( XXX, ImageHelper.ToBytes(temp)); // blobs! var bc = new BlobCounter { BackgroundThreshold = Color.FromArgb(254, 254, 254) }; bc.ProcessImage(temp); Rectangle[] rects = bc.GetObjectsRectangles(); var rectanglesToDraw = new List <Rectangle>(); foreach (Rectangle rect in rects) { if (rect.Width < _maximumDetectionWidthPixels && rect.Width > _minimumDetectionWidthPixels && rect.Height < _maximumDetectionHeightPixels && rect.Height > _minimumDetectionHeightPixels) { countDetected++; rectanglesToDraw.Add(rect); } } temp.Dispose(); _interceptor.Intercept(InputFrameDebugView, GrayScaleImageHelper.FromData2(_backgroundModel._width, _backgroundModel._height, _backgroundModel._stride, grayScaleHW)); _interceptor.Intercept(DifferenceDebugView, GrayScaleImageHelper.FromData2(_backgroundModel._width, _backgroundModel._height, _backgroundModel._stride, foreground)); using (Graphics graphics = Graphics.FromImage(bitmap)) using (var brush = new SolidBrush(Color.Red)) using (var pen = new Pen(brush, 3)) { if (rectanglesToDraw.Any()) { graphics.DrawRectangles(pen, rectanglesToDraw.ToArray()); } _interceptor.Intercept(DetectedBlobDebugView, ImageHelper.ToBytes(bitmap)); } if (countDetected > 0) { return("Alarm: " + countDetected); } } return(null); }