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
        /// <summary>
        /// 选择轮廓并计算轮廓特征
        /// </summary>
        private void NumListContours_ValueChanged(object sender, EventArgs e)
        {
            //先绘制此条轮廓
            mArgs.FeatureType  = ContourFeatureType.Contour;
            mArgs.ContourIndex = (int)NumListContours.Value;
            Params_Changed();

            //再计算此条轮廓的特征
            VectorOfPoint cnt = mContours[mArgs.ContourIndex];

            TxtContourArea.Text = CvInvoke.ContourArea(cnt).ToString();
            TxtArcLength.Text   = CvInvoke.ArcLength(cnt, true).ToString();
            MCvMoments moments = CvInvoke.Moments(cnt);

            TxtMoments.Text = string.Format("M00: {0}\r\nM01: {1}\r\nM02: {02}\r\nM03: {3}\r\nM10: {4}\r\nM11: {5}\r\nM12: {6}\r\nM20: {7}\r\nM21: {8}\r\nM30: {9}\r\n" +
                                            "Mu02: {10}\r\nMu03: {11}\r\nMu11: {12}\r\nMu12: {13}\r\nMu20: {14}\r\nMu21: {15}\r\nMu30: {16}", moments.M00,
                                            moments.M01, moments.M02, moments.M03, moments.M10, moments.M11, moments.M12, moments.M20, moments.M21, moments.M30,
                                            moments.Mu02, moments.Mu03, moments.Mu11, moments.Mu12, moments.Mu20, moments.Mu21, moments.Mu30);
            TxtContourCenter.Text = string.Format("({0},{1})", moments.M10 / moments.M00, moments.M01 / moments.M00);

            double[] huMoments = moments.GetHuMoment();
            for (int i = 0; i < huMoments.Length; i++)
            {
                TxtHuMoments.Text += huMoments[i] + "\r\n";
            }
        }
        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;
        }
Пример #4
0
        private Rectangle LocateROI()
        {
            int           prediction        = -1;
            VectorOfPoint contourOfInterest = new VectorOfPoint();

            int index = 0;

            index             = ImgProc.LargestContourIndex(_contour);
            contourOfInterest = _contour[index];

            MCvMoments moment = CvInvoke.Moments(contourOfInterest);

            double[] huMoment = moment.GetHuMoment();

            prediction = _svm.Compute(huMoment);

            //foreach (VectorOfPoint vp in _listOfContours.GetRange(0, 5))
            //{
            //    MCvMoments moment = CvInvoke.Moments(vp);
            //    double[] huMoment = moment.GetHuMoment();

            //    prediction = _svm.Compute(huMoment);

            //    if (prediction == CLASSIFICATION_ARM || prediction == CLASSIFICATION_HAND)
            //    {
            //        contourOfInterest = vp;
            //        break;
            //    }
            //}

            if (prediction == CLASSIFICATION_REJECT)
            {
                return(Rectangle.Empty);
            }
            else if (prediction == CLASSIFICATION_HAND)
            {
                //Rectangle rectRotRect = rectRot.MinAreaRect();
                //Rectangle init = CvInvoke.MinAreaRect(contoursEval1[largestContourIndexEval1]).MinAreaRect();
                //Point final = new Point(rectRotRect.X + init.X, rectRotRect.Y + init.Y);

                //return new Rectangle(final, init.Size);


                return(CvInvoke.MinAreaRect(contourOfInterest).MinAreaRect());
            }
            else if (prediction == CLASSIFICATION_ARM)
            {
                Mat         convexityDefect = new Mat();
                VectorOfInt hull            = new VectorOfInt();
                CvInvoke.ConvexHull(contourOfInterest, hull, false, false);
                CvInvoke.ConvexityDefects(contourOfInterest, hull, convexityDefect);
                RotatedRect         rectRot    = CvInvoke.MinAreaRect(contourOfInterest);
                ModifiedRotatedRect rotRectMod = new ModifiedRotatedRect(rectRot);
                int yDel = 0;

                double ptLftToRight = Geometry.Distance(rotRectMod.Pul, rotRectMod.Pur);
                double ptUpToDown   = Geometry.Distance(rotRectMod.Pul, rotRectMod.Pll);

                if (!convexityDefect.IsEmpty)
                {
                    Matrix <int> convex = new Matrix <int>(convexityDefect.Rows, convexityDefect.Cols, convexityDefect.NumberOfChannels);

                    convexityDefect.CopyTo(convex);

                    List <Point> contourTmp = new List <Point>();

                    for (int i = 0; i < contourOfInterest.Size; i++)
                    {
                        contourTmp.Add(contourOfInterest[i]);
                    }


                    List <ConvexDefects> convexDefectList = new List <ConvexDefects>();

                    for (int i = 0; i < convex.Rows; i++)
                    {
                        // do not touch
                        int startIdx = convex.Data[i, 0];
                        int endIdx   = convex.Data[i, 1];
                        int pointIdx = convex.Data[i, 2];

                        Point startPt  = contourOfInterest[startIdx];
                        Point endPt    = contourOfInterest[endIdx];
                        Point defectPt = contourOfInterest[pointIdx];

                        // do not touch
                        convexDefectList.Add(new ConvexDefects(startPt, endPt, defectPt));
                    }


                    if (ptLftToRight <= ptUpToDown)
                    {
                        Point pc1Tmp = convexDefectList[0].DefectPt;
                        Point pc2Tmp = convexDefectList[1].DefectPt;

                        Point pc = pc1Tmp.Y > pc2Tmp.Y ? pc1Tmp : pc2Tmp;


                        Point ptUpLeft   = rotRectMod.Pul;
                        Point ptUpRight  = rotRectMod.Pur;
                        Point ptLowLeft  = rotRectMod.Pll;
                        Point ptLowRight = rotRectMod.Plr;

                        ModifiedRotatedRect rotRectEval1 = ModifiedRotatedRect.Cut(ptUpLeft, ptUpRight, ptLowLeft, ptLowRight, pc);
                        ModifiedRotatedRect rotRectEval2 = ModifiedRotatedRect.Cut(ptUpLeft, ptUpRight, ptLowLeft, ptLowRight, pc, true);

                        Size      sizeFrame    = ImageInput.Size;
                        Rectangle rectROIEval1 = rotRectEval1.ToRect(sizeFrame);
                        Rectangle rectROIEval2 = rotRectEval2.ToRect(sizeFrame);

                        Mat cloneMat1 = ImageInput.Clone().Mat;

                        Mat matToBeEval1 = new Mat(cloneMat1, rectROIEval1);

                        VectorOfVectorOfPoint contoursEval1 = new VectorOfVectorOfPoint();

                        Mat matHierachyEval1 = new Mat();
                        CvInvoke.FindContours(matToBeEval1, contoursEval1, matHierachyEval1, Emgu.CV.CvEnum.RetrType.External,
                                              Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxTc89L1);

                        int largestContourIndexEval1 = ImgProc.LargestContourIndex(contoursEval1);

                        MCvMoments momentEval1 = CvInvoke.Moments(contoursEval1[largestContourIndexEval1]);

                        double[] huMomentsEval1 = momentEval1.GetHuMoment();

                        double[] featureVectorSearch = ScaleValues(huMomentsEval1, 5000.0);

                        int predictionEval1 = _svm.Compute(featureVectorSearch, MulticlassComputeMethod.Elimination);

                        //double[] featureVectorHand = ScaleValues(huMomentsEval1.
                        //    .GetRange(0, _svmMachineHand.Inputs).ToArray(), 1000.0);

                        if (predictionEval1 == CLASSIFICATION_HAND)
                        {
                            Rectangle rectRotRect = rectRot.MinAreaRect();
                            Rectangle init        = CvInvoke.MinAreaRect(contoursEval1[largestContourIndexEval1]).MinAreaRect();
                            Point     final       = new Point(rectRotRect.X + init.X, rectRotRect.Y + init.Y);

                            return(new Rectangle(final, init.Size));
                        }

                        else
                        {
                            return(Rectangle.Empty);
                        }
                    }
                    else
                    {
                        return(Rectangle.Empty);
                    }
                }
                else
                {
                    return(Rectangle.Empty);
                }
            }
            else
            {
                return(Rectangle.Empty);
            }
        }
Пример #5
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();
        }