Object Height Using Kinect

For example, I stand in front of my Kinect. Kinect can identify joints and it will reveal them as a data structure. I still understand.

So, can we define the height as the difference between Head joint - ((LeftAnkle + RightAnkle) / 2) ?

I tried trigonometric formulas, but there are two problems that I am facing. One of them is the identification of the person in the view. The second is the exact position of the upper part of the head and lower part of the foot.

I tried a point cloud, but got lost in how to create a human-specific point cloud. I mean without turning on background objects.

Please suggest some ideas on how I can calculate the height of a person using Kinect?

+6
source share
4 answers

You can transform the head joint into a global coordinate system. No need to do math. The y coordinate in the global coordinate will be equal to its height.

All you have to do is check which pixel represents the joint of the head and convert the pixel information + depth into the word coordinate space in mm.

I don’t know which API you are using, but if it is able to segment a person and bring back his joint, perhaps you are using the OpenNI / NITE or Microsoft SDK. Both of them have a function that converts the coordinate of the pixel + depth to x, y, z in mm. I don’t know exactly which functions, but their names will be like: depth_to_mm or disparity_to_mm. You need to check both documentation to find it, or you can do it yourself. This site has information on how to convert depth to mm: http://nicolas.burrus.name/index.php/Research/KinectCalibration

+4
source

I extracted two points: the head and the left leg (or right leg), then I found that the Euclidean distance between these points gave the distance with a 4-inch shift. My test results are satisfactory, so we use this approach as temporary work.

+3
source

Old question, but I found a very nice explanation and example here . This also explains that height is not a function of the heads and ankles, but instead a function of the following line segments:

  • Head - ShoulderCenter
  • Shoulder Center - Spine
  • Spine - HipCenter
  • HipCenter - KneeLeft or KneeRight
  • KneeLeft / KneeRight - AnkleLeft / AnkleRight
  • AnkleLeft / AnkleRight - FootLeft / FootRight
+1
source

Here is the formula for the Kinect SDK 2.0. The full project is available at https://github.com/jhealy/kinect2/tree/master/020-FaceNSkin_HowTallAmI ....

using System; using Microsoft.Kinect; // Skeleton is now Bones public enum BodyHeightMeasurementSystem { Meters = 0, Imperial = 1 } public static class BodyHeightExtension { // change this to change the way values are returned, by default everything is meters public static BodyHeightMeasurementSystem MeasurementSystem = BodyHeightMeasurementSystem.Meters; /// <summary> /// Get Height of a body in CM /// </summary> /// <param name="TargetBody">used for extension method purposes - uses should not see</param> /// <returns> /// positive value: height in meters /// -1.0 : null body passed in /// -2.0 : body not tracked, no height available /// </returns> public static double Height( this Body TargetBody ) { if ( TargetBody == null ) return -1.0; if (TargetBody.IsTracked == false) return -2.0; const double HEAD_DIVERGENCE = 0.1; Joint _head = TargetBody.Joints[JointType.Head]; Joint _neck = TargetBody.Joints[JointType.Neck]; // var spine = skeleton.Joints[JointType.Spine]; // ? Joint _spine = TargetBody.Joints[JointType.SpineShoulder]; // var waist = skeleton.Joints[JointType.HipCenter]; // ? // jeh: spinemid is ignored Joint _waist = TargetBody.Joints[JointType.SpineBase]; Joint _hipLeft = TargetBody.Joints[JointType.HipLeft]; Joint _hipRight = TargetBody.Joints[JointType.HipRight]; Joint _kneeLeft = TargetBody.Joints[JointType.KneeLeft]; Joint _kneeRight = TargetBody.Joints[JointType.KneeRight]; Joint _ankleLeft = TargetBody.Joints[JointType.AnkleLeft]; Joint _ankleRight = TargetBody.Joints[JointType.AnkleRight]; Joint _footLeft = TargetBody.Joints[JointType.FootLeft]; Joint _footRight = TargetBody.Joints[JointType.FootRight]; // Find which leg is tracked more accurately. int legLeftTrackedJoints = NumberOfTrackedJoints(_hipLeft, _kneeLeft, _ankleLeft, _footLeft); int legRightTrackedJoints = NumberOfTrackedJoints(_hipRight, _kneeRight, _ankleRight, _footRight); double legLength = legLeftTrackedJoints > legRightTrackedJoints ? Length(_hipLeft, _kneeLeft, _ankleLeft, _footLeft) : Length(_hipRight, _kneeRight, _ankleRight, _footRight); // default is meters. adjust if imperial to feet double _retval = Length(_head, _neck, _spine, _waist) + legLength + HEAD_DIVERGENCE; if (MeasurementSystem == BodyHeightMeasurementSystem.Imperial) _retval = MetricHelpers.MetersToFeet(_retval); return _retval; } /// <summary> /// Returns the upper height of the specified skeleton (head to waist). Useful whenever Kinect provides a way to track seated users. /// </summary> /// <param name="skeleton">The specified user skeleton.</param> /// <returns>The upper height of the skeleton in meters.</returns> public static double UpperHeight( this Body TargetBody ) { Joint _head = TargetBody.Joints[JointType.Head]; // used to be ShoulderCenter. Think its SpineMid now Joint _neck = TargetBody.Joints[JointType.SpineMid]; // .Spine is now .SpineShoulder Joint _spine = TargetBody.Joints[JointType.SpineShoulder]; // HipCenter is now SpineBase Joint _waist = TargetBody.Joints[JointType.SpineBase]; return Length(_head, _neck, _spine, _waist); } /// <summary> /// Returns the length of the segment defined by the specified joints. /// </summary> /// <param name="p1">The first joint (start of the segment).</param> /// <param name="p2">The second joint (end of the segment).</param> /// <returns>The length of the segment in meters.</returns> public static double Length(Joint p1, Joint p2) { return Math.Sqrt( Math.Pow(p1.Position.X - p2.Position.X, 2) + Math.Pow(p1.Position.Y - p2.Position.Y, 2) + Math.Pow(p1.Position.Z - p2.Position.Z, 2)); } /// <summary> /// Returns the length of the segments defined by the specified joints. /// </summary> /// <param name="joints">A collection of two or more joints.</param> /// <returns>The length of all the segments in meters.</returns> public static double Length(params Joint[] joints) { double length = 0; for (int index = 0; index < joints.Length - 1; index++) { length += Length(joints[index], joints[index + 1]); } return length; } /// <summary> /// Given a collection of joints, calculates the number of the joints that are tracked accurately. /// </summary> /// <param name="joints">A collection of joints.</param> /// <returns>The number of the accurately tracked joints.</returns> public static int NumberOfTrackedJoints(params Joint[] joints) { int trackedJoints = 0; foreach (var joint in joints) { // if (joint.TrackingState == JointTrackingState.Tracked) if ( joint.TrackingState== TrackingState.Tracked ) { trackedJoints++; } } return trackedJoints; } /// <summary> /// Scales the specified joint according to the specified dimensions. /// </summary> /// <param name="joint">The joint to scale.</param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="MaxX">Maximum X.</param> /// <param name="MaxY">Maximum Y.</param> /// <returns>The scaled version of the joint.</returns> public static Joint ScaleTo(Joint joint, int width, int height, float MaxX, float MaxY) { // SkeletonPoint position = new SkeletonPoint() Microsoft.Kinect.CameraSpacePoint position = new Microsoft.Kinect.CameraSpacePoint() { X = Scale(width, MaxX, joint.Position.X), Y = Scale(height, MaxY, -joint.Position.Y), Z = joint.Position.Z }; joint.Position = position; return joint; } /// <summary> /// Scales the specified joint according to the specified dimensions. /// </summary> /// <param name="joint">The joint to scale.</param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <returns>The scaled version of the joint.</returns> public static Joint ScaleTo(Joint joint, int width, int height) { return ScaleTo(joint, width, height, 1.0f, 1.0f); } /// <summary> /// Returns the scaled value of the specified position. /// </summary> /// <param name="maxPixel">Width or height.</param> /// <param name="maxBody">Border (X or Y).</param> /// <param name="position">Original position (X or Y).</param> /// <returns>The scaled value of the specified position.</returns> private static float Scale(int maxPixel, float maxBody, float position) { float value = ((((maxPixel / maxBody ) / 2) * position) + (maxPixel / 2)); if (value > maxPixel) { return maxPixel; } if (value < 0) { return 0; } return value; } 

}

0
source

Source: https://habr.com/ru/post/902902/


All Articles