Example #1
0
        /// <summary>
        ///   Performs object detection on the given frame.
        /// </summary>
        ///
        public Rectangle[] ProcessFrame(UnmanagedImage image)
        {
            // Creates an integral image representation of the frame
            SIntegralImage integralImage = SIntegralImage.FromBitmap(
                image, channel, classifier.Cascade.HasTiltedFeatures);

            // Creates a new list of detected objects.
            this.detectedObjects.Clear();

            int width  = integralImage.Width;
            int height = integralImage.Height;

            // Update parameters only if different size
            if (steps == null || width != lastWidth || height != lastHeight)
            {
                update(width, height);
            }


            Rectangle window = Rectangle.Empty;

            // For each scaling step
            foreach (float scaling in steps)
            {
                // Set the classifier window scale
                classifier.Scale = scaling;

                // Get the scaled window size
                window.Width  = (int)(baseWidth * scaling);
                window.Height = (int)(baseHeight * scaling);

                // Check if the window is lesser than the minimum size
                if (window.Width < minSize.Width && window.Height < minSize.Height &&
                    window.Width > maxSize.Width && window.Height > maxSize.Height)
                {
                    // If we are searching in greater to smaller mode,
                    if (scalingMode == ObjectDetectorScalingMode.GreaterToSmaller)
                    {
                        goto EXIT; // it won't get bigger, so we should stop.
                    }
                    else
                    {
                        continue; // continue until it gets greater.
                    }
                }


                // Grab some scan loop parameters
                int xStep = window.Width >> 3;
                int yStep = window.Height >> 3;

                int xEnd = width - window.Width;
                int yEnd = height - window.Height;

                // Check if we should run in parallel or sequential
                if (!UseParallelProcessing)
                {
                    // Sequential mode. Scan the integral image searching
                    // for objects in the window without parallelization.

                    // For every pixel in the window column
                    for (int y = 0; y < yEnd; y += yStep)
                    {
                        window.Y = y;

                        // For every pixel in the window row
                        for (int x = 0; x < xEnd; x += xStep)
                        {
                            window.X = x;

                            if (searchMode == ObjectDetectorSearchMode.NoOverlap && overlaps(window))
                            {
                                continue; // We have already detected something here, moving along.
                            }
                            // Try to detect and object inside the window
                            if (classifier.Compute(integralImage, window))
                            {
                                // an object has been detected
                                detectedObjects.Add(window);

                                if (searchMode == ObjectDetectorSearchMode.Single)
                                {
                                    goto EXIT; // Stop on first object found
                                }
                            }
                        }
                    }
                }

                else
                {
                    // Parallel mode. Scan the integral image searching
                    // for objects in the window with parallelization.
                    ConcurrentBag <Rectangle> bag = new ConcurrentBag <Rectangle>();

                    int numSteps = (int)Math.Ceiling((double)yEnd / yStep);

                    // For each pixel in the window column
                    Parallel.For(0, numSteps, (j, options) => {
                        int y = j * yStep;

                        // Create a local window reference
                        Rectangle localWindow = window;

                        localWindow.Y = y;

                        // For each pixel in the window row
                        for (int x = 0; x < xEnd; x += xStep)
                        {
                            if (options.ShouldExitCurrentIteration)
                            {
                                return;
                            }

                            localWindow.X = x;

                            // Try to detect and object inside the window
                            if (classifier.Compute(integralImage, localWindow))
                            {
                                // an object has been detected
                                bag.Add(localWindow);

                                if (searchMode == ObjectDetectorSearchMode.Single)
                                {
                                    options.Stop();
                                }
                            }
                        }
                    });

                    // If required, avoid adding overlapping objects at
                    // the expense of extra computation. Otherwise, only
                    // add objects to the detected objects collection.
                    switch (searchMode)
                    {
                    case ObjectDetectorSearchMode.NoOverlap:
                        foreach (Rectangle obj in bag.Where(obj => !overlaps(obj)))
                        {
                            detectedObjects.Add(obj);
                        }
                        break;

                    case ObjectDetectorSearchMode.Single:
                        if (bag.TryPeek(out window))
                        {
                            detectedObjects.Add(window);
                            goto EXIT;
                        }
                        break;

                    default:
                        foreach (Rectangle obj in bag)
                        {
                            detectedObjects.Add(obj);
                        }
                        break;
                    }
                }
            }


EXIT:

            Rectangle[] objects = detectedObjects.ToArray();

            checkSteadiness(objects);
            lastObjects = objects;

            return(objects); // Returns the array of detected objects.
        }
Example #2
0
        /// <summary>
        ///   Performs object detection on the given frame.
        /// </summary>
        ///
        //public Rectangle[] ProcessFrame(Bitmap frame)
        //{
        //    using (FastBitmap fastBitmap = new FastBitmap(frame))
        //    {
        //        return ProcessFrame(fastBitmap);
        //    }
        //}

        /// <summary>
        ///   Performs object detection on the given frame.
        /// </summary>
        ///
        public Rectangle[] ProcessFrame(Bitmap image)
        {
            //  int colorChannel =
            //   image.PixelFormat == PixelFormat.Format8bppIndexed ? 0 : channel;

            Rectangle[] objects;

            // Creates an integral image representation of the frame
            using (var fastBitmap = new FastBitmap(image, _classifier.Cascade.HasTiltedFeatures))
            {
                // Creates a new list of detected objects.
                _detectedObjects.Clear();

                var width  = fastBitmap.Width;
                var height = fastBitmap.Height;

                // Update parameters only if different size
                if (_steps == null || width != _lastWidth || height != _lastHeight)
                {
                    Update(width, height);
                }


                var window = Rectangle.Empty;

                // For each scaling step
                for (var i = 0; i < _steps.Length; i++)
                {
                    var scaling = _steps[i];

                    // Set the classifier window scale
                    _classifier.Scale = scaling;

                    // Get the scaled window size
                    window.Width  = (int)(_baseWidth * scaling);
                    window.Height = (int)(_baseHeight * scaling);

                    // Check if the window is lesser than the minimum size
                    if (window.Width < _minSize.Width || window.Height < _minSize.Height)
                    {
                        // If we are searching in greater to smaller mode,
                        if (_scalingMode == ObjectDetectorScalingMode.GreaterToSmaller)
                        {
                            break; // it won't get bigger, so we should stop.
                        }
                        else
                        {
                            continue;  // continue until it gets greater.
                        }
                    }

                    // Check if the window is greater than the maximum size
                    else if (window.Width > _maxSize.Width || window.Height > _maxSize.Height)
                    {
                        // If we are searching in greater to smaller mode,
                        if (_scalingMode == ObjectDetectorScalingMode.GreaterToSmaller)
                        {
                            continue; // continue until it gets smaller.
                        }

                        break; // it won't get smaller, so we should stop.
                    }

                    // Grab some scan loop parameters
                    var xStep = window.Width >> 3;
                    var yStep = window.Height >> 3;

                    var xEnd = width - window.Width;
                    var yEnd = height - window.Height;


                    // Parallel mode. Scan the integral image searching
                    // for objects in the window with parallelization.
                    var bag = new System.Collections.Concurrent.ConcurrentBag <Rectangle>();

                    var numSteps = (int)Math.Ceiling((double)yEnd / yStep);

                    // For each pixel in the window column
                    var window1 = window;
                    Parallel.For(
                        0,
                        numSteps,
                        (j, options) =>
                    {
                        var y = j * yStep;

                        // Create a local window reference
                        var localWindow = window1;

                        localWindow.Y = y;

                        // For each pixel in the window row
                        for (var x = 0; x < xEnd; x += xStep)
                        {
                            if (options.ShouldExitCurrentIteration)
                            {
                                return;
                            }

                            localWindow.X = x;

                            // Try to detect and object inside the window
                            if (_classifier.Compute(fastBitmap, localWindow))
                            {
                                // an object has been detected
                                bag.Add(localWindow);

                                if (_searchMode == ObjectDetectorSearchMode.Single)
                                {
                                    options.Stop();
                                }
                            }
                        }
                    });

                    // If required, avoid adding overlapping objects at
                    // the expense of extra computation. Otherwise, only
                    // add objects to the detected objects collection.
                    if (_searchMode == ObjectDetectorSearchMode.NoOverlap)
                    {
                        foreach (var obj in bag)
                        {
                            if (!Overlaps(obj))
                            {
                                _detectedObjects.Add(obj);
                            }
                        }
                    }
                    else if (_searchMode == ObjectDetectorSearchMode.Single)
                    {
                        if (bag.TryPeek(out window))
                        {
                            _detectedObjects.Add(window);
                            break;
                        }
                    }
                    else
                    {
                        foreach (var obj in bag)
                        {
                            _detectedObjects.Add(obj);
                        }
                    }
                }
            }

            objects = _detectedObjects.ToArray();

            if (_searchMode == ObjectDetectorSearchMode.Average)
            {
                objects = _match.Group(objects);
            }

            CheckSteadiness(objects);
            _lastObjects = objects;

            return(objects); // Returns the array of detected objects.
        }