Example #1
0
        /// <summary>
        /// Process a new video frame.
        /// </summary>
        public void ProcessFrame(UnmanagedImage frame)
        {
            filterImage = filter.Apply(frame);

            Blob blob = extractBlob();

            if (blob == null)
            {
                trackingObject.Reset();
                return;
            }


            trackingObject.Rectangle = blob.Rectangle;
            trackingObject.Center    = (IntPoint)blob.CenterOfGravity;

            if (rotation)
            {
                // Locate moments
                CentralMoments moments = new CentralMoments();
                moments.Compute(filterImage, blob.Rectangle);
                trackingObject.Angle = moments.GetOrientation();
            }


            if (extract)
            {
                blobCounter.ExtractBlobsImage(filterImage, blob, false);
                trackingObject.Image = blob.Image;
            }
        }
Example #2
0
        public void ComputeTest()
        {
            Bitmap image = Accord.Imaging.Image.Clone(Resources.hu);

            CentralMoments target = new CentralMoments(image, order: 3);

            Assert.AreEqual(86424.0 / target.Mu00, 1, 1e-4);
            Assert.AreEqual(0, target.Mu01);
            Assert.AreEqual(0, target.Mu10);
            Assert.AreEqual(5.868206472635379E8 / target.Mu02, 1, 1e-2);

            Assert.AreEqual(6348920.945848465 / target.Mu11, 1, 1e-2);
            Assert.AreEqual(9.084235762166061E8 / target.Mu20, 1, 1e-3);

            Assert.AreEqual(-2.155191E9 / target.Mu12, 1, 1e-4);
            Assert.AreEqual(7.125893E8 / target.Mu21, 1, 1e-3);

            Assert.AreEqual(-1.26244547E10 / target.Mu30, 1, 1e-4);
            Assert.AreEqual(1.71818829E9 / target.Mu03, 1, 1e-4);

            SizeF size  = target.GetSize();
            float angle = target.GetOrientation();

            Assert.AreEqual(410.207916f, size.Height);
            Assert.AreEqual(329.534637f, size.Width);
            Assert.AreEqual(0.0196384024f, angle, 1e-4);
        }
        /// <summary>
        ///   Computes the Hu moments from the specified central moments.
        /// </summary>
        ///
        /// <param name="moments">The central moments to use as base of calculations.</param>
        ///
        public void Compute(CentralMoments moments)
        {
            double inv    = 1.0 / moments.Mu00;
            double inv2   = 1.0 / (moments.Mu00 * moments.Mu00);
            double inv5d2 = System.Math.Sqrt(inv2 * inv2 * inv);


            float n20 = (float)(moments.Mu20 * inv2);
            float n02 = (float)(moments.Mu02 * inv2);
            float n11 = (float)(moments.Mu11 * inv2);

            float n21 = (float)(moments.Mu21 * inv5d2);
            float n12 = (float)(moments.Mu12 * inv5d2);
            float n30 = (float)(moments.Mu30 * inv5d2);
            float n03 = (float)(moments.Mu03 * inv5d2);


            //   (η20 + η02)
            I1 = (n20 + n02);


            //   (η20 − η02)²              + 4    η11²
            I2 = (n20 - n02) * (n20 - n02) + 4 * (n11 * n11);


            //   (η30 − 3   η12)²
            I3 = (n30 - 3 * n12) * (n30 - 3 * n12)

                 // + (3   η21 − η03)²
                 + (3 * n21 - n03) * (3 * n21 - n03);


            //   (η30 + η12)²              + (η21 + η03)²
            I4 = (n30 + n12) * (n30 + n12) + (n21 + n03) * (n21 + n03);


            //   (η30 − 3   η12)   (η30 + η12)   [(η30 + η12)²               −3   (η21 + η03)²             ]
            I5 = (n30 - 3 * n12) * (n30 + n12) * ((n30 + n12) * (n30 + n12) - 3 * (n21 + n03) * (n21 + n03))

                 //   (3   η21 − η03)   (η21 + η03)   [3   (η30 + η12)²              − (η21 + η03)²             ]
                 + (3 * n21 - n03) * (n21 + n03) * (3 * (n30 + n12) * (n30 + n12) - (n21 + n03) * (n21 + n03));


            //   (η20 − η02)   [(η30 + η12)²              − (η21 + η03)²             ]
            I6 = (n20 - n02) * ((n30 + n12) * (n30 + n12) - (n21 + n03) * (n21 + n03))

                 //  + 4   η11   (η30 + η12)   (η21 + η03)
                 + 4 * n11 * (n30 + n12) * (n21 + n03);


            //   (3   η21 − η03)   (η30 + η12)                 [(η30 + η12)²              − 3   (η21 + η03)²             ]
            I7 = (3 * n21 - n03) * (n30 + n12) * (n30 + n12) * ((n30 + n12) * (n30 + n12) - 3 * (n21 + n03) * (n21 + n03))

                 // - (η30 − 3   η12)   (η21 + η03)   [3   (η30 + η12)²              − (η21 + η03)²             ]
                 - (n30 - 3 * n12) * (n21 + n03) * (3 * (n30 + n12) * (n30 + n12) - (n21 + n03) * (n21 + n03));
        }
        internal override void Compute(IImage image)
        {
            RawMoments raw = new RawMoments(Order);

            raw.Compute(image);

            CentralMoments center = new CentralMoments(raw);

            this.Compute(center);
        }
Example #5
0
        /// <summary>
        /// Computes moments for the provided image.
        /// </summary>
        /// <param name="image">Image.</param>
        /// <param name="area">Area</param>
        public void Compute(Gray <float>[,] image, Rectangle area)
        {
            RawMoments raw = new RawMoments(Order);

            raw.Compute(image, area);

            CentralMoments center = new CentralMoments(raw);

            this.Compute(center);
        }
Example #6
0
        public void ComputeTest2()
        {
            // 0 and 1 are only translated
            var cm0 = new CentralMoments(Accord.Imaging.Image.Clone(Resources.hu0), 3);
            var cm1 = new CentralMoments(Accord.Imaging.Image.Clone(Resources.hu1), 3);

            Assert.AreEqual(cm0.Mu00, cm1.Mu00);
            Assert.AreEqual(cm0.Mu01, cm1.Mu01);
            Assert.AreEqual(cm0.Mu10, cm1.Mu10);
            Assert.AreNotEqual(cm0.Mu11, cm1.Mu11);
        }
Example #7
0
        public void ComputeTest2()
        {
            // 0 and 1 are only translated
            var cm0 = new CentralMoments(Resources.hu0, 3);
            var cm1 = new CentralMoments(Resources.hu1, 3);

            Assert.AreEqual(cm0.Mu00, cm1.Mu00);
            Assert.AreEqual(cm0.Mu01, cm1.Mu01);
            Assert.AreEqual(cm0.Mu10, cm1.Mu10);
            Assert.AreNotEqual(cm0.Mu11, cm1.Mu11);
        }
Example #8
0
        private static Rectangle process(Gray <byte>[,] probabilityMap, Rectangle roi, TermCriteria termCriteria, out CentralMoments centralMoments)
        {
            Rectangle imageArea = new Rectangle(0, 0, probabilityMap.Width(), probabilityMap.Height());

            Rectangle  searchWindow = roi;
            RawMoments moments      = new RawMoments(order: 1);

            // Mean shift with fixed number of iterations
            int    i     = 0;
            double shift = Byte.MaxValue;

            while (termCriteria.ShouldTerminate(i, shift) == false && !searchWindow.IsEmptyArea())
            {
                // Locate first order moments
                moments.Compute(probabilityMap, searchWindow);

                int shiftX = (int)(moments.CenterX - searchWindow.Width / 2f);
                int shiftY = (int)(moments.CenterY - searchWindow.Height / 2f);

                // Shift the mean (centroid)
                searchWindow.X += shiftX;
                searchWindow.Y += shiftY;

                // Keep the search window inside the image
                searchWindow.Intersect(imageArea);

                shift = System.Math.Abs((double)shiftX) + System.Math.Abs((double)shiftY); //for term criteria only
                i++;
            }

            if (searchWindow.IsEmptyArea() == false)
            {
                // Locate second order moments and perform final shift
                moments.Order = 2;
                moments.Compute(probabilityMap, searchWindow);

                searchWindow.X += (int)(moments.CenterX - searchWindow.Width / 2f);
                searchWindow.Y += (int)(moments.CenterY - searchWindow.Height / 2f);

                // Keep the search window inside the image
                searchWindow.Intersect(imageArea);
            }

            centralMoments = new CentralMoments(moments); // moments to be used by camshift
            return(searchWindow);
        }
Example #9
0
        /// <summary>
        /// Camshift algorithm
        /// </summary>
        /// <param name="probabilityMap">Probability map [0-255].</param>
        /// <param name="roi">Initial Search area</param>
        /// <param name="termCriteria">Mean shift termination criteria (PLEASE DO NOT REMOVE (but you can move it) THIS CLASS; PLEASE!!!)</param>
        /// <param name="centralMoments">Calculated central moments (up to order 2).</param>
        /// <returns>Object position, size and angle packed into a structure.</returns>
        public static Box2D Process(Gray <byte>[,] probabilityMap, Rectangle roi, TermCriteria termCriteria, out CentralMoments centralMoments)
        {
            // Compute mean shift
            Rectangle objArea = Meanshift.Process(probabilityMap, roi, termCriteria, out centralMoments);

            //fit ellipse
            Ellipse ellipse = centralMoments.GetEllipse();

            ellipse.Center = objArea.Center();

            //return empty structure is the object is lost
            var sz = ellipse.Size;

            if (Single.IsNaN(sz.Width) || Single.IsNaN(sz.Height) ||
                sz.Width < 1 || sz.Height < 1)
            {
                return(Box2D.Empty);
            }

            return((Box2D)ellipse);
        }
Example #10
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));
        }
Example #11
0
 /// <summary>
 /// Meanshift algorithm
 /// </summary>
 /// <param name="probabilityMap">Probability map [0-255].</param>
 /// <param name="roi">Initial search area</param>
 /// <param name="termCriteria">Mean shift termination criteria</param>
 /// <param name="centralMoments">Calculated central moments (up to order 2).</param>
 /// <returns>Object area.</returns>
 public static Rectangle Process(Gray <byte>[,] probabilityMap, Rectangle roi, TermCriteria termCriteria, out CentralMoments centralMoments)
 {
     return(process(probabilityMap, roi, termCriteria, out centralMoments));
 }
        internal override void Compute(IImage image)
        {
            RawMoments raw = new RawMoments(Order);
            raw.Compute(image);

            CentralMoments center = new CentralMoments(raw);
            this.Compute(center);
        }
        /// <summary>
        ///   Computes the Hu moments from the specified central moments.
        /// </summary>
        /// 
        /// <param name="moments">The central moments to use as base of calculations.</param>
        /// 
        public void Compute(CentralMoments moments)
        {
            double inv = 1.0 / moments.Mu00;
            double inv2 = 1.0 / (moments.Mu00 * moments.Mu00);
            double inv5d2 = System.Math.Sqrt(inv2 * inv2 * inv);

            float n20 = (float)(moments.Mu20 * inv2);
            float n02 = (float)(moments.Mu02 * inv2);
            float n11 = (float)(moments.Mu11 * inv2);

            float n21 = (float)(moments.Mu21 * inv5d2);
            float n12 = (float)(moments.Mu12 * inv5d2);
            float n30 = (float)(moments.Mu30 * inv5d2);
            float n03 = (float)(moments.Mu03 * inv5d2);

            //   (η20 + η02)
            I1 = (n20 + n02);

            //   (η20 − η02)²              + 4    η11²
            I2 = (n20 - n02) * (n20 - n02) + 4 * (n11 * n11);

            //   (η30 − 3   η12)²
            I3 = (n30 - 3 * n12) * (n30 - 3 * n12)

            // + (3   η21 − η03)²
               + (3 * n21 - n03) * (3 * n21 - n03);

            //   (η30 + η12)²              + (η21 + η03)²
            I4 = (n30 + n12) * (n30 + n12) + (n21 + n03) * (n21 + n03);

            //   (η30 − 3   η12)   (η30 + η12)   [(η30 + η12)²               −3   (η21 + η03)²             ]
            I5 = (n30 - 3 * n12) * (n30 + n12) * ((n30 + n12) * (n30 + n12) - 3 * (n21 + n03) * (n21 + n03))

            //   (3   η21 − η03)   (η21 + η03)   [3   (η30 + η12)²              − (η21 + η03)²             ]
               + (3 * n21 - n03) * (n21 + n03) * (3 * (n30 + n12) * (n30 + n12) - (n21 + n03) * (n21 + n03));

            //   (η20 − η02)   [(η30 + η12)²              − (η21 + η03)²             ]
            I6 = (n20 - n02) * ((n30 + n12) * (n30 + n12) - (n21 + n03) * (n21 + n03))

            //  + 4   η11   (η30 + η12)   (η21 + η03)
                + 4 * n11 * (n30 + n12) * (n21 + n03);

            //   (3   η21 − η03)   (η30 + η12)                 [(η30 + η12)²              − 3   (η21 + η03)²             ]
            I7 = (3 * n21 - n03) * (n30 + n12) * (n30 + n12) * ((n30 + n12) * (n30 + n12) - 3 * (n21 + n03) * (n21 + n03))

            // - (η30 − 3   η12)   (η21 + η03)   [3   (η30 + η12)²              − (η21 + η03)²             ]
               - (n30 - 3 * n12) * (n21 + n03) * (3 * (n30 + n12) * (n30 + n12) - (n21 + n03) * (n21 + n03));
        }