public void IdentifyContours(Bitmap colorImage, int minPerimeter, int maxPerimeter, out List <RecognitionType> detectedObj) { detectedObj = new List <RecognitionType>(); #region Conversion To grayscale colorImage.RotateFlip(RotateFlipType.RotateNoneFlipX); Image <Gray, byte> grayImage = new Image <Gray, byte>(colorImage); Image <Bgr, byte> color = new Image <Bgr, byte>(colorImage); IColorSkinDetector skinDetection; Ycc YCrCb_min = new Ycc(0, 131, 80); Ycc YCrCb_max = new Ycc(255, 185, 135); #endregion skinDetection = new YCrCbSkinDetector(); Image <Gray, byte> skin = skinDetection.DetectSkin(color, YCrCb_min, YCrCb_max); using (MemStorage storage = new MemStorage()) { for (Contour <Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, storage); contours != null; contours = contours.HNext) { Contour <Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.015, storage); if (currentContour.BoundingRectangle.Width > 20) { if (contours.Perimeter > minPerimeter && contours.Perimeter < maxPerimeter) { CvInvoke.cvDrawContours(skin, contours, new MCvScalar(255), new MCvScalar(255), -1, 2, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0)); color.Draw(currentContour.BoundingRectangle, new Bgr(0, 255, 0), 1); detectedObj.Add(new RecognitionType() { GesturePosition = currentContour.BoundingRectangle, GestureImage = skin.ToBitmap().Clone(currentContour.BoundingRectangle, skin.ToBitmap().PixelFormat) }); } } } } }
private Mat DetectHandSkin() { if (capture == null) { return(null); } Mat m = new Mat(); Mat n = new Mat(); Mat o = new Mat(); Mat binaryDiffFrame = new Mat(); Mat denoisedDiffFrame = new Mat(); Mat finalFrame = new Mat(); capture.Read(m); Image <Bgr, byte> mr = m.ToImage <Bgr, byte>(); mr = mr.Rotate(180, new Bgr(255, 255, 255), false); m = mr.Mat; if (!m.IsEmpty) { Image <Bgr, byte> ret = m.ToImage <Bgr, byte>(); skinDetector = new YCrCbSkinDetector(); Image <Gray, Byte> skin = skinDetector.DetectSkin(ret, YCrCb_min, YCrCb_max); m.CopyTo(finalFrame); //DetectObject(skin.Mat, finalFrame); //return DetectObject(denoisedDiffFrame, finalFrame); return(DetectObject(skin.Mat, finalFrame)); } else { // break; } return(null); }
public void IdentifyContours(Bitmap colorImage, int thresholdValue, bool invert, int minPerimeter, int maxPerimeter, int Y_h, int Cr_h, int Cb_h, int Y_l, int Cr_l, int Cb_l, out Bitmap processedGray, out Bitmap processedColor, out List <RecognitionType> detectedObj) { detectedObj = new List <RecognitionType>(); Rectangle gestureRectangle = new Rectangle(0, 0, 1, 1); #region Conversion To grayscale colorImage.RotateFlip(RotateFlipType.RotateNoneFlipX); Image <Gray, byte> grayImage = new Image <Gray, byte>(colorImage); Image <Bgr, byte> color = new Image <Bgr, byte>(colorImage); IColorSkinDetector skinDetection; #endregion #region Extracting the Contours skinDetection = new YCrCbSkinDetector(); Image <Gray, byte> skin = skinDetection.DetectSkin(color, new Ycc(Y_l, Cr_l, Cb_l), new Ycc(Y_h, Cr_h, Cb_h)); if (invert) { skin._Not(); } using (MemStorage storage = new MemStorage()) { for (Contour <Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, storage); contours != null; contours = contours.HNext) { Contour <Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.015, storage); if (currentContour.BoundingRectangle.Width > 20) { if (contours.Perimeter > minPerimeter && contours.Perimeter < maxPerimeter) { CvInvoke.cvDrawContours(skin, contours, new MCvScalar(255), new MCvScalar(255), -1, 2, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0)); color.Draw(currentContour.BoundingRectangle, new Bgr(0, 255, 0), 1); detectedObj.Add(new RecognitionType() { GesturePosition = currentContour.BoundingRectangle, GestureImage = skin.ToBitmap().Clone(currentContour.BoundingRectangle, skin.ToBitmap().PixelFormat) }); } } } } #endregion #region Asigning output processedColor = color.ToBitmap(); processedGray = skin.ToBitmap(); #endregion }
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(); }