Skip to content
No results
Purple hexagonal logo with white diamond-shaped center featuring geometric star pattern design suitable for corporate branding and digital applications
LIPS®Developer
Documentation
Back To LIPS
Purple hexagonal logo with white diamond-shaped center featuring geometric star pattern design suitable for corporate branding and digital applications
LIPS®Developer
Documentation
Back To LIPS

Quick Introduction

7
  • LIPS® Documentation Overview
  • 3D Depth Camera Tech Overview
  • Depth Image
  • Understanding Depth
  • An Ideal Depth Camera
  • LIPSedge™ AE Series Camera Selection Guide
  • Frequently Asked Questions

LIPSedge Documents

57
  • LIPSMetric™ ST110d
    • User’s Manual
    • SDK Release
  • LIPSMetric™ ST115b
    • User’s Manual
    • SDK Release
  • LIPSMetric™ HA110-M
    • User’s Manual
    • SDK Release
  • LIPSMetric™ HA115a
    • SDK Release
    • User’s Manual
  • LIPSedge™ AE400 / AE450
    • LIPSedge™ AE400 / AE450 Complementary Documents
      • Certifications Documents
      • STEP files for CAD Use
      • Firmware
    • LIPSedge™ AE400 / AE450 User Guide
      • LIPSedge™ AE400 / AE450
      • User Guide
      • Previous Releases (Archive)
    • LIPSedge™ AE400 / AE450 SDK Release
      • SDK Release
      • Previous Releases (Archive)
    • LIPSedge™ AE400 / AE450 Installation
      • Installation
      • Linux
      • Windows
      • ROS Wrapper
      • NVIDIA ISAAC Wrapper
      • Persistent Connection
  • LIPSedge™ AE430 / AE470
    • LIPSedge™ AE430 / AE470 Supplementary Documents
      • Firmware
      • STEP files for CAD Use
    • LIPSedge™ AE430 / AE470 User Guide
      • LIPSedge™ AE430 / AE470
      • User Guide
      • Previous Releases (Archive)
    • LIPSedge™ AE430 / AE470 SDK Release
      • SDK Release
      • Previous Releases (Archive)
  • LIPSedge™ DL & M3 Series
    • LIPSedge™ DL & M3 Series Installation
      • Installation
      • Ubuntu
      • Windows
    • LIPSedge™ DL & M3 Supplementary Documents
      • STEP files for CAD Use
    • LIPSedge™ DL & M3 Series SDK Release
      • SDK Release
      • Changelog
      • Previous Releases (Archive)
    • LIPSedge™ DL & M3 Series User Guide
      • LIPSedge™ DL & M3 Series
      • User Guide
      • Previous Releases (Archive)
  • LIPSedge™ L215u / L210u
    • LIPSedge™ L215u / L210u User Guide
      • LIPSedge™ L215u / L210u
      • User Guide
      • Previous Releases (Archive)
    • LIPSedge™ L215u / L210u SDK Release
      • SDK Release
      • Changelog
      • Previous Releases (Archive)
    • LIPSedge™ L215u / L210u Installation
      • Installation
      • Linux
      • Windows
    • LIPSedge™ L215u / L210u Supplementary Documents
      • STEP files for CAD Use
  • LIPSedge™ L235
    •  LIPSedge™ L235 User’s Manual
    • LIPSedge™ L235 SDK Release
  • LIPSedge™ S Series
    • LIPSedge™ S Series User Guide
      •  LIPSedge™ S Series
      • User Guide
    • LIPSedge™ S Series SDK Release
      • SDK Release
    • LIPSedge™ S Series Installation
      • Windows
  • LIPSedge™ AE430-DK / AE470-DK
    • LIPSedge™ AE430-DK / AE470-DK
    • User Guide

LIPSedge™ SDK 1.x

82
  • Introduction to LIPSedge™ SDK 1.x
    • LIPSedge™ SDK 1.x
    • Benefits from LIPSedge™ SDK implementation
    • LIPSedge™ SDK 1.x Installation Architecture
    • How to identify each camera SDK
  • Tutorial and deployment
    • Tutorials
    • Development and Deployment on arm64
  • Features Articles
    • Features Articles
    • LIPSedge™ SDK Persistent Connection for PoE and USB
  • LIPSedge™ SDK Frameworks
    • LIPSedge™ SDK Frameworks
    • ROS
    • ROS2
    • NVIDIA Isaac Wrapper
    • GenICam (for Halcon / Aurora Vision)
      • GenICam (for Halcon / Aurora Vision)
      • User Manual
      • Driver(.cti) and Nodemap (.xml)
      • Supported LIPSedge™ Camera SDK
      • Installation Example
  • LIPSedge™ SDK v1.02 Tools
    • LIPSedge™ SDK v1.02 Tools
    • DepthViewer
    • PointCloudViewer
    • CameraParameterViewer
    • CameraCenterViewer
    • CameraEventListener
    • CameraPowerTest
    • LensModeSelector
    • LIPSImuReader
    • CameraSimpleViewer
    • RawFileViewer
  • LIPSedge™ SDK Languages & Libraries
    • LIPSedge™ SDK Languages & Libraries
    • OpenCV
    • C++
      • C++
      • environment-setup
      • hello-lipsedge-sdk
      • opencv-viewer
      • roi
      • depth-data
      • align-depth-color
      • range-filter
      • remove-background
      • record
      • pointcloud
      • config-resolution
      • camera-parameter
      • align
      • distance
      • grabcuts
      • measure
      • motion
      • post-processing
      • save-to-disk
      • sensor-control
    • Python
      • Python
      • environment-setup
      • hello-lipsedge-sdk
      • opencv-viewer
      • roi
      • depth-data
      • align-depth-color
      • range-filter
      • remove-background
      • record
    • Java
      • Java
      • ni-hello
    • C#
      • C#
      • ni-hello
      • simple-read
  • New Features for v1.02
    • New Features for v1.02
    • Installing and identifying packages on Windows
    • Saving Captures and Videos with the DepthViewer
    • Saving Point Cloud with PointCloudViewer
    • Live On-Screen displaying Depth, FPS
    • Live On-Screen displaying XYZ parameters in RawfileViewer
    • Distance measurement on-screen from point-to-point
    • Mouse Pointer Change
    • LIPSedge™ AE and S series Colormap new feature addition
    • Simple naming for LIPSedge™ SDK Tools
    • Importing parameters from .json files for LIPSedge™ AE and S series
  • LIPSedge™ SDK Sample Codes
    • LIPSedge™ SDK Sample Codes
    • Sample Applications & Viewer & Utilities
      • Sample Applications & Viewer & Utilities
      • ni-viewer
      • ni-pointcloud-gl
      • ni-camera-matrix

LIPSense Documents

33
  • LIPSense™ 3D Body Pose Middleware
    • LIPSense™ 3D Body Pose SDK
    • User Manual & SDK Download
    • License Management
    • Changelog
    • Previous Releases (Archive)
    • Examples
      • Python
        • Python
        • python_example
      • c#
        • SkeletonCSharp
        • C#
      • C++
        • C++
        • skeleton_example
        • skeleton_opencv
  • LIPScan 3D ™ Middleware
    • LIPScan 3D ™ Middleware
    • LIPScan 3D™ Desktop
      • LIPScan 3D™ Desktop
      • User Guide
      • Application Download
      • Release Notes
      • Previous Releases
    • LIPScan 3D™ SDK
      • LIPScan 3D™ SDK
      • User Guide
      • SDK Download
      • Release Notes
      • Previous Releases
  • LIPSFace™ SDK
    • LIPSFace™ SDK
    • LIPSFace Overview
    • Changelog
  • LIPSFace™ HW120/125 On-Device 3D Facial Recognition
    • LIPSFace™ HW120/125 On-Device 3D Facial Recognition
    • User Guide
    • SDK Download
    • STEP files for CAD Use
  • LIPSFace™ HW110/115 On-Device 3D Facial Recognition
    • LIPSFace™ HW110/115 On-Device 3D Facial Recognition
    • User Guide & SDK Download
    • STEP files for CAD Use

LIPSMetric Documents

9
  • LIPSMetric™ Measure Master
    • User’s Manual
    • SDK Release
  • LIPSMetric™ VD115 Vehicle Dimensioner
    • LIPSMetric™ VD115 Vehicle Dimensioner
  • LIPSMetric™ ST115 Static Dimensioner
    • LIPSMetric™ ST115 Static Dimensioner
    • User’s Manual
  • LIPSMetric™ ST130 Pallet Dimensioner
    • LIPSMetric™ ST130 Pallet Dimensioner
    • User Guide
  • LIPSMetric™ HA110 Handheld Dimensioner
    • LIPSMetric™ HA110 Handheld Dimensioner
    • User’s Manual

Other LIPS Documents

1
  • LIPS License Management
    • LIPS License Management
View Categories
  • Home
  • LIPS® Developer Documentation
  • LIPSense Documents
  • LIPSense™ 3D Body Pose Middleware
  • Examples
  • Python
  • python_example

python_example

Overview #

This is a Python implementation of a Real-time 3D Body Pose Estimation application using  LIPSBodyPose SDK(Pro Version). It captures data from LIPSedge cameras, processes it to find human skeletons, and visualizes the results using OpenCV.

Tutorial #

  1. First, the script imports the libraries, connect the DLLs and initializing the Pose Engine
Python
import sys
import os
import json
import numpy as np
import cv2

if sys.platform == 'win32':
    LIPSBODYPOSE_SDK_ROOT = os.environ.get("LIPSBODYPOSE_SDK_ROOT")
    CUDA_PATH = os.environ.get("CUDA_PATH")
    os.add_dll_directory(LIPSBODYPOSE_SDK_ROOT+"bin")
    os.add_dll_directory(LIPSBODYPOSE_SDK_ROOT+"bin\\OpenNI2\\Drivers")
    os.add_dll_directory(LIPSBODYPOSE_SDK_ROOT+"3rdparty\\openvino\\bin")
    os.add_dll_directory(LIPSBODYPOSE_SDK_ROOT+"3rdparty\\zlib\\bin")
    os.add_dll_directory(CUDA_PATH+"\\bin")

import pylipsbodypose as pose

2. The function convertInt converts 2D floating-point coordinates (decimals) into integer pixels to ensure coordinates are compatible with drawing functions.

Python
def convertInt(point2d):
    return (int(point2d[0]+0.5),
            int(point2d[1]+0.5))

3. Create the Skeleton Drawing Function to:
(1) Define Connections: Establish a map of joint pairs (connection_pairs) to connect keypoints for the face, body, and high-fidelity hand joints.

(2) Assign Unique Colors: Use the skeleton ID to select a specific color from the list, ensuring different people are easily distinguishable.

(3) Render Bones and Joints: Iterate through all valid keypoints to draw connection lines (bones) and solid circles (joints) onto the image.

(4) Display 3D Distance: Retrieve the depth (Z-axis) from the NECK position, convert it from millimeters to meters, and overlay the distance text on the BGR image.

Python
def drawSkeletons(img, skeletons):
    connection_pairs = [
        # Face
        ('R_EYE', 'R_EAR'),
        ('L_EYE', 'L_EAR'),
        ('R_EYE', 'NOSE'),
        ('L_EYE', 'NOSE'),
        ('R_EYE', 'HEAD'),
        ('L_EYE', 'HEAD'),
        # Body
        ('NOSE', 'NECK'),
        ('NECK', 'R_SHOULDER'),
        ('NECK', 'L_SHOULDER'),
        ('R_SHOULDER', 'R_HIP'),
        ('L_SHOULDER', 'L_HIP'),
        ('L_HIP', 'R_HIP'),
        ('NECK', 'CHEST_SPINE'),
        ('CHEST_SPINE', 'NAVEL_SPINE'),
        ('NAVEL_SPINE', 'PELVIS'),
        # Right arm
        ('R_SHOULDER', 'R_ELBOW'),
        ('R_ELBOW', 'R_WRIST'),
        ('R_WRIST', 'R_HAND'),
        ('R_WRIST', 'R_THUMB_TIP'),
        ('R_HAND', 'R_HAND_TIP'),
        # Left arm
        ('L_SHOULDER', 'L_ELBOW'),
        ('L_ELBOW', 'L_WRIST'),
        ('L_WRIST', 'L_HAND'),
        ('L_WRIST', 'L_THUMB_TIP'),
        ('L_HAND', 'L_HAND_TIP'),
        # Right leg
        ('R_HIP', 'R_KNEE'),
        ('R_KNEE', 'R_ANKLE'),
        ('R_ANKLE', 'R_FOOT'),
        # Left leg
        ('L_HIP', 'L_KNEE'),
        ('L_KNEE', 'L_ANKLE'),
        ('L_ANKLE', 'L_FOOT'),
        # Right hand
        ('R_WRIST', 'HAND_R_THUMB_CMC'),
        ('HAND_R_THUMB_CMC', 'HAND_R_THUMB_MCP'),
        ('HAND_R_THUMB_MCP', 'HAND_R_THUMB_IP'),
        ('HAND_R_THUMB_IP', 'HAND_R_THUMB_TIP'),
        ('R_WRIST', 'HAND_R_INDEX_MCP'),
        ('HAND_R_INDEX_MCP', 'HAND_R_INDEX_PIP'),
        ('HAND_R_INDEX_PIP', 'HAND_R_INDEX_DIP'),
        ('HAND_R_INDEX_DIP', 'HAND_R_INDEX_TIP'),
        ('R_WRIST', 'HAND_R_MIDDLE_MCP'),
        ('HAND_R_MIDDLE_MCP', 'HAND_R_MIDDLE_PIP'),
        ('HAND_R_MIDDLE_PIP', 'HAND_R_MIDDLE_DIP'),
        ('HAND_R_MIDDLE_DIP', 'HAND_R_MIDDLE_TIP'),
        ('R_WRIST', 'HAND_R_RING_MCP'),
        ('HAND_R_RING_MCP', 'HAND_R_RING_PIP'),
        ('HAND_R_RING_PIP', 'HAND_R_RING_DIP'),
        ('HAND_R_RING_DIP', 'HAND_R_RING_TIP'),
        ('R_WRIST', 'HAND_R_LITTLE_MCP'),
        ('HAND_R_LITTLE_MCP', 'HAND_R_LITTLE_PIP'),
        ('HAND_R_LITTLE_PIP', 'HAND_R_LITTLE_DIP'),
        ('HAND_R_LITTLE_DIP', 'HAND_R_LITTLE_TIP'),
        # Left hand
        ('L_WRIST', 'HAND_L_THUMB_CMC'),
        ('HAND_L_THUMB_CMC', 'HAND_L_THUMB_MCP'),
        ('HAND_L_THUMB_MCP', 'HAND_L_THUMB_IP'),
        ('HAND_L_THUMB_IP', 'HAND_L_THUMB_TIP'),
        ('L_WRIST', 'HAND_L_INDEX_MCP'),
        ('HAND_L_INDEX_MCP', 'HAND_L_INDEX_PIP'),
        ('HAND_L_INDEX_PIP', 'HAND_L_INDEX_DIP'),
        ('HAND_L_INDEX_DIP', 'HAND_L_INDEX_TIP'),
        ('L_WRIST', 'HAND_L_MIDDLE_MCP'),
        ('HAND_L_MIDDLE_MCP', 'HAND_L_MIDDLE_PIP'),
        ('HAND_L_MIDDLE_PIP', 'HAND_L_MIDDLE_DIP'),
        ('HAND_L_MIDDLE_DIP', 'HAND_L_MIDDLE_TIP'),
        ('L_WRIST', 'HAND_L_RING_MCP'),
        ('HAND_L_RING_MCP', 'HAND_L_RING_PIP'),
        ('HAND_L_RING_PIP', 'HAND_L_RING_DIP'),
        ('HAND_L_RING_DIP', 'HAND_L_RING_TIP'),
        ('L_WRIST', 'HAND_L_LITTLE_MCP'),
        ('HAND_L_LITTLE_MCP', 'HAND_L_LITTLE_PIP'),
        ('HAND_L_LITTLE_PIP', 'HAND_L_LITTLE_DIP'),
        ('HAND_L_LITTLE_DIP', 'HAND_L_LITTLE_TIP')
    ]

    color_list = [(255, 100, 100),
                  (255, 255, 100),
                  (100, 255, 100),
                  (100, 255, 255),
                  (100, 100, 255)] 
    # skeletons = [{ 'id': 12,
    #                'keypoints': { 'NOSE': {'is_valid': True,  'point2d': (x, y), 'point3d': (x, y, z)},
    #                               'NECK': {'is_valid': False, 'point2d': (0, 0), 'point3d': (0, 0, 0)},
    #                               ... }
    #              }, {}, ... , {}]
    for skeleton in skeletons:
        # Draw connection lines
        color_idx = skeleton['id'] % len(color_list)
        line_color = color_list[color_idx]
        line_width = 2
        for pair in connection_pairs:
            keypoint_a = skeleton['keypoints'][pair[0]]
            keypoint_b = skeleton['keypoints'][pair[1]]
            if keypoint_a['is_valid'] and keypoint_b['is_valid']:
                cv2.line(img, convertInt(keypoint_a['point2d']), convertInt(keypoint_b['point2d']),
                         line_color, line_width)

        # Draw keypoints
        circle_color = (line_color[0]+100,
                        line_color[1]+100,
                        line_color[2]+100)
        circle_radius = 4
        circle_line_width = -1  # solid
        for keypoint in skeleton['keypoints'].values():
            if keypoint['is_valid']:
                cv2.circle(img, convertInt(keypoint['point2d']),
                           circle_radius, circle_color, circle_line_width)

        # Draw distance text
        keypoint_neck = skeleton['keypoints']['NECK']
        if keypoint_neck['is_valid']:
            # Get z value of neck's 3D position in millimeter
            distance_mm = keypoint_neck['point3d'][2]
            distance_m = round(distance_mm/1000, 2)

            text = str(distance_m) + "m"
            org = convertInt(keypoint_neck['point2d'])
            font_face = cv2.FONT_HERSHEY_COMPLEX_SMALL
            font_scale = 1
            color = (255, 255, 255)
            cv2.putText(img, text, org, font_face, font_scale, color)

    return img

4. The function colorizeDepthMap turns distance into colormap for visualization.

Python
def colorizeDepthMap(depth, display_min_z=300, display_max_z=3000):
    normalize_alpha = 255.0 / (display_max_z-display_min_z)
    normalize_beta = (-255.0*display_min_z) / (display_max_z-display_min_z)

    depth_normal = (depth*normalize_alpha + normalize_beta).astype(np.uint8)
    output = cv2.applyColorMap(depth_normal, cv2.COLORMAP_JET)

    return output

5. The function drawProfileInfo overlays real-time diagnostic data onto the video feed, allowing developers to monitor the SDK’s performance during execution.

Python
def drawProfileInfo(img, profile_info):
    height, width, channels = img.shape

    fps = round(profile_info['fps'], 2)
    latency = round(profile_info['latency_ms'], 2)

    text = "FPS:" + str(fps) + " | LATENCY:" + str(latency) + "ms"
    org = (10, height-10)
    font_face = cv2.FONT_HERSHEY_COMPLEX_SMALL
    font_scale = 1
    color = (255, 255, 255)
    cv2.putText(img, text, org, font_face, font_scale, color)

    return img

6.Create the Main Loop to :

(1)Starts the SDK and prints camera information.

(2)Enter a loop that grabs a new “frame” from the camera.

(3)Updates the display of depth image, rgb image, with the skeleton overlays and the profile information.

(4)Stop everything safely when you hit the ESC key.

Python
def main():
    config = {}
    if sys.platform == 'win32':
        config['runtime_dir'] = LIPSBODYPOSE_SDK_ROOT + "bin"
    config['mirroring'] = True
    config['profiling'] = True

    pose.run(json.dumps(config))

    versions = pose.getVersions()
    print("LIPSBodyPose version: ", versions['LIPSBodyPose'])
    print("Camera SDK   version: ", versions['Camera_SDK'])

    fx, fy, ppx, ppy = pose.getIntrinsics()
    print("Camera intrinsics: fx={}, fy={}, ppx={}, ppy={}".format(fx, fy, ppx, ppy))

    print("Current config: \n", pose.dumpConfig())

    print("\nPress ESC to exit")
    while True:
        key_input = cv2.waitKey(1)

        if key_input == 27:  # press ESC to exit
            break

        depth_image_mm, color_image_bgr, skeletons, profile_info = pose.readFrame()

        color_image_bgr = drawSkeletons(color_image_bgr, skeletons)
        color_image_bgr = drawProfileInfo(color_image_bgr, profile_info)

        cv2.imshow("BGR Image", color_image_bgr)
        cv2.imshow("Depth Image", colorizeDepthMap(depth_image_mm))

    pose.stop()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    sys.exit(main())

Expected Outcome #

Picture6 1 | LIPS® Developer Documentation

Full Code #

Python
# Copyright LIPS Corporation.  All rights reserved.

import sys
import os
import json
import numpy as np
import cv2

if sys.platform == 'win32':
    LIPSBODYPOSE_SDK_ROOT = os.environ.get("LIPSBODYPOSE_SDK_ROOT")
    CUDA_PATH = os.environ.get("CUDA_PATH")
    os.add_dll_directory(LIPSBODYPOSE_SDK_ROOT+"bin")
    os.add_dll_directory(LIPSBODYPOSE_SDK_ROOT+"bin\\OpenNI2\\Drivers")
    os.add_dll_directory(LIPSBODYPOSE_SDK_ROOT+"3rdparty\\openvino\\bin")
    os.add_dll_directory(LIPSBODYPOSE_SDK_ROOT+"3rdparty\\zlib\\bin")
    os.add_dll_directory(CUDA_PATH+"\\bin")

import pylipsbodypose as pose


def convertInt(point2d):
    return (int(point2d[0]+0.5),
            int(point2d[1]+0.5))


def drawSkeletons(img, skeletons):
    connection_pairs = [
        # Face
        ('R_EYE', 'R_EAR'),
        ('L_EYE', 'L_EAR'),
        ('R_EYE', 'NOSE'),
        ('L_EYE', 'NOSE'),
        ('R_EYE', 'HEAD'),
        ('L_EYE', 'HEAD'),
        # Body
        ('NOSE', 'NECK'),
        ('NECK', 'R_SHOULDER'),
        ('NECK', 'L_SHOULDER'),
        ('R_SHOULDER', 'R_HIP'),
        ('L_SHOULDER', 'L_HIP'),
        ('L_HIP', 'R_HIP'),
        ('NECK', 'CHEST_SPINE'),
        ('CHEST_SPINE', 'NAVEL_SPINE'),
        ('NAVEL_SPINE', 'PELVIS'),
        # Right arm
        ('R_SHOULDER', 'R_ELBOW'),
        ('R_ELBOW', 'R_WRIST'),
        ('R_WRIST', 'R_HAND'),
        ('R_WRIST', 'R_THUMB_TIP'),
        ('R_HAND', 'R_HAND_TIP'),
        # Left arm
        ('L_SHOULDER', 'L_ELBOW'),
        ('L_ELBOW', 'L_WRIST'),
        ('L_WRIST', 'L_HAND'),
        ('L_WRIST', 'L_THUMB_TIP'),
        ('L_HAND', 'L_HAND_TIP'),
        # Right leg
        ('R_HIP', 'R_KNEE'),
        ('R_KNEE', 'R_ANKLE'),
        ('R_ANKLE', 'R_FOOT'),
        # Left leg
        ('L_HIP', 'L_KNEE'),
        ('L_KNEE', 'L_ANKLE'),
        ('L_ANKLE', 'L_FOOT'),
        # Right hand
        ('R_WRIST', 'HAND_R_THUMB_CMC'),
        ('HAND_R_THUMB_CMC', 'HAND_R_THUMB_MCP'),
        ('HAND_R_THUMB_MCP', 'HAND_R_THUMB_IP'),
        ('HAND_R_THUMB_IP', 'HAND_R_THUMB_TIP'),
        ('R_WRIST', 'HAND_R_INDEX_MCP'),
        ('HAND_R_INDEX_MCP', 'HAND_R_INDEX_PIP'),
        ('HAND_R_INDEX_PIP', 'HAND_R_INDEX_DIP'),
        ('HAND_R_INDEX_DIP', 'HAND_R_INDEX_TIP'),
        ('R_WRIST', 'HAND_R_MIDDLE_MCP'),
        ('HAND_R_MIDDLE_MCP', 'HAND_R_MIDDLE_PIP'),
        ('HAND_R_MIDDLE_PIP', 'HAND_R_MIDDLE_DIP'),
        ('HAND_R_MIDDLE_DIP', 'HAND_R_MIDDLE_TIP'),
        ('R_WRIST', 'HAND_R_RING_MCP'),
        ('HAND_R_RING_MCP', 'HAND_R_RING_PIP'),
        ('HAND_R_RING_PIP', 'HAND_R_RING_DIP'),
        ('HAND_R_RING_DIP', 'HAND_R_RING_TIP'),
        ('R_WRIST', 'HAND_R_LITTLE_MCP'),
        ('HAND_R_LITTLE_MCP', 'HAND_R_LITTLE_PIP'),
        ('HAND_R_LITTLE_PIP', 'HAND_R_LITTLE_DIP'),
        ('HAND_R_LITTLE_DIP', 'HAND_R_LITTLE_TIP'),
        # Left hand
        ('L_WRIST', 'HAND_L_THUMB_CMC'),
        ('HAND_L_THUMB_CMC', 'HAND_L_THUMB_MCP'),
        ('HAND_L_THUMB_MCP', 'HAND_L_THUMB_IP'),
        ('HAND_L_THUMB_IP', 'HAND_L_THUMB_TIP'),
        ('L_WRIST', 'HAND_L_INDEX_MCP'),
        ('HAND_L_INDEX_MCP', 'HAND_L_INDEX_PIP'),
        ('HAND_L_INDEX_PIP', 'HAND_L_INDEX_DIP'),
        ('HAND_L_INDEX_DIP', 'HAND_L_INDEX_TIP'),
        ('L_WRIST', 'HAND_L_MIDDLE_MCP'),
        ('HAND_L_MIDDLE_MCP', 'HAND_L_MIDDLE_PIP'),
        ('HAND_L_MIDDLE_PIP', 'HAND_L_MIDDLE_DIP'),
        ('HAND_L_MIDDLE_DIP', 'HAND_L_MIDDLE_TIP'),
        ('L_WRIST', 'HAND_L_RING_MCP'),
        ('HAND_L_RING_MCP', 'HAND_L_RING_PIP'),
        ('HAND_L_RING_PIP', 'HAND_L_RING_DIP'),
        ('HAND_L_RING_DIP', 'HAND_L_RING_TIP'),
        ('L_WRIST', 'HAND_L_LITTLE_MCP'),
        ('HAND_L_LITTLE_MCP', 'HAND_L_LITTLE_PIP'),
        ('HAND_L_LITTLE_PIP', 'HAND_L_LITTLE_DIP'),
        ('HAND_L_LITTLE_DIP', 'HAND_L_LITTLE_TIP')
    ]

    color_list = [(255, 100, 100),
                  (255, 255, 100),
                  (100, 255, 100),
                  (100, 255, 255),
                  (100, 100, 255)]

    # skeletons = [{ 'id': 12,
    #                'keypoints': { 'NOSE': {'is_valid': True,  'point2d': (x, y), 'point3d': (x, y, z)},
    #                               'NECK': {'is_valid': False, 'point2d': (0, 0), 'point3d': (0, 0, 0)},
    #                               ... }
    #              }, {}, ... , {}]
    for skeleton in skeletons:
        # Draw connection lines
        color_idx = skeleton['id'] % len(color_list)
        line_color = color_list[color_idx]
        line_width = 2
        for pair in connection_pairs:
            keypoint_a = skeleton['keypoints'][pair[0]]
            keypoint_b = skeleton['keypoints'][pair[1]]
            if keypoint_a['is_valid'] and keypoint_b['is_valid']:
                cv2.line(img, convertInt(keypoint_a['point2d']), convertInt(keypoint_b['point2d']),
                         line_color, line_width)

        # Draw keypoints
        circle_color = (line_color[0]+100,
                        line_color[1]+100,
                        line_color[2]+100)
        circle_radius = 4
        circle_line_width = -1  # solid
        for keypoint in skeleton['keypoints'].values():
            if keypoint['is_valid']:
                cv2.circle(img, convertInt(keypoint['point2d']),
                           circle_radius, circle_color, circle_line_width)

        # Draw distance text
        keypoint_neck = skeleton['keypoints']['NECK']
        if keypoint_neck['is_valid']:
            # Get z value of neck's 3D position in millimeter
            distance_mm = keypoint_neck['point3d'][2]
            distance_m = round(distance_mm/1000, 2)

            text = str(distance_m) + "m"
            org = convertInt(keypoint_neck['point2d'])
            font_face = cv2.FONT_HERSHEY_COMPLEX_SMALL
            font_scale = 1
            color = (255, 255, 255)
            cv2.putText(img, text, org, font_face, font_scale, color)

    return img


def colorizeDepthMap(depth, display_min_z=300, display_max_z=3000):
    normalize_alpha = 255.0 / (display_max_z-display_min_z)
    normalize_beta = (-255.0*display_min_z) / (display_max_z-display_min_z)

    depth_normal = (depth*normalize_alpha + normalize_beta).astype(np.uint8)
    output = cv2.applyColorMap(depth_normal, cv2.COLORMAP_JET)

    return output


def drawProfileInfo(img, profile_info):
    height, width, channels = img.shape

    fps = round(profile_info['fps'], 2)
    latency = round(profile_info['latency_ms'], 2)

    text = "FPS:" + str(fps) + " | LATENCY:" + str(latency) + "ms"
    org = (10, height-10)
    font_face = cv2.FONT_HERSHEY_COMPLEX_SMALL
    font_scale = 1
    color = (255, 255, 255)
    cv2.putText(img, text, org, font_face, font_scale, color)

    return img


def main():
    config = {}
    if sys.platform == 'win32':
        config['runtime_dir'] = LIPSBODYPOSE_SDK_ROOT + "bin"
    config['mirroring'] = True
    config['profiling'] = True

    pose.run(json.dumps(config))

    versions = pose.getVersions()
    print("LIPSBodyPose version: ", versions['LIPSBodyPose'])
    print("Camera SDK   version: ", versions['Camera_SDK'])

    fx, fy, ppx, ppy = pose.getIntrinsics()
    print("Camera intrinsics: fx={}, fy={}, ppx={}, ppy={}".format(fx, fy, ppx, ppy))

    print("Current config: \n", pose.dumpConfig())

    print("\nPress ESC to exit")
    while True:
        key_input = cv2.waitKey(1)

        if key_input == 27:  # press ESC to exit
            break

        depth_image_mm, color_image_bgr, skeletons, profile_info = pose.readFrame()

        color_image_bgr = drawSkeletons(color_image_bgr, skeletons)
        color_image_bgr = drawProfileInfo(color_image_bgr, profile_info)

        cv2.imshow("BGR Image", color_image_bgr)
        cv2.imshow("Depth Image", colorizeDepthMap(depth_image_mm))

    pose.stop()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    sys.exit(main())
Updated on 2026 年 4 月 7 日

PythonPython
Table of Contents
  • Overview
  • Tutorial
  • Expected Outcome
  • Full Code

#LIPS

About Us

Store

Blog

Terms of Use

DEVELOPER

Technical Support

SDK Download

Code Samples

Github

Copyright © 2026 LIPS Corporation | Privacy Policy | Cookie Policy | Do Not Sell My Personal Information