由于对环境的鲁棒性能并不够优异所以在每次移动到新的环境中需要对肤色进行重新采样。虽然这样的做法相对来说比较繁复,但对于不同肤色的人来说或是对于不同的环境(包括环境色的干扰、光照的强弱、光源的位置等等)来说,至少能够保证我们的程序使能够良好运行的。
在我们完成键盘的配置、手势的识别后,需要实现把手的位置投影到场景中来。
demo画面先大致这样,
Point center; Point temp; Moments moment = Imgproc.moments(contour1, false); center = new Point(moment.m10 / moment.m00, moment.m01 / moment.m00); //质心点 Imgproc.circle(rgbaMat, center, 6, new Scalar(0, 0, 255, 255), -1); MatOfPoint conPointMat = contours[boundPos1]; List<Point> conPoint = conPointMat.toList(); List<Point> fingerTips = new List<Point>(); double max = 0; int count = 0; int notice = 0; for (int i = 0; i < conPoint.Count; i++) { temp = conPoint [i]; double dist = (temp.x - center.x) * (temp.x - center.x) + (temp.y - center.y) * (temp.y - center.y); if (dist > max) { max = dist; notice = i; } if (dist != max) { count++; if (count > 40) { count = 0; max = 0; bool flag = false; if (center.y < conPoint [notice].y) continue; for (int j = 0; j < fingerTips.Count; j++) { if (Mathf.Abs ((float)conPoint [notice].x - (float)fingerTips [j].x) < 20) { flag = true; break; } } if (flag) continue; fingerTips.Add (conPoint [notice]); Imgproc.circle (rgbaMat, conPoint [notice], 6, new Scalar (0, 0, 255, 255), -1); Imgproc.line (rgbaMat, center, conPoint [notice], new Scalar (0, 0, 255, 255), 2); } } }
这样检测出手指的位置是用conPoint这个list来存储。center是手的质心。我们把comPoint的位置用白色的小圆来代替。
在前面的图上以正中心的小圆为instance。然后乘上系数,对应到键盘的canvas上。
void Update () { //Imgproc.circle(my_thumb) if (hand.listPoDefect1.Count > key) { my_thumb = hand.listPoDefect1 [key]; //Debug.Log (hand.listPoDefect [key].y + ""); //this.gameObject.SetActive (true); this.GetComponent<Image>().enabled=true; } else { //this.gameObject.SetActive (false); this.GetComponent<Image>().enabled=false; } Vector3 pos=this.gameObject.transform.position; //Debug.Log ("" + my_thumb.x); pos.x = (float)my_thumb.x; pos.y =450f -(float)my_thumb.y; this.gameObject.transform.position = WorldToUI(Camera.main,pos); //this.gameObject.transform.position=WorldToUI(Camera.main,Vector3.Lerp(this.gameObject.transform.position,pos,0.5f)); } public Vector3 WorldToUI(Camera camera,Vector3 pos){ CanvasScaler scaler = GameObject.Find("Canvas").GetComponent<CanvasScaler>(); float resolutionX = scaler.referenceResolution.x; float resolutionY = scaler.referenceResolution.y; Vector3 viewportPos = camera.WorldToViewportPoint(pos); Vector3 uiPos = new Vector3(viewportPos.x * resolutionX - resolutionX * 0.5f, viewportPos.y * resolutionY - resolutionY * 0.5f,0); return uiPos; }
然后调整一下在场景中的位置就行