Example #1
0
        /// <summary>
        /// Analyzes the image frame, applies filters and creates new <see cref="TrackerResult"/> objects.
        /// This method performs a deep analysis over the frame and is computationally expensive.
        /// Use this method wisely and never more than once per frame. If you need to get the tracker results
        /// multiple times in a frame use <see cref="GetLatestResult"/> instead.
        /// </summary>
        /// <param name="weightThreshold">The allowed amount of particles distribution to consider a good result.</param>
        /// <returns>The latest tracking result.</returns>
        public List <TrackerResult> Compute(float weightThreshold = 0.01f)
        {
            _result.Clear();

            if (_input != null && _running)
            {
                int dstW = _input.width / _downscaleAmount;
                int dstH = _input.height / _downscaleAmount;

                if (_input.data == null)
                {
                    return(_result);
                }

                if (_downscaleAmount > 1)
                {
                    int requiredBufferLenght = dstW * dstH * 3;

                    if (_resizedBuffer == null || _resizedBuffer.Length != requiredBufferLenght)
                    {
                        _resizedBuffer = new byte[requiredBufferLenght];
                    }

                    ResizeBuffer(_resizedBuffer, _input.data, _input.width, _input.height, dstW, dstH, 3, 3);
                }
                else
                {
                    _resizedBuffer = _input.data;
                }

                if (enableColorTrack)
                {
                    for (int i = 0; i < _processors.Count; ++i)
                    {
                        ColorProcessor clp    = _processors[i];
                        TrackerResult  result = _resultHash[i];

                        clp.Compute(_resizedBuffer, result, dstW, dstH, weightThreshold, useKalmanFilter);

                        if (!IsPositionNearToBounds(ref result.center, 10.0f))
                        {
                            result.center *= _downscaleAmount;
                            _result.Add(result);
                        }
                    }
                }

                if (enableColorMap)
                {
                    _colorMap.ComputeColorMap(_resizedBuffer, dstW, dstH, colorTargets, _downscaleAmount, colorMapPointSpacing);
                }

                if (listener != null && _result.Count > 0)
                {
                    listener.WhenNewResultAvailable(this);
                }
            }

            return(_result);
        }
Example #2
0
            /// <summary>
            /// Search the color on the image buffer. When color is found it enables a new <see cref="TrackerResult"/> and sets the
            /// proper <see cref="TrackingState"/> to the object. To improve the memory usage the results are cached and persistent so
            /// it is safe to store reference to results.
            /// </summary>
            /// <param name="pixelsRGB">The image buffer in RGB format.</param>
            /// <param name="result">A reference to the cached result to write on.</param>
            /// <param name="width">The current frame width. (useful for occasional frame dimension changes)</param>
            /// <param name="height">The current frame height. (useful for occasional frame dimension changes)</param>
            /// <param name="weightThreshold">The allowed amount of particles distribution to consider a good result.</param>
            /// <param name="useKalmanFilter">Toggles the use of <see cref="KalmanFilter"/>.</param>
            public void Compute(byte[] pixelsRGB, TrackerResult result, int width, int height, float weightThreshold, bool useKalmanFilter)
            {
                if (target == null || pixelsRGB.Length == 0)
                {
                    return;
                }

                _particle.colorTolerance = target.tolerance;
                _particle.Resample(width, height);
                _particle.Predict();

                double w = _particle.ComputeWeight(pixelsRGB);

                if (w <= weightThreshold)
                {
                    result.state = TrackingState.Lost;
                    _particle.Reset();
                }
                else
                {
                    Vector3 prevCenter = result.center;
                    _particle.Measure(ref result.center);

                    float depth = ((float)w * 100 / _particle.ParticleCount());
                    result.center.z = depth;

                    if (useKalmanFilter)
                    {
                        if (result.state == TrackingState.Tracked)
                        {
                            _kalman.Predict(ref result.center);
                        }
                        else
                        {
                            _kalman.ResetTo(result.center);
                        }
                    }

                    Vector2 lvel = (result.center - prevCenter);
                    lvel.y *= -1;
                    result.linearVelocity = lvel;
                    result.state          = TrackingState.Tracked;
                }
            }