void Hu(Image <Gray, byte> img, ref Double[] MomentHu, ref Double[] MomentR)
        {
            double             r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0, r8 = 0, r9 = 0, r10 = 0;
            Image <Gray, byte> imgA = new Image <Gray, byte>(img.Size);

            imgA = img.ThresholdBinary(new Gray(60), new Gray(255));
            Contour <Point> contourA   = imgA.FindContours();
            MCvMoments      momentsA   = contourA.GetMoments();
            MCvHuMoments    HuMomentsA = momentsA.GetHuMoment();

            MomentHu[0] = HuMomentsA.hu1;
            MomentHu[1] = HuMomentsA.hu2;
            MomentHu[2] = HuMomentsA.hu3;
            MomentHu[3] = HuMomentsA.hu4;
            MomentHu[4] = HuMomentsA.hu5;
            MomentHu[5] = HuMomentsA.hu6;

            Rmoment(HuMomentsA.hu1, HuMomentsA.hu2, HuMomentsA.hu3, HuMomentsA.hu4, HuMomentsA.hu5, HuMomentsA.hu6, ref r1, ref r2, ref r3, ref r4, ref r5, ref r6, ref r7, ref r8, ref r9, ref r10);

            MomentR[0] = r1;
            MomentR[1] = r2;
            MomentR[2] = r3;
            MomentR[3] = r4;
            MomentR[4] = r5;
            MomentR[5] = r6;
            MomentR[6] = r7;
            MomentR[7] = r8;
            MomentR[8] = r9;
            MomentR[9] = r10;
        }
示例#2
0
        public static void PrintHuMoments(MCvHuMoments huMoment)
        {
            double[] m = new double[7];
            m[0] = huMoment.hu1;
            m[1] = huMoment.hu2;
            m[2] = huMoment.hu3;
            m[3] = huMoment.hu4;
            m[4] = huMoment.hu5;
            m[5] = huMoment.hu6;
            m[6] = huMoment.hu7;

            for (int i = 0; i < 7; i++)
            {
                int    sign;
                double result = Math.Abs(m[i]);

                if (m[i] > 0)
                {
                    sign = 1;
                }
                else if (m[i] < 0)
                {
                    sign = -1;
                }
                else
                {
                    sign = 0;
                }

                result = sign * Math.Log10(result);

                Console.WriteLine("hu{0}: {1}", i + 1, result);
            }
        }
示例#3
0
        static void Main(string[] args)
        {
            string img1 = "image1.bmp";
            string img2 = "image2.bmp";

            double dist;

            MCvHuMoments huMoments = new MCvHuMoments();

            /*
             * IsGetShapeFeature(img1, ref huMoments);
             * PrintHuMoments(huMoments);
             *
             * IsGetShapeFeature(img2, ref huMoments);
             * PrintHuMoments(huMoments);
             *
             * IsGetShapeFeature(img1, ref huMoments);
             * PrintHuMoments(huMoments);
             */
            //Console.ReadLine();

            if ((dist = MatchShapes(img1, img2)) >= 0)
            {
                Console.WriteLine("The distance between {0} and {1} is {2}", img1, img2, dist);
            }
            else
            {
                Console.WriteLine("Fail to compute the distance");
            }
            Console.ReadLine();
        }
        void Hu(Image <Gray, byte> img, ref Double[] MomentHu)
        {
            Image <Gray, byte> imgA = new Image <Gray, byte>(img.Size);

            imgA = img.ThresholdBinary(new Gray(60), new Gray(255));
            Contour <Point> contourA   = imgA.FindContours();
            MCvMoments      momentsA   = contourA.GetMoments();
            MCvHuMoments    HuMomentsA = momentsA.GetHuMoment();

            MomentHu[0] = HuMomentsA.hu1;
            MomentHu[1] = HuMomentsA.hu2;
            MomentHu[2] = HuMomentsA.hu3;
            MomentHu[3] = HuMomentsA.hu4;
            MomentHu[4] = HuMomentsA.hu5;
            MomentHu[5] = HuMomentsA.hu6;
        }
示例#5
0
        public void GetHuMoments(Image <Gray, Byte> img, double[] m_hu)
        {
            MCvMoments   moments = new MCvMoments();
            MCvHuMoments hu      = new MCvHuMoments();

            CvInvoke.cvMoments(img, ref moments, 0);
            CvInvoke.cvGetHuMoments(ref moments, ref hu);

            m_hu[0] = hu.hu1;
            m_hu[1] = hu.hu2;
            m_hu[2] = hu.hu3;
            m_hu[3] = hu.hu4;
            m_hu[4] = hu.hu5;
            m_hu[5] = hu.hu6;
            m_hu[6] = hu.hu7;
        }
示例#6
0
        // get the Hu
        public static bool IsGetShapeFeature(string ImgPath, ref MCvHuMoments huMoments)
        {
            IntPtr     img     = IntPtr.Zero;
            MCvMoments moments = new MCvMoments();

            if ((img = CvInvoke.cvLoadImage(ImgPath, LOAD_IMAGE_TYPE.CV_LOAD_IMAGE_GRAYSCALE)) != IntPtr.Zero)
            {
                CvInvoke.cvMoments(img, ref moments, 0);
                CvInvoke.cvGetHuMoments(ref moments, ref huMoments);
                CvInvoke.cvReleaseImage(ref img);
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#7
0
        public void ComputeFeatures(Segment s)
        {
            //Add the relative size
            NamedFeature f = new NamedFeature("RelativeSize");

            f.values.Add(s.points.Count() / (double)(imageWidth * imageHeight));
            s.features.Add(f);

            // Relative centroid
            PointF c = NormalizedCentroid(s);

            s.features.Add(new NamedFeature("RelativeCentroid", new List <double> {
                c.X, c.Y
            }));

            // One interior point
            PointF np = RandomNormalizedInteriorPoint(s);

            s.features.Add(new NamedFeature("OneInteriorPoint", new List <double> {
                np.X, np.Y
            }));

            //Radial distance
            s.features.Add(new NamedFeature("RadialDistance", new List <double> {
                Math.Sqrt(c.X * c.X + c.Y * c.Y)
            }));


            //Normalized Discrete Compactness http://www.m-hikari.com/imf-password2009/25-28-2009/bribiescaIMF25-28-2009.pdf
            //Find the segment id
            Point sp   = s.points.First();
            int   sidx = assignments[sp.X, sp.Y];

            //count number of perimeter edges
            int perimeter = 0;

            foreach (Point p in s.points)
            {
                for (int i = -1; i <= 1; i++)
                {
                    for (int j = -1; j <= 1; j++)
                    {
                        if (Math.Abs(i) == Math.Abs(j))
                        {
                            continue;
                        }
                        if (Util.InBounds(p.X + i, p.Y + j, imageWidth, imageHeight) && assignments[p.X + i, p.Y + j] != sidx)
                        {
                            perimeter++;
                        }
                        else if (!Util.InBounds(p.X + i, p.Y + j, imageWidth, imageHeight)) //edge pixels should be considered perimeter too
                        {
                            perimeter++;
                        }
                    }
                }
            }
            int    n     = s.points.Count();
            double CD    = (4.0 * n - perimeter) / 2;
            double CDmin = n - 1;
            double CDmax = (4 * n - 4 * Math.Sqrt(n)) / 2;
            double CDN   = (CD - CDmin) / Math.Max(1, (CDmax - CDmin));

            s.features.Add(new NamedFeature("NormalizedDiscreteCompactness", new List <double> {
                CDN
            }));


            //Add elongation (width/length normalized between 0-square to 1-long http://hal.archives-ouvertes.fr/docs/00/44/60/37/PDF/ARS-Journal-SurveyPatternRecognition.pdf
            PointF[] points = s.points.Select <Point, PointF>(p => new PointF(p.X, p.Y)).ToArray <PointF>();
            Emgu.CV.Structure.MCvBox2D box = Emgu.CV.PointCollection.MinAreaRect(points);

            PointF[] vertices   = box.GetVertices();
            double   elongation = 1 - Math.Min(box.size.Width + 1, box.size.Height + 1) / Math.Max(box.size.Width + 1, box.size.Height + 1);

            s.features.Add(new NamedFeature("Elongation", new List <double> {
                elongation
            }));


            //Add Hu shape moments, invariant to translation, scale, and rotation (not sure what each measure refers to intuitively though, or if there is an intuitive analog)
            //They may also do badly on noisy data however. See: http://hal.archives-ouvertes.fr/docs/00/44/60/37/PDF/ARS-Journal-SurveyPatternRecognition.pdf (called Invariant Moments)

            Bitmap   regionBitmap = new Bitmap(imageWidth, imageHeight);
            Graphics g            = Graphics.FromImage(regionBitmap);

            g.FillRectangle(new SolidBrush(Color.Black), 0, 0, imageWidth, imageHeight);
            foreach (Point p in s.points)
            {
                regionBitmap.SetPixel(p.X, p.Y, Color.White);
            }

            Emgu.CV.Image <Gray, byte> region = new Emgu.CV.Image <Gray, byte>(regionBitmap);

            MCvMoments   moment = region.GetMoments(true);
            MCvHuMoments hu     = moment.GetHuMoment();

            s.features.Add(new NamedFeature("HuMoments", new List <double> {
                hu.hu1, hu.hu2, hu.hu3, hu.hu4, hu.hu5, hu.hu6, hu.hu7
            }));
            region.Dispose();
            regionBitmap.Dispose();
        }
示例#8
0
        //return the distances between two pics. dist >= 0: func works right, else fail
        public static double MatchShapes(string ImgPath1, string ImgPath2)
        {
            const double eps       = 0.000000000000000001;
            MCvHuMoments huMoment1 = new MCvHuMoments();
            MCvHuMoments huMoment2 = new MCvHuMoments();

            double[] ma = new double[7];
            double[] mb = new double[7];

            IsGetShapeFeature(ImgPath1, ref huMoment1);

            /* Here is a bug.
             * I still cannot figure out why the first time calling IsGetShapeFeautre() it returns wrong anwser
             *
             * Details:
             *   CvInvoke.cvMoments(img, ref moments, 0) cannot work right first time, then CVInvoke.cvGetHuMoments() returns wrong hu
             *   And I find when I use C++ to call this function, it works fine at the first, just for C#, it has this problem
             * Actual:
             *   moments.m00, moments.m01, moments.02 etc returns NaN
             *   huMoments.hu[i] returns NaN
             * Excepted:
             *   moments.m00 etc returns double value
             *   huMoments.hu[i] returns double value
             *
             * So I call the IsGetShapeFeature() once to pass the wrong anwser, it's really an ugly way to fix it. I will back to fix it when I am free.
             *
             *  2009/8/30
             */
            if (IsGetShapeFeature(ImgPath1, ref huMoment1) && IsGetShapeFeature(ImgPath2, ref huMoment2))
            {
                ma[0] = huMoment1.hu1;
                ma[1] = huMoment1.hu2;
                ma[2] = huMoment1.hu3;
                ma[3] = huMoment1.hu4;
                ma[4] = huMoment1.hu5;
                ma[5] = huMoment1.hu6;
                ma[6] = huMoment1.hu7;

                mb[0] = huMoment1.hu1;
                mb[1] = huMoment2.hu2;
                mb[2] = huMoment2.hu3;
                mb[3] = huMoment2.hu4;
                mb[4] = huMoment2.hu5;
                mb[5] = huMoment2.hu6;
                mb[6] = huMoment2.hu7;

                double result = 0;

                for (int i = 0; i < 7; i++)
                {
                    double ama = Math.Abs(ma[i]);
                    double amb = Math.Abs(mb[i]);

                    int sma, smb;
                    if (ma[i] > 0)
                    {
                        sma = 1;
                    }
                    else if (ma[i] < 0)
                    {
                        sma = -1;
                    }
                    else
                    {
                        sma = 0;
                    }
                    if (mb[i] > 0)
                    {
                        smb = 1;
                    }
                    else if (mb[i] < 0)
                    {
                        smb = -1;
                    }
                    else
                    {
                        smb = 0;
                    }

                    if (ama > eps && amb > eps)
                    {
                        ama     = sma * Math.Log10(ama);
                        amb     = smb * Math.Log10(amb);
                        result += (amb - ama) * (amb - ama);
                    }
                }

                result = Math.Sqrt(result);

                return(result);
            }
            else
            {
                return(-1);
            }
        }