Пример #1
0
        // chiết xuất ra đường viền bao bọc bàn tay
        private void ExtractContourAndHull(Image <Gray, byte> skin)
        {
            {
                // tìm đường viền bao bọc bàn tay
                Contour <Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                // biggest contour chính là đường biểu thị đường bao bọc bàn tay
                Contour <Point> biggestContour = null;
                // class contour() đê taọ đường viền, sử dụng bộ nhớ storage
                Double Result1 = 0;
                Double Result2 = 0;
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2        = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    // class ApproxPoly(Double, MemStorage) xấp xỉ 1 đường cong và trả về kết quả xấp xỉ
                    Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    // dung màu xanh là cây để biểu diễn đường viền bao tay
                    currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2);

                    biggestContour = currentContour;


                    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box  = biggestContour.GetMinAreaRect();
                    PointF[] points = box.GetVertices();


                    Point[] ps = new Point[points.Length];
                    for (int i = 0; i < points.Length; i++)
                    {
                        ps[i] = new Point((int)points[i].X, (int)points[i].Y);
                    }

                    currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                    currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);

                    filteredHull = new Seq <Point>(storage);
                    for (int i = 0; i < hull.Total; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            filteredHull.Push(hull[i]);
                        }
                    }

                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                    defectArray = defects.ToArray();
                }
            }
        }
        private List <MCvBox2D> GetOrderedInsideBoxes(List <MCvBox2D> allFoundRectangles, int startIndex)
        {
            PointF[]        vertices    = m_OuterBox.GetVertices();
            List <MCvBox2D> insideBoxes = new List <MCvBox2D>(m_CellInfos.Length);

            // The first three boxes are the outer boxes. Hence we skip them.
            for (int i = startIndex; i < allFoundRectangles.Count; i++)
            {
                if (PolygonContains(vertices, allFoundRectangles[i].center))
                {
                    insideBoxes.Add(allFoundRectangles[i]);
                }
            }
            if (insideBoxes.Count != m_CellInfos.Length)
            {
                return(null);
            }

            insideBoxes.Sort(delegate(MCvBox2D box1, MCvBox2D box2)
            {
                if (Math.Abs(box1.center.Y - box2.center.Y) < box1.size.Height / 2)
                {
                    // the x location determines the order
                    return(box1.center.X.CompareTo(box2.center.X));
                }
                else
                {
                    // the x location determines the order
                    return(box1.center.Y.CompareTo(box2.center.Y));
                }
            });
            return(insideBoxes);
        }
Пример #3
0
        private void GetContour_Hull(Image <Gray, byte> skin)
        {
            using (MemStorage Mem = new MemStorage())
            {
                Contour <Point> Contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
                                                             Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, Mem);
                Contour <Point> Maxium = null;

                Double area_cur = 0, area_max = 0;
                while (Contours != null)
                {
                    area_cur = Contours.Area;
                    if (area_cur > area_max)
                    {
                        area_max = area_cur;
                        Maxium   = Contours;
                    }
                    Contours = Contours.HNext;
                }

                if (Maxium != null)
                {
                    Contour <Point> CurrentContour = Maxium.ApproxPoly(Maxium.Perimeter * 0.0025, Mem);
                    Cam_Income.Draw(CurrentContour, new Bgr(Color.LimeGreen), 2);
                    Maxium = CurrentContour;

                    hull = Maxium.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box  = Maxium.GetMinAreaRect();
                    PointF[] points = box.GetVertices();
                    //box.center.Y += 30;
                    judge.X = (float)(box.center.X - (box.size.Width - box.center.X) * 0.20);
                    judge.Y = (float)(box.center.Y + (box.size.Height - box.center.Y) * 0.40);
                    //dif = box.center.Y + (box.size.Height - box.center.Y) * 0.30;
                    Point[] P_To_int = new Point[points.Length];
                    for (int i = 0; i < points.Length; i++)
                    {
                        P_To_int[i] = new Point((int)points[i].X, (int)points[i].Y);
                    }

                    Cam_Income.DrawPolyline(hull.ToArray(), true, new Bgr(Color.Pink), 2);
                    Cam_Income.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(Color.DarkOrchid), 5);
                    Cam_Income.Draw(new CircleF(new PointF(judge.X, judge.Y), 3), new Bgr(Color.Cyan), 5);

                    FilterHull = new Seq <Point>(Mem);
                    for (int i = 0; i < hull.Total - 1; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            FilterHull.Push(hull[i]);
                        }
                    }
                    Defects     = Maxium.GetConvexityDefacts(Mem, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    DefectArray = Defects.ToArray();
                    Get_Result();
                    //MessageBox.Show(DefectArray.Count().ToString());
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Use camshift to track the feature
        /// </summary>
        /// <param name="observedFeatures">The feature found from the observed image</param>
        /// <param name="initRegion">The predicted location of the model in the observed image. If not known, use MCvBox2D.Empty as default</param>
        /// <param name="priorMask">The mask that should be the same size as the observed image. Contains a priori value of the probability a match can be found. If you are not sure, pass an image fills with 1.0s</param>
        /// <returns>If a match is found, the homography projection matrix is returned. Otherwise null is returned</returns>
        public HomographyMatrix CamShiftTrack(SURFFeature[] observedFeatures, MCvBox2D initRegion, Image <Gray, Single> priorMask)
        {
            using (Image <Gray, Single> matchMask = new Image <Gray, Single>(priorMask.Size))
            {
                #region get the list of matched point on the observed image
                Single[, ,] matchMaskData = matchMask.Data;

                //Compute the matched features
                MatchedSURFFeature[] matchedFeature = _matcher.MatchFeature(observedFeatures, 2, 20);
                matchedFeature = VoteForUniqueness(matchedFeature, 0.8);

                foreach (MatchedSURFFeature f in matchedFeature)
                {
                    PointF p = f.ObservedFeature.Point.pt;
                    matchMaskData[(int)p.Y, (int)p.X, 0] = 1.0f / (float)f.SimilarFeatures[0].Distance;
                }
                #endregion

                Rectangle startRegion;
                if (initRegion.Equals(MCvBox2D.Empty))
                {
                    startRegion = matchMask.ROI;
                }
                else
                {
                    startRegion = PointCollection.BoundingRectangle(initRegion.GetVertices());
                    if (startRegion.IntersectsWith(matchMask.ROI))
                    {
                        startRegion.Intersect(matchMask.ROI);
                    }
                }

                CvInvoke.cvMul(matchMask.Ptr, priorMask.Ptr, matchMask.Ptr, 1.0);

                MCvConnectedComp comp;
                MCvBox2D         currentRegion;
                //Updates the current location
                CvInvoke.cvCamShift(matchMask.Ptr, startRegion, new MCvTermCriteria(10, 1.0e-8), out comp, out currentRegion);

                #region find the SURF features that belongs to the current Region
                MatchedSURFFeature[] featuesInCurrentRegion;
                using (MemStorage stor = new MemStorage())
                {
                    Contour <System.Drawing.PointF> contour = new Contour <PointF>(stor);
                    contour.PushMulti(currentRegion.GetVertices(), Emgu.CV.CvEnum.BACK_OR_FRONT.BACK);

                    CvInvoke.cvBoundingRect(contour.Ptr, 1); //this is required before calling the InContour function

                    featuesInCurrentRegion = Array.FindAll(matchedFeature,
                                                           delegate(MatchedSURFFeature f)
                                                           { return(contour.InContour(f.ObservedFeature.Point.pt) >= 0); });
                }
                #endregion

                return(GetHomographyMatrixFromMatchedFeatures(VoteForSizeAndOrientation(featuesInCurrentRegion, 1.5, 20)));
            }
        }
Пример #5
0
      /// <summary>
      /// Use camshift to track the feature
      /// </summary>
      /// <param name="observedFeatures">The feature found from the observed image</param>
      /// <param name="initRegion">The predicted location of the model in the observed image. If not known, use MCvBox2D.Empty as default</param>
      /// <param name="priorMask">The mask that should be the same size as the observed image. Contains a priori value of the probability a match can be found. If you are not sure, pass an image fills with 1.0s</param>
      /// <returns>If a match is found, the homography projection matrix is returned. Otherwise null is returned</returns>
      public HomographyMatrix CamShiftTrack(SURFFeature[] observedFeatures, MCvBox2D initRegion, Image<Gray, Single> priorMask)
      {
         using (Image<Gray, Single> matchMask = new Image<Gray, Single>(priorMask.Size))
         {
            #region get the list of matched point on the observed image
            Single[, ,] matchMaskData = matchMask.Data;

            //Compute the matched features
            MatchedSURFFeature[] matchedFeature = _matcher.MatchFeature(observedFeatures, 2, 20);
            matchedFeature = VoteForUniqueness(matchedFeature, 0.8);

            foreach (MatchedSURFFeature f in matchedFeature)
            {
               PointF p = f.ObservedFeature.Point.pt;
               matchMaskData[(int)p.Y, (int)p.X, 0] = 1.0f / (float) f.SimilarFeatures[0].Distance;
            }
            #endregion

            Rectangle startRegion;
            if (initRegion.Equals(MCvBox2D.Empty))
               startRegion = matchMask.ROI;
            else
            {
               startRegion = PointCollection.BoundingRectangle(initRegion.GetVertices());
               if (startRegion.IntersectsWith(matchMask.ROI))
                  startRegion.Intersect(matchMask.ROI);
            }

            CvInvoke.cvMul(matchMask.Ptr, priorMask.Ptr, matchMask.Ptr, 1.0);

            MCvConnectedComp comp;
            MCvBox2D currentRegion;
            //Updates the current location
            CvInvoke.cvCamShift(matchMask.Ptr, startRegion, new MCvTermCriteria(10, 1.0e-8), out comp, out currentRegion);

            #region find the SURF features that belongs to the current Region
            MatchedSURFFeature[] featuesInCurrentRegion;
            using (MemStorage stor = new MemStorage())
            {
               Contour<System.Drawing.PointF> contour = new Contour<PointF>(stor);
               contour.PushMulti(currentRegion.GetVertices(), Emgu.CV.CvEnum.BACK_OR_FRONT.BACK);

               CvInvoke.cvBoundingRect(contour.Ptr, 1); //this is required before calling the InContour function

               featuesInCurrentRegion = Array.FindAll(matchedFeature,
                  delegate(MatchedSURFFeature f)
                  { return contour.InContour(f.ObservedFeature.Point.pt) >= 0; });
            }
            #endregion

            return GetHomographyMatrixFromMatchedFeatures(VoteForSizeAndOrientation(featuesInCurrentRegion, 1.5, 20 ));
         }
      }
Пример #6
0
        private Polygon MCvBox2D2Polygon(MCvBox2D box)
        {
            System.Windows.Media.PointCollection polyPoints = new System.Windows.Media.PointCollection();
            foreach (var p in box.GetVertices())
            {
                polyPoints.Add(new System.Windows.Point(p.X, p.Y));
            }
            Polygon poly = new Polygon();

            poly.Points = polyPoints;
            return(poly);
        }
        void ExtractContourAndHull(Image <Gray, Byte> skin)
        {
            Contour <Point> contours       = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST);
            Contour <Point> biggestContour = null;

            Double result1 = 0;
            Double result2 = 0;

            while (contours != null)
            {
                result1 = contours.Area;
                if (result1 > result2)
                {
                    result2        = result1;
                    biggestContour = contours;
                }
                contours = contours.HNext;
            }
            if (biggestContour != null)
            {
                Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2);
                biggestContour = currentContour;

                hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                box  = biggestContour.GetMinAreaRect();
                PointF[] points = box.GetVertices();

                Point[] ps = new Point[points.Length];
                for (int i = 0; i < points.Length; i++)
                {
                    ps[i] = new Point((int)points[i].X, (int)points[i].Y);
                }
                currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);

                PointF center;
                float  radius;

                filterredHull = new Seq <Point>(storage);
                for (int i = 0; i < hull.Total; i++)
                {
                    if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                    {
                        filterredHull.Push(hull[i]);
                    }
                }

                defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                defectArray = defects.ToArray();
            }
        }
Пример #8
0
        public static RectangleF GetBoundingRectangleF(this MCvBox2D cvRotatedBox2D)
        {
            List <PointF> verticesList = new List <PointF>(cvRotatedBox2D.GetVertices());
            float         verticesMinX = verticesList.Min(ptf => ptf.X);
            float         verticesMinY = verticesList.Min(ptf => ptf.Y);
            float         verticesMaxX = verticesList.Max(ptf => ptf.X);
            float         verticesMaxY = verticesList.Max(ptf => ptf.Y);
            RectangleF    resRect      = new RectangleF(verticesMinX, verticesMinY, verticesMaxX - verticesMinX,
                                                        verticesMaxY - verticesMinY);

            return(resRect);
        }
Пример #9
0
        /// <summary>
        /// Returns the end points of the major and minor axes of an ellipse.
        /// </summary>
        /// <param name="ellipse"></param>
        /// <returns></returns>
        public static PointF[] EllipseAxes(MCvBox2D ellipse)
        {
            var vertices  = ellipse.GetVertices();
            var midPoints = new PointF[vertices.Length];

            for (int i = 0; i < midPoints.Length; i++)
            {
                var p1  = vertices[i];
                var p2  = vertices[(i + 1) % vertices.Length];
                var mid = new PointF((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2);
                // Correct the bug in the angle of the ellipse in OpenCV.
                midPoints[i] = Rotate(mid, ellipse.center, Math.PI / 2);
            }

            return(midPoints);
        }
Пример #10
0
        private void DrawHand(MCvBox2D rect, Image<Bgr, Byte> image, HandEnum handEnum)
        {
            System.Drawing.Point[] points = rect.GetVertices().Select(x => x.ToPoint()).ToArray();
            DrawPoly(points, image, new MCvScalar(0, 0, 255));
            Point center = rect.center.ToPoint();
            DrawPoint(image, center, new MCvScalar(255, 0, 0));

            if (handEnum == HandEnum.Right)
            {
                RightHandCenter = center;
            }
            if (handEnum == HandEnum.Left)
            {
                LeftHandCenter = center;
            }
            if (handEnum == HandEnum.Intersect)
            {
                RightHandCenter = center;
            }
        }
Пример #11
0
        // Extrait la "coque" du contour et les verticles afin de pouvoir calculer plus tard le nombre de doigts détectés
        // Ce code vient en partie de ce projet : https://www.youtube.com/watch?v=Fjj9gqTCTfc
        public void ExtractHull()
        {
            try
            {
                // Récupère la "coque" du plus grand contour ainsi que le rectangle qui l'englobe
                hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                box  = biggestContour.GetMinAreaRect();

                // Récupère les vertexes de la box
                PointF[] points = box.GetVertices();

                // On va créer un tableau de "Point" avec tous les points trouvés par "GetVerticles"
                Point[] ps = new Point[points.Length];
                for (int i = 0; i < points.Length; i++)
                {
                    ps[i] = new Point((int)points[i].X, (int)points[i].Y);
                }

                // Dessine la "coque" (qui entoure tous les verticles) en rouge sur l'image traitée
                imgProc.DrawPolyline(hull.ToArray(), true, new Bgr(Color.Red), 2);

                // Dessine un cercle bleu au centre de la box
                imgProc.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 5), new Bgr(Color.Blue), 2);

                // Va filtrer les points de la "coque" afin de ne garder que ceux qui sont vraiment utiles
                filteredHull = new Seq <Point>(hullStorage);
                for (int i = 0; i < hull.Total; i++)
                {
                    if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                    {
                        filteredHull.Push(hull[i]);
                    }
                }

                defects = biggestContour.GetConvexityDefacts(hullStorage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                defectArray = defects.ToArray();
            } catch (Exception ex) {
                return;
            }
        }
        public static FeatureVector ExtractFeatures(Image<Gray, byte> skin, Image<Bgr, Byte> imagen)
        {
            Contour<Point> currentContour = null;
            Contour<Point> biggestContour = null;

            using (MemStorage storage = new MemStorage())
            {

            #region extractContourAndHull
                Contour<Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);

                Double Result1 = 0;
                Double Result2 = 0;
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2 = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    imagen.Draw(currentContour, new Bgr(Color.LimeGreen), 2);
                    biggestContour = currentContour;

                    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box = biggestContour.GetMinAreaRect();
                    PointF[] points = box.GetVertices();

                    Point[] ps = new Point[points.Length];
                    for (int i = 0; i < points.Length; i++)
                        ps[i] = new Point((int)points[i].X, (int)points[i].Y);

                    imagen.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                    // imagen.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);

                    //  PointF center;
                    // float radius;

                    filteredHull = new Seq<Point>(storage);
                    for (int i = 0; i < hull.Total; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            filteredHull.Push(hull[i]);
                        }
                    }

                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                    defectArray = defects.ToArray();
                }
            }

                #endregion

            #region find palm center(needs change)

               searchRadius = 6;
               contourReduction = 3;

            //this.result = null;

            DetectarCentroPalma(biggestContour.ToList<Point>(), obtenerListaCandidatos(box));

            PointF punto = new PointF(405, 380);
            Point punt = new Point(405, 380);
            CircleF centerCircle = new CircleF(punto, 5f);
            //CircleF centerCircle = new CircleF(result.Location, 5f);
            imagen.Draw(centerCircle, new Bgr(Color.Brown), 3);

            /*
             for (int i = 0; i < defects.Total; i++)
             {
                 LineSegment2D lineaDedoCentro = new LineSegment2D(defectArray[i].StartPoint, punt);
                 imagen.Draw(lineaDedoCentro, new Bgr(Color.Green), 2);

             }
             * */

            #endregion

            List<PointF> fingertips = defectsDrawing(imagen, ref punt);

            #region create feature vector
            List<PointF> newFingertips = ordenarFingertips(fingertips);
            List<float> angles = calculateFingerAngles(fingertips, punto);

            FeatureVector vector = new FeatureVector(newFingertips, angles, punto, 5);
            //MessageBox.Show("Done");

               // frmPruebaDatos datos = new frmPruebaDatos(vector);
               // datos.Show();

            #endregion

            return vector;
        }
        private void ExtractContourAndHull(Image<Gray, byte> skin)
        {
            using (MemStorage storage = new MemStorage())
            {

                Contour<Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                Contour<Point> biggestContour = null;

                Double Result1 = 0;
                Double Result2 = 0;
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2 = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                   // currentFrame.Draw(biggestContour, new Bgr(Color.Black), 2);
                    Contour<Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    //currentFrame.Draw(currentContour, new Bgr(Color.Red), 2);
                    biggestContour = currentContour;

                    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box = biggestContour.GetMinAreaRect();
                    PointF[] points = box.GetVertices();
                    handRect = box.MinAreaRect();
                    //int xx = (handRect.Width) / 2;
                    //int yy = (handRect.Height) / 2;
                    currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1);

                    // currentFrame.Draw(new CircleF(new PointF(xx, yy), 3), new Bgr(200, 125, 75), 2);
                    Point[] ps = new Point[points.Length];
                    for (int i = 0; i < points.Length; i++)
                        ps[i] = new Point((int)points[i].X, (int)points[i].Y);

                    currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                    currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);
                   // currentFrame.Draw(new CircleF(new PointF(handRect.center.X, handRect.center.Y), 3), new Bgr(200, 125, 75), 2);

                    //ellip.MCvBox2D= CvInvoke.cvFitEllipse2(biggestContour.Ptr);
                    //currentFrame.Draw(new Ellipse(ellip.MCvBox2D), new Bgr(Color.LavenderBlush), 3);

                   // PointF center;
                    // float radius;
                    //CvInvoke.cvMinEnclosingCircle(biggestContour.Ptr, out  center, out  radius);
                    //currentFrame.Draw(new CircleF(center, radius), new Bgr(Color.Gold), 2);

                    //currentFrame.Draw(new CircleF(new PointF(ellip.MCvBox2D.center.X, ellip.MCvBox2D.center.Y), 3), new Bgr(100, 25, 55), 2);
                    //currentFrame.Draw(ellip, new Bgr(Color.DeepPink), 2);

                    //CvInvoke.cvEllipse(currentFrame, new Point((int)ellip.MCvBox2D.center.X, (int)ellip.MCvBox2D.center.Y), new System.Drawing.Size((int)ellip.MCvBox2D.size.Width, (int)ellip.MCvBox2D.size.Height), ellip.MCvBox2D.angle, 0, 360, new MCvScalar(120, 233, 88), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0);
                    //currentFrame.Draw(new Ellipse(new PointF(box.center.X, box.center.Y), new SizeF(box.size.Height, box.size.Width), box.angle), new Bgr(0, 0, 0), 2);

                    filteredHull = new Seq<Point>(storage);
                    for (int i = 0; i < hull.Total; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            filteredHull.Push(hull[i]);
                        }
                    }

                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                    defectArray = defects.ToArray();
                }
                            MCvMoments moment = new MCvMoments();               // a new MCvMoments object

            try
            {
                moment = biggestContour.GetMoments();           // Moments of biggestContour
            }
            catch (NullReferenceException)
            {

            }
            int fingerNum = 0;
            CvInvoke.cvMoments(biggestContour, ref moment, 0);

            double m_00 = CvInvoke.cvGetSpatialMoment(ref moment, 0, 0);
            double m_10 = CvInvoke.cvGetSpatialMoment(ref moment, 1, 0);
            double m_01 = CvInvoke.cvGetSpatialMoment(ref moment, 0, 1);

            int current_X = Convert.ToInt32(m_10 / m_00) / 10;      // X location of centre of contour
            int current_Y = Convert.ToInt32(m_01 / m_00) / 10;      // Y location of center of contour

             if (fingerNum == 1 || fingerNum == 0 || blue == 6)
             {
                 Cursor.Position = new Point(current_X * 10, current_Y * 10);
             }
             //Leave the cursor where it was and Do mouse click, if finger count >= 3

                }
        }
Пример #14
0
        //::::::::::::Method to calculate the convex hull:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

        public List<object> HandConvexHull(Image<Gray, Byte> frame, Rectangle Roi)
        {
            List<object> ListReturn = new List<object>(); 
            Image<Gray, Byte> BinaryImage;
            //PointF centerPalm; 

            BinaryImage = frame.Copy(Roi);
            
            BinaryImage = openingOperation(BinaryImage);
            BinaryImage = closeOperation(BinaryImage);
            BinaryImage.Save(path1 + numFrames.ToString() + ".png");  
            BinaryImage = binaryNiBlack(BinaryImage); 
            //naryImage = binaryThresholdNiBlack(BinaryImage);
            //

            using (MemStorage storage = new MemStorage())
            {
                Double result1 = 0;
                Double result2 = 0;
                
                Contour<System.Drawing.Point> contours = BinaryImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                Contour<System.Drawing.Point> biggestContour = null;

                while (contours != null)
                {
                    result1 = contours.Area;
                    if (result1 > result2)
                    {
                        result2 = result1;
                      biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    Contour<System.Drawing.Point> concurrentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    biggestContour = concurrentContour;

                    Hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_COUNTER_CLOCKWISE);
                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_COUNTER_CLOCKWISE);
                    defectsArray = defects.ToArray();

                    box = biggestContour.GetMinAreaRect();
                    points = box.GetVertices();

                    contourArea = result2;
                    contourPerimeter = biggestContour.Perimeter;
                    convexHullArea = Hull.Area;
                    convexHullPerimeter = Hull.Perimeter;

                    BinaryImage.Draw(Hull, new Gray(155), 1);
                    //ABinaryImage.Save(path1 + "ConvexHull_" + numFrames.ToString() + ".png");

                    ListReturn = GetFingersHand(BinaryImage);
                    ListReturn.Add(contourPerimeter);
                    ListReturn.Add(contourArea);
                    ListReturn.Add(convexHullPerimeter);
                    ListReturn.Add(convexHullArea);
                }
            }
            
            numFrames++; 

            return ListReturn;
        }//end HandConvexHull  
Пример #15
0
        // chi?t xu?t ra du?ng vi?n bao b?c bàn tay
        private void ExtractContourAndHull(Image <Gray, byte> skin)
        {
            {
                // tìm du?ng vi?n bao b?c bàn tay
                Contour <Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                // biggest contour chính là du?ng bi?u th? du?ng bao b?c bàn tay
                Contour <Point> biggestContour = null;
                // class contour() dê ta? du?ng vi?n s? d?ng b? nh? storage
                Double Result1 = 0;
                Double Result2 = 0;
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2        = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    // class ApproxPoly(Double, MemStorage) x?p x? 1 du?ng cong và tr? v? k?t qu? x?p x?
                    Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    // dung màu xanh là cây d? bi?u di?n du?ng vi?n bao tay
                    currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2);

                    biggestContour = currentContour;


                    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box  = biggestContour.GetMinAreaRect();
                    PointF[] points = box.GetVertices();

                    /* hi?n th? toàn b? khung chua bàn tay khi s? d?ng 2 câu l?nh sau
                     * -handRect = box.MinAreaRect();
                     * -currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1);*/

                    Point[] ps = new Point[points.Length];
                    for (int i = 0; i < points.Length; i++)
                    {
                        ps[i] = new Point((int)points[i].X, (int)points[i].Y);
                    }

                    currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                    currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);

                    PointF center;
                    float  radius;
                    #region v? ellip gi?i h?n
                    // v? du?ng ellip gi?i h?n bao quanh khi s? d?ng nh?ng câu l?nh du?i dây (2 câu l?nh s? ra 1 màu khác nhau)

                    //ellip.MCvBox2D= CvInvoke.cvFitEllipse2(biggestContour.Ptr);
                    //currentFrame.Draw(new Ellipse(ellip.MCvBox2D), new Bgr(Color.LavenderBlush), 3);

                    //CvInvoke.cvMinEnclosingCircle(biggestContour.Ptr, out  center, out  radius);
                    //currentFrame.Draw(new CircleF(center, radius), new Bgr(Color.Gold), 2);

                    //currentFrame.Draw(new CircleF(new PointF(ellip.MCvBox2D.center.X, ellip.MCvBox2D.center.Y), 3), new Bgr(100, 25, 55), 2);
                    //currentFrame.Draw(ellip, new Bgr(Color.DeepPink), 2);

                    //CvInvoke.cvEllipse(currentFrame, new Point((int)ellip.MCvBox2D.center.X, (int)ellip.MCvBox2D.center.Y), new System.Drawing.Size((int)ellip.MCvBox2D.size.Width, (int)ellip.MCvBox2D.size.Height), ellip.MCvBox2D.angle, 0, 360, new MCvScalar(120, 233, 88), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0);
                    //currentFrame.Draw(new Ellipse(new PointF(box.center.X, box.center.Y), new SizeF(box.size.Height, box.size.Width), box.angle), new Bgr(0, 0, 0), 2);
                    #endregion

                    filteredHull = new Seq <Point>(storage);
                    for (int i = 0; i < hull.Total; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            filteredHull.Push(hull[i]);
                        }
                    }

                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                    defectArray = defects.ToArray();
                }
            }
        }
        private void ExtractContourAndHull(Image<Gray, byte> skin)
        {
            using (MemStorage storage = new MemStorage())
            {

                Contour<Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                Contour<Point> biggestContour = null;

                Double Result1 = 0;
                Double Result2 = 0;
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2 = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    //currentFrame.Draw(biggestContour, new Bgr(Color.DarkViolet), 2);
                    Contour<Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2);
                    biggestContour = currentContour;
                    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box = biggestContour.GetMinAreaRect();
                    PointF[] points = box.GetVertices();
                    mv = biggestContour.GetMoments();
                    CvInvoke.cvMoments(biggestContour,ref mv, 1);
                    double m00 = CvInvoke.cvGetSpatialMoment(ref mv, 0, 0) ;
                    double m10 = CvInvoke.cvGetSpatialMoment(ref mv, 1, 0) ;
                    double m01 = CvInvoke.cvGetSpatialMoment(ref mv, 0, 1) ;
                    if (m00 != 0) { // calculate center
                    int xCenter = (int) Math.Round(m10/m00)*2;  //scale = 2
                    int yCenter = (int) Math.Round(m01/m00)*2;
                    cogPt.X =xCenter;
                    cogPt.Y =yCenter;
                    }

                    double m11 = CvInvoke.cvGetCentralMoment(ref mv, 1, 1);
                    double m20 = CvInvoke.cvGetCentralMoment(ref mv, 2, 0);
                    double m02 = CvInvoke.cvGetCentralMoment(ref mv, 0, 2);
                    contourAxisAngle = calculateTilt(m11, m20, m02);
                    Point[] ps = new Point[points.Length];
                    for (int i = 0; i < points.Length; i++)
                        ps[i] = new Point((int)points[i].X, (int)points[i].Y);

                    currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                    currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);

                    filteredHull = new Seq<Point>(storage);
                    for (int i = 0; i < hull.Total; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            filteredHull.Push(hull[i]);
                        }
                    }

                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    defectArray = defects.ToArray();
                }
            }
        }
Пример #17
0
        private void ExtractDoor(NiFile model, Matrix4 worldMatrix, int fixtureid)
        {
            // take everything that is under a doorX node and use it for the hull...
            if (model == null)
            {
                return;
            }

            var doorVertices = new Dictionary <string, List <Vector3> >();

            // find all trimeshs and tristrips
            foreach (var obj in model.ObjectsByRef.Values)
            {
                var avNode = obj as NiAVObject;
                if (avNode == null)
                {
                    continue;
                }

                if (!IsMatched(avNode, new[] { "visible", "collidee", "collide" }))
                {
                    continue;
                }

                var doorName = FindMatchRegex(avNode, new[] { DoorRegex });

                if (doorName == string.Empty)
                {
                    continue;
                }

                Vector3[]  vertices  = null;
                Triangle[] triangles = null;

                TryExtractTriShape(obj, worldMatrix, false, false, ref vertices, ref triangles);

                if (vertices == null)
                {
                    TryExtractTriStrips(obj, worldMatrix, false, false, ref vertices, ref triangles);
                }

                if (vertices == null)
                {
                    continue;
                }

                if (!doorVertices.ContainsKey(doorName))
                {
                    doorVertices.Add(doorName, new List <Vector3>());
                }
                doorVertices[doorName].AddRange(vertices);
            }


            foreach (var key in doorVertices.Keys)
            {
                float hullMinZ = float.MaxValue;
                float hullMaxZ = float.MinValue;

                var verts = doorVertices[key].ToArray();

                var pts = new List <PointF>();
                foreach (Vector3 vert in verts)
                {
                    hullMinZ = Math.Min(vert.Z, hullMinZ);
                    hullMaxZ = Math.Max(vert.Z, hullMaxZ);
                    pts.Add(new PointF(vert.X, vert.Y));
                }

                MCvBox2D box = PointCollection.MinAreaRect(pts.ToArray());

                float maxSize = box.size.Width;
                maxSize = Math.Max(maxSize, box.size.Height);
                maxSize = Math.Max(maxSize, hullMaxZ - hullMinZ);

                // There are some weird door ids in e.g. Jordheim (z120): "door01:0" e.g. -- how do they translate to IDs?
                var doorID  = Regex.Match(key.Replace(":", ""), "([0-9]+)").Groups[1].Value;
                var heading = ((box.angle + (box.size.Width < box.size.Height ? 0.0 : 90.0 + 90.0)) * DEGREES_TO_HEADING) % 0x1000;
                if (heading < 0)
                {
                    heading += 0x1000;
                }
                DoorWriter.WriteDoor(Zone.ID * 1000000 + fixtureid * 100 + int.Parse(doorID), model.FileName, (int)box.center.X, (int)box.center.Y, (int)hullMinZ, (int)heading, (int)maxSize);


                // Make sure we have a min of 20f for doors on width/height
                box.size.Width  = Math.Max(20f, box.size.Width);
                box.size.Height = Math.Max(20f, box.size.Height);

                // Make sure the door touches the ground...
                hullMinZ -= 16.0f;

                var boxVertices = box.GetVertices();
                GeomSetWriter.WriteConvexVolume(boxVertices.Length, hullMinZ, hullMaxZ, CEM.GeomSetWriter.eAreas.Door);

                foreach (var vert in boxVertices)
                {
                    GeomSetWriter.WriteConvexVolumeVertex(new Vector3(vert.X, vert.Y, hullMinZ)); // debug
                }
            }
        }
        public static List<PointF> obtenerListaCandidatos(MCvBox2D box)
        {
            PointF[] points = box.GetVertices();

            float p1 = points[0].X;
            float p2 = points[0].Y;
            float p3 = points[1].X;
            float p4 = points[1].Y;
            float p5 = points[2].X;
            float p6 = points[2].Y;
            float p7 = points[3].X;
            float p8 = points[3].Y;

            float[] equises = new float[]
               {
               p1,p3,p5,p7

               };

            float[] yes = new float[]
               {
               p2,p4,p6,p8

               };

            float minimo = p1;
            float maximo = p1;
            foreach (float i in equises)
            {
                if (i < minimo)
                {
                    minimo = i;
                }

                if (i > maximo)
                {
                    maximo = i;
                }

            }

            float minimoY = p2;
            float maximoY = p2;

            foreach (float i in yes)
            {
                if (i < minimoY)
                {
                    minimoY = i;
                }

                if (i > maximoY)
                {
                    maximoY = i;
                }

            }

            PointF vertice1 = new PointF(minimo, minimoY);
            PointF vertice2 = new PointF(maximo, maximoY);

            List<PointF> listaPuntos = new List<PointF>();

            for (float i = vertice1.X + 1; i < vertice2.X; i = i + 4)
            {
                for (float j = vertice1.Y - 1; j < vertice2.Y; j = j + 4)
                {

                    PointF punto = new PointF(i, j);

                    listaPuntos.Add(punto);

                }
            }

            return listaPuntos;
        }
Пример #19
0
        private void ExtractContourAndHull(Image <Gray, byte> skin)
        {
            using (MemStorage storage = new MemStorage())
            {
                Contour <Point> contours       = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                Contour <Point> biggestContour = null;

                Double Result1 = 0;
                Double Result2 = 0;
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2        = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    //currentFrame.Draw(biggestContour, new Bgr(Color.DarkViolet), 2);
                    Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2);
                    biggestContour = currentContour;


                    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box  = biggestContour.GetMinAreaRect();
                    PointF[] points = box.GetVertices();



                    mv = biggestContour.GetMoments();
                    CvInvoke.cvMoments(biggestContour, ref mv, 1);
                    double m00 = CvInvoke.cvGetSpatialMoment(ref mv, 0, 0);
                    double m10 = CvInvoke.cvGetSpatialMoment(ref mv, 1, 0);
                    double m01 = CvInvoke.cvGetSpatialMoment(ref mv, 0, 1);

                    if (m00 != 0)                                     // calculate center
                    {
                        int xCenter = (int)Math.Round(m10 / m00) * 2; //scale = 2
                        int yCenter = (int)Math.Round(m01 / m00) * 2;
                        cogPt.X = xCenter;
                        cogPt.Y = yCenter;
                    }

                    double m11 = CvInvoke.cvGetCentralMoment(ref mv, 1, 1);
                    double m20 = CvInvoke.cvGetCentralMoment(ref mv, 2, 0);
                    double m02 = CvInvoke.cvGetCentralMoment(ref mv, 0, 2);
                    contourAxisAngle = calculateTilt(m11, m20, m02);



                    Point[] ps = new Point[points.Length];
                    for (int i = 0; i < points.Length; i++)
                    {
                        ps[i] = new Point((int)points[i].X, (int)points[i].Y);
                    }

                    currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                    currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);



                    PointF center;
                    float  radius;

                    filteredHull = new Seq <Point>(storage);
                    for (int i = 0; i < hull.Total; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            filteredHull.Push(hull[i]);
                        }
                    }

                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                    defectArray = defects.ToArray();
                }
            }
        }
Пример #20
0
 public static float GetTrueArea(this MCvBox2D rec)
 {
     PointF[] pl = rec.GetVertices();
     return(pl[0].DistanceTo(pl[1]) * pl[1].DistanceTo(pl[2]));
 }
Пример #21
0
        private unsafe void ProcessImage(ref Image <Bgr, byte> img)
        {
            Image <Gray, byte> gray_image = img.Convert <Gray, byte>();

            grayImg   = gray_image;
            binaryImg = gray_image.ThresholdBinaryInv(new Gray(200), new Gray(255));
            //Find contours with no holes try CV_RETR_EXTERNAL to find holes
            IntPtr Dyncontour = new IntPtr();//存放检测到的图像块的首地址

            IntPtr Dynstorage = CvInvoke.cvCreateMemStorage(0);
            int    n          = CvInvoke.cvFindContours(binaryImg.Ptr, Dynstorage, ref Dyncontour, sizeof(MCvContour),
                                                        Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, new Point(0, 0));
            Seq <Point>     DyncontourTemp1 = new Seq <Point>(Dyncontour, null);//方便对IntPtr类型进行操作
            Seq <Point>     DyncontourTemp  = DyncontourTemp1;
            List <MCvBox2D> rectList        = new List <MCvBox2D>();

            for (; DyncontourTemp != null && DyncontourTemp.Ptr.ToInt32() != 0; DyncontourTemp = DyncontourTemp.HNext)
            {
                CvInvoke.cvDrawContours(image, DyncontourTemp, new MCvScalar(255, 0, 0), new MCvScalar(0, 255, 0), 10, 1, Emgu.CV.CvEnum.LINE_TYPE.FOUR_CONNECTED, new Point(0, 0));
                PointF[] rect1 = DyncontourTemp.GetMinAreaRect().GetVertices();
                rectList.Add(DyncontourTemp.GetMinAreaRect());
                var pointfSeq =
                    from p in rect1
                    select new Point((int)p.X, (int)p.Y);
                Point[] points = pointfSeq.ToArray();
                for (int j = 0; j < 4; j++)
                {
                    CvInvoke.cvLine(image, points[j], points[(j + 1) % 4], new MCvScalar(0, 0, 255), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0);
                }
                //CvInvoke.cvNamedWindow("main");
            }
            for (int i = 0; i < rectList.Count(); i++)
            {
                MCvBox2D rect   = rectList[i];
                PointF[] pl     = rect.GetVertices();
                var      points =
                    from p in pl
                    orderby p.Y ascending
                    select p;
                pl = points.ToArray();
                PointF startP = pl[0];
                PointF shortP = pl[1];
                PointF longP  = pl[2];
                if (pl[1].DistanceTo(startP) > pl[2].DistanceTo(startP))
                {
                    shortP = pl[2];
                    longP  = pl[1];
                }

                float longDis = longP.DistanceTo(startP);
                if (longDis < minLength)
                {
                    continue;
                }
                float  shortDis  = shortP.DistanceTo(startP);
                float  longslope = Math.Abs(longP.X - startP.X) / longDis;
                float  min       = 9999;
                PointF ap1       = new PointF();
                PointF ap2       = new PointF();

                if (longslope < 0.707)//vert
                {
                    for (int y = begin; y < Convert.ToInt32(Math.Abs(longP.Y - startP.Y)) && Math.Abs(y) < width; y++)
                    {
                        PointF p1  = InterPolateP(startP, longP, y / Math.Abs(longP.Y - startP.Y));
                        PointF p2  = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y);
                        float  dis = GetHandWidthBetween(p1, p2);
                        if (dis < min)
                        {
                            min = dis;
                            ap1 = p1;
                            ap2 = p2;
                        }
                    }
                }
                else
                {
                    for (int X = begin; X < Convert.ToInt32(Math.Abs(longP.X - startP.X)) && Math.Abs(X) < width; X++)
                    {
                        PointF p1  = InterPolateP(startP, longP, X / Math.Abs(longP.X - startP.X));
                        PointF p2  = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y);
                        float  dis = GetHandWidthBetween(p1, p2);
                        if (dis < min)
                        {
                            min = dis;
                            ap1 = p1;
                            ap2 = p2;
                        }
                    }
                }
                CvInvoke.cvLine(image, ap1.ToPoint(), ap2.ToPoint(), new MCvScalar(0, 0, 255), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0);
            }



            //CvInvoke.cvShowImage("main", tempImage);


            //image = binaryImg.Convert<Bgr, Byte>();
            //Bitmap bmp = image.ToBitmap();
            //using (Graphics g = Graphics.FromImage(bmp))
            //{
            //    List<Rectangle> recList = new List<Rectangle>();
            //    double max_area = 0;
            //    for (int i = 0; contours != null; contours = contours.HNext)
            //    {
            //        if ((contours.Area > Math.Pow(25, 2)) && (contours.Area < Math.Pow(300, 2)))
            //        {
            //            // Console.WriteLine(contours.Area);
            //            Seq<Point> seq = contours.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
            //            var pointfSeq =
            //                    from p in seq
            //                    select new PointF(p.X, p.Y);
            //            //max_area = contours.Area;
            //            // MCvBox2D ellp = CvInvoke.cvFitEllipse2(seq.Ptr);
            //            MCvBox2D ellp = contours.GetMinAreaRect();

            //            //g.DrawPolygon(new Pen(Brushes.Red, 2), contours.ToArray());
            //            //Ellipse elps = PointCollection.EllipseLeastSquareFitting(pointfSeq.ToArray());
            //            g.TranslateTransform(ellp.center.X, ellp.center.Y);
            //            g.RotateTransform(ellp.angle);
            //            g.DrawRectangle(new Pen(Brushes.Red, 2), -ellp.MinAreaRect().Width / 2,
            //                                                    -ellp.MinAreaRect().Height / 2,
            //                                                    ellp.MinAreaRect().Width,
            //                                                    ellp.MinAreaRect().Height);
            //            g.RotateTransform(-ellp.angle);

            //            g.DrawRectangle(new Pen(Brushes.Red, 2), -ellp.MinAreaRect().Width / 2,
            //                                                   -ellp.MinAreaRect().Height / 2,
            //                                                   ellp.MinAreaRect().Width,
            //                                                   ellp.MinAreaRect().Height);
            //            // g.DrawRectangle(new Pen(Brushes.Red, 2), -elps.MCvBox2D.MinAreaRect().Width / 2, -elps.MCvBox2D.MinAreaRect().Height / 2, elps.MCvBox2D.MinAreaRect().Width, elps.MCvBox2D.MinAreaRect().Height);
            //            //g.DrawEllipse(new Pen(Brushes.Red, 2), -ellp.MinAreaRect().Width / 2,
            //            //                                        -ellp.MinAreaRect().Height / 2,
            //            //                                        ellp.MinAreaRect().Width,
            //            //                                        ellp.MinAreaRect().Height);
            //            g.ResetTransform();

            //            // break;
            //        }
            //    }
            //}

            //imageBox1.Image = new Image<Bgr, byte>(bmp);
        }
Пример #22
0
        private MCvBox2D SplitHand(MCvBox2D rect, HandEnum handEnum, PointF Elbow2HandVector)
        {

            if (handEnum == HandEnum.Both || handEnum == HandEnum.Intersect)
            {
                return new MCvBox2D(rect.center, rect.MinAreaRect().Size, 0);
            }
            PointF[] pl = rect.GetVertices();
            Point[] splittedHands = new Point[4];
            //find angle of long edge
            PointF startP = pl[1];
            PointF shortP = pl[0];
            PointF longP = pl[2];
            PointF ap1 = new PointF();
            PointF ap2 = new PointF();

          
            if (pl[0].DistanceTo(startP) > pl[2].DistanceTo(startP))
            {
                shortP = pl[2];
                longP = pl[0];
            }

            SizeF size = new SizeF();
            size.Width = shortP.DistanceTo(startP);
            size.Height = longP.DistanceTo(startP);
            PointF shortEdge = new PointF(shortP.X - startP.X, shortP.Y - startP.Y);
            float t_angle = (float)(Math.Atan(shortEdge.Tan())*180/Math.PI);
  
            MCvBox2D box = new MCvBox2D();
            box.size = size;
            box.center = pl.GetCenter();
       
            float longDis = longP.DistanceTo(startP);
            float shortDis = shortP.DistanceTo(startP);
            // x and long edge slope 
            float longslope = Math.Abs(longP.X - startP.X) / longDis;
            float min = float.MaxValue;

            float factor = Math.Max(Math.Abs(longP.Y - startP.Y) / longDis, Math.Abs(longP.X - startP.X) / longDis);
            int TransformEnd = Convert.ToInt32(factor * end);
            int TransformBegin = Convert.ToInt32(factor * begin);
            //Console.WriteLine(TransformBegin);
            //Console.WriteLine(TransformEnd);
            // > 45
            if (longslope < 0.707)//vert
            {
                // point up
                if (Elbow2HandVector.Y <= 0)
                {
                    box.angle = t_angle;
                    startP = pl.OrderBy((x => x.Y)).First();
                }
                else
                {
                    box.angle = t_angle + 180;
                    startP = pl.OrderByDescending((x => x.Y)).First();
                }


                if (longDis < minLength)
                {
                    return box;
                }

                pl = pl.OrderBy(x => x.DistanceTo(startP)).ToArray();
                shortP = pl[1];
                longP = pl[2];

                for (int y = TransformBegin; y < Convert.ToInt32(Math.Abs(longP.Y - startP.Y)) && Math.Abs(y) < TransformEnd; y++)
                {
                    PointF p1 = InterPolateP(startP, longP, y / Math.Abs(longP.Y - startP.Y));
                    PointF p2 = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y);
                    float dis = GetHandWidthBetween(p1, p2);
                    if (dis < min)
                    {
                        min = dis;
                        ap1 = p1;
                        ap2 = p2;
                    }
                }
            }
            else // horizontal 
            {
                // point top for right hand
                if (t_angle <0)
                {
                    if (handEnum == HandEnum.Right)
                    {
                        box.angle = t_angle;
                    }
                    else
                    {
                        box.angle = t_angle + 180;
                    }
                }
                // point bottom for right hand
                else
                {
                    if (handEnum == HandEnum.Right)
                    {
                        box.angle = t_angle - 180;
                    }
                    else
                    {
                        box.angle = t_angle;
                    }
                }
                if (handEnum == HandEnum.Right)
                {
                    startP = pl.OrderBy((x => x.X)).ToArray()[0];

                }
                else if (handEnum == HandEnum.Left)
                {
                    startP = pl.OrderByDescending((x => x.X)).ToArray()[0];
                }


                if (longDis < minLength)
                {
                    return box;
                }
                pl = pl.OrderBy(x => x.DistanceTo(startP)).ToArray();
                shortP = pl[1];
                longP = pl[2];
                for (int X = TransformBegin; X < Convert.ToInt32(Math.Abs(longP.X - startP.X)) && Math.Abs(X) < TransformEnd; X++)
                {
                    PointF p1 = InterPolateP(startP, longP, X / Math.Abs(longP.X - startP.X));
                    PointF p2 = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y);
                    float dis = GetHandWidthBetween(p1, p2);
                    if (dis < min)
                    {
                        min = dis;
                        ap1 = p1;
                        ap2 = p2;
                    }
                }
            }
            if (ap1 == null || ap1 == PointF.Empty)
            {
                return box;
            }
            splittedHands[0] = startP.ToPoint();
            splittedHands[1] = ap1.ToPoint();
            splittedHands[2] = ap2.ToPoint();
            splittedHands[3] = shortP.ToPoint();


            //Point lowP = p.OrderByDescending(x => x.Y).First();
            //Point highP = p.OrderByDescending(x => x.DistanceTo(lowP)).First();
            //Point widthP = p.OrderBy(x => x.TanWith(lowP)).First();
            box.center = splittedHands.GetCenter();
            box.size.Height = startP.DistanceTo(ap1);
            
            return box;
        }
Пример #23
0
        public static FeatureVector ExtractFeatures(Image <Gray, byte> skin, Image <Bgr, Byte> imagen)
        {
            Contour <Point> currentContour = null;
            Contour <Point> biggestContour = null;

            using (MemStorage storage = new MemStorage())
            {
                #region extractContourAndHull
                Contour <Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);


                Double Result1 = 0;
                Double Result2 = 0;
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2        = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    imagen.Draw(currentContour, new Bgr(Color.LimeGreen), 2);
                    biggestContour = currentContour;


                    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box  = biggestContour.GetMinAreaRect();
                    PointF[] points = box.GetVertices();



                    Point[] ps = new Point[points.Length];
                    for (int i = 0; i < points.Length; i++)
                    {
                        ps[i] = new Point((int)points[i].X, (int)points[i].Y);
                    }

                    imagen.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                    // imagen.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);

                    //  PointF center;
                    // float radius;

                    filteredHull = new Seq <Point>(storage);
                    for (int i = 0; i < hull.Total; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            filteredHull.Push(hull[i]);
                        }
                    }

                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                    defectArray = defects.ToArray();
                }
            }

            #endregion

            #region find palm center(needs change)

            searchRadius     = 6;
            contourReduction = 3;

            //this.result = null;

            DetectarCentroPalma(biggestContour.ToList <Point>(), obtenerListaCandidatos(box));



            PointF  punto        = new PointF(405, 380);
            Point   punt         = new Point(405, 380);
            CircleF centerCircle = new CircleF(punto, 5f);
            //CircleF centerCircle = new CircleF(result.Location, 5f);
            imagen.Draw(centerCircle, new Bgr(Color.Brown), 3);

            /*
             * for (int i = 0; i < defects.Total; i++)
             * {
             *   LineSegment2D lineaDedoCentro = new LineSegment2D(defectArray[i].StartPoint, punt);
             *   imagen.Draw(lineaDedoCentro, new Bgr(Color.Green), 2);
             *
             * }
             * */


            #endregion

            List <PointF> fingertips = defectsDrawing(imagen, ref punt);

            #region create feature vector
            List <PointF> newFingertips = ordenarFingertips(fingertips);
            List <float>  angles        = calculateFingerAngles(fingertips, punto);

            FeatureVector vector = new FeatureVector(newFingertips, angles, punto, 5);
            //MessageBox.Show("Done");

            // frmPruebaDatos datos = new frmPruebaDatos(vector);
            // datos.Show();

            #endregion

            return(vector);
        }
Пример #24
0
        public static List <PointF> obtenerListaCandidatos(MCvBox2D box)
        {
            PointF[] points = box.GetVertices();


            float p1 = points[0].X;
            float p2 = points[0].Y;
            float p3 = points[1].X;
            float p4 = points[1].Y;
            float p5 = points[2].X;
            float p6 = points[2].Y;
            float p7 = points[3].X;
            float p8 = points[3].Y;

            float[] equises = new float[]
            {
                p1, p3, p5, p7
            };

            float[] yes = new float[]
            {
                p2, p4, p6, p8
            };


            float minimo = p1;
            float maximo = p1;

            foreach (float i in equises)
            {
                if (i < minimo)
                {
                    minimo = i;
                }

                if (i > maximo)
                {
                    maximo = i;
                }
            }

            float minimoY = p2;
            float maximoY = p2;

            foreach (float i in yes)
            {
                if (i < minimoY)
                {
                    minimoY = i;
                }

                if (i > maximoY)
                {
                    maximoY = i;
                }
            }

            PointF vertice1 = new PointF(minimo, minimoY);
            PointF vertice2 = new PointF(maximo, maximoY);

            List <PointF> listaPuntos = new List <PointF>();

            for (float i = vertice1.X + 1; i < vertice2.X; i = i + 4)
            {
                for (float j = vertice1.Y - 1; j < vertice2.Y; j = j + 4)
                {
                    PointF punto = new PointF(i, j);

                    listaPuntos.Add(punto);
                }
            }

            return(listaPuntos);
        }
Пример #25
0
 public void TestGetBox2DPoints()
 {
     MCvBox2D box = new MCvBox2D(
     new PointF(3.0f, 2.0f),
     new SizeF(4.0f, 6.0f),
     0.0f);
      PointF[] vertices = box.GetVertices();
      Assert.IsTrue(vertices[0].Equals(new PointF(0.0f, 0.0f)));
      Assert.IsTrue(vertices[1].Equals(new PointF(6.0f, 0.0f)));
 }
Пример #26
0
        private void ExtractContourAndHull(Image <Gray, byte> skin)
        {
            using (MemStorage storage = new MemStorage())
            {
                Contour <Point> contours       = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                Contour <Point> biggestContour = null;

                Double Result1 = 0;
                Double Result2 = 0;
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2        = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    // currentFrame.Draw(biggestContour, new Bgr(Color.Black), 2);
                    Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    //currentFrame.Draw(currentContour, new Bgr(Color.Red), 2);
                    biggestContour = currentContour;


                    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box  = biggestContour.GetMinAreaRect();
                    PointF[] points = box.GetVertices();
                    handRect = box.MinAreaRect();
                    //int xx = (handRect.Width) / 2;
                    //int yy = (handRect.Height) / 2;
                    currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1);

                    // currentFrame.Draw(new CircleF(new PointF(xx, yy), 3), new Bgr(200, 125, 75), 2);
                    Point[] ps = new Point[points.Length];
                    for (int i = 0; i < points.Length; i++)
                    {
                        ps[i] = new Point((int)points[i].X, (int)points[i].Y);
                    }

                    currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                    currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);
                    // currentFrame.Draw(new CircleF(new PointF(handRect.center.X, handRect.center.Y), 3), new Bgr(200, 125, 75), 2);


                    //ellip.MCvBox2D= CvInvoke.cvFitEllipse2(biggestContour.Ptr);
                    //currentFrame.Draw(new Ellipse(ellip.MCvBox2D), new Bgr(Color.LavenderBlush), 3);

                    // PointF center;
                    // float radius;
                    //CvInvoke.cvMinEnclosingCircle(biggestContour.Ptr, out  center, out  radius);
                    //currentFrame.Draw(new CircleF(center, radius), new Bgr(Color.Gold), 2);

                    //currentFrame.Draw(new CircleF(new PointF(ellip.MCvBox2D.center.X, ellip.MCvBox2D.center.Y), 3), new Bgr(100, 25, 55), 2);
                    //currentFrame.Draw(ellip, new Bgr(Color.DeepPink), 2);

                    //CvInvoke.cvEllipse(currentFrame, new Point((int)ellip.MCvBox2D.center.X, (int)ellip.MCvBox2D.center.Y), new System.Drawing.Size((int)ellip.MCvBox2D.size.Width, (int)ellip.MCvBox2D.size.Height), ellip.MCvBox2D.angle, 0, 360, new MCvScalar(120, 233, 88), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0);
                    //currentFrame.Draw(new Ellipse(new PointF(box.center.X, box.center.Y), new SizeF(box.size.Height, box.size.Width), box.angle), new Bgr(0, 0, 0), 2);


                    filteredHull = new Seq <Point>(storage);
                    for (int i = 0; i < hull.Total; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            filteredHull.Push(hull[i]);
                        }
                    }

                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                    defectArray = defects.ToArray();
                }
                MCvMoments moment = new MCvMoments();                           // a new MCvMoments object

                try
                {
                    moment = biggestContour.GetMoments();       // Moments of biggestContour
                }
                catch (NullReferenceException)
                {
                }
                int fingerNum = 0;
                CvInvoke.cvMoments(biggestContour, ref moment, 0);

                double m_00 = CvInvoke.cvGetSpatialMoment(ref moment, 0, 0);
                double m_10 = CvInvoke.cvGetSpatialMoment(ref moment, 1, 0);
                double m_01 = CvInvoke.cvGetSpatialMoment(ref moment, 0, 1);

                int current_X = Convert.ToInt32(m_10 / m_00) / 10;  // X location of centre of contour
                int current_Y = Convert.ToInt32(m_01 / m_00) / 10;  // Y location of center of contour


                if (fingerNum == 1 || fingerNum == 0 || blue == 6)
                {
                    Cursor.Position = new Point(current_X * 10, current_Y * 10);
                }
                //Leave the cursor where it was and Do mouse click, if finger count >= 3
            }
        }
Пример #27
0
        //::::::::::::Method to calculate the convex hull:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

        public List<object> HandConvexHull(Image<Gray, Byte> frame, Rectangle Roi)
        {
            List<object> ListReturn = new List<object>(); 
            Image<Gray, Byte> BinaryImage;
            Image<Gray,Byte> frameImagePtr;  

            BinaryImage = frame.Copy(Roi);
            //BinaryImage.Save(path1 + numFrames.ToString() + ".png");

            //Binarization using Otsu algortihm 
            frameImagePtr= BinaryImage; 

            IntPtr framePtr = frameImagePtr.Ptr;
            IntPtr binaryPrt = BinaryImage.Ptr; 
            
            CvInvoke.cvThreshold(framePtr, binaryPrt, 0, 255, Emgu.CV.CvEnum.THRESH.CV_THRESH_OTSU);
            BinaryImage.Save(path1 + numFrames.ToString() + "B_Otsu.png");
            //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
            
            BinaryImage = openingOperation(BinaryImage);
            BinaryImage = closeOperation(BinaryImage);
            //BinaryImage.Save(path1 + numFrames.ToString() + "B_OC.png");


            using (MemStorage storage = new MemStorage())
            {
                Double result1 = 0;
                Double result2 = 0;
                
                Contour<System.Drawing.Point> contours = BinaryImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                Contour<System.Drawing.Point> biggestContour = null;

                while (contours != null)
                {
                    result1 = contours.Area;
                    if (result1 > result2)
                    {
                        result2 = result1;
                      biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    Contour<System.Drawing.Point> concurrentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    biggestContour = concurrentContour;

                    Hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_COUNTER_CLOCKWISE);
                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_COUNTER_CLOCKWISE);
                    defectsArray = defects.ToArray();

                    box = biggestContour.GetMinAreaRect(); 
                    points = box.GetVertices();

                    CircleF centerBoxDraw = new CircleF(box.center, 4f); 

                    contourArea = result2;
                    contourPerimeter = biggestContour.Perimeter;
                    convexHullArea = Hull.Area;
                    convexHullPerimeter = Hull.Perimeter;

                    BinaryImage.Draw(Hull, new Gray(155), 1);
                    BinaryImage.Draw(box, new Gray(100), 1);
                    BinaryImage.Draw(centerBoxDraw, new Gray(200), 1); 
                    BinaryImage.Save(path1 + "ConvexHull_" + numFrames.ToString() + ".png");

                    ListReturn = GetFingers(BinaryImage);
                    
                    //::::::Old features
                    //ListReturn.Add(contourPerimeter);
                    //ListReturn.Add(contourArea);
                    //ListReturn.Add(convexHullPerimeter);
                    //ListReturn.Add(convexHullArea);
                }
            }
            
            numFrames++; 

            return ListReturn;
        }//end HandConvexHull  
        // Extrait la "coque" du contour et les verticles afin de pouvoir calculer plus tard le nombre de doigts détectés
        // Ce code vient en partie de ce projet : https://www.youtube.com/watch?v=Fjj9gqTCTfc
        public void ExtractHull()
        {
            try
            {
                // Récupère la "coque" du plus grand contour ainsi que le rectangle qui l'englobe
                hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                box = biggestContour.GetMinAreaRect();

                // Récupère les vertexes de la box
                PointF[] points = box.GetVertices();

                // On va créer un tableau de "Point" avec tous les points trouvés par "GetVerticles"
                Point[] ps = new Point[points.Length];
                for (int i = 0; i < points.Length; i++)
                {
                    ps[i] = new Point((int)points[i].X, (int)points[i].Y);
                }

                // Dessine la "coque" (qui entoure tous les verticles) en rouge sur l'image traitée
                imgProc.DrawPolyline(hull.ToArray(), true, new Bgr(Color.Red), 2);

                // Dessine un cercle bleu au centre de la box
                imgProc.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 5), new Bgr(Color.Blue), 2);

                // Va filtrer les points de la "coque" afin de ne garder que ceux qui sont vraiment utiles
                filteredHull = new Seq<Point>(hullStorage);
                for (int i = 0; i < hull.Total; i++)
                {
                    if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                    {
                        filteredHull.Push(hull[i]);
                    }
                }

                defects = biggestContour.GetConvexityDefacts(hullStorage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                defectArray = defects.ToArray();
            } catch(Exception ex) {
                return;
            }
        }
Пример #29
0
        /// <summary>
        /// Returns the end points of the major and minor axes of an ellipse.
        /// </summary>
        /// <param name="ellipse"></param>
        /// <returns></returns>
        public static PointF[] EllipseAxes(MCvBox2D ellipse)
        {
            var vertices = ellipse.GetVertices();
              var midPoints = new PointF[vertices.Length];
              for (int i = 0; i < midPoints.Length; i++) {
            var p1 = vertices[i];
            var p2 = vertices[(i + 1) % vertices.Length];
            var mid = new PointF((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2);
            // Correct the bug in the angle of the ellipse in OpenCV.
            midPoints[i] = Rotate(mid, ellipse.center, Math.PI / 2);
              }

              return midPoints;
        }
Пример #30
0
        private Image<Gray, Byte> CalculateConvexityDefacts(Image<Gray, Byte> image)
        {
            Gray cannyThreshold = new Gray(80);
            Gray cannyThresholdLinking = new Gray(80);

            //image = image.Canny(cannyThreshold, cannyThresholdLinking);
            image = image.ThresholdBinary(cannyThreshold, cannyThresholdLinking);
            //image = image.Erode(1);
            //image = image.SmoothBilatral(1, 1, 1);
            //image = image.SmoothMedian(5);
            //image = image.SmoothBlur(1,1);
            using (MemStorage storage = new MemStorage())
            {

                Contour<Point> contours = image.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                Contour<Point> biggestContour = null;

                Double Result1 = 0;
                Double Result2 = 0;

                //takes the biggest contour to track (not really relevant if u paint only the hand.)
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2 = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }
                double contourArea = biggestContour.Area;

                if (biggestContour != null)
                {
                    //Drawing the contour of the hand
                    Contour<Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    image.Draw(currentContour, new Gray(250), 1);

                    biggestContour = currentContour;

                    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box = biggestContour.GetMinAreaRect();

                    PointF[] points = box.GetVertices();
                    Point[] ps = new Point[points.Length];

                    for (int i = 0; i < points.Length; i++)
                    {
                        ps[i] = new Point((int)points[i].X, (int)points[i].Y);
                    }

                    image.DrawPolyline(hull.ToArray(), true, new Gray(255), 1);
                    image.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 2), new Gray(255), 1);

                    filteredHull = new Seq<Point>(storage);
                    for (int i = 0; i < hull.Total; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            filteredHull.Push(hull[i]);
                        }
                    }

                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    defectArray = defects.ToArray();
                }
            }
            return image;
        }
Пример #31
0
        /// /////////// paste here

        private void ExtractContourAndHull(Image <Gray, byte> skin)
        {
            using (MemStorage storage = new MemStorage())
            {
                Contour <Point> contours       = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                Contour <Point> biggestContour = null;

                Double Result1 = 0;
                Double Result2 = 0;
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2        = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    //currentFrame.Draw(biggestContour, new Bgr(Color.DarkViolet), 2);
                    Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2);
                    biggestContour = currentContour;


                    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box  = biggestContour.GetMinAreaRect();
                    PointF[] points = box.GetVertices();



                    mv = biggestContour.GetMoments();
                    CvInvoke.cvMoments(biggestContour, ref mv, 1);
                    double m00 = CvInvoke.cvGetSpatialMoment(ref mv, 0, 0);
                    double m10 = CvInvoke.cvGetSpatialMoment(ref mv, 1, 0);
                    double m01 = CvInvoke.cvGetSpatialMoment(ref mv, 0, 1);

                    if (m00 != 0)                                     // calculate center
                    {
                        int xCenter = (int)Math.Round(m10 / m00) * 2; //scale = 2
                        int yCenter = (int)Math.Round(m01 / m00) * 2;
                        cogPt.X = xCenter;
                        cogPt.Y = yCenter;
                    }

                    double m11 = CvInvoke.cvGetCentralMoment(ref mv, 1, 1);
                    double m20 = CvInvoke.cvGetCentralMoment(ref mv, 2, 0);
                    double m02 = CvInvoke.cvGetCentralMoment(ref mv, 0, 2);
                    contourAxisAngle = calculateTilt(m11, m20, m02);
                    tbHandAngle.Text = contourAxisAngle.ToString();

                    // deal with hand contour pointing downwards

/* uses fingertips inf
 * ormation generated on the last update of
 * the hand, so will be out
 * -
 * of
 * -
 * date */

                    /*
                     *      if (fingerTips.size() > 0) {
                     *      int yTotal = 0;
                     *      for(Point pt : fingerTips)
                     *      yTotal += pt.y;
                     *      int avgYFinger = yTotal/fingerTips.size();
                     *      if (avgYFinger > cogPt.y) // fingers below COG
                     *      contourAxisAngle += 180;
                     *      }
                     *      contourAxisAngle = 180-contourAxisAngle;
                     *
                     *
                     *
                     * /* this makes the angle relative to a positive y
                     * -
                     * axis that
                     * runs up the screen */


                    //handRect = box.MinAreaRect();
                    //currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1);

                    Point[] ps = new Point[points.Length];
                    for (int i = 0; i < points.Length; i++)
                    {
                        ps[i] = new Point((int)points[i].X, (int)points[i].Y);
                    }

                    currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                    currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);

                    //ellip.MCvBox2D= CvInvoke.cvFitEllipse2(biggestContour.Ptr);
                    //currentFrame.Draw(new Ellipse(ellip.MCvBox2D), new Bgr(Color.LavenderBlush), 3);

                    PointF center;
                    float  radius;
                    //CvInvoke.cvMinEnclosingCircle(biggestContour.Ptr, out  center, out  radius);
                    //currentFrame.Draw(new CircleF(center, radius), new Bgr(Color.Gold), 2);

                    //currentFrame.Draw(new CircleF(new PointF(ellip.MCvBox2D.center.X, ellip.MCvBox2D.center.Y), 3), new Bgr(100, 25, 55), 2);
                    //currentFrame.Draw(ellip, new Bgr(Color.DeepPink), 2);

                    //CvInvoke.cvEllipse(currentFrame, new Point((int)ellip.MCvBox2D.center.X, (int)ellip.MCvBox2D.center.Y), new System.Drawing.Size((int)ellip.MCvBox2D.size.Width, (int)ellip.MCvBox2D.size.Height), ellip.MCvBox2D.angle, 0, 360, new MCvScalar(120, 233, 88), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0);
                    //currentFrame.Draw(new Ellipse((box.center.X, box.centernew PointF.Y), new SizeF(box.size.Height, box.size.Width), box.angle), new Bgr(0, 0, 0), 2);


                    filteredHull = new Seq <Point>(storage);
                    for (int i = 0; i < hull.Total; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            filteredHull.Push(hull[i]);
                        }
                    }

                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                    defectArray = defects.ToArray();
                }
            }
        }
Пример #32
0
        private void ExtractContourAndHull(Image<Gray, byte> skin)
        {
            List<Contour<Point>> contourList = new List<Contour<Point>>();
            Contour<Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, contourStorage);
            Contour<Point> biggestContour = null;

            Double current = 0;
            Double largest = 0;

            while (contours != null)
            {
                current = contours.Area;
                if (current > largest)
                {
                    largest = current;
                    biggestContour = contours;
                }
                contours = contours.HNext;
            }

            if (biggestContour != null)
            {
                //currentFrame.Draw(biggestContour, new Bgr(Color.DarkViolet), 2);
                Contour<Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, contourStorage);
                currentFrame.Draw(currentContour, new Bgr(System.Drawing.Color.LimeGreen), 2);
                biggestContour = currentContour;

                hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                box = biggestContour.GetMinAreaRect();
                PointF[] points = box.GetVertices();
                //handRect = box.MinAreaRect();
                //currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1);

                Point[] ps = new Point[points.Length];
                for (int i = 0; i < points.Length; i++)
                    ps[i] = new Point((int)points[i].X, (int)points[i].Y);

                currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);

                //ellip.MCvBox2D= CvInvoke.cvFitEllipse2(biggestContour.Ptr);
                //currentFrame.Draw(new Ellipse(ellip.MCvBox2D), new Bgr(Color.LavenderBlush), 3);

                PointF center;
                float radius;
                //CvInvoke.cvMinEnclosingCircle(biggestContour.Ptr, out  center, out  radius);
                //currentFrame.Draw(new CircleF(center, radius), new Bgr(System.Drawing.Color.Gold), 2);

                //currentFrame.Draw(new CircleF(new PointF(ellip.MCvBox2D.center.X, ellip.MCvBox2D.center.Y), 3), new Bgr(100, 25, 55), 2);
                //currentFrame.Draw(ellip, new Bgr(Color.DeepPink), 2);

                //CvInvoke.cvEllipse(currentFrame, new Point((int)ellip.MCvBox2D.center.X, (int)ellip.MCvBox2D.center.Y), new System.Drawing.Size((int)ellip.MCvBox2D.size.Width, (int)ellip.MCvBox2D.size.Height), ellip.MCvBox2D.angle, 0, 360, new MCvScalar(120, 233, 88), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0);
                //currentFrame.Draw(new Ellipse(new PointF(box.center.X, box.center.Y), new SizeF(box.size.Height, box.size.Width), box.angle), new Bgr(0, 0, 0), 2);

                filteredHull = new Seq<Point>(contourStorage);
                for (int i = 0; i < hull.Total; i++)
                {
                    if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                    {
                        filteredHull.Push(hull[i]);
                    }
                }

                defects = biggestContour.GetConvexityDefacts(contourStorage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                defectArray = defects.ToArray();
            }
        }
Пример #33
0
        private void ExtractContourAndHull(Image <Gray, byte> skin)
        {
            using (MemStorage storage = new MemStorage())
            {
                Contour <Point> contours       = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                Contour <Point> biggestContour = null;

                Double Result1 = 0;
                Double Result2 = 0;
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2        = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    //currentFrame.Draw(biggestContour, new Bgr(Color.DarkViolet), 2);
                    Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2);
                    biggestContour = currentContour;


                    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box  = biggestContour.GetMinAreaRect();
                    PointF[] points = box.GetVertices();
                    //handRect = box.MinAreaRect();
                    //currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1);

                    Point[] ps = new Point[points.Length];
                    for (int i = 0; i < points.Length; i++)
                    {
                        ps[i] = new Point((int)points[i].X, (int)points[i].Y);
                    }

                    currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                    currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);

                    //ellip.MCvBox2D= CvInvoke.cvFitEllipse2(biggestContour.Ptr);
                    //currentFrame.Draw(new Ellipse(ellip.MCvBox2D), new Bgr(Color.LavenderBlush), 3);

                    PointF center;
                    float  radius;
                    //CvInvoke.cvMinEnclosingCircle(biggestContour.Ptr, out  center, out  radius);
                    //currentFrame.Draw(new CircleF(center, radius), new Bgr(Color.Gold), 2);

                    //currentFrame.Draw(new CircleF(new PointF(ellip.MCvBox2D.center.X, ellip.MCvBox2D.center.Y), 3), new Bgr(100, 25, 55), 2);
                    //currentFrame.Draw(ellip, new Bgr(Color.DeepPink), 2);

                    //CvInvoke.cvEllipse(currentFrame, new Point((int)ellip.MCvBox2D.center.X, (int)ellip.MCvBox2D.center.Y), new System.Drawing.Size((int)ellip.MCvBox2D.size.Width, (int)ellip.MCvBox2D.size.Height), ellip.MCvBox2D.angle, 0, 360, new MCvScalar(120, 233, 88), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0);
                    //currentFrame.Draw(new Ellipse(new PointF(box.center.X, box.center.Y), new SizeF(box.size.Height, box.size.Width), box.angle), new Bgr(0, 0, 0), 2);


                    filteredHull = new Seq <Point>(storage);
                    for (int i = 0; i < hull.Total; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            filteredHull.Push(hull[i]);
                        }
                    }

                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                    defectArray = defects.ToArray();
                }
            }
        }
        private void ExtractContourAndHull(Image<Gray, byte> skin, Image<Bgr,byte> currentFrame)
        {
            using (MemStorage storage = new MemStorage())
            {
                Contour<System.Drawing.Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                Contour<System.Drawing.Point> biggestContour = null;

                Double Result1 = 0;
                Double Result2 = 0;
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2 = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    currentFrame.Draw(biggestContour, new Bgr(Color.DarkViolet), 2);
                    Contour<System.Drawing.Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                    currentFrame.Draw(currentContour, new Bgr(System.Drawing.Color.LimeGreen), 2);
                    biggestContour = currentContour;


                    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    box = biggestContour.GetMinAreaRect();
                    PointF[] points = box.GetVertices();
                    //handRect = box.MinAreaRect();
                    //currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1);

                    System.Drawing.Point[] ps = new System.Drawing.Point[points.Length];
                    for (int i = 0; i < points.Length; i++)
                        ps[i] = new System.Drawing.Point((int)points[i].X, (int)points[i].Y);

                    currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                    currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);


                    filteredHull = new Seq<System.Drawing.Point>(storage);
                    for (int i = 0; i < hull.Total; i++)
                    {
                        if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                        {
                            filteredHull.Push(hull[i]);
                        }
                    }

                    
                    defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                    defectArray = defects.ToArray();
                    DrawAndComputeFingersNum(currentFrame,filteredHull,defects,defectArray);
                }
                

                imageConvexHull.Source = toBitmapSourceFromImage(currentFrame);
            }
        }