public static FeatureVector createFirstHypothesis(Image<Bgr, Byte> imagen)
        {
            List<PointF> fingertips = new List<PointF>();

               fingertips.Add(new PointF(110,220));
               fingertips.Add(new PointF(175, 60));
               fingertips.Add(new PointF(270, 4));
               fingertips.Add(new PointF(410, 26));
               fingertips.Add(new PointF(640, 200));

               PointF punto = new PointF(400, 400);
               //List<PointF> newFingertips = new List<PointF>();
               List<float> angles = calculateFingerAngles(fingertips, punto);

               FeatureVector vector = new FeatureVector(fingertips, angles, punto, 5);

               //dibujar punto central mano
               PointF puntoC = new PointF(400, 400);
               Point punt = new Point(400, 400);
               CircleF centerCircle = new CircleF(puntoC, 5f);
               imagen.Draw(centerCircle, new Bgr(Color.Brown), 3);

               foreach (PointF p in fingertips)
               {

               CircleF circle = new CircleF(p, 5f);

               imagen.Draw(circle, new Bgr(Color.Red), 3);

               Point pun = new Point(int.Parse(p.X.ToString()), int.Parse(p.Y.ToString()));
               LineSegment2D lineaDedoCentro = new LineSegment2D(pun, punt);
               imagen.Draw(lineaDedoCentro, new Bgr(Color.Green), 2);

               }

               Point p1 = new Point(int.Parse((puntoC.X - 90).ToString()), int.Parse((puntoC.Y - 90).ToString()));
               Point p2 = new Point(int.Parse((puntoC.X - 90).ToString()), int.Parse((puntoC.Y + 90).ToString()));
               Point p3 = new Point(int.Parse((puntoC.X + 90).ToString()), int.Parse((puntoC.Y - 90).ToString()));
               Point p4 = new Point(int.Parse((puntoC.X + 90).ToString()), int.Parse((puntoC.Y + 90).ToString()));

               LineSegment2D line = new LineSegment2D(p1, p2);
               LineSegment2D line1 = new LineSegment2D(p1, p3);
               LineSegment2D line2 = new LineSegment2D(p3, p4);
               LineSegment2D line3 = new LineSegment2D(p2, p4);

               imagen.Draw(line, new Bgr(Color.Brown), 3);
               imagen.Draw(line1, new Bgr(Color.Brown), 3);
               imagen.Draw(line2, new Bgr(Color.Brown), 3);
               imagen.Draw(line3, new Bgr(Color.Brown), 3);

               return vector;
        }
        public frmPruebaDatos(FeatureVector vector)
        {
            InitializeComponent();

            lblThumb.Text += " " + vector.LocationThumb.ToString();
            lblIndex.Text += " " + vector.LocationIndexFinger.ToString();
            lblHeart.Text += " " + vector.LocationHeartFinger.ToString();
            lblFourth.Text += " " + vector.Location4Finger.ToString();
            lblLittle.Text += " " + vector.LocationLittleFinger.ToString();

            lblThumbAngle.Text += " " + vector.thumbAngle.ToString();
            lblIndexAngle.Text += " " + vector.indexAngle.ToString();
            lblHeartAngle.Text += " " + vector.heartAngle.ToString();
            lblFourthAngle.Text += " " + vector.fourthAngle.ToString();
            lblLittleAngle.Text += " " + vector.littleAngle.ToString();

            lblPalmCenter.Text += " " + vector.PalmCenter.ToString();
            lblPalmSize.Text += " " + vector.palmSize.ToString();
        }
        private void procesarImagen()
        {
            //Image<Gray, Byte> skin = new Image<Gray, byte>(imagen.Width, imagen.Height);
               // detector.Process(imagen,skin);

            skinDetector = new YCrCbSkinDetector();

            Image<Gray, Byte> skin = skinDetector.DetectSkin(imagen, YCrCb_min, YCrCb_max);

            observedImageVector =  ObservedImageFunctions.ExtractFeatures(skin,imagen);
               hypothesisImageVector = HypothesisImageFunctions.createFirstHypothesis(imagen2);

            //imgCaja.Image = skin;

            imgCaja.Refresh();
            imgCaja2.Refresh();
        }
        private void btnMAP_Click(object sender, EventArgs e)
        {
            while (MAPestimationOperations.definiteL > 35)
            {

                FeatureVector newVector = MAPestimationOperations.core(observedImageVector, hypothesisImageVector);
                hypothesisImageVector = newVector;

                // imagen2 = imagen2copia;
                //imgCaja2.Image = imagen2;
                // imgCaja2.Refresh();

                label1.Text = "L = " + MAPestimationOperations.definiteL.ToString();

                label1.Refresh();

                imagen2 = new Image<Bgr, byte>(archivo);
                imgCaja2.Image = imagen2;

                PointF puntoC = hypothesisImageVector.PalmCenter; ;
                Point punt = new Point(int.Parse(puntoC.X.ToString()), int.Parse(puntoC.Y.ToString()));
                CircleF centerCircle = new CircleF(puntoC, 5f);
                imagen2.Draw(centerCircle, new Bgr(Color.Brown), 3);

                Point p1 = new Point(int.Parse((hypothesisImageVector.PalmCenter.X - 90).ToString()), int.Parse((hypothesisImageVector.PalmCenter.Y - 90).ToString()));
                Point p2 = new Point(int.Parse((hypothesisImageVector.PalmCenter.X - 90).ToString()), int.Parse((hypothesisImageVector.PalmCenter.Y + 90).ToString()));
                Point p3 = new Point(int.Parse((hypothesisImageVector.PalmCenter.X + 90).ToString()), int.Parse((hypothesisImageVector.PalmCenter.Y - 90).ToString()));
                Point p4 = new Point(int.Parse((hypothesisImageVector.PalmCenter.X + 90).ToString()), int.Parse((hypothesisImageVector.PalmCenter.Y + 90).ToString()));

                LineSegment2D line = new LineSegment2D(p1,p2);
                LineSegment2D line1 = new LineSegment2D(p1,p3);
                LineSegment2D line2 = new LineSegment2D(p3, p4);
                LineSegment2D line3 = new LineSegment2D(p2, p4);

                imagen2.Draw(line, new Bgr(Color.Brown), 3);
                imagen2.Draw(line1, new Bgr(Color.Brown), 3);
                imagen2.Draw(line2, new Bgr(Color.Brown), 3);
                imagen2.Draw(line3, new Bgr(Color.Brown), 3);

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

                fingertips.Add(hypothesisImageVector.LocationThumb);
                fingertips.Add(hypothesisImageVector.LocationIndexFinger);
                fingertips.Add(hypothesisImageVector.LocationHeartFinger);
                fingertips.Add(hypothesisImageVector.Location4Finger);
                fingertips.Add(hypothesisImageVector.LocationLittleFinger);

                foreach (PointF p in fingertips)
                {

                    CircleF circle = new CircleF(p, 5f);

                    imagen2.Draw(circle, new Bgr(Color.Red), 3);

                    Point pun = new Point(int.Parse(p.X.ToString()), int.Parse(p.Y.ToString()));
                    LineSegment2D lineaDedoCentro = new LineSegment2D(pun, punt);
                    imagen2.Draw(lineaDedoCentro, new Bgr(Color.Green), 2);

                    imgCaja2.Refresh();
                }

            }

            MessageBox.Show("Done!");
        }
        public static FeatureVector core(FeatureVector original, FeatureVector hypothesis)
        {
            List<PointF> thumbPoints = possiblePositions(hypothesis.LocationThumb);
            List<PointF> indexPoints = possiblePositions(hypothesis.LocationIndexFinger);
            List<PointF> heartPoints = possiblePositions(hypothesis.LocationHeartFinger);
            List<PointF> fourthPoints = possiblePositions(hypothesis.Location4Finger);
            List<PointF> littlePoints = possiblePositions(hypothesis.LocationLittleFinger);
            List<PointF> centerPoints = possiblePositions(hypothesis.PalmCenter);

            Double mismatch = 0;
            Double cost = 0;
            Double L=9999999;
            FeatureVector finalHypothesis = new FeatureVector();

            foreach (PointF pThumb in thumbPoints)
            {
                foreach (PointF pIndex in indexPoints)
                {
                    foreach (PointF pHeart in heartPoints)
                    {
                        foreach (PointF pFourth in fourthPoints)
                        {
                            foreach (PointF pLittle in littlePoints)
                            {
                                foreach (PointF pCent in centerPoints)
                                {

                                    Double misCent = mismatchCalc(original.PalmCenter, pCent);
                                    Double misThumb = mismatchCalc(original.LocationThumb, pThumb);
                                    Double misIndex = mismatchCalc(original.LocationIndexFinger, pIndex);
                                    Double misHeart = mismatchCalc(original.LocationHeartFinger, pHeart);
                                    Double misFourth = mismatchCalc(original.Location4Finger, pFourth);
                                    Double misLittle = mismatchCalc(original.LocationLittleFinger, pLittle);

                                    Double costCent = relativeCost(hypothesis.PalmCenter, pCent);
                                    Double costThumb = relativeCost(hypothesis.LocationThumb, pThumb);
                                    Double costIndex = relativeCost(hypothesis.LocationIndexFinger, pIndex);
                                    Double costHeart = relativeCost(hypothesis.LocationHeartFinger, pHeart);
                                    Double costFourth = relativeCost(hypothesis.Location4Finger, pFourth);
                                    Double costLittle = relativeCost(hypothesis.LocationLittleFinger, pLittle);

                                    mismatch = misCent + misThumb + misIndex + misHeart + misFourth + misLittle;
                                    cost = costCent+ costThumb + costIndex + costHeart + costFourth + costLittle;

                                    Double newL = mismatch + cost;

                                    List<PointF> fingertips = new List<PointF>();
                                    fingertips.Add(pThumb);
                                    fingertips.Add(pIndex);
                                    fingertips.Add(pHeart);
                                    fingertips.Add(pFourth);
                                    fingertips.Add(pLittle);

                                    List<float> angulos = new List<float>();
                                    angulos = calculateFingerAngles(fingertips,pCent);

                                    FeatureVector newHypothesis = new FeatureVector(fingertips,angulos,pCent,5);

                                    if (L >= newL)
                                    {
                                        L = newL;
                                        definiteL = newL;
                                        finalHypothesis = newHypothesis;
                                    }
                                }
                            }

                        }
                    }
                }
            }

            return finalHypothesis;
        }
        public static FeatureVector core(FeatureVector original, FeatureVector hypothesis)
        {
            List<PointF> thumbPoints = possiblePositions(hypothesis.LocationThumb);
            List<PointF> indexPoints = possiblePositions(hypothesis.LocationIndexFinger);
            List<PointF> heartPoints = possiblePositions(hypothesis.LocationHeartFinger);
            List<PointF> fourthPoints = possiblePositions(hypothesis.Location4Finger);
            List<PointF> littlePoints = possiblePositions(hypothesis.LocationLittleFinger);
            List<PointF> centerPoints = possiblePositions(hypothesis.PalmCenter);

            Double mismatch = 0;
            Double cost = 0;
            Double L=9999999;
            FeatureVector finalHypothesis = new FeatureVector();

            foreach (PointF pThumb in thumbPoints)
            {
                foreach (PointF pIndex in indexPoints)
                {
                    foreach (PointF pHeart in heartPoints)
                    {
                        foreach (PointF pFourth in fourthPoints)
                        {
                            foreach (PointF pLittle in littlePoints)
                            {
                                foreach (PointF pCent in centerPoints)
                                {

                                    Double misCent = mismatchCalc(original.PalmCenter, pCent);
                                    Double misThumb = mismatchCalc(original.LocationThumb, pThumb);
                                    Double misIndex = mismatchCalc(original.LocationIndexFinger, pIndex);
                                    Double misHeart = mismatchCalc(original.LocationHeartFinger, pHeart);
                                    Double misFourth = mismatchCalc(original.Location4Finger, pFourth);
                                    Double misLittle = mismatchCalc(original.LocationLittleFinger, pLittle);

                                    Double costCent = relativeCost(hypothesis.PalmCenter, pCent);
                                    Double costThumb = relativeCost(hypothesis.LocationThumb, pThumb);
                                    Double costIndex = relativeCost(hypothesis.LocationIndexFinger, pIndex);
                                    Double costHeart = relativeCost(hypothesis.LocationHeartFinger, pHeart);
                                    Double costFourth = relativeCost(hypothesis.Location4Finger, pFourth);
                                    Double costLittle = relativeCost(hypothesis.LocationLittleFinger, pLittle);

                                    mismatch = misCent + misThumb + misIndex + misHeart + misFourth + misLittle;
                                    cost = costCent+ costThumb + costIndex + costHeart + costFourth + costLittle;

                                    Double newL = mismatch + cost;

                                    List<PointF> fingertips = new List<PointF>();
                                    fingertips.Add(pThumb);
                                    fingertips.Add(pIndex);
                                    fingertips.Add(pHeart);
                                    fingertips.Add(pFourth);
                                    fingertips.Add(pLittle);

                                    List<float> angulos = new List<float>();
                                    angulos = calculateFingerAngles(fingertips,pCent);

                                    FeatureVector newHypothesis = new FeatureVector(fingertips,angulos,pCent,5);

                                    if (L >= newL)
                                    {
                                        L = newL;
                                        definiteL = newL;
                                        finalHypothesis = newHypothesis;
                                    }
                                }
                            }

                        }
                    }
                }
            }

            return finalHypothesis;
        }
        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;
        }