예제 #1
0
파일: Form1.cs 프로젝트: RimasR/TTISR
        public Image <Bgr, byte> GetPalm(Mat mask)
        {
            int width  = mask.Width;
            int height = mask.Height;
            var temp   = new Mat();
            var result = mask.ToImage <Bgr, byte>();
            VectorOfVectorOfPoint contours       = new VectorOfVectorOfPoint();
            VectorOfPoint         biggestContour = new VectorOfPoint();

            CvInvoke.FindContours(mask, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
            if (contours.Size > 0)
            {
                biggestContour = contours[0];
                for (int i = 0; i < contours.Size; i++)
                {
                    if (contours[i].Size > biggestContour.Size)
                    {
                        biggestContour = contours[i];
                    }
                }
            }
            if (biggestContour.Size != 0)
            {
                //Gaunam rankos konturus
                CvInvoke.ApproxPolyDP(biggestContour, biggestContour, 0.00000001, false);
                var         points = biggestContour.ToArray();
                VectorOfInt hull   = new VectorOfInt();
                //find the palm hand area using convexitydefect
                CvInvoke.ConvexHull(biggestContour, hull, true);
                var box     = CvInvoke.MinAreaRect(biggestContour);
                Mat defects = new Mat();
                CvInvoke.ConvexityDefects(biggestContour, hull, defects);

                if (!defects.IsEmpty)
                {
                    //Data from Mat are not directly readable so we convert it to Matrix<>
                    Matrix <int> m = new Matrix <int>(defects.Rows, defects.Cols, defects.NumberOfChannels);
                    defects.CopyTo(m);

                    for (int i = 0; i < m.Rows; i++)
                    {
                        int   startIdx   = m.Data[i, 0];
                        int   endIdx     = m.Data[i, 1];
                        Point startPoint = points[startIdx];
                        Point endPoint   = points[endIdx];
                        //draw  a line connecting the convexity defect start point and end point in thin red line
                        CvInvoke.Line(result, startPoint, endPoint, new MCvScalar(0, 0, 255));
                    }
                }
            }

            return(result);
        }
예제 #2
0
    Image <Bgr, byte> ProcessFrame(Mat colorPicture, MCvScalar skinHsv)
    {//, Mat binPicture) {
        Mat picture = colorPicture.Clone();

        picture = BackgroundSubtraction(picture, skinHsv);
        //picture = binPicture;
        //return new Image<Bgr, byte>(picture.Bitmap);

        //contour stuff
        VectorOfVectorOfPoint contoursss = new VectorOfVectorOfPoint();

        CvInvoke.FindContours(picture, contoursss, null, RetrType.List, ChainApproxMethod.ChainApproxNone);
        VectorOfPoint handContour = FindLargestContour(contoursss);

        if ((handContour == null || CvInvoke.ContourArea(handContour) < 100 || CvInvoke.ContourArea(handContour) > 200000))
        {
            return(new Image <Bgr, byte>(colorPicture.Bitmap));
        }

        VectorOfVectorOfPoint hulls = new VectorOfVectorOfPoint(1);
        //VectorOfVectorOfPoint hullDefects = new VectorOfVectorOfPoint(1);
        VectorOfInt hullI = new VectorOfInt();

        CvInvoke.ConvexHull(handContour, hullI, false, false);
        CvInvoke.ConvexHull(handContour, hulls[0], false, true);

        //convexity defects
        Mat defects = new Mat();

        CvInvoke.ConvexityDefects(handContour, hullI, defects);
        try
        {
            Matrix <int> m = new Matrix <int>(defects.Rows, defects.Cols, defects.NumberOfChannels); // copy Mat to a matrix...
            defects.CopyTo(m);
            CvInvoke.DrawContours(colorPicture, hulls, -1, new MCvScalar(0, 0, 255), 1);
            Image <Bgr, byte> image = new Image <Bgr, byte>(colorPicture.Bitmap);
            return(DrawPoints(image, m, handContour));
        }
        catch (Exception)
        {
            return(new Image <Bgr, byte>(colorPicture.Bitmap));
        }

        //CvInvoke.Imshow("picture", colorPicture);
        //CvInvoke.WaitKey(); // Render image and keep window opened until any key is pressed
    }
        /// Calculate convex hull and convexity defects for accurate finger calculation
        private Matrix <int> CalculateConvexityDefects(Image <Gray, Byte> img, VectorOfPoint biggestContour, VectorOfVectorOfPoint contours)
        {
            VectorOfPoint currentContour = new VectorOfPoint();
            VectorOfInt   hullIndices    = new VectorOfInt();

            CvInvoke.ApproxPolyDP(biggestContour, currentContour, CvInvoke.ArcLength(biggestContour, true) * .005, true);
            biggestContour = currentContour;
            CvInvoke.ConvexHull(biggestContour, hullIndices, false, false);

            /// Calcualate convexity defects
            /// Defects is a 4-element integer vector
            /// (start_index, end_index, farthest_pt_index, fixpt_depth)
            /// stored in a matrix where each row is a defect
            Matrix <int> defects = null;
            Mat          mat     = new Mat();

            CvInvoke.ConvexityDefects(biggestContour, hullIndices, mat);
            if (mat.Rows > 0)
            {
                defects = new Matrix <int>(mat.Rows, mat.Cols, mat.NumberOfChannels);
                mat.CopyTo(defects);

                /// For debugging and training purposes
                /// Draws finger points using convexity defects
                Matrix <int>[] channels = defects.Split();
                /// channel[0] = start_point, channel[1] = end_point, channel[2] = fixpt_depth

                for (int j = 0; j < defects.Rows; ++j)
                {
                    if (j < 5)
                    {
                        CvInvoke.Circle(img, System.Drawing.Point.Round(new System.Drawing.PointF(biggestContour[channels[0][j, 0]].X, biggestContour[channels[0][j, 0]].Y)), 10, new MCvScalar(255, 255, 255), 10);
                    }
                }
            }

            /// For debugging and training purposes
            /// Draws convex hull of biggest contour
            VectorOfPoint hullPoints = new VectorOfPoint();

            CvInvoke.ConvexHull(biggestContour, hullPoints, false);
            CvInvoke.Polylines(img, hullPoints.ToArray(), true, new MCvScalar(255, 255, 255), 10);

            return(defects);
        }
예제 #4
0
        private void ExtractContourAndHull(Image <Gray, byte> skin) // kiem vien va lop ngoai
        {
            using (MemStorage storage = new MemStorage())
            {
                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
                Double        Result1        = 0;                   // area dang xet
                Result = 0;

                for (int i = 0; i < contours.Size; i++)
                {
                    VectorOfPoint contour = contours[i];                          // chuyen sang Point[][]
                    double        area    = CvInvoke.ContourArea(contour, false); // tinh area
                    Result1 = area;
                    if (Result1 > Result)
                    {
                        Result         = Result1;
                        biggestContour = contour;
                    }
                }
                label8.Text = "Size Rect :" + Result.ToString();
                if (biggestContour != null)
                {
                    CvInvoke.ApproxPolyDP(biggestContour, biggestContour, 0.00025, false);

                    points = biggestContour.ToArray();

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


                    VectorOfPoint hull       = new VectorOfPoint();
                    VectorOfInt   convexHull = new VectorOfInt();
                    CvInvoke.ConvexHull(biggestContour, hull, false); //~ Hull
                    box = CvInvoke.MinAreaRect(hull);


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

                    CvInvoke.ConvexHull(biggestContour, convexHull);

                    //PointF[] Vertices = box.GetVertices();
                    // handRect = box.MinAreaRect();
                    currentFrame.Draw(box, 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(box.Center.X, box.Center.Y), 3), new Bgr(200, 125, 75));

                    // tim  convex defect

                    CvInvoke.ConvexityDefects(biggestContour, convexHull, defect);

                    // chuyen sang Matrix
                    if (!defect.IsEmpty)
                    {
                        mDefect = new Matrix <int>(defect.Rows, defect.Cols, defect.NumberOfChannels);
                        defect.CopyTo(mDefect);
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Count number of fingers on skinMask and draw debug information
        /// </summary>
        /// <param name="skinMask">Skin mask to count fingers on</param>
        /// <returns>Mat with detection debug information</returns>
        public Mat FindFingersCount(Mat skinMask)
        {
            Mat contoursImage = Mat.Ones(skinMask.Height, skinMask.Width, DepthType.Cv8U, 3);

            if (skinMask.IsEmpty || skinMask.NumberOfChannels != 1)
            {
                return(contoursImage);
            }

            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            Mat hierarchy = new Mat();

            CvInvoke.FindContours(skinMask, contours, hierarchy, RetrType.External, ChainApproxMethod.ChainApproxNone);

            if (contours.Size <= 0)
            {
                return(contoursImage);
            }

            int    biggestContourIndex = -1;
            double biggestArea         = 0;

            for (int i = 0; i < contours.Size; i++)
            {
                double area = CvInvoke.ContourArea(contours[i], false);
                if (area > biggestArea)
                {
                    biggestArea         = area;
                    biggestContourIndex = i;
                }
            }
            if (biggestContourIndex < 0)
            {
                return(contoursImage);
            }

            VectorOfPoint hullPoints = new VectorOfPoint();
            VectorOfInt   hullInts   = new VectorOfInt();


            CvInvoke.ConvexHull(contours[biggestContourIndex], hullPoints, true);
            CvInvoke.ConvexHull(contours[biggestContourIndex], hullInts, false);

            Mat defects = new Mat();

            if (hullInts.Size > 3)
            {
                CvInvoke.ConvexityDefects(contours[biggestContourIndex], hullInts, defects);
            }
            else
            {
                return(contoursImage);
            }

            Rectangle boundingRectangle = CvInvoke.BoundingRectangle(hullPoints);

            Point         centerBoundingRectangle = new Point((boundingRectangle.X + boundingRectangle.Right) / 2, (boundingRectangle.Y + boundingRectangle.Bottom) / 2);
            VectorOfPoint startPoints             = new VectorOfPoint();
            VectorOfPoint farPoints = new VectorOfPoint();

            int[,,] defectsData = (int[, , ])defects.GetData();
            for (int i = 0; i < defectsData.Length / 4; i++)
            {
                Point startPoint = contours[biggestContourIndex][defectsData[i, 0, 0]];
                if (!startPoints.ToArray().ToList().Any(p => Math.Abs(p.X - startPoint.X) < 30 && Math.Abs(p.Y - startPoint.Y) < 30))
                {
                    VectorOfPoint startPointVector = new VectorOfPoint(new Point[] { startPoint });
                    startPoints.Push(startPointVector);
                }
                Point farPoint = contours[biggestContourIndex][defectsData[i, 0, 2]];
                if (findPointsDistance(farPoint, centerBoundingRectangle) < boundingRectangle.Height * BOUNDING_RECT_FINGER_SIZE_SCALING)
                {
                    VectorOfPoint farPointVector = new VectorOfPoint(new Point[] { farPoint });
                    farPoints.Push(farPointVector);
                }
            }


            VectorOfPoint filteredStartPoints = CompactOnNeighborhoodMedian(startPoints, boundingRectangle.Height * BOUNDING_RECT_NEIGHBOR_DISTANCE_SCALING);
            VectorOfPoint filteredFarPoints   = CompactOnNeighborhoodMedian(farPoints, boundingRectangle.Height * BOUNDING_RECT_NEIGHBOR_DISTANCE_SCALING);

            VectorOfPoint filteredFingerPoints = new VectorOfPoint();

            if (filteredFarPoints.Size > 1)
            {
                VectorOfPoint fingerPoints = new VectorOfPoint();

                for (int i = 0; i < filteredStartPoints.Size; i++)
                {
                    VectorOfPoint closestPoints = findClosestOnX(filteredFarPoints, filteredStartPoints[i]);

                    if (isFinger(closestPoints[0], filteredStartPoints[i], closestPoints[1], LIMIT_ANGLE_INF, LIMIT_ANGLE_SUP, centerBoundingRectangle, boundingRectangle.Height * BOUNDING_RECT_FINGER_SIZE_SCALING))
                    {
                        fingerPoints.Push(new Point[] { filteredStartPoints[i] });
                    }
                }
                if (fingerPoints.Size > 0)
                {
                    while (fingerPoints.Size > 5)
                    {
                        //Remove extra fingers
                        //Convert to list and remove last item
                        List <Point> points = new List <Point>(fingerPoints.ToArray());
                        points.Remove(points.Last());
                        fingerPoints = new VectorOfPoint(points.ToArray());
                    }
                    for (int i = 0; i < fingerPoints.Size - 1; i++)
                    {
                    }
                    filteredFingerPoints       = fingerPoints;
                    this.NumberOfFingersRaised = filteredFingerPoints.Size;
                }
            }

            Bgr colorRed    = new Bgr(Color.Red);
            Bgr colorGreen  = new Bgr(Color.Green);
            Bgr colorBlue   = new Bgr(Color.Blue);
            Bgr colorYellow = new Bgr(Color.Yellow);
            Bgr colorPurple = new Bgr(Color.Purple);
            Bgr colorWhite  = new Bgr(Color.White);

            //Debug, draw defects
            defectsData = (int[, , ])defects.GetData();
            for (int i = 0; i < defectsData.Length / 4; i++)
            {
                Point start = contours[biggestContourIndex][defectsData[i, 0, 0]];
                Point far   = contours[biggestContourIndex][defectsData[i, 0, 2]];
                Point end   = contours[biggestContourIndex][defectsData[i, 0, 1]];

                CvInvoke.Polylines(contoursImage, new Point[] { start, far, end }, true, colorPurple.MCvScalar, DRAW_THICKNESS / 2);
                CvInvoke.Circle(contoursImage, start, 5, colorWhite.MCvScalar);
                CvInvoke.Circle(contoursImage, far, 5, colorRed.MCvScalar, 10);
                CvInvoke.Circle(contoursImage, end, 5, colorBlue.MCvScalar);
            }

            //Draw information about what was detected (Contours, key points, fingers / how many fingers)
            CvInvoke.DrawContours(contoursImage, contours, 0, colorGreen.MCvScalar, DRAW_THICKNESS, LineType.AntiAlias);
            CvInvoke.Polylines(contoursImage, hullPoints, true, colorBlue.MCvScalar, DRAW_THICKNESS);
            CvInvoke.Rectangle(contoursImage, boundingRectangle, colorRed.MCvScalar, DRAW_THICKNESS);
            CvInvoke.Circle(contoursImage, centerBoundingRectangle, 5, colorYellow.MCvScalar, DRAW_THICKNESS);
            drawVectorPoints(contoursImage, filteredStartPoints, colorRed.MCvScalar, true, 3);
            drawVectorPoints(contoursImage, filteredFarPoints, colorWhite.MCvScalar, true, 3);
            drawVectorPoints(contoursImage, filteredFingerPoints, colorYellow.MCvScalar, false, 3);
            CvInvoke.PutText(contoursImage, filteredFingerPoints.Size.ToString(), centerBoundingRectangle, FontFace.HersheyComplex, 2, colorYellow.MCvScalar);


            return(contoursImage);
        }
예제 #6
0
        private void ProcessFrame(object sender, EventArgs args)
        {
            //Get frame
            Mat frame = camera.QueryFrame();

            //Process frame
            Image <Bgr, Byte> img = frame.ToImage <Bgr, Byte>();

            img.ROI = new Rectangle(100, 100, 300, 300);
            Image <Hsv, Byte>  HSVimg  = img.Convert <Hsv, Byte>();
            Image <Gray, Byte> binary  = HSVimg.InRange(new Hsv(minH, minS, minV), new Hsv(maxH, maxS, maxV));
            Image <Gray, Byte> eroded  = binary.Erode(erosions);
            Image <Gray, Byte> dilated = eroded.Dilate(dilations);

            //Detect largest blob
            CvBlobDetector blobDetector = new CvBlobDetector();
            CvBlobs        blobs        = new CvBlobs();

            blobDetector.Detect(dilated, blobs);


            int    maxBlobArea = 0;
            CvBlob largestBlob = null;

            foreach (CvBlob blob in blobs.Values)
            {
                if (blob.Area > maxBlobArea)
                {
                    maxBlobArea = blob.Area;
                    largestBlob = blob;
                }
            }


            if (largestBlob != null && largestBlob.Area >= 10000)
            {
                handContour = largestBlob.GetContour();

                VectorOfInt   convexHullIndices = new VectorOfInt();
                VectorOfPoint convexHull        = new VectorOfPoint();

                CvInvoke.ConvexHull(new VectorOfPoint(handContour), convexHull);
                CvInvoke.ConvexHull(new VectorOfPoint(handContour), convexHullIndices);

                Mat defects = new Mat();


                //img.Draw(handContour, new Bgr(0, 0, 255),3);
                img.Draw(convexHull.ToArray(), new Bgr(255, 0, 0), 3);

                try
                {
                    CvInvoke.ConvexityDefects(new VectorOfPoint(handContour), convexHullIndices, defects);
                }

                catch (CvException exc)
                {
                    MessageBox.Show(exc.Message);
                }


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

                    defects.CopyTo(defectsInt);


                    int countFingers = 0;

                    for (int i = 0; i < defectsInt.Rows; i++)
                    {
                        int   startIdx    = defectsInt.Data[i, 0];
                        int   endIdx      = defectsInt.Data[i, 1];
                        int   farthestIdx = defectsInt.Data[i, 2];
                        float distance    = defectsInt.Data[i, 3];


                        if (distance >= 15000)
                        {
                            //distances.Add(distance);

                            Point startPoint    = handContour[startIdx];
                            Point endPoint      = handContour[endIdx];
                            Point farthestPoint = handContour[farthestIdx];

                            img.Draw(new CircleF(startPoint, 2.0f), new Bgr(0, 255, 0), 2);
                            img.Draw(new CircleF(endPoint, 2.0f), new Bgr(255, 0, 0), 2);
                            img.Draw(new CircleF(farthestPoint, 2.0f), new Bgr(0, 0, 255), 2);


                            CvInvoke.Line(img, startPoint, farthestPoint, new MCvScalar(255, 255, 0));
                            countFingers++;
                        }
                    }


                    //Approssimo conteggio dita, e classifico : 1 dito = play, 5 dita = pausa

                    if (Math.Abs(countFingers - 1) < Math.Abs(countFingers - 5)
                        &&
                        Math.Abs(countFingers - 1) < Math.Abs(countFingers - 2))
                    {
                        label10.Text = "Play";
                        axWindowsMediaPlayer1.Ctlcontrols.play();
                    }

                    else if (Math.Abs(countFingers - 5) < Math.Abs(countFingers - 1)
                             &&
                             Math.Abs(countFingers - 5) < Math.Abs(countFingers - 2))
                    {
                        label10.Text = "Pause";
                        axWindowsMediaPlayer1.Ctlcontrols.pause();
                    }

                    else if (Math.Abs(countFingers - 2) < Math.Abs(countFingers - 1)
                             &&
                             Math.Abs(countFingers - 2) < Math.Abs(countFingers - 5))
                    {
                        label10.Text = "Volume Up";
                        axWindowsMediaPlayer1.Ctlcontrols.pause();

                        axWindowsMediaPlayer1.settings.volume++;
                    }
                }
            }

            pictureBox1.Image = binary.Bitmap;
        }
예제 #7
0
        private Rectangle LocateROI()
        {
            int           prediction        = -1;
            VectorOfPoint contourOfInterest = new VectorOfPoint();

            int index = 0;

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

            MCvMoments moment = CvInvoke.Moments(contourOfInterest);

            double[] huMoment = moment.GetHuMoment();

            prediction = _svm.Compute(huMoment);

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

            //    prediction = _svm.Compute(huMoment);

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

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

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


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

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

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

                    convexityDefect.CopyTo(convex);

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

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


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

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

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

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


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

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


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

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

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

                        Mat cloneMat1 = ImageInput.Clone().Mat;

                        Mat matToBeEval1 = new Mat(cloneMat1, rectROIEval1);

                        VectorOfVectorOfPoint contoursEval1 = new VectorOfVectorOfPoint();

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

                        int largestContourIndexEval1 = ImgProc.LargestContourIndex(contoursEval1);

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

                        double[] huMomentsEval1 = momentEval1.GetHuMoment();

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

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

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

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

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

                        else
                        {
                            return(Rectangle.Empty);
                        }
                    }
                    else
                    {
                        return(Rectangle.Empty);
                    }
                }
                else
                {
                    return(Rectangle.Empty);
                }
            }
            else
            {
                return(Rectangle.Empty);
            }
        }
        void timer_Tick(object sender, EventArgs e)
        {
            sw.Start();

            currentFrame = capture.QueryFrame().ToImage<Hsv, byte>();
            currentFrame = currentFrame.AbsDiff(backgroundFrame);
            smoothedFrame = currentFrame.PyrDown().PyrUp();
            smoothedFrame._SmoothGaussian(3);
            filteredFrame = smoothedFrame.InRange(new Hsv(hueLower, saturationLower, valueLower), new Hsv(hueHigher, saturationHigher, valueHigher));

            outFrame = filteredFrame;//.Canny((cannyThresh), (cannyThreshLink));
            CvInvoke.FindContours(outFrame, contours, hierarchy, Emgu.CV.CvEnum.RetrType.List, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);
            for (int i = 0; i < contours.Size; i++)
            {
                double area = CvInvoke.ContourArea(contours[i], false);
                if (area > maxArea)
                {
                    maxArea = area;
                    idx = i;
                }
            }
            image.SetValue(new MCvScalar(180, 0, 255));
            CvInvoke.DrawContours(image, contours, idx, new MCvScalar(255, 255, 255), 3);
            ContourArea.Text = maxArea.ToString();
            if (maxArea != 0)
            {
                CvInvoke.ConvexHull(contours[idx], cvh, false);
                CvInvoke.ConvexityDefects(contours[idx], cvh, cvd);
                moments = CvInvoke.Moments(contours[idx], true);
                centroid = new System.Drawing.Point((int) moments.GravityCenter.X, (int) moments.GravityCenter.Y);
                CvInvoke.Circle(image, centroid, 5, new MCvScalar(100,50,25), 1);
                if (contours.Size != 0)
                {
                    polyline = contours[idx].ToArray();

                    if (!cvd.IsEmpty && contours[idx].Size > 10)
                    {
                        Matrix<int> m = new Matrix<int>(cvd.Rows, cvd.Cols,
                                          cvd.NumberOfChannels);
                        cvd.CopyTo(m);
                        for (int i = 0; i < m.Rows; i++)
                        {
                            int startIdx = m.Data[i, 0];
                            int endIdx = m.Data[i, 1];
                            int fpIdx = m.Data[i, 2];
                            int depth = m.Data[i, 3];
                            
                            startPoint = polyline[startIdx];
                            endPoint = polyline[endIdx];
                            midPoint = new System.Drawing.Point(
                                (startPoint.X + endPoint.X) / 2, (startPoint.Y + endPoint.Y) / 2);
                            farthestPoint = polyline[fpIdx];
                            CvInvoke.Line(image, midPoint, farthestPoint, new MCvScalar(180, 255, 0));
                            CvInvoke.Line(image, startPoint, endPoint, new MCvScalar(180, 255, 255));
                        }
                    }

                    if(trained.Size!=0)
                    {
                        double match=1000000;
                        
                        int d = 0;
                        for (int i = 0; i  < trained.Size; i++)
                        {
                            double curr = CvInvoke.MatchShapes(contours[idx], trained[i], ContoursMatchType.I3);
                            if(curr < match)
                            {
                                d = i;
                                match = curr;
                            }

                        }
                        if(match<0.25)
                        {
                            ContourArea.Text = words[d];
                            image.Draw(words[d], centroid, FontFace.HersheyTriplex, 1, new Hsv(90,100, 100));
                        }
                        
                    }
                }
            }



            if (currentFrame != null)
            {
                sw.Stop();
                imgPros.Source = ToBitmapSource(outFrame);
                imgOrig.Source = ToBitmapSource(currentFrame);
                imgSmooth.Source = ToBitmapSource(image);

                
                sw.Reset();
            }

            maxArea = 0;
            idx = 0;

        }
예제 #9
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();
        }
        private Mat DetectObject(Mat detectionFrame, Mat displayFrame)
        {
            using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
            {
                detectGesture = false;
                VectorOfPoint biggestContour = null;
                IOutputArray  hirarchy       = null;
                // Crear lista de contornos
                CvInvoke.FindContours(detectionFrame, contours, hirarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple);

                // Selecciona el contour mas grande
                if (contours.Size > 0)
                {
                    double        maxArea = 0;
                    int           chosen  = 0;
                    VectorOfPoint contour = null;
                    for (int i = 0; i < contours.Size; i++)
                    {
                        contour = contours[i];

                        double area = CvInvoke.ContourArea(contour);
                        if (area > maxArea)
                        {
                            maxArea = area;
                            chosen  = i;
                        }
                    }

                    // Dibuja un frame
                    MarkDetectedObject(displayFrame, contours[chosen], maxArea);

                    VectorOfPoint hullPoints = new VectorOfPoint();
                    VectorOfInt   hullInt    = new VectorOfInt();

                    CvInvoke.ConvexHull(contours[chosen], hullPoints, true);
                    CvInvoke.ConvexHull(contours[chosen], hullInt, false);

                    Mat defects = new Mat();

                    if (hullInt.Size > 3)
                    {
                        detectGesture = true;
                    }
                    CvInvoke.ConvexityDefects(contours[chosen], hullInt, defects);

                    Rectangle box = CvInvoke.BoundingRectangle(hullPoints);
                    CvInvoke.Rectangle(displayFrame, box, drawingColor);

                    Point center = new Point(box.X + box.Width / 2, box.Y + box.Height / 2);

                    VectorOfPoint start_points = new VectorOfPoint();
                    VectorOfPoint far_points   = new VectorOfPoint();

                    if (!defects.IsEmpty)
                    {
                        //Los datos del Mat no se pueden leer directamente, por lo que los convertimos a Matrix<>
                        Matrix <int> m = new Matrix <int>(defects.Rows, defects.Cols,
                                                          defects.NumberOfChannels);
                        defects.CopyTo(m);
                        gestualNum = 0;
                        int x = int.MaxValue, y = int.MaxValue;
                        for (int i = 0; i < m.Rows; i++)
                        {
                            int   startIdx   = m.Data[i, 0];
                            int   endIdx     = m.Data[i, 1];
                            int   farIdx     = m.Data[i, 2];
                            Point startPoint = contours[chosen][startIdx];
                            Point endPoint   = contours[chosen][endIdx];
                            Point farPoint   = contours[chosen][farIdx];
                            CvInvoke.Circle(displayFrame, endPoint, 3, new MCvScalar(0, 255, 255));
                            CvInvoke.Circle(displayFrame, startPoint, 3, new MCvScalar(255, 255, 0));

                            //if (true)
                            //{
                            if (endPoint.Y < y)
                            {
                                x = endPoint.X;
                                y = endPoint.Y;
                            }

                            //}

                            double distance = Math.Round(Math.Sqrt(Math.Pow((center.X - farPoint.X), 2) + Math.Pow((center.Y - farPoint.Y), 2)), 1);
                            if (distance < box.Height * 0.3)
                            {
                                CvInvoke.Circle(displayFrame, farPoint, 10, new MCvScalar(255, 0, 0), 4);
                                gestualNum++;
                            }
                            //dibuja una línea que conecta el punto de inicio del defecto de convexidad y el punto final en una línea roja
                            CvInvoke.Line(displayFrame, startPoint, endPoint, new MCvScalar(0, 255, 255));
                        }

                        if (gestualNum >= 4)
                        {
                            //Console.WriteLine("numero gestual 4");
                            gestualNumRepite++;
                        }
                        else
                        {
                            gestualNumRepite = 0;
                        }
                        if (gestualNumRepite == 3)
                        {
                            Console.WriteLine("numero gestual 5 Click");
                            gestualNumRepite = 0;

                            if (detectClick == true)
                            {
                                detectClick = false;
                            }
                            else
                            {
                                detectClick = true;
                            }
                        }
                        Console.WriteLine("numero gestual " + gestualNum);
                        //var info = new string[] { $"Puntero", $"Posicion: {x}, {y}" };

                        //WriteMultilineText(displayFrame, info, new Point(x + 30, y));
                        centerSensor.X = x;
                        centerSensor.Y = y;
                        CvInvoke.Circle(displayFrame, new Point(x, y), 20, new MCvScalar(255, 0, 255), 2);
                        //CvInvoke.Circle(picture, new Point(x * 2, y * 4), 20, new MCvScalar(255, 0, 255), 2);
                        return(displayFrame);
                    }
                    // detectGesture = false;
                    //  return displayFrame;
                }

                return(displayFrame);
            }
        }
예제 #11
0
        private void ImageRecognition_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Image <Gray, byte> OutputImage = InputImage.Convert <Gray, byte>().ThresholdBinary(new Gray(100), new Gray(255));
                int i;

                //Применение фильтрации при необходимости
                if (FilterBox.IsChecked == true)
                {
                    CvInvoke.Erode(OutputImage, OutputImage, new Mat(), new System.Drawing.Point(-1, -1), 5, Emgu.CV.CvEnum.BorderType.Default, new MCvScalar());
                    CvInvoke.Dilate(OutputImage, OutputImage, new Mat(), new System.Drawing.Point(-1, -1), 5, Emgu.CV.CvEnum.BorderType.Default, new MCvScalar());
                }

                //Поиск контура
                VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
                Mat hierarchy = new Mat();
                CvInvoke.FindContours(OutputImage,
                                      contours,
                                      hierarchy,
                                      Emgu.CV.CvEnum.RetrType.Tree,
                                      Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);

                //ResultImage для фильтров
                Image <Bgr, byte> ResultImage = OutputImage.Convert <Bgr, byte>();

                //Отрисовка контура
                CvInvoke.DrawContours(ResultImage, contours, -1, new MCvScalar(255, 10, 10), 3);

                //Опорные точки
                VectorOfPoint contour = new VectorOfPoint();
                VectorOfInt   hull    = new VectorOfInt();
                contour = contours[0];
                CvInvoke.ConvexHull(contour, hull, false, false);

                //Дефекты выпуклости
                Mat convexityDefects = new Mat();
                CvInvoke.ConvexityDefects(contour, hull, convexityDefects);

                //Преобразование в матрицу для удобства
                Matrix <int> matrixOfDefects = new Matrix <int>(convexityDefects.Rows, convexityDefects.Cols, convexityDefects.NumberOfChannels);
                convexityDefects.CopyTo(matrixOfDefects);
                Matrix <int>[] channels = matrixOfDefects.Split();
                CircleF        circle   = CvInvoke.MinEnclosingCircle(contour);
                //
                List <System.Drawing.PointF> PointsMemory = new List <System.Drawing.PointF>();

                //Для поиска центра
                RotatedRect minAreaRect = CvInvoke.MinAreaRect(contour);

                //Отбор точек
                for (i = 0; i < matrixOfDefects.Rows; ++i)
                {
                    if (PropertyBox.IsChecked == true)
                    {
                        #region Через Описывающий прямоугольник
                        //C - Center  S - Start[0]  E - End[1]  D - Depth[2]
                        //Start - Center
                        float LengthXSC = contour[channels[0][i, 0]].X - minAreaRect.Center.X;
                        float LengthYSC = contour[channels[0][i, 0]].Y - minAreaRect.Center.Y;
                        float LengthSC  = (float)Math.Sqrt(Math.Pow(LengthXSC, 2) + Math.Pow(LengthYSC, 2));

                        //Расстояние от начальной точки до дефекта
                        float LengthXSD = contour[channels[0][i, 0]].X - contour[channels[2][i, 0]].X;
                        float LengthYSD = contour[channels[0][i, 0]].Y - contour[channels[2][i, 0]].X;
                        float LengthSD  = (float)Math.Sqrt(Math.Pow(LengthXSD, 2) + Math.Pow(LengthYSD, 2));

                        //Расстояние от начала до конца вектора
                        float LengthXSE = contour[channels[0][i, 0]].X - contour[channels[1][i, 0]].X;
                        float LengthYSE = contour[channels[0][i, 0]].Y - contour[channels[1][i, 0]].X;
                        float LengthSE  = (float)Math.Sqrt(Math.Pow(LengthXSE, 2) + Math.Pow(LengthYSE, 2));

                        //Расстояние от дефекта до центра
                        float LengthXDC = contour[channels[2][i, 0]].X - minAreaRect.Center.X;
                        float LengthYDC = contour[channels[2][i, 0]].Y - minAreaRect.Center.Y;
                        float LengthDC  = (float)Math.Sqrt(Math.Pow(LengthXDC, 2) + Math.Pow(LengthYDC, 2));

                        //Расстояние от центра до грани под 90
                        float MinRadius = minAreaRect.Size.Width / 2;

                        //Отбор точек по условиям
                        if (LengthSC >= MinRadius * 0.85 &&
                            (LengthSE <= MinRadius || LengthSE >= MinRadius * 0.95) &&
                            (LengthSD > MinRadius * 0.3 && LengthDC <= MinRadius * 0.9))
                        {
                            PointsMemory.Add(new System.Drawing.PointF(contour[channels[0][i, 0]].X, contour[channels[0][i, 0]].Y));
                            ResultImage.Draw(new System.Drawing.Point[] { contour[channels[0][i, 0]], contour[channels[2][i, 0]] }, new Bgr(0, 255, 0), 2);
                        }
                        ResultImage.Draw(new RotatedRect(minAreaRect.Center, minAreaRect.Size, minAreaRect.Angle), new Bgr(125, 125, 125), 2);
                        #endregion
                    }
                    else
                    {
                        #region Через описывающую окружность
                        //C - Center  S - Start[0]  E - End[1]  D - Depth[2]
                        //Start - Center
                        float LengthXSC = contour[channels[0][i, 0]].X - circle.Center.X;
                        float LengthYSC = contour[channels[0][i, 0]].Y - circle.Center.Y;
                        float LengthSC  = (float)Math.Sqrt(Math.Pow(LengthXSC, 2) + Math.Pow(LengthYSC, 2));

                        //Расстояние от начальной точки до дефекта
                        float LengthXSD = contour[channels[0][i, 0]].X - contour[channels[2][i, 0]].X;
                        float LengthYSD = contour[channels[0][i, 0]].Y - contour[channels[2][i, 0]].X;
                        float LengthSD  = (float)Math.Sqrt(Math.Pow(LengthXSD, 2) + Math.Pow(LengthYSD, 2));

                        //Расстояние от начала до конца вектора
                        float LengthXSE = contour[channels[0][i, 0]].X - contour[channels[1][i, 0]].X;
                        float LengthYSE = contour[channels[0][i, 0]].Y - contour[channels[1][i, 0]].X;
                        float LengthSE  = (float)Math.Sqrt(Math.Pow(LengthXSE, 2) + Math.Pow(LengthYSE, 2));

                        //Расстояние от дефекта до центра
                        float LengthXDC = contour[channels[2][i, 0]].X - circle.Center.X;
                        float LengthYDC = contour[channels[2][i, 0]].Y - circle.Center.Y;
                        float LengthDC  = (float)Math.Sqrt(Math.Pow(LengthXDC, 2) + Math.Pow(LengthYDC, 2));


                        //Отбор точек по условиям
                        if (LengthSC >= circle.Radius * 0.5 &&
                            (LengthSE <= circle.Radius * 0.8 || LengthSE >= circle.Radius) &&
                            (LengthDC <= LengthSD * 0.9 || LengthSD > circle.Radius * 0.4))
                        {
                            ResultImage.Draw(new System.Drawing.Point[] { contour[channels[0][i, 0]], contour[channels[2][i, 0]] }, new Bgr(0, 255, 0), 2);
                            PointsMemory.Add(new System.Drawing.PointF(contour[channels[0][i, 0]].X, contour[channels[0][i, 0]].Y));
                        }
                        ResultImage.Draw(new CircleF(circle.Center, circle.Radius), new Bgr(0, 255, 255), 2);
                        #endregion
                    }
                }
                foreach (System.Drawing.PointF pt in PointsMemory)
                {
                    ResultImage.Draw(new CircleF(pt, 3), new Bgr(0, 0, 255), 3);
                }

                OutputImageBox.Source = BitmapSourceConvert.ToBitmapSource(ResultImage);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
예제 #12
0
        private Mat DetectObject(Mat detectionFrame, Mat displayFrame, Rectangle box)
        {
            Image <Bgr, Byte> buffer_im = displayFrame.ToImage <Bgr, Byte>();

            using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
            {
                IOutputArray hirarchy = null;
                // Construir lista de contur (contornos)
                CvInvoke.FindContours(detectionFrame, contours, hirarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple);

                // seleccionar el contour (contorno) mas grande
                if (contours.Size > 0)
                {
                    double        maxArea = 0;
                    int           chosen  = 0;
                    VectorOfPoint contour = null;
                    for (int i = 0; i < contours.Size; i++)
                    {
                        contour = contours[i];

                        double area = CvInvoke.ContourArea(contour);
                        if (area > maxArea)
                        {
                            maxArea = area;
                            chosen  = i;
                        }
                    }

                    // Draw on a frame
                    //MarkDetectedObject(displayFrame, contours[chosen], maxArea);//dibuja una envoltura roja

                    VectorOfPoint hullPoints = new VectorOfPoint();
                    VectorOfInt   hullInt    = new VectorOfInt();

                    CvInvoke.ConvexHull(contours[chosen], hullPoints, true);
                    CvInvoke.ConvexHull(contours[chosen], hullInt, false);

                    Mat defects = new Mat();


                    if (hullInt.Size > 3)
                    {
                        CvInvoke.ConvexityDefects(contours[chosen], hullInt, defects);
                    }

                    box = CvInvoke.BoundingRectangle(hullPoints);
                    CvInvoke.Rectangle(displayFrame, box, drawingColor); //Box rectangulo que encierra el area mas grande
                                                                         // cropbox = crop_color_frame(displayFrame, box);

                    buffer_im.ROI = box;

                    Image <Bgr, Byte> cropped_im = buffer_im.Copy();
                    textImage   = cropped_im.Mat;
                    imagenFinal = cropped_im.Bitmap;

                    //imagenFinal.RotateFlip(RotateFlipType.Rotate180FlipNone);
                    //if (imagenFinal != null)
                    //{
                    //    try

                    //    {
                    //        var assembly = Assembly.GetExecutingAssembly();
                    //        var folder = Path.GetDirectoryName(assembly.Location);
                    //        imagenFinal.Save(folder + "/texto.png", System.Drawing.Imaging.ImageFormat.Png);
                    //    }
                    //    catch (Exception)
                    //    {

                    //        throw;
                    //    }
                    //}

                    return(displayFrame);
                }
                textImage = detectionFrame;
                return(displayFrame);
            }
        }
        private void DetectObject(Mat detectionFrame, Mat displayFrame, Rectangle box)
        {
            Image <Bgr, Byte> buffer_im = displayFrame.ToImage <Bgr, Byte>();

            using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
            {
                VectorOfPoint biggestContour = null;
                IOutputArray  hirarchy       = null;

                CvInvoke.FindContours(detectionFrame, contours, hirarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple);


                if (contours.Size > 0)
                {
                    double        maxArea = 0;
                    int           chosen  = 0;
                    VectorOfPoint contour = null;
                    for (int i = 0; i < contours.Size; i++)
                    {
                        contour = contours[i];

                        double area = CvInvoke.ContourArea(contour);
                        if (area > maxArea)
                        {
                            maxArea = area;
                            chosen  = i;
                        }
                    }


                    //MarkDetectedObject(displayFrame, contours[chosen], maxArea);//dibuja una envoltura roja

                    VectorOfPoint hullPoints = new VectorOfPoint();
                    VectorOfInt   hullInt    = new VectorOfInt();

                    CvInvoke.ConvexHull(contours[chosen], hullPoints, true);
                    CvInvoke.ConvexHull(contours[chosen], hullInt, false);

                    Mat defects = new Mat();


                    if (hullInt.Size > 3)
                    {
                        CvInvoke.ConvexityDefects(contours[chosen], hullInt, defects);
                    }

                    box = CvInvoke.BoundingRectangle(hullPoints);
                    CvInvoke.Rectangle(displayFrame, box, drawingColor); //Box rectangulo que encierra el area mas grande
                                                                         // cropbox = crop_color_frame(displayFrame, box);

                    buffer_im.ROI = box;

                    Image <Bgr, Byte> cropped_im = buffer_im.Copy();
                    pictureBox8.Image = cropped_im.Bitmap;
                    Point center = new Point(box.X + box.Width / 2, box.Y + box.Height / 2);//centro  rectangulo MOUSE

                    VectorOfPoint start_points = new VectorOfPoint();
                    VectorOfPoint far_points   = new VectorOfPoint();

                    if (!defects.IsEmpty)
                    {
                        Matrix <int> m = new Matrix <int>(defects.Rows, defects.Cols,
                                                          defects.NumberOfChannels);
                        defects.CopyTo(m);
                        int xe = 2000, ye = 2000;
                        int xs = 2000, ys = 2000;
                        int xer = 2000, yer = 2000;
                        int xsr = 2000, ysr = 2000;
                        int xem = 0, yem = 0;
                        int xsm = 0, ysm = 0;
                        int xez = 0, yez = 0;
                        int xsz = 0, ysz = 0;
                        int y = 0, x = 0;
                        int ym = 0, xm = 0;
                        int yr = 0, xr = 0;
                        int yz = 0, xz = 0;
                        for (int i = 0; i < m.Rows; i++)
                        {
                            int   startIdx   = m.Data[i, 0];
                            int   endIdx     = m.Data[i, 1];
                            int   farIdx     = m.Data[i, 2];
                            Point startPoint = contours[chosen][startIdx];
                            Point endPoint   = contours[chosen][endIdx];
                            Point farPoint   = contours[chosen][farIdx];
                            CvInvoke.Circle(displayFrame, endPoint, 3, new MCvScalar(0, 255, 255));
                            CvInvoke.Circle(displayFrame, startPoint, 3, new MCvScalar(255, 255, 0));

                            if (true)
                            {
                                if (endPoint.Y < ye)
                                {
                                    xe = endPoint.X;

                                    ye = endPoint.Y;
                                }

                                if (startPoint.Y < ys)
                                {
                                    xs = startPoint.X;

                                    ys = startPoint.Y;
                                }

                                if (ye < ys)
                                {
                                    y = ye;
                                    x = xe;
                                }
                                else
                                {
                                    y = ys;
                                    x = xs;
                                }


                                if (endPoint.Y > yem)
                                {
                                    xem = endPoint.X;

                                    yem = endPoint.Y;
                                }

                                if (startPoint.Y > ysm)
                                {
                                    xsm = startPoint.X;

                                    ysm = startPoint.Y;
                                }

                                if (yem > ysm)
                                {
                                    ym = yem;
                                    xm = xem;
                                }
                                else
                                {
                                    y = ys;
                                    x = xs;
                                }

                                if (endPoint.X < xer)
                                {
                                    xer = endPoint.X;

                                    yer = endPoint.Y;
                                }

                                if (startPoint.X < xsr)
                                {
                                    xsr = startPoint.X;

                                    ysr = startPoint.Y;
                                }

                                if (xer < xsr)
                                {
                                    yr = yer;
                                    xr = xer;
                                }
                                else
                                {
                                    yr = ysr;
                                    xr = xsr;
                                }


                                if (endPoint.X > xez)
                                {
                                    xez = endPoint.X;

                                    yez = endPoint.Y;
                                }

                                if (startPoint.X > xsz)
                                {
                                    xsz = startPoint.X;

                                    ysz = startPoint.Y;
                                }

                                if (xez > xsz)
                                {
                                    yz = yez;
                                    xz = xez;
                                }

                                else
                                {
                                    yz = ysz;
                                    xz = xsz;
                                }
                            }

                            /*var info = new string[] {
                             *
                             * $"Posicion: {endPoint.X}, {endPoint.Y}"
                             * };
                             *
                             * WriteMultilineText(displayFrame, info, new Point(endPoint.X + 5, endPoint.Y));*/

                            double distance = Math.Round(Math.Sqrt(Math.Pow((center.X - farPoint.X), 2) + Math.Pow((center.Y - farPoint.Y), 2)), 1);
                            if (distance < box.Height * 0.3)
                            {
                                CvInvoke.Circle(displayFrame, farPoint, 3, new MCvScalar(255, 0, 0));
                            }

                            CvInvoke.Line(displayFrame, startPoint, endPoint, new MCvScalar(0, 255, 0));
                            // CvInvoke.Line(displayFrame, startPoint, farPoint, new MCvScalar(0, 255, 255));
                        }
                        var infoe      = new string[] { $"Punto", $"Posicion: {x}, {y}" };
                        var infos      = new string[] { $"Punto", $"Posicion: {xm}, {ym}" };
                        var infor      = new string[] { $"Punto", $"Posicion: {x}, {y}" };
                        var infoz      = new string[] { $"Punto", $"Posicion: {xm}, {ym}" };
                        var infoCentro = new string[] { $"Centro", $"Posicion: {xm}, {ym}" };

                        var xCentro = (x + xm + xr + xz) / 4;
                        var yCentro = (y + ym + yr + yz) / 4;

                        WriteMultilineText(displayFrame, infoe, new Point(x + 30, y));
                        CvInvoke.Circle(displayFrame, new Point(x, y), 5, new MCvScalar(255, 0, 255), 2);
                        Image <Bgr, byte> temp = detectionFrame.ToImage <Bgr, byte>();
                        var temp2 = temp.SmoothGaussian(5).Convert <Gray, byte>().ThresholdBinary(new Gray(230), new Gray(255));
                        VectorOfVectorOfPoint contorno = new VectorOfVectorOfPoint();
                        Mat mat = new Mat();
                        CvInvoke.FindContours(temp2, contorno, mat, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.LinkRuns);
                        for (int i = 0; i < contorno.Size; i++)
                        {
                            double        perimetro = CvInvoke.ArcLength(contorno[i], true);
                            VectorOfPoint approx    = new VectorOfPoint();
                            CvInvoke.ApproxPolyDP(contorno[i], approx, 0.04 * perimetro, true);
                            CvInvoke.DrawContours(displayFrame, contorno, i, new MCvScalar(0, 255, 255), 2);
                        }

                        WriteMultilineText(displayFrame, infos, new Point(xm + 30, ym));
                        CvInvoke.Circle(displayFrame, new Point(xm, ym), 5, new MCvScalar(255, 0, 255), 2);
                        WriteMultilineText(displayFrame, infor, new Point(xr + 30, yr));
                        CvInvoke.Circle(displayFrame, new Point(xr, yr), 5, new MCvScalar(255, 0, 255), 2);
                        WriteMultilineText(displayFrame, infoz, new Point(xz + 30, yz));
                        CvInvoke.Circle(displayFrame, new Point(xz, yz), 5, new MCvScalar(255, 0, 255), 2);

                        WriteMultilineText(displayFrame, infoz, new Point(xCentro + 30, yCentro));
                        CvInvoke.Circle(displayFrame, new Point(xCentro, yCentro), 2, new MCvScalar(0, 100, 0), 4);
                        //CvInvoke.Circle(picture, new Point(x * 2, y * 4), 20, new MCvScalar(255, 0, 255), 2);*/
                    }
                }
            }
        }
예제 #14
0
        private Mat DetectObject(Mat detectionFrame, Mat displayFrame, Rectangle box)
        {
            Image <Bgr, Byte> buffer_im = displayFrame.ToImage <Bgr, Byte>();

            using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
            {
                IOutputArray hirarchy = null;
                // Construir lista de contur (contornos)
                CvInvoke.FindContours(detectionFrame, contours, hirarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple);

                // seleccionar el contour (contorno) mas grande
                if (contours.Size > 0)
                {
                    double        maxArea = 0;
                    int           chosen  = 0;
                    VectorOfPoint contour = null;
                    for (int i = 0; i < contours.Size; i++)
                    {
                        contour = contours[i];

                        double area = CvInvoke.ContourArea(contour);
                        if (area > maxArea)
                        {
                            maxArea = area;
                            chosen  = i;
                        }
                    }


                    VectorOfPoint hullPoints = new VectorOfPoint();
                    VectorOfInt   hullInt    = new VectorOfInt();

                    CvInvoke.ConvexHull(contours[chosen], hullPoints, true);
                    CvInvoke.ConvexHull(contours[chosen], hullInt, false);

                    Mat defects = new Mat();


                    if (hullInt.Size > 3)
                    {
                        CvInvoke.ConvexityDefects(contours[chosen], hullInt, defects);
                    }

                    box = CvInvoke.BoundingRectangle(hullPoints);
                    CvInvoke.Rectangle(displayFrame, box, drawingColor);               //Box rectangulo que encierra el area mas grande

                    center = new Point(box.X + box.Width / 2, box.Y + box.Height / 2); //centro  rectangulo MOUSE

                    var infoCentro = new string[] { $"Centro", $"Posicion: {center.X}, {center.Y}" };
                    WriteMultilineText(displayFrame, infoCentro, new Point(center.X + 30, center.Y));
                    CvInvoke.Circle(displayFrame, new Point(center.X, center.Y), 2, new MCvScalar(0, 100, 0), 4);
                    detectGesture = true;

                    buffer_im.Dispose();
                    defects.Dispose();
                    detectionFrame.Dispose();
                    return(displayFrame);
                }
                buffer_im.Dispose();
                detectionFrame.Dispose();
                detectGesture = false;
                return(displayFrame);
            }
        }
예제 #15
0
        private void ExtractContourAndHull(Image <Bgr, byte> originalImage, Image <Gray, byte> skin)
        {
            var contours = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(skin, contours, new Mat(), RetrType.List, ChainApproxMethod.ChainApproxSimple);
            var           result2        = 0;
            VectorOfPoint biggestContour = null;

            if (contours.Size != 0)
            {
                biggestContour = contours[0];
            }

            for (var i = 0; i < contours.Size; i++)
            {
                var result1 = contours[i].Size;
                if (result1 <= result2)
                {
                    continue;
                }
                result2        = result1;
                biggestContour = contours[i];
            }

            if (biggestContour == null)
            {
                return;
            }

            currentContour = new VectorOfPoint();
            CvInvoke.ApproxPolyDP(biggestContour, currentContour, 0, true);
            //TODO Get to know why it gives exception
            //ImageFrame.Draw(biggestContour, 3, new Bgr(Color.LimeGreen));
            biggestContour = currentContour;


            var pointsToFs = new PointF[currentContour.Size];

            for (var i = 0; i < currentContour.Size; i++)
            {
                pointsToFs[i] = new PointF(currentContour[i].X, currentContour[i].Y);
            }

            var hull = CvInvoke.ConvexHull(pointsToFs, true);

            pointsToFs = new PointF[biggestContour.Size];
            for (var i = 0; i < biggestContour.Size; i++)
            {
                pointsToFs[i] = new PointF(biggestContour[i].X, biggestContour[i].Y);
            }

            box = CvInvoke.MinAreaRect(pointsToFs);
            var points = box.GetVertices();

            var ps = new Point[points.Length];

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

            var hullToPoints = new Point[hull.Length];

            for (var i = 0; i < hull.Length; i++)
            {
                hullToPoints[i] = Point.Round(hull[i]);
            }

            originalImage.DrawPolyline(hullToPoints, true, new Bgr(200, 125, 75), 2);
            originalImage.Draw(new CircleF(new PointF(box.Center.X, box.Center.Y), 3), new Bgr(200, 125, 75), 2);

            var convexHull = new VectorOfInt();

            CvInvoke.ConvexHull(currentContour, convexHull, false, false);
            defects = new Mat();
            CvInvoke.ConvexityDefects(currentContour, convexHull, defects);
            if (!defects.IsEmpty)
            {
                Matrix <int> m = new Matrix <int>(defects.Rows, defects.Cols,
                                                  defects.NumberOfChannels); // copy Mat to a matrix...
                defects.CopyTo(m);
                Matrix <int>[] channels = m.Split();
                if (channels.Length >= 2)
                {
                    startIndex = channels.ElementAt(0).Data;
                    endIndex   = channels.ElementAt(1).Data;
                    depthIndex = channels.ElementAt(2).Data;
                }
            }
        }
        private void ProcessFrame(object sender, EventArgs arg)
        {
            Mat frame = new Mat();

            capture.Retrieve(frame, 0);
            //preprocessing
            Image <Bgr, byte>  finalImg      = frame.ToImage <Bgr, byte>().Flip(FlipType.Horizontal);
            Image <Gray, byte> processingImg = finalImg.Convert <Gray, byte>();

            BiTonalLevel.Dispatcher.BeginInvoke(new Action(() =>
            {
                if (BiTonalLevel.Value > 0)
                {
                    processingImg = processingImg.ThresholdBinary(new Gray(BiTonalLevel.Value), new Gray(255));
                }
            }));
            BlurLevel.Dispatcher.BeginInvoke(new Action(() =>
            {
                if (BlurLevel.Value > 1)
                {
                    CvInvoke.Blur(processingImg, processingImg, new System.Drawing.Size((int)BlurLevel.Value, (int)BlurLevel.Value), new System.Drawing.Point(-1, -1));
                }
            }));
            //morphological processing
            processingImg.MorphologyEx(firstMorphOp, kernel, new System.Drawing.Point(-1, -1), firstMorphSteps, BorderType.Default, new MCvScalar());
            if (doubleMorph)
            {
                processingImg.MorphologyEx(secondMorphOp, kernel2, new System.Drawing.Point(-1, -1), secondMorphSteps, BorderType.Default, new MCvScalar());
            }
            ProcessingVideoBox.Dispatcher.BeginInvoke(new Action(() => ProcessingVideoBox.Source = ToBitmapGrey(processingImg)));
            //edge detection
            Mat edges = new Mat(frame.Size, frame.Depth, 1);

            CvInvoke.Canny(processingImg, edges, lowerTresholdLevel, upperTresholdLevel, cannyKernelSize);
            //contours finding
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            Mat    hierarchy             = new Mat();
            int    largest_contour_index = 0;
            double largest_area          = 0;

            CvInvoke.FindContours(edges, contours, hierarchy, contouringMode, contouringMethod);
            for (int i = 0; i < contours.Size; i++)
            {
                double a = CvInvoke.ContourArea(contours[i], false);
                if (a > largest_area)
                {
                    largest_area          = a;
                    largest_contour_index = i;
                }
            }
            CvInvoke.DrawContours(finalImg, contours, largest_contour_index, redColor, 3, LineType.EightConnected, hierarchy);
            //defects points finding
            VectorOfInt hull    = new VectorOfInt();
            Mat         defects = new Mat();

            if (contours.Size > 0)
            {
                VectorOfPoint largestContour = new VectorOfPoint(contours[largest_contour_index].ToArray());
                CvInvoke.ConvexHull(largestContour, hull, false, true);
                CvInvoke.ConvexityDefects(largestContour, hull, defects);
                if (!defects.IsEmpty)
                {
                    Matrix <int> m = new Matrix <int>(defects.Rows, defects.Cols, defects.NumberOfChannels);
                    defects.CopyTo(m);
                    Matrix <int>[] channels = m.Split();
                    for (int i = 1; i < defects.Rows; ++i)
                    {
                        finalImg.Draw(new System.Drawing.Point[] { largestContour[channels[0][i, 0]], largestContour[channels[1][i, 0]] }, new Bgr(100, 255, 100), 2);
                        CvInvoke.Circle(finalImg, new System.Drawing.Point(largestContour[channels[0][i, 0]].X, largestContour[channels[0][i, 0]].Y), 7, new MCvScalar(255, 0, 0), -1);
                    }
                }
            }
            MainVideoBox.Dispatcher.BeginInvoke(new Action(() => MainVideoBox.Source = ToBitmapFinal(finalImg)));
        }
예제 #17
0
        public void Tick(Object sender, EventArgs args)
        {
            if (mKinect != null)
            {
                MultiSourceFrame frame = mFrameReader.AcquireLatestFrame();

                TrackFingers();

                if (frame != null)
                {
                    using (var depthFrame = frame.DepthFrameReference.AcquireFrame())
                    {
                        if (depthFrame != null)
                        {
                            if (depthData == null)
                            {
                                depthWidth  = depthFrame.FrameDescription.Width;
                                depthHeight = depthFrame.FrameDescription.Height;

                                depthData = new ushort[depthWidth * depthHeight];
                                pixelData = new byte[depthWidth * depthHeight * 3];
                                mFrame    = new Mat(depthHeight, depthWidth, DepthType.Cv8U, 1);
                            }

                            ushort minDepth = depthFrame.DepthMinReliableDistance;
                            ushort maxDepth = depthFrame.DepthMaxReliableDistance;

                            depthFrame.CopyFrameDataToArray(depthData);
                            Image <Gray, Byte> img = mFrame.ToImage <Gray, Byte>();

                            for (int i = 0; i < depthData.Length; i++)
                            {
                                ushort depth = depthData[i];
                                //byte intensity = (byte)(depth >= minDepth && depth <= maxDepth ? depth : 0);
                                byte intensity = (byte)(depth < 1000 && depth > 10 ? 0 : 255);

                                img.Data[i / depthWidth, i % depthWidth, 0] = intensity;
                            }

                            mFrame = img.Mat;

                            // DISPLAY Depth image
                            //(Controls["FrameImageBox"] as ImageBox).Image = img;

                            //*********************
                            // Gaussian Blur
                            //*********************
                            CvInvoke.GaussianBlur(img, img, new Size(5, 5), 0);

                            //*********************
                            // Threshold
                            //*********************
                            //mFrame = img.Mat;

                            //Mat thresholds = new Mat(); ;

                            //CvInvoke.Threshold(mFrame, thresholds, THRESHOLD, THRESHOLD_MAX_VALUE, ThresholdType.Binary);

                            //// DISPLAY Thresholds
                            //(Controls["FrameImageBox"] as ImageBox).Image = img;

                            //*********************
                            // Contours
                            //*********************
                            Mat hierarchy = new Mat();

                            VectorOfVectorOfPoint  contours            = new VectorOfVectorOfPoint();
                            VectorOfVectorOfPointF significantContours = new VectorOfVectorOfPointF();
                            CvInvoke.FindContours(mFrame, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxNone);

                            Image <Gray, Byte> contourImage = new Image <Gray, Byte>(mFrame.Size);

                            for (int i = 0; i < contours.Size; i++)
                            {
                                if (CvInvoke.ContourArea(contours[i]) > 500.0)
                                {
                                    VectorOfPointF          bigContour = new VectorOfPointF();
                                    System.Drawing.PointF[] points     = new System.Drawing.PointF[contours[i].Size];
                                    Point[] intPoints = contours[i].ToArray();

                                    for (int j = 0; j < intPoints.Length; j++)
                                    {
                                        points[j] = intPoints[j];
                                    }

                                    bigContour.Push(points);
                                    significantContours.Push(bigContour);
                                }
                            }

                            //if (contours.Size > 0)
                            //{
                            //    CvInvoke.DrawContours(contourImage, significantContours, -1, new MCvScalar(255, 0, 0));
                            //}

                            //(Controls["FrameImageBox"] as ImageBox).Image = contourImage;

                            //*********************
                            // Convex Hulls
                            //*********************
                            for (int i = 0; i < significantContours.Size; i++)
                            {
                                System.Drawing.PointF[] hullPoints;
                                VectorOfPoint           contourPoints = new VectorOfPoint(Array.ConvertAll(significantContours[i].ToArray(), Point.Round));
                                VectorOfInt             convexHull    = new VectorOfInt();

                                hullPoints = CvInvoke.ConvexHull(significantContours[i].ToArray());
                                CvInvoke.ConvexHull(contourPoints, convexHull);

                                CvInvoke.Polylines(mFrame, Array.ConvertAll(hullPoints, Point.Round), true, new MCvScalar(255, 255, 255));

                                // How many defects tho?
                                //VectorOfVectorOfInt defects = new VectorOfVectorOfInt();
                                Mat defects = new Mat();
                                CvInvoke.ConvexityDefects(contourPoints /*significantContours[i]*/,
                                                          convexHull /*new VectorOfPointF(hullPoints)*/,
                                                          defects);

                                if (!defects.IsEmpty)
                                {
                                    Matrix <int> m = new Matrix <int>(defects.Rows, defects.Cols, defects.NumberOfChannels);
                                    defects.CopyTo(m);

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

                                    // Draw tha defacts
                                    for (int d = 0; d < m.Rows; d++)
                                    {
                                        int startIndex    = m.Data[d, 0];
                                        int endIndex      = m.Data[d, 1];
                                        int farthestIndex = m.Data[d, 2];

                                        Point farthestPoint = contourPoints[farthestIndex];
                                        Point startPoint    = contourPoints[startIndex];

                                        if (IsDefectUnique(startPoint, validPoints) &&
                                            IsDefectOutsideHandRadius(startPoint))
                                        {
                                            validPoints.Add(startPoint);
                                        }

                                        //if (true/*endIndex - startIndex > 10*/)
                                        //{
                                        //    CvInvoke.Circle(mFrame, startPoint, 3, new MCvScalar(255, 0, 0), 2);
                                        //}
                                    }

                                    // Draw valid indices
                                    foreach (Point p in validPoints)
                                    {
                                        CvInvoke.Circle(mFrame, p, 3, new MCvScalar(255, 0, 0), 2);
                                    }
                                }
                            }

                            (Controls["FrameImageBox"] as ImageBox).Image = mFrame;
                        }
                    }
                }
            }
        }
예제 #18
0
        public VectorOfPoint FindLargestContour(IInputOutputArray cannyEdges, IInputOutputArray result, out int num)
        {
            int           largest_contour_index = 0;
            double        largest_area          = 0;
            int           handnum = 0;
            VectorOfPoint largestContour;
            int           defectcount = 0;

            num         = 0;
            defectcount = 0;
            using (Mat hierachy = new Mat())
                using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
                {
                    IOutputArray hirarchy;

                    CvInvoke.FindContours(cannyEdges, contours, hierachy, RetrType.List, ChainApproxMethod.ChainApproxSimple);

                    for (int i = 0; i < contours.Size; i++)
                    {
                        MCvScalar color = new MCvScalar(0, 0, 255);

                        double a = CvInvoke.ContourArea(contours[i], false); //  Find the area of contour

                        if (a > largest_area)
                        {
                            largest_area = a;



                            largest_contour_index = i;            //Store the index of largest contour
                        }


                        CvInvoke.DrawContours(result, contours, largest_contour_index, new MCvScalar(255, 0, 0));
                    }

                    if (largest_area == 0)
                    {
                        largestContour = new VectorOfPoint();
                        goto goto3;
                    }
                    int num4 = 0;
                    int num1 = 0;
                    int num2 = 0;
                    CvInvoke.DrawContours(result, contours, largest_contour_index, new MCvScalar(0, 0, 255), 3, LineType.EightConnected, hierachy);



                    //   RotatedRect contour_center= CvInvoke.MinAreaRect(hull[0]);
                    //       Point armcenter = new Point();
                    //     armcenter.X = (int)contour_center.Center.X;
                    //   armcenter.Y = (int)contour_center.Center.Y;
                    // CvInvoke.Circle(result, armcenter, 10, new MCvScalar(255, 255, 255));



                    try
                    {
                        // CascadeClassifier haar = new CascadeClassifier("C:\\Users\\ykk\\Downloads\\Opencv-master\\aarcascade\\closed_frontal_palm.xml");

                        using (VectorOfPoint contour = contours[largest_contour_index])
                            using (Mat defects = new Mat())
                                using (VectorOfPoint approxContour = new VectorOfPoint())
                                    using (VectorOfPoint hull = new VectorOfPoint())
                                        using (VectorOfInt Hull = new VectorOfInt())
                                        {
                                            CvInvoke.ApproxPolyDP(contour, approxContour, 50, true);
                                            //  CvInvoke.DrawContours(result, approxContour, 0, new MCvScalar(255, 0, 0));
                                            CvInvoke.ConvexHull(contour, hull, false);
                                            CvInvoke.ConvexHull(contour, Hull, false, false);
                                            CvInvoke.Polylines(result, hull, true, new MCvScalar(0, 255, 0), 1, LineType.AntiAlias);

                                            CvInvoke.ConvexityDefects(contour, Hull, defects);

                                            RotatedRect box  = CvInvoke.MinAreaRect(contour);
                                            Rectangle   rect = CvInvoke.BoundingRectangle(hull);
                                            CvInvoke.Rectangle(result, rect, new MCvScalar(255, 100, 0));
                                            Point CENTER = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
                                            if (defects.Cols == 1 && defects.Rows > 0)
                                            {
                                                Matrix <int> m = new Matrix <int>(defects.Rows, defects.Cols, defects.NumberOfChannels); // copy Mat to a matrix...
                                                defects.CopyTo(m);
                                                Matrix <int>[] channels = m.Split();
                                                float          max      = 0;
                                                float          distance = 0;
                                                //List<PointF> palm = new List<PointF>();
                                                int[]         Distance    = new int[defects.Rows];
                                                VectorOfPoint palm_points = new VectorOfPoint();
                                                for (int i = 0; i < defects.Rows; i++)
                                                {
                                                    Distance[i] = channels[3][i, 0];
                                                    //Distance[i]= (int)Math.Sqrt(Math.Pow(contour[channels[2][i,0]].X - contour[channels[2][i,0]].X, 2) + Math.Pow(contour[channels[2][i, 0]].Y- contour[channels[2][i, 0]].Y, 2));
                                                    max = (int)Math.Max(max, Distance[i]);
                                                }
                                                List <PointF> importantdepthpoint = new List <PointF>();
                                                for (int i = 0; i < defects.Rows; i++)
                                                {
                                                    if (Distance[i] > 0.15 * max)
                                                    {
                                                        importantdepthpoint.Add(new Point(contour[channels[2][i, 0]].X, contour[channels[2][i, 0]].Y));
                                                    }
                                                }
                                                PointF[] depth = importantdepthpoint.ToArray();
                                                CircleF  palm  = CvInvoke.MinEnclosingCircle(depth);

                                                //palm = new CircleF(palm.Center,(float))
                                                CvInvoke.Circle(result, new Point((int)palm.Center.X, (int)palm.Center.Y), (int)palm.Radius, new MCvScalar(255, 100, 255), 3);
                                                for (int i = 0; i < defects.Rows; i++)
                                                {
                                                    int startIdx = channels[0][i, 0];
                                                    int endIdx   = channels[1][i, 0];

                                                    int hhh = channels[2][i, 0];


                                                    Point         p1             = contour[startIdx];
                                                    Point         p2             = contour[endIdx];
                                                    Point         p3             = contour[hhh];
                                                    LineSegment2D startdepthline = new LineSegment2D(p1, p3);
                                                    LineSegment2D depthendline   = new LineSegment2D(p3, p2);
                                                    CircleF       startcircle    = new CircleF(p1, (float)5);
                                                    CircleF       depthcircle    = new CircleF(p3, 5f);
                                                    CircleF       endcircle      = new CircleF(p2, 5f);
                                                    distance = (float)(channels[3][i, 0] / 256);
                                                    //   CvInvoke.Circle(result, p1, 8, new MCvScalar(255, 100, 0));
                                                    //  CvInvoke.Circle(result, p2, 20, new MCvScalar(100, 255, 255));
                                                    //CvInvoke.Circle(result, p3, 20, new MCvScalar(0, 255, 100));
                                                    if (distance > 25 && distance < 110)
                                                    {
                                                        double angle   = Math.Atan2(CENTER.Y - p1.Y, CENTER.X - p1.X) * 180 / Math.PI;
                                                        float  inangle = innerAngle((float)p1.X, (float)p1.Y, (float)p2.X, (float)p2.Y, (float)p3.X, (float)p3.Y);
                                                        double length  = Math.Sqrt(Math.Pow(p1.X - p3.X, 2) + Math.Pow(p1.Y - p3.Y, 2));
                                                        float  Angle   = getAngle(p1, p3, p2);
                                                        // CvInvoke.PointPolygonTest(palm, p1,false);
                                                        if (!(p2.X < palm.Center.X + palm.Radius + 15 && p2.X > palm.Center.X - palm.Radius - 15 && p2.Y > palm.Center.Y - palm.Radius - 15 && p2.Y < palm.Center.Y + palm.Radius + 15))
                                                        // if (!(p1.X < palm.Center.X && p1.X < palm.Center.X + palm.Radius + 15 && p1.X > palm.Center.X - palm.Radius - 15 && p1.Y < palm.Center.Y && p1.Y < palm.Center.Y + palm.Radius + 15 && p1.Y > palm.Center.Y - palm.Radius - 15))
                                                        {
                                                            //if (Math.Abs(inangle) > 20 && Math.Abs(inangle) < 200 && angle > -180 && angle < 270)
                                                            if (Angle > 20 && Angle < 100 && length < 120 && length > 40)
                                                            {
                                                                if ((startcircle.Center.Y < box.Center.Y || depthcircle.Center.Y < box.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)) > box.Size.Height / 7))
                                                                {
                                                                    //hand = true;
                                                                    defectcount++;
                                                                    handnum = defectcount + 1;
                                                                    CvInvoke.Line(result, p1, p3, new MCvScalar(255, 255, 0), 5);
                                                                    CvInvoke.Line(result, p2, p3, new MCvScalar(255, 255, 0), 5);
                                                                    CvInvoke.PutText(result, (int)length + " " + (int)Angle, p1, FontFace.HersheyPlain, 1, new MCvScalar(255, 255, 0));

                                                                    //    currentFrame.Draw(startDepthLine, new Bgr(Color.Green), 2);
                                                                }
                                                            }
                                                            else if (defectcount == 0)
                                                            {
                                                                CvInvoke.Line(result, p1, p3, new MCvScalar(25, 200, 0), 5);
                                                                CvInvoke.Line(result, p2, p3, new MCvScalar(25, 200, 0), 5);
                                                                CvInvoke.PutText(result, (int)distance + " " + Angle.ToString(), p1, FontFace.HersheyPlain, 1, new MCvScalar(255, 255, 0));

                                                                handnum = 1;
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        CvInvoke.Circle(result, contour[channels[0][i, 0]], 4, new MCvScalar(255, 255, 255), 5);
                                                        CvInvoke.PutText(result, (int)distance + " ", p1, FontFace.HersheyPlain, 1, new MCvScalar(255, 255, 0), 2);
                                                        //CvInvoke.Circle(result, contour[channels[1][i, 0]], 4, new MCvScalar(255, 255, 0),5);
                                                    }


                                                    distance = channels[3][i, 0];

                                                    if (distance <= 10000)
                                                    {
                                                        continue;
                                                    }
                                                    //defectcount++;



                                                    /*  if (distance <= 20000) { continue; }
                                                     *
                                                     *
                                                     * CvInvoke.Circle(result, p1, 8, new MCvScalar(255, 255, 0));
                                                     * CvInvoke.Circle(result, p2, 7, new MCvScalar(255, 255, 255));
                                                     * CvInvoke.Circle(result, p3, 10, new MCvScalar(0, 255, 255));
                                                     * defectcount++;
                                                     *
                                                     */
                                                }

                                                // RotatedRect con = CvInvoke.MinAreaRect(contour);

                                                //CircleF palmcircle = CvInvoke.MinEnclosingCircle(palm.ToArray());
                                                //int radiu = (int)(1.1 * (con.Center.Y - palmcircle.Center.Y));
                                                //if (radiu < 0) radiu = -radiu;
                                                // CvInvoke.Circle(result,new Point((int)palmcircle.Center.X,(int)palmcircle.Center.Y),radiu,new MCvScalar(255,0,255));
                                            }

                                            num = handnum;


                                            // CvInvoke.ConvexityDefects(contour, hull, defects);



                                            /*  Mat defects = new Mat();
                                             * largestContour = new VectorOfPoint(contours[largest_contour_index].ToArray());
                                             * VectorOfVectorOfPoint La = new VectorOfVectorOfPoint(contours[largest_contour_index]);
                                             * if (largestContour != null)
                                             * {
                                             *
                                             *     for (int i = 0; i < La.Size; i++)
                                             *
                                             *     {
                                             *
                                             *         VectorOfPoint contour;
                                             *         Mat hierarchy = new Mat();
                                             *         VectorOfInt hull = new VectorOfInt();
                                             *         contour = La[i];
                                             *         CvInvoke.ConvexHull(contour, hull, false, false);
                                             *         //CvInvoke.DrawContours(result,hull,1,new MCvScalar(255,255,0));
                                             *       // CvInvoke.Polylines(result, hull, true, new MCvScalar(0, 255, 0), 1, LineType.AntiAlias);
                                             *         CvInvoke.ConvexityDefects(contour, hull, defects);
                                             *         Matrix<int> m = new Matrix<int>(defects.Rows, defects.Cols, defects.NumberOfChannels); // copy Mat to a matrix...
                                             *         defects.CopyTo(m);
                                             *         Matrix<int>[] channels = m.Split();
                                             *         for (i = 0; i < defects.Rows; i++)
                                             *         {
                                             *             Point p1 = contour[channels[0][i, 0]];
                                             *             Point p2 = contour[channels[1][i, 0]];
                                             *             Point p3 = contour[channels[2][i, 0]];
                                             *             float distance = channels[3][i, 0];
                                             *             if (distance > 10000) { continue; }
                                             *             CvInvoke.Circle(result, p1, 3, new MCvScalar(255, 255, 0));
                                             *             CvInvoke.Circle(result, p2, 8, new MCvScalar(0, 255, 0));
                                             *             CvInvoke.Circle(result, p3, 3, new MCvScalar(0, 255, 255));
                                             *             defectcount++;
                                             *
                                             *         }
                                             *
                                             *
                                             *
                                             */
                                            //  }

                                            /*  using (VectorOfPoint contour = La[i])
                                             * using ( defects = new Mat())
                                             * using (VectorOfPoint approxContour = new VectorOfPoint())
                                             * using (VectorOfInt hull = new VectorOfInt())
                                             * {
                                             *    CvInvoke.ApproxPolyDP(contour, approxContour, 50, true);
                                             *    CvInvoke.ConvexHull(approxContour, hull, false);
                                             *  // CvInvoke.DrawContours(result,contours,i,new MCvScalar(0,255,0));
                                             *  CvInvoke.Polylines(result, hull, true, new MCvScalar(0, 255, 0), 1, LineType.AntiAlias);
                                             *    CvInvoke.ConvexityDefects(contour, hull, defects);
                                             *
                                             *    if (!defects.IsEmpty)
                                             *    {
                                             *        int nomdef = defects.Total.ToInt32();
                                             *
                                             *
                                             *    }
                                             *
                                             */



                                            /*
                                             * for (int u = 0; u < defects.; u++)
                                             * {
                                             *
                                             *    Point p1 = contour[defects[u][0]];
                                             *    Point p2 = contour[defects[u][1]];
                                             *    Point p3 = contour[defects[u][2]];
                                             *    float dist = defects[u][3];
                                             *    if (dist <= 1000) { continue; }
                                             *    CvInvoke.Circle(result, p1, 3, new MCvScalar(255, 255, 0));
                                             *    CvInvoke.Circle(result, p2, 8, new MCvScalar(0, 255, 0));
                                             *    CvInvoke.Circle(result, p3, 3, new MCvScalar(0, 255, 255));
                                             *    defectcount++;
                                             *    num = p1.X;
                                             * }
                                             */

                                            //2个扩


                                            largestContour = new VectorOfPoint();

                                            //CvInvokde.DrawContours(, contours, largest_contour_index, new MCvScalar(0, 0, 255), 1, LineType.EightConnected)
                                            //}
                                        }
                    }



                    catch (Exception e)
                    {
                        MessageBox.Show(e.ToString());
                        int value  = num1;
                        int value2 = num2;
                        int vaalu  = num4;
                        largestContour = new VectorOfPoint();
                        num            = 0;
                    }
                }


goto3:


            return(largestContour);
        }