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); }
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); }
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); } } } }
/// <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); }
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; }
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; }
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); } }
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); } }
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);*/ } } } }
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); } }
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))); }
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; } } } } }
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); }