Ex) Face, Background image of environment Simple solutions are.. method 1) Define the area for hand detection. method 2) Detect and exclude face area.
depth threshold, we can remove background image. Surly you can do the same thing by applying depth filtering to raw depth data from Kinect SDK. maxDepth=8 maxDepth=4 maxDepth=2
color into white and others int black. 【Problem】 Thresholding for RGB color is difficult 【Solution】 Using HSV color space H(Hue) is described as 0~360° ※0~180 for OpenCV S(Saturation) is 0~100% ※0~255 for OpenCV V(Value) is 0~100% This means brightness of color ※0~255 for OpenCV RGB HSV
minS is changed private void minS_Scroll(object sender, EventArgs e) { //lower value of S-threshold is changed lower.Val1 = minS.Value; } //Called when value of trackbar maxS is changed private void maxS_Scroll(object sender, EventArgs e) { //upper value of S-threshold is changed upper.Val1 = maxS.Value; }
minV is changed private void minV_Scroll(object sender, EventArgs e) { //lower value of V-threshold is changed lower.Val2 = minV.Value; } //Called when value of trackbar maxV is changed private void maxV_Scroll(object sender, EventArgs e) { //upper value of V-threshold is changed upper.Val2 = maxV.Value; }
bgr to gray depthMat = depthMat.CvtColor(ColorConversionCodes.BGR2GRAY); //Binarization with threshold=20 depthMat = depthMat.Threshold(20, 255, ThresholdTypes.Binary); //Conversion bgr to hsv Mat hsv = bgrMat.CvtColor(ColorConversionCodes.BGR2HSV); //Binarization of HSV with lower/upper threshold binMat = hsv.InRange(lower, upper); //Visualization of the result pictureBox3.Image = binMat.ToBitmap(); //Extract common white area between binMat & depthMat Cv2.BitwiseAnd(binMat, depthMat, binMat); //Visualization of the result pictureBox4.Image = binMat.ToBitmap(); hsv.Release(); }
HierarchyIndex[] h; //Find contours from binMat binMat.FindContours(out lines, out h, RetrievalModes.External, ContourApproximationModes.ApproxSimple); double maxArea = -1; for (int i = 0; i < lines.Length; i++) { double area = Cv2.ContourArea(lines[i]); //Contour of maximum area is treated as hand if (area > maxArea) { maxArea = area; contour = lines[i]; } } return contour;
{ int[] hullIdx = Cv2.ConvexHullIndices(contour); Point[] hullPt = Cv2.ConvexHull(contour); for(int i=0;i<hullIdx.Length;i++) { int index = hullIdx[i]; bgrMat.Circle(contour[index], 10, Scalar.Red, 2); } DrawPolyLine(bgr, hullPt, Scalar.Blue); return hullIdx; } Many points are exists at the tip of finger They should integrated into the one point.
Point[] hullPt = Cv2.ConvexHull(contour); //Terating label numbers of each vertices of hull int[] labels; //clustering based on the role written in Predicate Cv2.Partition(hullPt, out labels, Predicate); for (int i = 0; i < hullIdx.Length; i++) { int index = hullIdx[i]; bgrMat.Circle(contour[index], 10, Scalar.Red, 2); //Visualization of label number bgrMat.PutText(labels[i].ToString(), contour[index], HersheyFonts.HersheyDuplex, 1, Scalar.White); } DrawPolyLine(hullPt, Scalar.Blue); return hullIdx; }
labels, Predicate); /*****omitted below*****/ } private bool Predicate(Point t1, Point t2) { //2 points are treated as the same point if //distance is less than 20pixels if (t1.DistanceTo(t2) < 20) { return true; } else { return false; } }
{ int num = 0; //Calculation of defect points Vec4i[] defects = Cv2.ConvexityDefects(contour, hull); //Visualization of defect points. foreach (Vec4i v in defects) { bgrMat.Circle(contour[v.Item2], 5, Scalar.White, 2); } return num; } 【Info.】 ConvexityDefets calculates degree of lack versus convex hull Detail of return value is below. Item0: Index of start point Item1: Index of end point Item2: Index of defect point Item3: Distance to defect point Item0 Item2 Item1
{ Vec4i[] defects = Cv2.ConvexityDefects(contour, hull); foreach (Vec4i v in defects) { bgr.Circle(contour[v.Item2], 5, Scalar.White, 2); } //Judge each point is finger tip or not. for (int i = 0; i < defects.Length; i++) { Vec4i d1 = defects[i]; Vec4i d2 = defects[(i + 1) % defects.Length]; //Defect points and tip. Point p1 = contour[d1.Item2]; Point p2 = contour[d2.Item2]; Point tip = contour[d1.Item1]; //calculate vector p1 = p1 - tip; p2 = p2 - tip; } } p1 tip p2