void Update() { // parsing json for foot keypoints VideoPlayer vp = this.transform.GetComponent <VideoPlayer>(); currentJsonFrame = (int)vp.frame % maxJsonFrameCount; currentJsonString = System.IO.File.ReadAllText(openPoseJsonPath + "/v1_" + currentJsonFrame.ToString("000000000000") + "_keypoints.json"); //Debug.Log(currentJsonString); currentOpenPoseJson = JsonUtility.FromJson <OpenPoseJson>(currentJsonString); // parsing body part link json string bodyPartLinkJsonString = System.IO.File.ReadAllText(bodyPartLinkJsonFile); bodyPartLinks = JsonUtility.FromJson <BodyPartLinks>(bodyPartLinkJsonString); // loop people in json for (int i = 0; i < currentOpenPoseJson.people.Count; i++) { float xLeftFoot = currentOpenPoseJson.people[i].pose_keypoints[3 * jointIDLeftFoot + xx]; float yLeftFoot = currentOpenPoseJson.people[i].pose_keypoints[3 * jointIDLeftFoot + yy]; float confLeftFoot = currentOpenPoseJson.people[i].pose_keypoints[3 * jointIDLeftFoot + conf]; float xRightFoot = currentOpenPoseJson.people[i].pose_keypoints[3 * jointIDRightFoot + xx]; float yRightFoot = currentOpenPoseJson.people[i].pose_keypoints[3 * jointIDRightFoot + yy]; float confRightFoot = currentOpenPoseJson.people[i].pose_keypoints[3 * jointIDRightFoot + conf]; Color currentPersonColor = helperMaterials[i % 3].color; Material currentPersonMaterial = helperMaterials[i % 3]; Color colorTmp = currentPersonMaterial.color; currentPersonMaterial.color = new Color(colorTmp.r, colorTmp.g, colorTmp.b, colorAlpha); // only viz if left and right feet are both present confidently if ((xLeftFoot > 0.0f && yLeftFoot > 0.0f && confLeftFoot >= confidentThreshold) && (xRightFoot > 0.0f && yRightFoot > 0.0f && confRightFoot >= confidentThreshold)) { Vector3 pxlLeftFoot = new Vector3(xLeftFoot, videoPixelHeight - yLeftFoot, 0.0f); //Debug.Log("pxlLeftFoot: " + pxlLeftFoot.ToString()); Vector3 pxlRightFoot = new Vector3(xRightFoot, videoPixelHeight - yRightFoot, 0.0f); //Debug.Log("pxlRightFoot: " + pxlRightFoot.ToString()); Vector3 pxlCenterBottom = new Vector3((xLeftFoot + xRightFoot) / 2f, videoPixelHeight - (yLeftFoot + yRightFoot) / 2f, 0f); // screen to world for foot keypoints // shoot ray from camera to ground srf and get intersections as world positions of persons RaycastHit hit; Ray ray = cam.ScreenPointToRay(pxlCenterBottom); Debug.DrawRay(ray.origin, ray.direction * 100, currentPersonColor, Time.deltaTime * 1f); // visualize body key points and links if (Physics.Raycast(ray, out hit, (float)100f)) { // intersection plane // creat a quad plane for intersection GameObject plane = GameObject.CreatePrimitive(PrimitiveType.Cube); //cleanups.Add(plane); Destroy(plane, Time.deltaTime * lifeSpan); plane.transform.localScale = new Vector3(10f, 10f, 0.001f); // move to viz location plane.transform.position = hit.point; // rotate face to cam plane.transform.LookAt(new Vector3(cam.transform.position.x, plane.transform.position.y, cam.transform.position.z)); plane.transform.Rotate(new Vector3(0f, 180f, 0f)); // viz person ID in space float x2 = currentOpenPoseJson.people[i].pose_keypoints[1 * 3 + xx]; float y2 = currentOpenPoseJson.people[i].pose_keypoints[1 * 3 + yy]; Vector3 posJoint1 = new Vector3(x2, videoPixelHeight - y2, 0f); RaycastHit hit3; Ray ray3 = cam.ScreenPointToRay(posJoint1); if (Physics.Raycast(ray3, out hit3, 100)) { Vector3 posJoint1Projected = hit3.point + new Vector3(0f, 0.4f, 0f); GameObject idText = DrawText(i.ToString(), posJoint1Projected, 0.1f, new Color(1f, 1f, 1f, colorAlpha), TextAlignment.Center, TextAnchor.MiddleCenter); tmpVizGOs.Add(idText); Destroy(idText, Time.deltaTime * lifeSpan); // rotate face to cam idText.transform.LookAt(new Vector3(cam.transform.position.x, idText.transform.position.y, cam.transform.position.z)); idText.transform.Rotate(new Vector3(0f, 180f, 0f)); } // loop each key point List <Vector3> keyPtProjPoss = new List <Vector3>(); for (int j = 0; j < currentOpenPoseJson.people[i].pose_keypoints.Length / 3; j++) { float x = currentOpenPoseJson.people[i].pose_keypoints[j * 3 + xx]; float y = currentOpenPoseJson.people[i].pose_keypoints[j * 3 + yy]; float c = currentOpenPoseJson.people[i].pose_keypoints[j * 3 + conf]; Vector3 keyPoint = new Vector3(x, videoPixelHeight - y, 0f); /* * // screen * // add sphere and remove its collider * GameObject sphere2 = GameObject.CreatePrimitive(PrimitiveType.Sphere); * Destroy(sphere2.GetComponent<Collider>()); * sphere2.transform.localScale = new Vector3(sphereSizeScreen, sphereSizeScreen, sphereSizeScreen); * sphere2.GetComponent<Renderer>().material = helperMaterials[i % 3]; * // move sphere to viz location * sphere2.transform.position = imageVideo.transform.TransformPoint(new Vector3(x / videoPixelWidth * imageVideo.rectTransform.rect.width, -y / videoPixelHeight * imageVideo.rectTransform.rect.height, 0.0f)); */ // world // shoot ray from camera to plane and get intersection RaycastHit hit2; Ray ray2 = cam.ScreenPointToRay(keyPoint); // visualize key point Vector3 keyPtProjPos = Vector3.zero; if (c >= confidentThreshold && Physics.Raycast(ray2, out hit2, 100)) { // key point // add sphere and remove its collider GameObject sphere3 = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere3.name = "myJoint"; tmpVizGOs.Add(sphere3); Destroy(sphere3.GetComponent <Collider>()); Destroy(sphere3, Time.deltaTime * lifeSpan); sphere3.transform.localScale = new Vector3(sphereSizeWorld * c, sphereSizeWorld * c, sphereSizeWorld * c); sphere3.GetComponent <Renderer>().material = currentPersonMaterial; // move sphere to viz location keyPtProjPos = hit2.point; sphere3.transform.position = keyPtProjPos; } keyPtProjPoss.Add(keyPtProjPos); } // loop each link for (int k = 0; k < bodyPartLinks.links.Count; k++) { int startID = bodyPartLinks.links[k].link[0]; int endID = bodyPartLinks.links[k].link[1]; float sc = currentOpenPoseJson.people[i].pose_keypoints[startID * 3 + conf]; float ec = currentOpenPoseJson.people[i].pose_keypoints[endID * 3 + conf]; Vector3 startProjPos = keyPtProjPoss[startID]; Vector3 endProjPos = keyPtProjPoss[endID]; // if both key points of the link are confident enough if (sc >= confidentThreshold && ec >= confidentThreshold) { GameObject link = DrawLine(startProjPos, endProjPos, linkWidth * (sc + ec) / 2, currentPersonMaterial, Time.deltaTime * lifeSpan); tmpVizGOs.Add(link); } } // move plane up before next person to avoid hit test obstacle (destroy doesn't work!) plane.transform.Translate(0f, 9999f, 0f); } } } }
void Update() { // parsing json for foot keypoints VideoPlayer vp = this.transform.GetComponent <VideoPlayer>(); currentJsonFrame = (int)vp.frame % maxJsonFrameCount; currentJsonString = System.IO.File.ReadAllText(openPoseJsonPath + "/v2_" + currentJsonFrame.ToString("000000000000") + "_keypoints.json"); //Debug.Log(currentJsonString); currentOpenPoseJson = JsonUtility.FromJson <OpenPoseJson>(currentJsonString); // parsing body part link json string bodyPartLinkJsonString = System.IO.File.ReadAllText(bodyPartLinkJsonFile); bodyPartLinks = JsonUtility.FromJson <BodyPartLinks>(bodyPartLinkJsonString); // put isOnScreen to false for all the people obj in global list every frame foreach (PeopleObj pplObj in globalPeopleList) { pplObj.isOnScreen = false; } // loop people in json for (int i = 0; i < currentOpenPoseJson.people.Count; i++) { PeopleJsonObj currentPeopleJson = currentOpenPoseJson.people[i]; float xLeftFoot = currentPeopleJson.pose_keypoints[3 * jointIDLeftFoot + xx]; float yLeftFoot = currentPeopleJson.pose_keypoints[3 * jointIDLeftFoot + yy]; float confLeftFoot = currentPeopleJson.pose_keypoints[3 * jointIDLeftFoot + conf]; float xRightFoot = currentPeopleJson.pose_keypoints[3 * jointIDRightFoot + xx]; float yRightFoot = currentPeopleJson.pose_keypoints[3 * jointIDRightFoot + yy]; float confRightFoot = currentPeopleJson.pose_keypoints[3 * jointIDRightFoot + conf]; Color currentPersonColor = helperMaterials[i % 3].color; Material currentPersonMaterial = helperMaterials[i % 3]; Color colorTmp = currentPersonMaterial.color; currentPersonMaterial.color = new Color(colorTmp.r, colorTmp.g, colorTmp.b, colorAlpha); // only viz if left and right feet are both present confidently if (confLeftFoot >= confidentThreshold && confRightFoot >= confidentThreshold) { Vector3 pxlLeftFoot = new Vector3(xLeftFoot, videoPixelHeight - yLeftFoot, 0.0f); //Debug.Log("pxlLeftFoot: " + pxlLeftFoot.ToString()); Vector3 pxlRightFoot = new Vector3(xRightFoot, videoPixelHeight - yRightFoot, 0.0f); //Debug.Log("pxlRightFoot: " + pxlRightFoot.ToString()); Vector3 pxlCenterBottom = new Vector3((xLeftFoot + xRightFoot) / 2f, videoPixelHeight - (yLeftFoot + yRightFoot) / 2f, 0f); // screen to world for foot keypoints // shoot ray from camera to ground srf and get intersections as world positions of persons RaycastHit hit; Ray ray = cam.ScreenPointToRay(pxlCenterBottom); Debug.DrawRay(ray.origin, ray.direction * 100, currentPersonColor, Time.deltaTime * 1f); // visualize body key points and links if (Physics.Raycast(ray, out hit, (float)100f)) { // intersection plane // creat a quad plane for intersection GameObject plane = GameObject.CreatePrimitive(PrimitiveType.Cube); //cleanups.Add(plane); Destroy(plane, Time.deltaTime * lifeSpan); plane.transform.localScale = new Vector3(10f, 10f, 0.001f); // move to viz location plane.transform.position = hit.point; // rotate face to cam plane.transform.LookAt(new Vector3(cam.transform.position.x, plane.transform.position.y, cam.transform.position.z)); plane.transform.Rotate(new Vector3(0f, 180f, 0f)); // viz person ID in space float x2 = currentOpenPoseJson.people[i].pose_keypoints[1 * 3 + xx]; float y2 = currentOpenPoseJson.people[i].pose_keypoints[1 * 3 + yy]; Vector3 posJoint1 = new Vector3(x2, videoPixelHeight - y2, 0f); RaycastHit hit3; Ray ray3 = cam.ScreenPointToRay(posJoint1); if (Physics.Raycast(ray3, out hit3, 100)) { Vector3 posJoint1Projected = hit3.point + new Vector3(0f, 0.4f, 0f); GameObject idText = DrawText(i.ToString(), posJoint1Projected, 0.1f, new Color(1f, 1f, 1f, colorAlpha), TextAlignment.Center, TextAnchor.MiddleCenter); tmpVizGOs.Add(idText); Destroy(idText, Time.deltaTime * lifeSpan); // rotate face to cam idText.transform.LookAt(new Vector3(cam.transform.position.x, idText.transform.position.y, cam.transform.position.z)); idText.transform.Rotate(new Vector3(0f, 180f, 0f)); } // add this valid person to global people list if not found close enough one in the list, otherwise update PeopleObj currentPeopleObj = new PeopleObj(); currentPeopleObj = (PeopleObj)currentPeopleJson; currentPeopleObj.GUID = (int)Random.Range(0f, 999999999f); currentPeopleObj.centerBottomPositionWorld = hit.point; currentPeopleObj.posJoint1Projected = hit3.point; // this will overwite isOnScreen currentPeopleObj.isOnScreen = true; // check exist and update at same time in "IsExist" function if (IsExist(currentPeopleObj) == false) { //Debug.Log("no exist, add to the list"); globalPeopleList.Add(currentPeopleObj); } else { //Debug.Log("exist, update the one in the list"); } // loop each key point List <Vector3> keyPtProjPoss = new List <Vector3>(); for (int j = 0; j < currentOpenPoseJson.people[i].pose_keypoints.Length / 3; j++) { float x = currentOpenPoseJson.people[i].pose_keypoints[j * 3 + xx]; float y = currentOpenPoseJson.people[i].pose_keypoints[j * 3 + yy]; float c = currentOpenPoseJson.people[i].pose_keypoints[j * 3 + conf]; Vector3 keyPoint = new Vector3(x, videoPixelHeight - y, 0f); /* * // screen * // add sphere and remove its collider * GameObject sphere2 = GameObject.CreatePrimitive(PrimitiveType.Sphere); * Destroy(sphere2.GetComponent<Collider>()); * sphere2.transform.localScale = new Vector3(sphereSizeScreen, sphereSizeScreen, sphereSizeScreen); * sphere2.GetComponent<Renderer>().material = helperMaterials[i % 3]; * // move sphere to viz location * sphere2.transform.position = imageVideo.transform.TransformPoint(new Vector3(x / videoPixelWidth * imageVideo.rectTransform.rect.width, -y / videoPixelHeight * imageVideo.rectTransform.rect.height, 0.0f)); */ // world // shoot ray from camera to plane and get intersection RaycastHit hit2; Ray ray2 = cam.ScreenPointToRay(keyPoint); // visualize key point Vector3 keyPtProjPos = Vector3.zero; if (c >= confidentThreshold && Physics.Raycast(ray2, out hit2, 100)) { // key point // add sphere and remove its collider GameObject sphere3 = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere3.name = "myJoint"; tmpVizGOs.Add(sphere3); Destroy(sphere3.GetComponent <Collider>()); Destroy(sphere3, Time.deltaTime * lifeSpan); sphere3.transform.localScale = new Vector3(sphereSizeWorld * c, sphereSizeWorld * c, sphereSizeWorld * c); sphere3.GetComponent <Renderer>().material = currentPersonMaterial; // move sphere to viz location keyPtProjPos = hit2.point; sphere3.transform.position = keyPtProjPos; } keyPtProjPoss.Add(keyPtProjPos); } // loop each link for (int k = 0; k < bodyPartLinks.links.Count; k++) { int startID = bodyPartLinks.links[k].link[0]; int endID = bodyPartLinks.links[k].link[1]; float sc = currentOpenPoseJson.people[i].pose_keypoints[startID * 3 + conf]; float ec = currentOpenPoseJson.people[i].pose_keypoints[endID * 3 + conf]; Vector3 startProjPos = keyPtProjPoss[startID]; Vector3 endProjPos = keyPtProjPoss[endID]; // if both key points of the link are confident enough if (sc >= confidentThreshold && ec >= confidentThreshold) { GameObject link = DrawLine(startProjPos, endProjPos, linkWidth * (sc + ec) / 2, currentPersonMaterial, Time.deltaTime * lifeSpan); tmpVizGOs.Add(link); } } // move plane up before next person to avoid hit test obstacle (destroy doesn't work!) plane.transform.Translate(0f, 9999f, 0f); } } } // viz the current GUID for each person in global people list foreach (PeopleObj pplObj in globalPeopleList) { Color c = new Color(); if (pplObj.isOnScreen) { c = new Color(1f, 1f, 1f, colorAlpha); } else { c = new Color(0f, 0f, 0f, colorAlpha); } GameObject guidText = DrawText(pplObj.GUID.ToString(), pplObj.posJoint1Projected + new Vector3(0f, 0.5f, 0f), 0.075f, c, TextAlignment.Center, TextAnchor.MiddleCenter); tmpVizGOs.Add(guidText); Destroy(guidText, Time.deltaTime * lifeSpan); // rotate face to cam guidText.transform.LookAt(new Vector3(cam.transform.position.x, guidText.transform.position.y, cam.transform.position.z)); guidText.transform.Rotate(new Vector3(0f, 180f, 0f)); } // viz the trajectory for each person in global people list foreach (PeopleObj pplObj in globalPeopleList) { for (int t2 = pplObj.trajectory.Count - 1; t2 > 0; t2--) { GameObject trajectoryLine = DrawLine(pplObj.trajectory[t2], pplObj.trajectory[t2 - 1], trajectoryWidth, helperMaterials[2], Time.deltaTime); tmpVizGOs.Add(trajectoryLine); } } // viz the dummy interaction links between each two onscreen people, the closer the wider if (toggleInteration.isOn) { for (int t3 = 0; t3 < globalPeopleList.Count - 1; t3++) { PeopleObj pplObj1 = globalPeopleList[t3]; for (int t4 = t3 + 1; t4 < globalPeopleList.Count; t4++) { PeopleObj pplObj2 = globalPeopleList[t4]; if (pplObj1.isOnScreen && pplObj2.isOnScreen) { float d = Vector3.Distance(pplObj1.posJoint1Projected, pplObj2.posJoint1Projected); float w = interactionWidth * Mathf.Pow(1.0f / d, 2.0f); GameObject interactionLine = DrawLine(pplObj1.posJoint1Projected, pplObj2.posJoint1Projected, w, helperMaterials[1], Time.deltaTime); tmpVizGOs.Add(interactionLine); } } } } // purge missing object for tmpVizGOs every frame for (int t1 = tmpVizGOs.Count - 1; t1 > -1; t1--) { if (tmpVizGOs[t1] == null) { tmpVizGOs.RemoveAt(t1); } } }