internal static void FaceTexMapper(IFaceImageData imageData, IFaceData faceData, int width = 512, int height = 512) { Vector2 left = TransformUV(faceData.FaceBones[AvatarTools.FaceLeft].position, faceData.FaceMesh.bounds); Vector2 right = TransformUV(faceData.FaceBones[AvatarTools.FaceRight].position, faceData.FaceMesh.bounds); Vector2 nose = TransformUV(faceData.FaceBones[AvatarTools.FaceNose].position, faceData.FaceMesh.bounds); Vector2 chin = TransformUV(faceData.FaceBones[AvatarTools.FaceChin].position, faceData.FaceMesh.bounds); Vector2 center = nose; float x_scale = Vector2.Distance(right, left); float y_scale = Vector2.Distance((right + left) / 2f, chin); Texture2D tex = new Texture2D(width, height); //OutputTex = new Texture2D(base.FaceImageData.FinalImage.width, base.FaceImageData.FinalImage.height); Vector2 _left = imageData.DataImageData[AvatarTools.FaceLeft]; Vector2 _right = imageData.DataImageData[AvatarTools.FaceRight]; x_scale = x_scale / Vector2.Distance(_left, _right); y_scale = y_scale / Vector2.Distance((_left + _right) / 2f, imageData.DataImageData[AvatarTools.FaceChin]); Vector2 _center = imageData.DataImageData[AvatarTools.FaceNose]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Vector2 v = new Vector2((float)x / width, (float)y / height); v -= center; //asix x inverse v = new Vector2(-v.x / x_scale, v.y / y_scale); v += _center; tex.SetPixel(x, y, imageData.DataImage.GetPixelBilinear(v.x, v.y)); } } tex.Apply(); faceData.DataImage = tex; }
private void RaiseFaceReceived(IFaceData data) { var handler = this.FaceReceived; if (handler != null) { handler(this, data); } }
} //시간이 다된경우 호출 public void OnFace(IFaceData face, uint degree) { // Draw marks Vector2[] points = face.Landmark; if (debugFlag == true) { DrawPoint(tex2d, points[104], Color.red); DrawPoint(tex2d, points[105], Color.blue); for (int i = 96; i < 104; i++) { DrawPoint(tex2d, points[i], Color.green); } DrawPoint(tex2d, points[2], new Color(1, 0, 1, 1)); DrawPoint(tex2d, points[30], new Color(1, 0, 1, 1)); DrawPoint(tex2d, points[16], new Color(1, 0, 1, 1)); } //입 좌우상하 float x1 = points[96].x; float y1 = points[96].y; float x2 = points[100].x; float y2 = points[100].y; float x3 = points[98].x; float y3 = points[98].y; float x4 = points[102].x; float y4 = points[102].y; float HorRadius = Mathf.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); float VerRadius = Mathf.Sqrt((x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4)); float centerXInView = (x1 + x2) / 2 - 320; float centerYInView = (y1 + y2) / 2 - 240; float resizeX = centerXInView * (float)24 / 250; float resizeY = centerYInView * (float)15.8 / 150; //-----------------입 그리기-------------- Vector3 pos = new Vector3(-1 * resizeX, resizeY, 20); player.transform.position = pos; player.transform.localScale = new Vector3(HorRadius / 12, VerRadius / 12, 1); Quaternion PlayerAngle = Quaternion.Euler(0, 0, Mathf.Atan2(y2 - y1, x1 - x2) * 180 / Mathf.PI); player.transform.rotation = PlayerAngle; //입 열고닫음 여부 확인 if (VerRadius / HorRadius > 0.4 && startFlag == true) { Player2.instance.mouseOpen = true; } else { Player2.instance.mouseOpen = false; } //----------------눈에 x 그리기-------------- float eyeCenterX = 0; float eyeCenterY = 0; for (int i = 0; i < 2; i++) { float eyeX = (points[104 + i].x - 320) * (float)24 / 250; float eyeY = (points[104 + i].y - 240) * (float)15.8 / 150; Vector3 eyepos = new Vector3(-1 * eyeX, eyeY, 22); if (badFlag == true) { Quaternion angle = Quaternion.Euler(0, 0, 0); bad[i] = (GameObject)Instantiate(badImage, eyepos, angle); } if (bad[i] != null) { bad[i].transform.position = eyepos; bad[i].transform.localScale = new Vector3(HorRadius / 17, HorRadius / 17, 1); } eyeCenterX += eyeX / 2; eyeCenterX += eyeY / 2; } badFlag = false; //-----------------얼굴그리기----------- float x5 = points[2].x; float y5 = points[2].y; float x6 = points[30].x; float y6 = points[30].y; float cenX = (x5 + x6) / 2; float cenY = (y5 + y6) / 2; float FaceHorRadius = Mathf.Sqrt((x5 - x6) * (x5 - x6) + (y5 - y6) * (y5 - y6)) / 2; float FaceVerRadius = Mathf.Sqrt((cenX - points[16].x) * (cenX - points[16].x) + (cenY - points[16].y) * (cenY - points[16].y)); float centerXInFView = cenX - 320; float centerYInFView = cenY - 240; float resizeFX = centerXInFView * 0.12f; float resizeFY = centerYInFView * 0.12f; face1.transform.localPosition = new Vector3(-resizeFX, resizeFY, 30); face1.transform.localScale = new Vector3(FaceHorRadius / 3.8f, FaceVerRadius / 3.8f, 1); Quaternion faceAngle = Quaternion.Euler(0, 0, Mathf.Atan2(y6 - y5, x5 - x6) * 180 / Mathf.PI); face1.transform.rotation = faceAngle; //-----------------디버그 창------------ HorTxt.text = "x좌표 : " + string.Format("{0:F1} {1:F1}", x5, x6); VerTxt.text = "y좌표 : " + string.Format("{0:F1} {1:F1}", y5, y6); TarTxt.text = "x평균 : " + string.Format("{0:F1}", (y5 + y6) / 2); RealTxt.text = "실제비율 : " + string.Format("{0:F2}", FaceVerRadius / FaceHorRadius);; tex2d.Apply(); }
} //시간이 다된경우 호출 public void OnFace(IFaceData face, uint degree) { // Draw marks Vector2[] points = face.Landmark; if (debugFlag == false) { DrawPoint(tex2d, points[104], Color.red); DrawPoint(tex2d, points[105], Color.blue); for (int i = 96; i < 104; i++) { DrawPoint(tex2d, points[i], Color.green); } } float x1 = points[96].x; float y1 = points[96].y; float x2 = points[100].x; float y2 = points[100].y; float x3 = points[98].x; float y3 = points[98].y; float x4 = points[102].x; float y4 = points[102].y; float HorRadius = Mathf.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); float VerRadius = Mathf.Sqrt((x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4)); float centerXInView = (x1 + x2) / 2 - 320; float centerYInView = (y1 + y2) / 2 - 240; float resizeX = centerXInView * (float)24 / 250; float resizeY = centerYInView * (float)15.8 / 150; //충돌검사용 원 생성 Vector3 pos = new Vector3(-1 * resizeX, resizeY, 20); player.transform.position = pos; player.transform.localScale = new Vector3(HorRadius / 12, VerRadius / 12, 1); Quaternion PlayerAngle = Quaternion.Euler(0, 0, Mathf.Atan2(y2 - y1, x1 - x2) * 180 / Mathf.PI); player.transform.rotation = PlayerAngle; //입 열고닫음 여부 확인 if (VerRadius / HorRadius > 0.4 && startFlag == true) { Player1.instance.mouseOpen = true; } else { Player1.instance.mouseOpen = false; } for (int i = 0; i < 2; i++) { float eyeX = (points[104 + i].x - 320) * (float)24 / 250; float eyeY = (points[104 + i].y - 240) * (float)15.8 / 150; Vector3 eyepos = new Vector3(-1 * eyeX, eyeY, 22); if (badFlag == true) { Quaternion angle = Quaternion.Euler(0, 0, 0); bad[i] = (GameObject)Instantiate(badImage, eyepos, angle); } if (bad[i] != null) { bad[i].transform.position = eyepos; bad[i].transform.localScale = new Vector3(HorRadius / 17, HorRadius / 17, 1); } } badFlag = false; HorTxt.text = "입 가로길이 :" + HorRadius; VerTxt.text = "입 세로길이 : " + VerRadius; TarTxt.text = "목표비율: " + 0.4; RealTxt.text = "실제비율 : " + VerRadius / HorRadius; tex2d.Apply(); }