Example #1
0
        /// <summary>
        ///   Camshift algorithm
        /// </summary>
        ///
        private void camshift(UnmanagedImage frame)
        {
            int width  = frame.Width;
            int height = frame.Height;

            Rectangle area = new Rectangle(0, 0, width, height);

            // Compute tracking object center
            float objX = Math.Max(0, Math.Min(searchWindow.X + searchWindow.Width * 0.5f, width));
            float objY = Math.Max(0, Math.Min(searchWindow.Y + searchWindow.Height * 0.5f, height));
            float objAngle;


            // Compute mean shift
            CentralMoments moments = meanShift(frame);

            SizeF objSize = moments.GetSizeAndOrientation(out objAngle);


            if (Single.IsNaN(objSize.Width) || Single.IsNaN(objSize.Height) ||
                Single.IsNaN(objAngle) || objSize.Width < 1 || objSize.Height < 1)
            {
                Reset();
                return;
            }

            // Truncate to integer coordinates
            IntPoint center = new IntPoint((int)objX, (int)objY);

            Rectangle rec = new Rectangle((int)(objX - objSize.Width * 0.5f),
                                          (int)(objY - objSize.Height * 0.5f),
                                          (int)objSize.Width, (int)objSize.Height);

            angleHistory.Push(objAngle);

            // Create tracking object
            IsSteady = checkSteadiness();
            trackingObject.Rectangle = rec;
            trackingObject.Center    = center;
            trackingObject.Angle     = smooth ? (float)angleHistory.Mean : objAngle;

            if (extract)
            {
                Rectangle inner = rec;

                xHistory.Push(rec.X);
                yHistory.Push(rec.Y);
                widthHistory.Push(rec.Width);
                heightHistory.Push(rec.Height);

                inner.X      = (int)xHistory.Mean;
                inner.Y      = (int)yHistory.Mean;
                inner.Width  = (int)widthHistory.Mean;
                inner.Height = (int)heightHistory.Mean;

                inner.Intersect(area);

                Crop crop = new Crop(inner);

                // TODO: Perform rotation of the extracted object
                //RotateNearestNeighbor rotate = new RotateNearestNeighbor((objAngle - Math.PI / 2) * 180f / Math.PI, true);
                //trackingObject.Image = rotate.Apply(crop.Apply(frame));

                trackingObject.Image = crop.Apply(frame);
            }

            // Compute a new search window size
            searchWindow.Width  = (int)(1.1f * objSize.Width);
            searchWindow.Height = (int)((aspectRatio != 0) ?
                                        (aspectRatio * objSize.Width) : (1.1f * objSize.Height));
        }