public void IdentifyContours(Bitmap colorImage, int minPerimeter, int maxPerimeter, out List <RecognitionType> detectedObj)
        {
            detectedObj = new List <RecognitionType>();

            #region Conversion To grayscale

            colorImage.RotateFlip(RotateFlipType.RotateNoneFlipX);
            Image <Gray, byte> grayImage = new Image <Gray, byte>(colorImage);
            Image <Bgr, byte>  color     = new Image <Bgr, byte>(colorImage);


            IColorSkinDetector skinDetection;

            Ycc YCrCb_min = new Ycc(0, 131, 80);
            Ycc YCrCb_max = new Ycc(255, 185, 135);

            #endregion



            skinDetection = new YCrCbSkinDetector();
            Image <Gray, byte> skin = skinDetection.DetectSkin(color, YCrCb_min, YCrCb_max);


            using (MemStorage storage = new MemStorage())
            {
                for (Contour <Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
                                                                  Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, storage); contours != null; contours = contours.HNext)
                {
                    Contour <Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.015, storage);

                    if (currentContour.BoundingRectangle.Width > 20)
                    {
                        if (contours.Perimeter > minPerimeter && contours.Perimeter < maxPerimeter)
                        {
                            CvInvoke.cvDrawContours(skin, contours, new MCvScalar(255), new MCvScalar(255),
                                                    -1, 2, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0));
                            color.Draw(currentContour.BoundingRectangle, new Bgr(0, 255, 0), 1);

                            detectedObj.Add(new RecognitionType()
                            {
                                GesturePosition = currentContour.BoundingRectangle,
                                GestureImage    = skin.ToBitmap().Clone(currentContour.BoundingRectangle, skin.ToBitmap().PixelFormat)
                            });
                        }
                    }
                }
            }
        }
        private Mat DetectHandSkin()
        {
            if (capture == null)
            {
                return(null);
            }

            Mat m = new Mat();
            Mat n = new Mat();
            Mat o = new Mat();
            Mat binaryDiffFrame   = new Mat();
            Mat denoisedDiffFrame = new Mat();
            Mat finalFrame        = new Mat();


            capture.Read(m);
            Image <Bgr, byte> mr = m.ToImage <Bgr, byte>();

            mr = mr.Rotate(180, new Bgr(255, 255, 255), false);
            m  = mr.Mat;

            if (!m.IsEmpty)
            {
                Image <Bgr, byte> ret = m.ToImage <Bgr, byte>();


                skinDetector = new YCrCbSkinDetector();

                Image <Gray, Byte> skin = skinDetector.DetectSkin(ret, YCrCb_min, YCrCb_max);
                m.CopyTo(finalFrame);
                //DetectObject(skin.Mat, finalFrame);
                //return DetectObject(denoisedDiffFrame, finalFrame);
                return(DetectObject(skin.Mat, finalFrame));
            }
            else
            {
                // break;
            }

            return(null);
        }
        public void IdentifyContours(Bitmap colorImage, int thresholdValue, bool invert, int minPerimeter, int maxPerimeter,
                                     int Y_h, int Cr_h, int Cb_h, int Y_l, int Cr_l, int Cb_l,
                                     out Bitmap processedGray, out Bitmap processedColor, out List <RecognitionType> detectedObj)
        {
            detectedObj = new List <RecognitionType>();
            Rectangle gestureRectangle = new Rectangle(0, 0, 1, 1);

            #region Conversion To grayscale

            colorImage.RotateFlip(RotateFlipType.RotateNoneFlipX);
            Image <Gray, byte> grayImage = new Image <Gray, byte>(colorImage);
            Image <Bgr, byte>  color     = new Image <Bgr, byte>(colorImage);


            IColorSkinDetector skinDetection;


            #endregion


            #region Extracting the Contours


            skinDetection = new YCrCbSkinDetector();
            Image <Gray, byte> skin = skinDetection.DetectSkin(color, new Ycc(Y_l, Cr_l, Cb_l), new Ycc(Y_h, Cr_h, Cb_h));

            if (invert)
            {
                skin._Not();
            }


            using (MemStorage storage = new MemStorage())
            {
                for (Contour <Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
                                                                  Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, storage); contours != null; contours = contours.HNext)
                {
                    Contour <Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.015, storage);

                    if (currentContour.BoundingRectangle.Width > 20)
                    {
                        if (contours.Perimeter > minPerimeter && contours.Perimeter < maxPerimeter)
                        {
                            CvInvoke.cvDrawContours(skin, contours, new MCvScalar(255), new MCvScalar(255),
                                                    -1, 2, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0));
                            color.Draw(currentContour.BoundingRectangle, new Bgr(0, 255, 0), 1);

                            detectedObj.Add(new RecognitionType()
                            {
                                GesturePosition = currentContour.BoundingRectangle,
                                GestureImage    = skin.ToBitmap().Clone(currentContour.BoundingRectangle, skin.ToBitmap().PixelFormat)
                            });
                        }
                    }
                }
            }


            #endregion


            #region Asigning output
            processedColor = color.ToBitmap();
            processedGray  = skin.ToBitmap();
            #endregion
        }
Esempio n. 4
0
        void ProcessFramAndUpdateGUI(object Sender, EventArgs agr)
        {
            int    Finger_num = 0;
            Double Result1    = 0;
            Double Result2    = 0;

            //querying image

            currentFrame = capture.QueryFrame().ToImage <Bgr, byte>();
            int widthROI  = currentFrame.Size.Width / 4;
            int heightROI = currentFrame.Size.Height / 4;

            // currentFrame = currentFrame.Copy(new Rectangle(widthROI, heightROI, widthROI * 2, heightROI * 2));
            if (currentFrame == null)
            {
                return;
            }


            //Cach 1***************************
            //Applying YCrCb filter
            //Image<Ycc, Byte> currentYCrCbFrame = currentFrame.Convert<Ycc, byte>();
            //Image<Gray, byte> skin = new Image<Gray, byte>(currentFrame.Width, currentFrame.Height);

            //skin = currentYCrCbFrame.InRange(new Ycc(0, minCr, minCb), new Ycc(255, maxCr, maxCb));

            ////Erode
            //Mat rect_12 = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(10, 10), new Point(5, 5));
            //CvInvoke.Erode(skin, skin, rect_12, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());

            ////Dilate
            //Mat rect_6 = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(6, 6), new Point(3, 3));
            //CvInvoke.Dilate(skin, skin, rect_6, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());
            //**********************************

            //Cach 2**************************** Phong
            IColorSkinDetector skinDetector = new YCrCbSkinDetector();
            Image <Gray, byte> skin         = skinDetector.DetectSkin(currentFrame, new Ycc(0, minCr, minCb), new Ycc(255, maxCr, maxCb));

            //**********************************

            skin = skin.Flip(FlipType.Horizontal);

            //smoothing the filterd , eroded and dilated image.
            skin             = skin.SmoothGaussian(9);
            picSkinCam.Image = skin.ToBitmap();
            currentFrame     = currentFrame.Flip(FlipType.Horizontal);

            #region Extract contours and hull
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            CvInvoke.FindContours(skin, contours, new Mat(), Emgu.CV.CvEnum.RetrType.External,
                                  Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);

            VectorOfPoint biggestContour = new VectorOfPoint();// mang point[] chua vien` lon nhat

            //Tim area contours lon nhat
            for (int i = 0; i < contours.Size; i++)
            {
                VectorOfPoint contour = contours[i];            // chuyen sang Point[][]
                Result1 = CvInvoke.ContourArea(contour, false); // tinh area

                if (Result1 > Result2)
                {
                    Result2        = Result1;
                    biggestContour = contour;
                }
            }

            //Gi do
            try
            {
                lblNote.Text = "";
                if (biggestContour != null)
                {
                    CvInvoke.ApproxPolyDP(biggestContour, biggestContour, 0.00025, false);

                    contourPoints = biggestContour.ToArray();

                    currentFrame.Draw(contourPoints, new Bgr(255, 0, 255), 4);


                    VectorOfPoint hull       = new VectorOfPoint();
                    VectorOfInt   convexHull = new VectorOfInt();
                    CvInvoke.ConvexHull(biggestContour, hull, true); //~ Hull   //Chinh clockwise thanh true
                    RotatedRect minAreaBox = CvInvoke.MinAreaRect(hull);


                    currentFrame.Draw(new CircleF(minAreaBox.Center, 5), new Bgr(Color.Black), 4);

                    CvInvoke.ConvexHull(biggestContour, convexHull, true);    //Chinh clockwise thanh true



                    currentFrame.Draw(minAreaBox, new Bgr(200, 0, 0), 1);


                    // ve khung ban tay khung bao quanh tay
                    currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 4);
                    currentFrame.Draw(new CircleF(new PointF(minAreaBox.Center.X, minAreaBox.Center.Y), 3), new Bgr(200, 125, 75));

                    // tim  convex defect
                    Mat defect = new Mat();
                    CvInvoke.ConvexityDefects(biggestContour, convexHull, defect);

                    // chuyen sang Matrix

                    if (!defect.IsEmpty)
                    {
                        mDefect = new Matrix <int>(defect.Rows, defect.Cols, defect.NumberOfChannels);
                        defect.CopyTo(mDefect);
                    }

                    #region Counting finger
                    if (mDefect.Rows == 0)
                    {
                        return;
                    }
                    PointF[] start = new PointF[mDefect.Rows];
                    int      num   = 0;
                    start[0] = new PointF(0, 0);

                    try
                    {
                        for (int i = 0; i < mDefect.Rows; i++)
                        {
                            int startIdx = mDefect.Data[i, 0];
                            int depthIdx = mDefect.Data[i, 1];
                            int endIdx   = mDefect.Data[i, 2];


                            Point startPoint = contourPoints[startIdx];
                            Point endPoint   = contourPoints[endIdx];
                            Point depthPoint = contourPoints[depthIdx];

                            CircleF startCircle = new CircleF(startPoint, 5f);
                            CircleF endCircle   = new CircleF(endPoint, 5f);
                            CircleF depthCircle = new CircleF(depthPoint, 5f);

                            LineSegment2D Line = new LineSegment2D(startPoint, new Point((int)minAreaBox.Center.X, (int)minAreaBox.Center.Y));


                            //Cach 1
                            //if ((startCircle.Center.Y < minAreaBox.Center.Y || depthCircle.Center.Y < minAreaBox.Center.Y) &&
                            //          (startCircle.Center.Y < depthCircle.Center.Y) &&
                            //          (Math.Sqrt(Math.Pow(startCircle.Center.X - depthCircle.Center.X, 2) +
                            //                     Math.Pow(startCircle.Center.Y - depthCircle.Center.Y, 2)) >
                            //                     minAreaBox.Size.Height / 6.5))
                            //{
                            //    Finger_num++;
                            //}

                            //Cach 2
                            if ((startPoint.Y < minAreaBox.Center.Y && endPoint.Y < minAreaBox.Center.Y) && (startPoint.Y < endPoint.Y) &&
                                (Math.Sqrt(Math.Pow(startPoint.X - endPoint.X, 2) + Math.Pow(startPoint.Y - endPoint.Y, 2)) > minAreaBox.Size.Height / 7))
                            {
                                if (getAngle(startPoint, minAreaBox.Center, start[num]) > 10)
                                {
                                    Finger_num++;
                                    start[num] = startPoint;
                                    num++;
                                    currentFrame.Draw(Line, new Bgr(Color.Violet), 2);
                                    currentFrame.Draw(startCircle, new Bgr(Color.OrangeRed), 5);
                                    //currentFrame.Draw(endCircle, new Bgr(Color.Black), 5);
                                    //currentFrame.Draw(Finger_num.ToString(), new Point(startPoint.X - 10, startPoint.Y), FontFace.HersheyPlain, 2, new Bgr(Color.Orange), 3);
                                    //currentFrame.Draw(Finger_num.ToString(), new Point(endPoint.X - 10, endPoint.Y), FontFace.HersheyPlain, 2, new Bgr(Color.Orange), 3);
                                }
                            }
                        }
                    }
                    catch
                    {
                        return;
                    }

                    #endregion
                }
                #region Tracking
                MCvMoments moment = new MCvMoments();               // a new MCvMoments object

                try
                {
                    moment = CvInvoke.Moments(biggestContour, false);        // Moments of biggestContour
                }
                catch (NullReferenceException except)
                {
                    //label3.Text = except.Message;
                    return;
                }

                //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

                #endregion

                if (useVirtualMouse)
                {
                    // move cursor to center of contour only if Finger count is 1 or 0
                    // i.e. palm is closed

                    if (Finger_num == 0 || Finger_num == 1)
                    {
                        Cursor.Position = new Point(current_X * 20, current_Y * 20);
                    }

                    // Leave the cursor where it was and Do mouse click, if finger count >= 4

                    if (Finger_num >= 3)
                    {
                        if (!isDrag)
                        {
                            DoMouseDown();
                            isDrag = true;
                        }
                        else
                        {
                            DoMouseUp();
                            isDrag = false;
                        }
                        //Cursor.Position = new Point(current_X * 20, current_Y * 20);
                        //Cursor.Position = new Point(300, 300);
                    }
                }
            }
            catch
            {
                Finger_num   = 0;
                lblNote.Text = "Opps! Make sure to have a 'white space'";
                return;
            }
            #endregion


            //Display image from camera
            picInputCam.Image = currentFrame.ToBitmap();

            lblNumFinger.Text = Finger_num.ToString();
        }