diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index 4c97fe8..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "skelda"]
- path = skelda
- url = https://gitlab.com/Percipiote/skelda.git
diff --git a/README.md b/README.md
index e087b90..c60436a 100644
--- a/README.md
+++ b/README.md
@@ -16,10 +16,10 @@ A general overview can be found in the paper [RapidPoseTriangulation: Multi-view
## Build
-- Clone this project with submodules:
+- Clone this project:
```bash
- git clone --recurse-submodules https://gitlab.com/Percipiote/RapidPoseTriangulation.git
+ git clone https://gitlab.com/Percipiote/RapidPoseTriangulation.git
cd RapidPoseTriangulation/
```
@@ -57,56 +57,14 @@ A general overview can be found in the paper [RapidPoseTriangulation: Multi-view
uv sync --group dev
uv run pytest tests/test_interface.py
uv build
-
- cd /RapidPoseTriangulation/scripts/ && \
- g++ -std=c++2a -fPIC -O3 -march=native -Wall -Werror -flto=auto \
- -I /RapidPoseTriangulation/rpt/ \
- -isystem /usr/include/opencv4/ \
- -isystem /onnxruntime/include/ \
- -isystem /onnxruntime/include/onnxruntime/core/session/ \
- -isystem /onnxruntime/include/onnxruntime/core/providers/tensorrt/ \
- -L /onnxruntime/build/Linux/Release/ \
- test_skelda_dataset.cpp \
- /RapidPoseTriangulation/rpt/*.cpp \
- -o test_skelda_dataset.bin \
- -Wl,--start-group \
- -lonnxruntime_providers_tensorrt \
- -lonnxruntime_providers_shared \
- -lonnxruntime_providers_cuda \
- -lonnxruntime \
- -Wl,--end-group \
- $(pkg-config --libs opencv4) \
- -Wl,-rpath,/onnxruntime/build/Linux/Release/ \
- && cd ..
- ```
-
-- Download _ONNX_ models from [model registry](https://gitlab.com/Percipiote/RapidPoseTriangulation/-/ml/models) and save them to `mmdeploy/extras/exports/`.
- Upon the first usage, they will be converted to _TensorRT_ models, which will take a few minutes. \
- (Note that this conversion is not deterministic and will each time result in slightly different models and therefore also slightly different benchmark results.)
-
-- Test with samples:
-
- ```bash
- python3 /RapidPoseTriangulation/scripts/test_triangulate.py
- ```
-
-- Test with [skelda](https://gitlab.com/Percipiote/skelda/) dataset:
-
- ```bash
- export CUDA_VISIBLE_DEVICES=0
- python3 /RapidPoseTriangulation/scripts/test_skelda_dataset.py
```
## Extras
-- Exporting tools for 2D models are at [mmdeploy](extras/mmdeploy/README.md) directory.
-
- For usage in combination with ROS2 see [ros](extras/ros/README.md) directory.
-- Running on a Nvidia Jetson is also possible following [jetson](extras/jetson/README.md) directory.
-
## Citation
diff --git a/data/q1/vis_steps.py b/data/q1/vis_steps.py
deleted file mode 100644
index 3b8ffdb..0000000
--- a/data/q1/vis_steps.py
+++ /dev/null
@@ -1,326 +0,0 @@
-import json
-import os
-
-import cv2
-import matplotlib.pyplot as plt
-import numpy as np
-
-from skelda import utils_pose, utils_view
-
-# ==================================================================================================
-
-filepath = os.path.dirname(os.path.realpath(__file__)) + "/"
-
-core_triangs = [
- [
- [0.287, -0.282, 1.264, 1.000],
- [0.504, -0.052, 1.272, 1.000],
- [0.276, -0.160, 0.764, 1.000],
- [0.443, -0.099, 0.768, 1.000],
- [0.258, -0.313, 0.999, 1.000],
- [0.513, -0.009, 1.008, 1.000],
- [0.204, -0.126, 0.439, 1.000],
- [0.422, -0.132, 0.436, 1.000],
- [0.195, -0.265, 0.807, 1.000],
- [0.415, 0.039, 0.823, 1.000],
- [0.113, -0.103, 0.096, 1.000],
- [0.389, -0.175, 0.097, 1.000],
- ],
- [
- [0.322, -0.192, 1.349, 1.000],
- [0.268, -0.594, 1.336, 1.000],
- [0.272, -0.100, 0.882, 1.000],
- [0.281, -0.379, 0.870, 1.000],
- [0.336, -0.104, 1.124, 1.000],
- [0.249, -0.578, 1.089, 1.000],
- [0.229, 0.009, 0.571, 1.000],
- [0.269, -0.345, 0.553, 1.000],
- [0.289, -0.016, 0.951, 1.000],
- [0.216, -0.327, 0.908, 1.000],
- [0.188, 0.128, 0.268, 1.000],
- [0.267, -0.273, 0.243, 1.000],
- ],
- [
- [0.865, 1.058, 1.613, 1.000],
- [0.862, 0.870, 1.604, 1.000],
- [0.927, 1.562, 1.491, 1.000],
- [0.954, 1.505, 1.486, 1.000],
- [0.908, 1.309, 1.542, 1.000],
- [0.905, 1.170, 1.525, 1.000],
- [0.968, 1.911, 1.454, 1.000],
- [1.019, 1.919, 1.457, 1.000],
- [0.921, 1.542, 1.514, 1.000],
- [0.931, 1.539, 1.506, 1.000],
- [1.008, 2.230, 1.455, 1.000],
- [1.071, 2.271, 1.460, 1.000],
- ],
- [
- [-0.260, 0.789, 1.316, 1.000],
- [0.039, 1.073, 1.322, 1.000],
- [-0.236, 0.798, 0.741, 1.000],
- [-0.048, 0.952, 0.759, 1.000],
- [-0.315, 0.734, 0.995, 1.000],
- [0.080, 1.026, 1.046, 1.000],
- [-0.291, 0.721, 0.339, 1.000],
- [-0.101, 0.887, 0.366, 1.000],
- [-0.300, 0.600, 0.742, 1.000],
- [0.066, 0.768, 0.897, 1.000],
- [-0.381, 0.685, -0.113, 1.000],
- [-0.169, 0.775, -0.040, 1.000],
- ],
- [
- [-0.199, 0.854, 1.414, 1.000],
- [-0.401, 0.566, 1.409, 1.000],
- [-0.242, 0.818, 0.870, 1.000],
- [-0.343, 0.654, 0.856, 1.000],
- [-0.176, 0.903, 1.140, 1.000],
- [-0.398, 0.480, 1.132, 1.000],
- [-0.245, 0.812, 0.492, 1.000],
- [-0.380, 0.642, 0.471, 1.000],
- [-0.145, 0.817, 0.912, 1.000],
- [-0.251, 0.396, 0.973, 1.000],
- [-0.255, 0.879, 0.107, 1.000],
- [-0.383, 0.633, 0.116, 1.000],
- ],
- [
- [0.641, 1.796, 1.681, 1.000],
- [0.603, 1.719, 1.680, 1.000],
- [0.711, 2.000, 1.518, 1.000],
- [0.706, 1.970, 1.515, 1.000],
- [0.689, 1.920, 1.588, 1.000],
- [0.651, 1.784, 1.585, 1.000],
- [0.786, 2.190, 1.448, 1.000],
- [0.780, 2.167, 1.444, 1.000],
- [0.747, 1.994, 1.531, 1.000],
- [0.720, 1.783, 1.546, 1.000],
- [0.868, 2.432, 1.427, 1.000],
- [0.849, 2.341, 1.410, 1.000],
- ],
-]
-
-core_joints = [
- "shoulder_left",
- "shoulder_right",
- "hip_left",
- "hip_right",
- "elbow_left",
- "elbow_right",
- "knee_left",
- "knee_right",
- "wrist_left",
- "wrist_right",
- "ankle_left",
- "ankle_right",
-]
-
-poses_2d = [
- [
- [
- [383.443, 144.912, 0.923],
- [382.629, 135.143, 0.83],
- [374.488, 134.329, 1.0],
- [349.251, 136.771, 0.478],
- [343.552, 139.213, 1.0],
- [356.578, 201.899, 0.73],
- [323.2, 201.899, 0.825],
- [357.392, 282.494, 0.663],
- [324.014, 289.821, 0.854],
- [378.558, 339.481, 0.621],
- [355.764, 356.577, 0.821],
- [370.417, 357.391, 0.714],
- [332.155, 359.834, 0.71],
- [391.584, 452.641, 0.768],
- [331.341, 458.34, 0.789],
- [414.379, 547.076, 0.864],
- [332.969, 550.333, 0.9],
- [351.286, 358.613, 0.71],
- [339.889, 201.899, 0.73],
- [346.402, 137.992, 0.478],
- ],
- [
- [640.948, 116.443, 0.908],
- [650.057, 100.249, 0.788],
- [642.972, 100.249, 0.681],
- [682.445, 103.285, 0.862],
- [684.469, 100.249, 0.518],
- [707.748, 181.219, 0.836],
- [693.578, 180.207, 0.705],
- [702.688, 290.528, 0.867],
- [664.227, 276.358, 0.786],
- [662.202, 375.547, 0.847],
- [605.523, 319.88, 0.881],
- [692.566, 373.522, 0.758],
- [679.409, 372.51, 0.739],
- [679.409, 500.038, 0.844],
- [672.324, 494.978, 0.837],
- [679.409, 635.663, 0.913],
- [659.166, 599.226, 0.894],
- [685.987, 373.016, 0.739],
- [700.663, 180.713, 0.705],
- [683.457, 101.767, 0.518],
- ],
- ],
- [
- [
- [495.125, 304.671, 0.581],
- [492.338, 301.885, 0.462],
- [502.091, 301.885, 0.295],
- [495.125, 308.851, 0.92],
- [528.562, 306.064, 0.754],
- [477.013, 359.703, 0.822],
- [557.819, 355.523, 0.855],
- [466.564, 431.452, 0.855],
- [565.481, 425.879, 0.836],
- [458.902, 480.911, 0.85],
- [544.583, 464.889, 0.596],
- [491.642, 490.663, 0.741],
- [539.707, 492.056, 0.746],
- [480.496, 569.379, 0.779],
- [531.348, 577.041, 0.784],
- [464.475, 646.005, 0.872],
- [518.809, 661.33, 0.913],
- [515.675, 491.36, 0.741],
- [517.416, 357.613, 0.822],
- [511.843, 307.458, 0.754],
- ],
- [
- [472.982, 273.983, 0.911],
- [477.875, 266.645, 0.848],
- [464.421, 266.645, 0.896],
- [483.378, 268.48, 0.599],
- [448.521, 268.48, 0.88],
- [493.163, 308.841, 0.753],
- [425.894, 311.899, 0.837],
- [502.336, 363.268, 0.625],
- [417.944, 368.16, 0.847],
- [499.278, 407.91, 0.495],
- [438.736, 410.357, 0.844],
- [484.602, 426.868, 0.682],
- [448.521, 427.48, 0.681],
- [485.825, 504.534, 0.745],
- [441.794, 505.757, 0.796],
- [489.494, 571.803, 0.688],
- [442.405, 577.918, 0.867],
- [466.561, 427.174, 0.681],
- [459.528, 310.37, 0.753],
- [465.95, 268.48, 0.599],
- ],
- [
- [702.349, 208.747, 0.215],
- [705.862, 207.944, 0.212],
- [700.341, 207.944, 0.209],
- [708.472, 196.399, 0.182],
- [699.538, 196.299, 0.193],
- [708.071, 196.7, 0.194],
- [696.927, 196.098, 0.22],
- [709.175, 206.137, 0.191],
- [696.526, 206.94, 0.188],
- [707.368, 210.052, 0.128],
- [699.738, 209.751, 0.145],
- [704.658, 215.172, 0.172],
- [701.445, 215.273, 0.168],
- [705.159, 224.007, 0.179],
- [703.654, 225.211, 0.185],
- [705.059, 225.914, 0.23],
- [704.457, 230.532, 0.241],
- [703.051, 215.223, 0.168],
- [702.499, 196.399, 0.194],
- [704.005, 196.349, 0.182],
- ],
- ],
-]
-
-joints_2d = [
- "nose",
- "eye_left",
- "eye_right",
- "ear_left",
- "ear_right",
- "shoulder_left",
- "shoulder_right",
- "elbow_left",
- "elbow_right",
- "wrist_left",
- "wrist_right",
- "hip_left",
- "hip_right",
- "knee_left",
- "knee_right",
- "ankle_left",
- "ankle_right",
- "hip_middle",
- "shoulder_middle",
- "head",
-]
-
-
-# ==================================================================================================
-
-
-def main():
-
- with open(os.path.join(filepath, "sample.json"), "r", encoding="utf-8") as file:
- sample = json.load(file)
-
- camparams = sample["cameras"]
- roomparams = {
- "room_size": sample["room_size"],
- "room_center": sample["room_center"],
- }
-
- fig2 = utils_view.draw_poses3d(core_triangs, core_joints, roomparams, camparams)
- fig2.axes[0].view_init(elev=30, azim=0)
- fig2.savefig(os.path.join(filepath, "core-triangs.png"), dpi=fig2.dpi)
-
- core_projections = []
- for i in range(len(camparams)):
- b2d, _ = utils_pose.project_poses(np.array(core_triangs), camparams[i])
- core_projections.append(b2d)
-
- img_size = [900, 900]
- scale = 0.66
- fig_size = 2
- plotsize = (35, 30)
- fig, axs = plt.subplots(fig_size, fig_size, figsize=plotsize)
- fig.suptitle("core reprojections", fontsize=20)
- fig.tight_layout(rect=[0, 0, 1, 0.97])
-
- num_persons = max((len(b2d) for b2d in core_projections))
- colors = plt.cm.hsv(np.linspace(0, 1, num_persons, endpoint=False)).tolist()
- colors = [[int(c[0] * 255), int(c[1] * 255), int(c[2] * 255)] for c in colors]
-
- for i in range(len(camparams)):
- img = np.ones((img_size[0], img_size[1], 3), dtype=np.uint8) * 255
-
- for j in range(len(core_projections[i])):
- color = colors[j]
- body = np.array(core_projections[i][j])
- img = utils_view.draw_body_in_image(img, body, core_joints, color)
-
- for k in range(len(poses_2d[i])):
- body = np.array(poses_2d[i][k])
- cjids = [joints_2d.index(j) for j in core_joints]
- body = body[cjids]
- img = utils_view.draw_body_in_image(
- img, body, core_joints, [0, 0, 0], thickness=2
- )
-
- img = cv2.resize(img, (int(img.shape[1] * scale), int(img.shape[0] * scale)))
- title = str(i)
-
- x, y = divmod(i, fig_size)
- axs[x][y].imshow(img)
- axs[x][y].set_title(title)
-
- # Delete empty plots
- for i in range(2, fig_size**2):
- x, y = divmod(i, fig_size)
- fig.delaxes(axs[x][y])
-
- fig.savefig(os.path.join(filepath, "core-reprojections.png"), dpi=fig.dpi)
-
-
-# ==================================================================================================
-
-if __name__ == "__main__":
- main()
diff --git a/dockerfile b/dockerfile
index 347de75..beda08b 100644
--- a/dockerfile
+++ b/dockerfile
@@ -12,7 +12,7 @@ RUN pip uninstall -y opencv-python && pip install --no-cache-dir "opencv-python<
# Show matplotlib images
RUN apt-get update && apt-get install -y --no-install-recommends python3-tk
-# Update pip to allow installation of skelda in editable mode
+# Python build frontend
RUN pip3 install --upgrade --no-cache-dir pip
# Install build dependencies
@@ -20,33 +20,5 @@ RUN apt-get update && apt-get install -y --no-install-recommends build-essential
RUN apt-get update && apt-get install -y --no-install-recommends libopencv-dev
RUN pip3 install --no-cache-dir uv
-# Install ONNX runtime
-# See: https://github.com/microsoft/onnxruntime/blob/main/dockerfiles/Dockerfile.tensorrt
-RUN pip3 uninstall -y onnxruntime-gpu
-RUN pip3 install --no-cache-dir psutil
-RUN git clone --recursive --depth=1 --branch=v1.20.1 https://github.com/Microsoft/onnxruntime.git
-# Next line fixes: https://github.com/microsoft/onnxruntime/issues/24861
-RUN cat /onnxruntime/cmake/deps.txt && \
- sed -i 's/;be8be39fdbc6e60e94fa7870b280707069b5b81a/;32b145f525a8308d7ab1c09388b2e288312d8eba/g' /onnxruntime/cmake/deps.txt && \
- cat /onnxruntime/cmake/deps.txt
-ENV PATH=/usr/local/nvidia/bin:/usr/local/cuda/bin:/cmake-3.30.1-linux-x86_64/bin:${PATH}
-ARG CMAKE_CUDA_ARCHITECTURES=75;80;90
-ENV TRT_VERSION=10.5.0.18
-RUN /bin/sh onnxruntime/dockerfiles/scripts/install_common_deps.sh \
- && /bin/sh onnxruntime/dockerfiles/scripts/checkout_submodules.sh ${trt_version}
-
-RUN cd onnxruntime && \
- /bin/sh build.sh --allow_running_as_root --parallel --build_shared_lib \
- --cuda_home /usr/local/cuda --cudnn_home /usr/lib/x86_64-linux-gnu/ --use_tensorrt \
- --tensorrt_home /usr/lib/x86_64-linux-gnu/ --config Release --build_wheel --skip_tests \
- --skip_submodule_sync --cmake_extra_defines '"CMAKE_CUDA_ARCHITECTURES='${CMAKE_CUDA_ARCHITECTURES}'"'
-RUN cd onnxruntime && pip install build/Linux/Release/dist/*.whl
-
-# Install skelda
-RUN pip3 install --upgrade --no-cache-dir scipy
-RUN apt-get update && apt-get install -y --no-install-recommends xvfb
-COPY ./skelda/ /skelda/
-RUN pip3 install --no-cache-dir -e /skelda/
-
WORKDIR /RapidPoseTriangulation/
CMD ["/bin/bash"]
diff --git a/extras/jetson/README.md b/extras/jetson/README.md
deleted file mode 100644
index 079ba2c..0000000
--- a/extras/jetson/README.md
+++ /dev/null
@@ -1,145 +0,0 @@
-# Setup with Nvidia-Jetson-Orin
-
-Initial setup and installation of _RapidPoseTriangulation_ on a _Nvidia Jetson_ device. \
-Tested with a _Jetson AGX Orin Developer Kit_ module.
-
-
-
-## Base installation
-
-- Install newest software image: \
- ()
-
- - Use manual recovery mode setup for first installation
-
- - Find out the _ip-address_ of the _Jetson_ for the runtime component installation with:
-
- ```bash
- sudo nmap -sn $(ip route get 1 | awk '{print $(NF-2);exit}')/24
- ```
-
-- Initialize system: \
- ()
-
- - Connect via _ssh_, because using _screen_ did not work, skip _oem-config_ step
-
- - Skip installation of _nvidia-jetpack_
-
-- Install basic tools:
-
- ```bash
- sudo apt install -y curl nano wget git
- ```
-
-- Update hostname:
-
- ```bash
- sudo nano /etc/hostname
- sudo nano /etc/hosts
- sudo reboot
- ```
-
-- Enable maximum performance mode:
-
- ```bash
- sudo nvpmodel -m 0
- sudo jetson_clocks
- ```
-
-- Test docker is working:
-
- ```bash
- sudo docker run --rm hello-world
- ```
-
-- Enable _docker_ without _sudo_: \
- ()
-
-- Enable GPU-access for docker building:
-
- - Run `sudo nano /etc/docker/daemon.json` and add:
-
- ```json
- {
- "runtimes": {
- "nvidia": {
- "args": [],
- "path": "nvidia-container-runtime"
- }
- },
- "default-runtime": "nvidia"
- }
- ```
-
- - Restart docker: `sudo systemctl restart docker`
-
-- Test docker is working:
-
- ```bash
- docker run --rm hello-world
- docker run -it --rm --runtime=nvidia --network=host dustynv/onnxruntime:1.20-r36.4.0
- ```
-
-
-
-## RPT installation
-
-- Build docker container:
-
- ```bash
- docker build --progress=plain -f extras/jetson/dockerfile -t rapidposetriangulation .
- ./run_container.sh
- ```
-
-- Build _rpt_ package inside container:
-
- ```bash
- cd /RapidPoseTriangulation/
- uv sync --group dev
- uv run pytest tests/test_interface.py
- uv build
-
- cd /RapidPoseTriangulation/scripts/ && \
- g++ -std=c++2a -fPIC -O3 -march=native -Wall -Werror -flto=auto \
- -I /RapidPoseTriangulation/rpt/ \
- -isystem /usr/include/opencv4/ \
- -isystem /usr/local/include/onnxruntime/ \
- -L /usr/local/lib/ \
- test_skelda_dataset.cpp \
- /RapidPoseTriangulation/rpt/*.cpp \
- -o test_skelda_dataset.bin \
- -Wl,--start-group \
- -lonnxruntime_providers_tensorrt \
- -lonnxruntime_providers_shared \
- -lonnxruntime_providers_cuda \
- -lonnxruntime \
- -Wl,--end-group \
- $(pkg-config --libs opencv4) \
- -Wl,-rpath,/onnxruntime/build/Linux/Release/ \
- && cd ..
- ```
-
-- Test with samples:
-
- ```bash
- python3 /RapidPoseTriangulation/scripts/test_triangulate.py
- ```
-
-
-
-## ROS interface
-
-- Build docker container:
-
- ```bash
- docker build --progress=plain -f extras/ros/dockerfile_2d -t rapidposetriangulation_ros2d .
- ```
-
-- Run and test:
-
- ```bash
- export CAMID="camera01" && docker compose -f extras/jetson/docker-compose-2d.yml up
-
- docker exec -it jetson-test_node-1 bash
- export ROS_DOMAIN_ID=18
- ```
diff --git a/extras/jetson/RESULTS.md b/extras/jetson/RESULTS.md
deleted file mode 100644
index e61d4ef..0000000
--- a/extras/jetson/RESULTS.md
+++ /dev/null
@@ -1,2801 +0,0 @@
-# Evaluation Results
-
-Results of the model in various experiments on different datasets. \
-(Note that batching poses did not work due to insufficient memory)
-
-### Human36m
-
-```json
-{
- "img_loading": 0.0302383,
- "demosaicing": 0.000569236,
- "avg_time_2d": 0.0182207,
- "avg_time_3d": 8.59194e-05,
- "fps": 52.9777
-}
-{
- "triangulator_calls": 600,
- "init_time": 7.91138e-06,
- "undistort_time": 6.66517e-06,
- "project_time": 1.07465e-07,
- "match_time": 4.032e-08,
- "pairs_time": 5.46962e-07,
- "pair_scoring_time": 1.78561e-05,
- "grouping_time": 2.83546e-06,
- "full_time": 2.12859e-05,
- "merge_time": 7.70588e-06,
- "post_time": 1.15723e-05,
- "convert_time": 1.67303e-07,
- "total_time": 7.7241e-05
-}
-{
- "person_nums": {
- "total_frames": 600,
- "total_labels": 600,
- "total_preds": 600,
- "considered_empty": 0,
- "valid_preds": 600,
- "invalid_preds": 0,
- "missing": 0,
- "invalid_fraction": 0.0,
- "precision": 1.0,
- "recall": 1.0,
- "f1": 1.0,
- "non_empty": 600
- },
- "mpjpe": {
- "count": 600,
- "mean": 0.061492,
- "median": 0.053155,
- "std": 0.028911,
- "sem": 0.001181,
- "min": 0.036169,
- "max": 0.188557,
- "recall-0.025": 0.0,
- "recall-0.05": 0.333333,
- "recall-0.1": 0.931667,
- "recall-0.15": 0.95,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 600,
- "ap-0.025": 0.0,
- "ap-0.05": 0.191369,
- "ap-0.1": 0.883717,
- "ap-0.15": 0.912197,
- "ap-0.25": 1.0,
- "ap-0.5": 1.0
- },
- "nose": {
- "count": 600,
- "mean": 0.107604,
- "median": 0.095831,
- "std": 0.037702,
- "sem": 0.00154,
- "min": 0.024352,
- "max": 0.258607,
- "recall-0.025": 0.003333,
- "recall-0.05": 0.023333,
- "recall-0.1": 0.556667,
- "recall-0.15": 0.865,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 600
- },
- "shoulder_left": {
- "count": 600,
- "mean": 0.035969,
- "median": 0.026188,
- "std": 0.033887,
- "sem": 0.001385,
- "min": 0.000962,
- "max": 0.170539,
- "recall-0.025": 0.461667,
- "recall-0.05": 0.82,
- "recall-0.1": 0.941667,
- "recall-0.15": 0.965,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 600
- },
- "shoulder_right": {
- "count": 600,
- "mean": 0.044382,
- "median": 0.032033,
- "std": 0.040034,
- "sem": 0.001636,
- "min": 0.003562,
- "max": 0.211991,
- "recall-0.025": 0.318333,
- "recall-0.05": 0.786667,
- "recall-0.1": 0.918333,
- "recall-0.15": 0.94,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 600
- },
- "elbow_left": {
- "count": 600,
- "mean": 0.045168,
- "median": 0.03552,
- "std": 0.036168,
- "sem": 0.001478,
- "min": 0.002655,
- "max": 0.19497,
- "recall-0.025": 0.251667,
- "recall-0.05": 0.781667,
- "recall-0.1": 0.935,
- "recall-0.15": 0.953333,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 600
- },
- "elbow_right": {
- "count": 600,
- "mean": 0.04269,
- "median": 0.031891,
- "std": 0.035634,
- "sem": 0.001456,
- "min": 0.004397,
- "max": 0.30887,
- "recall-0.025": 0.258333,
- "recall-0.05": 0.818333,
- "recall-0.1": 0.931667,
- "recall-0.15": 0.946667,
- "recall-0.25": 0.998333,
- "recall-0.5": 1.0,
- "num_labels": 600
- },
- "wrist_left": {
- "count": 600,
- "mean": 0.04157,
- "median": 0.024197,
- "std": 0.045672,
- "sem": 0.001866,
- "min": 0.000785,
- "max": 0.307112,
- "recall-0.025": 0.508333,
- "recall-0.05": 0.75,
- "recall-0.1": 0.895,
- "recall-0.15": 0.941667,
- "recall-0.25": 0.996667,
- "recall-0.5": 1.0,
- "num_labels": 600
- },
- "wrist_right": {
- "count": 599,
- "mean": 0.046022,
- "median": 0.027678,
- "std": 0.052245,
- "sem": 0.002136,
- "min": 0.002387,
- "max": 0.456498,
- "recall-0.025": 0.45,
- "recall-0.05": 0.766667,
- "recall-0.1": 0.891667,
- "recall-0.15": 0.905,
- "recall-0.25": 0.99,
- "recall-0.5": 0.998333,
- "num_labels": 600
- },
- "hip_left": {
- "count": 600,
- "mean": 0.068516,
- "median": 0.057202,
- "std": 0.035751,
- "sem": 0.001461,
- "min": 0.029037,
- "max": 0.217634,
- "recall-0.025": 0.0,
- "recall-0.05": 0.263333,
- "recall-0.1": 0.885,
- "recall-0.15": 0.946667,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 600
- },
- "hip_right": {
- "count": 600,
- "mean": 0.084867,
- "median": 0.081572,
- "std": 0.028768,
- "sem": 0.001175,
- "min": 0.016043,
- "max": 0.210257,
- "recall-0.025": 0.016667,
- "recall-0.05": 0.063333,
- "recall-0.1": 0.881667,
- "recall-0.15": 0.95,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 600
- },
- "knee_left": {
- "count": 599,
- "mean": 0.057348,
- "median": 0.043401,
- "std": 0.057834,
- "sem": 0.002365,
- "min": 0.016103,
- "max": 0.488334,
- "recall-0.025": 0.081667,
- "recall-0.05": 0.691667,
- "recall-0.1": 0.913333,
- "recall-0.15": 0.921667,
- "recall-0.25": 0.981667,
- "recall-0.5": 0.998333,
- "num_labels": 600
- },
- "knee_right": {
- "count": 600,
- "mean": 0.04705,
- "median": 0.034704,
- "std": 0.041186,
- "sem": 0.001683,
- "min": 0.011544,
- "max": 0.301894,
- "recall-0.025": 0.113333,
- "recall-0.05": 0.82,
- "recall-0.1": 0.925,
- "recall-0.15": 0.94,
- "recall-0.25": 0.996667,
- "recall-0.5": 1.0,
- "num_labels": 600
- },
- "ankle_left": {
- "count": 597,
- "mean": 0.090924,
- "median": 0.08248,
- "std": 0.040973,
- "sem": 0.001678,
- "min": 0.05157,
- "max": 0.495193,
- "recall-0.025": 0.0,
- "recall-0.05": 0.0,
- "recall-0.1": 0.87,
- "recall-0.15": 0.936667,
- "recall-0.25": 0.986667,
- "recall-0.5": 0.995,
- "num_labels": 600
- },
- "ankle_right": {
- "count": 599,
- "mean": 0.081952,
- "median": 0.066793,
- "std": 0.053367,
- "sem": 0.002182,
- "min": 0.028777,
- "max": 0.394296,
- "recall-0.025": 0.0,
- "recall-0.05": 0.028333,
- "recall-0.1": 0.891667,
- "recall-0.15": 0.913333,
- "recall-0.25": 0.97,
- "recall-0.5": 0.998333,
- "num_labels": 600
- },
- "joint_recalls": {
- "num_labels": 7800,
- "recall-0.025": 0.18885,
- "recall-0.05": 0.50782,
- "recall-0.1": 0.87949,
- "recall-0.15": 0.93244,
- "recall-0.25": 0.99333,
- "recall-0.5": 0.99885
- }
-}
-{
- "total_parts": 8400,
- "correct_parts": 8118,
- "pcp": 0.966429
-}
-```
-
-### Shelf
-
-```json
-{
- "img_loading": 0.0613517,
- "demosaicing": 0.000514999,
- "avg_time_2d": 0.0385883,
- "avg_time_3d": 0.000296986,
- "fps": 25.3805
-}
-{
- "triangulator_calls": 301,
- "init_time": 8.85134e-06,
- "undistort_time": 2.26089e-05,
- "project_time": 6.12477e-06,
- "match_time": 2.3381e-05,
- "pairs_time": 1.26549e-05,
- "pair_scoring_time": 7.41986e-05,
- "grouping_time": 1.17478e-05,
- "full_time": 7.31069e-05,
- "merge_time": 2.36468e-05,
- "post_time": 1.91408e-05,
- "convert_time": 3.9615e-07,
- "total_time": 0.000276402
-}
-{
- "person_nums": {
- "total_frames": 301,
- "total_labels": 477,
- "total_preds": 828,
- "considered_empty": 0,
- "valid_preds": 477,
- "invalid_preds": 351,
- "missing": 0,
- "invalid_fraction": 0.42391,
- "precision": 0.57609,
- "recall": 1.0,
- "f1": 0.73103,
- "non_empty": 828
- },
- "mpjpe": {
- "count": 477,
- "mean": 0.047914,
- "median": 0.042836,
- "std": 0.014864,
- "sem": 0.000681,
- "min": 0.029889,
- "max": 0.117015,
- "recall-0.025": 0.0,
- "recall-0.05": 0.689727,
- "recall-0.1": 0.987421,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 477,
- "ap-0.025": 0.0,
- "ap-0.05": 0.376744,
- "ap-0.1": 0.724781,
- "ap-0.15": 0.737472,
- "ap-0.25": 0.737472,
- "ap-0.5": 0.737472
- },
- "head": {
- "count": 477,
- "mean": 0.05384,
- "median": 0.050167,
- "std": 0.024098,
- "sem": 0.001105,
- "min": 0.004172,
- "max": 0.170521,
- "recall-0.025": 0.085954,
- "recall-0.05": 0.494759,
- "recall-0.1": 0.937107,
- "recall-0.15": 0.997904,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "shoulder_left": {
- "count": 477,
- "mean": 0.042385,
- "median": 0.037408,
- "std": 0.02045,
- "sem": 0.000937,
- "min": 0.004485,
- "max": 0.136944,
- "recall-0.025": 0.161426,
- "recall-0.05": 0.725367,
- "recall-0.1": 0.987421,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "shoulder_right": {
- "count": 477,
- "mean": 0.049633,
- "median": 0.04552,
- "std": 0.023226,
- "sem": 0.001065,
- "min": 0.005348,
- "max": 0.147448,
- "recall-0.025": 0.100629,
- "recall-0.05": 0.561845,
- "recall-0.1": 0.955975,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "elbow_left": {
- "count": 477,
- "mean": 0.040727,
- "median": 0.032035,
- "std": 0.029242,
- "sem": 0.00134,
- "min": 0.003942,
- "max": 0.326226,
- "recall-0.025": 0.318658,
- "recall-0.05": 0.748428,
- "recall-0.1": 0.949686,
- "recall-0.15": 0.997904,
- "recall-0.25": 0.997904,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "elbow_right": {
- "count": 477,
- "mean": 0.053395,
- "median": 0.044653,
- "std": 0.04129,
- "sem": 0.001893,
- "min": 0.002412,
- "max": 0.240443,
- "recall-0.025": 0.259958,
- "recall-0.05": 0.559748,
- "recall-0.1": 0.90566,
- "recall-0.15": 0.955975,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "wrist_left": {
- "count": 477,
- "mean": 0.060063,
- "median": 0.053941,
- "std": 0.039463,
- "sem": 0.001809,
- "min": 0.002965,
- "max": 0.314883,
- "recall-0.025": 0.138365,
- "recall-0.05": 0.404612,
- "recall-0.1": 0.907757,
- "recall-0.15": 0.962264,
- "recall-0.25": 0.989518,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "wrist_right": {
- "count": 477,
- "mean": 0.059287,
- "median": 0.054279,
- "std": 0.033944,
- "sem": 0.001556,
- "min": 0.009487,
- "max": 0.370517,
- "recall-0.025": 0.1174,
- "recall-0.05": 0.417191,
- "recall-0.1": 0.893082,
- "recall-0.15": 0.976939,
- "recall-0.25": 0.997904,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "hip_left": {
- "count": 477,
- "mean": 0.048015,
- "median": 0.042252,
- "std": 0.026197,
- "sem": 0.001201,
- "min": 0.008132,
- "max": 0.142831,
- "recall-0.025": 0.184486,
- "recall-0.05": 0.626834,
- "recall-0.1": 0.955975,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "hip_right": {
- "count": 477,
- "mean": 0.058081,
- "median": 0.056675,
- "std": 0.023893,
- "sem": 0.001095,
- "min": 0.005253,
- "max": 0.131652,
- "recall-0.025": 0.09434,
- "recall-0.05": 0.406709,
- "recall-0.1": 0.939203,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "knee_left": {
- "count": 477,
- "mean": 0.040331,
- "median": 0.037937,
- "std": 0.024461,
- "sem": 0.001121,
- "min": 0.00621,
- "max": 0.196135,
- "recall-0.025": 0.249476,
- "recall-0.05": 0.744235,
- "recall-0.1": 0.974843,
- "recall-0.15": 0.989518,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "knee_right": {
- "count": 477,
- "mean": 0.040068,
- "median": 0.036102,
- "std": 0.023063,
- "sem": 0.001057,
- "min": 0.006699,
- "max": 0.184932,
- "recall-0.025": 0.30608,
- "recall-0.05": 0.710692,
- "recall-0.1": 0.974843,
- "recall-0.15": 0.997904,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "ankle_left": {
- "count": 477,
- "mean": 0.036404,
- "median": 0.027798,
- "std": 0.030604,
- "sem": 0.001403,
- "min": 0.004789,
- "max": 0.223748,
- "recall-0.025": 0.431866,
- "recall-0.05": 0.815514,
- "recall-0.1": 0.943396,
- "recall-0.15": 0.983229,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "ankle_right": {
- "count": 477,
- "mean": 0.040652,
- "median": 0.030955,
- "std": 0.037264,
- "sem": 0.001708,
- "min": 0.002681,
- "max": 0.269572,
- "recall-0.025": 0.303983,
- "recall-0.05": 0.813417,
- "recall-0.1": 0.930818,
- "recall-0.15": 0.968553,
- "recall-0.25": 0.997904,
- "recall-0.5": 1.0,
- "num_labels": 477
- },
- "joint_recalls": {
- "num_labels": 6201,
- "recall-0.025": 0.21093,
- "recall-0.05": 0.617,
- "recall-0.1": 0.94211,
- "recall-0.15": 0.98645,
- "recall-0.25": 0.99871,
- "recall-0.5": 1.0
- }
-}
-{
- "total_parts": 6678,
- "correct_parts": 6619,
- "pcp": 0.991165
-}
-```
-
-### Panoptic
-
-```json
-{
- "img_loading": 0.0810738,
- "demosaicing": 0.00128778,
- "avg_time_2d": 0.0430177,
- "avg_time_3d": 0.00061816,
- "fps": 22.26
-}
-{
- "triangulator_calls": 420,
- "init_time": 9.17263e-06,
- "undistort_time": 2.80859e-05,
- "project_time": 4.63262e-08,
- "match_time": 4.00762e-08,
- "pairs_time": 4.43976e-06,
- "pair_scoring_time": 0.000387332,
- "grouping_time": 2.51575e-05,
- "full_time": 8.44224e-05,
- "merge_time": 2.88022e-05,
- "post_time": 2.191e-05,
- "convert_time": 6.62648e-07,
- "total_time": 0.000590614
-}
-{
- "person_nums": {
- "total_frames": 420,
- "total_labels": 1466,
- "total_preds": 1588,
- "considered_empty": 0,
- "valid_preds": 1462,
- "invalid_preds": 126,
- "missing": 4,
- "invalid_fraction": 0.07935,
- "precision": 0.92065,
- "recall": 0.99727,
- "f1": 0.95743,
- "non_empty": 1588
- },
- "mpjpe": {
- "count": 1462,
- "mean": 0.032647,
- "median": 0.029716,
- "std": 0.01527,
- "sem": 0.0004,
- "min": 0.010324,
- "max": 0.173435,
- "recall-0.025": 0.330832,
- "recall-0.05": 0.889495,
- "recall-0.1": 0.989768,
- "recall-0.15": 0.995907,
- "recall-0.25": 0.997271,
- "recall-0.5": 0.997271,
- "num_labels": 1466,
- "ap-0.025": 0.178394,
- "ap-0.05": 0.853362,
- "ap-0.1": 0.979514,
- "ap-0.15": 0.988084,
- "ap-0.25": 0.989861,
- "ap-0.5": 0.989861
- },
- "nose": {
- "count": 1461,
- "mean": 0.015625,
- "median": 0.011556,
- "std": 0.018701,
- "sem": 0.000489,
- "min": 0.001492,
- "max": 0.302115,
- "recall-0.025": 0.901572,
- "recall-0.05": 0.964457,
- "recall-0.1": 0.993848,
- "recall-0.15": 0.995899,
- "recall-0.25": 0.995899,
- "recall-0.5": 0.998633,
- "num_labels": 1463
- },
- "shoulder_left": {
- "count": 1462,
- "mean": 0.016743,
- "median": 0.014836,
- "std": 0.011022,
- "sem": 0.000288,
- "min": 0.001022,
- "max": 0.108094,
- "recall-0.025": 0.836971,
- "recall-0.05": 0.983629,
- "recall-0.1": 0.996589,
- "recall-0.15": 0.997271,
- "recall-0.25": 0.997271,
- "recall-0.5": 0.997271,
- "num_labels": 1466
- },
- "shoulder_right": {
- "count": 1461,
- "mean": 0.016806,
- "median": 0.014481,
- "std": 0.011788,
- "sem": 0.000309,
- "min": 0.000571,
- "max": 0.147482,
- "recall-0.025": 0.838225,
- "recall-0.05": 0.980205,
- "recall-0.1": 0.995904,
- "recall-0.15": 0.99727,
- "recall-0.25": 0.99727,
- "recall-0.5": 0.99727,
- "num_labels": 1465
- },
- "elbow_left": {
- "count": 1461,
- "mean": 0.022878,
- "median": 0.016645,
- "std": 0.021303,
- "sem": 0.000558,
- "min": 0.001625,
- "max": 0.210887,
- "recall-0.025": 0.735154,
- "recall-0.05": 0.913993,
- "recall-0.1": 0.988396,
- "recall-0.15": 0.994539,
- "recall-0.25": 0.99727,
- "recall-0.5": 0.99727,
- "num_labels": 1465
- },
- "elbow_right": {
- "count": 1461,
- "mean": 0.021114,
- "median": 0.015923,
- "std": 0.016509,
- "sem": 0.000432,
- "min": 0.000646,
- "max": 0.165407,
- "recall-0.025": 0.77717,
- "recall-0.05": 0.925496,
- "recall-0.1": 0.997949,
- "recall-0.15": 0.997949,
- "recall-0.25": 0.998633,
- "recall-0.5": 0.998633,
- "num_labels": 1463
- },
- "wrist_left": {
- "count": 1432,
- "mean": 0.036125,
- "median": 0.016999,
- "std": 0.055321,
- "sem": 0.001462,
- "min": 0.001937,
- "max": 0.459424,
- "recall-0.025": 0.665272,
- "recall-0.05": 0.842399,
- "recall-0.1": 0.90516,
- "recall-0.15": 0.953975,
- "recall-0.25": 0.97629,
- "recall-0.5": 0.998605,
- "num_labels": 1434
- },
- "wrist_right": {
- "count": 1455,
- "mean": 0.026799,
- "median": 0.016736,
- "std": 0.033876,
- "sem": 0.000888,
- "min": 0.001247,
- "max": 0.278664,
- "recall-0.025": 0.692995,
- "recall-0.05": 0.885989,
- "recall-0.1": 0.964286,
- "recall-0.15": 0.98283,
- "recall-0.25": 0.995192,
- "recall-0.5": 0.999313,
- "num_labels": 1456
- },
- "hip_left": {
- "count": 1461,
- "mean": 0.035134,
- "median": 0.031398,
- "std": 0.019999,
- "sem": 0.000523,
- "min": 0.002515,
- "max": 0.177406,
- "recall-0.025": 0.339249,
- "recall-0.05": 0.837543,
- "recall-0.1": 0.986348,
- "recall-0.15": 0.995904,
- "recall-0.25": 0.99727,
- "recall-0.5": 0.99727,
- "num_labels": 1465
- },
- "hip_right": {
- "count": 1462,
- "mean": 0.038572,
- "median": 0.033352,
- "std": 0.028142,
- "sem": 0.000736,
- "min": 0.003214,
- "max": 0.460624,
- "recall-0.025": 0.3206,
- "recall-0.05": 0.790587,
- "recall-0.1": 0.96794,
- "recall-0.15": 0.992497,
- "recall-0.25": 0.995907,
- "recall-0.5": 0.997271,
- "num_labels": 1466
- },
- "knee_left": {
- "count": 1461,
- "mean": 0.039333,
- "median": 0.033045,
- "std": 0.035258,
- "sem": 0.000923,
- "min": 0.003964,
- "max": 0.476098,
- "recall-0.025": 0.286007,
- "recall-0.05": 0.799317,
- "recall-0.1": 0.974061,
- "recall-0.15": 0.984983,
- "recall-0.25": 0.989761,
- "recall-0.5": 0.99727,
- "num_labels": 1465
- },
- "knee_right": {
- "count": 1455,
- "mean": 0.038522,
- "median": 0.031532,
- "std": 0.027606,
- "sem": 0.000724,
- "min": 0.004249,
- "max": 0.291018,
- "recall-0.025": 0.348184,
- "recall-0.05": 0.751199,
- "recall-0.1": 0.966415,
- "recall-0.15": 0.990404,
- "recall-0.25": 0.995888,
- "recall-0.5": 0.997258,
- "num_labels": 1459
- },
- "ankle_left": {
- "count": 1458,
- "mean": 0.057085,
- "median": 0.033833,
- "std": 0.063616,
- "sem": 0.001667,
- "min": 0.002162,
- "max": 0.431506,
- "recall-0.025": 0.351333,
- "recall-0.05": 0.660287,
- "recall-0.1": 0.852358,
- "recall-0.15": 0.911825,
- "recall-0.25": 0.969925,
- "recall-0.5": 0.996582,
- "num_labels": 1463
- },
- "ankle_right": {
- "count": 1446,
- "mean": 0.054388,
- "median": 0.030749,
- "std": 0.070352,
- "sem": 0.001851,
- "min": 0.001113,
- "max": 0.497085,
- "recall-0.025": 0.384932,
- "recall-0.05": 0.739726,
- "recall-0.1": 0.858904,
- "recall-0.15": 0.903425,
- "recall-0.25": 0.956849,
- "recall-0.5": 0.990411,
- "num_labels": 1460
- },
- "joint_recalls": {
- "num_labels": 18990,
- "recall-0.025": 0.57478,
- "recall-0.05": 0.85166,
- "recall-0.1": 0.95714,
- "recall-0.15": 0.97657,
- "recall-0.25": 0.9892,
- "recall-0.5": 0.99684
- }
-}
-{
- "total_parts": 20444,
- "correct_parts": 20194,
- "pcp": 0.987771
-}
-```
-
-### H3WB
-
-##### default joints
-
-```json
-{
- "img_loading": 0.038096,
- "demosaicing": 0.000570326,
- "avg_time_2d": 0.0184476,
- "avg_time_3d": 8.38664e-05,
- "fps": 52.3511
-}
-{
- "triangulator_calls": 200,
- "init_time": 7.36142e-06,
- "undistort_time": 6.69951e-06,
- "project_time": 4.096e-08,
- "match_time": 4.032e-08,
- "pairs_time": 5.845e-07,
- "pair_scoring_time": 1.70049e-05,
- "grouping_time": 2.61303e-06,
- "full_time": 2.09906e-05,
- "merge_time": 7.44657e-06,
- "post_time": 1.17096e-05,
- "convert_time": 1.47525e-07,
- "total_time": 7.51791e-05
-}
-{
- "person_nums": {
- "total_frames": 200,
- "total_labels": 200,
- "total_preds": 200,
- "considered_empty": 0,
- "valid_preds": 200,
- "invalid_preds": 0,
- "missing": 0,
- "invalid_fraction": 0.0,
- "precision": 1.0,
- "recall": 1.0,
- "f1": 1.0,
- "non_empty": 200
- },
- "mpjpe": {
- "count": 200,
- "mean": 0.023513,
- "median": 0.021453,
- "std": 0.010644,
- "sem": 0.000755,
- "min": 0.00968,
- "max": 0.093505,
- "recall-0.025": 0.665,
- "recall-0.05": 0.975,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200,
- "ap-0.025": 0.598818,
- "ap-0.05": 0.974228,
- "ap-0.1": 1.0,
- "ap-0.15": 1.0,
- "ap-0.25": 1.0,
- "ap-0.5": 1.0
- },
- "nose": {
- "count": 200,
- "mean": 0.039868,
- "median": 0.03088,
- "std": 0.035438,
- "sem": 0.002512,
- "min": 0.003064,
- "max": 0.25664,
- "recall-0.025": 0.41,
- "recall-0.05": 0.77,
- "recall-0.1": 0.945,
- "recall-0.15": 0.985,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "shoulder_left": {
- "count": 200,
- "mean": 0.018209,
- "median": 0.01532,
- "std": 0.011114,
- "sem": 0.000788,
- "min": 0.00307,
- "max": 0.08137,
- "recall-0.025": 0.805,
- "recall-0.05": 0.985,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "shoulder_right": {
- "count": 200,
- "mean": 0.022296,
- "median": 0.019255,
- "std": 0.01239,
- "sem": 0.000878,
- "min": 0.004945,
- "max": 0.079958,
- "recall-0.025": 0.66,
- "recall-0.05": 0.975,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "elbow_left": {
- "count": 200,
- "mean": 0.015854,
- "median": 0.012731,
- "std": 0.012731,
- "sem": 0.000902,
- "min": 0.002373,
- "max": 0.09088,
- "recall-0.025": 0.845,
- "recall-0.05": 0.975,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "elbow_right": {
- "count": 200,
- "mean": 0.021291,
- "median": 0.014584,
- "std": 0.01986,
- "sem": 0.001408,
- "min": 0.000743,
- "max": 0.112112,
- "recall-0.025": 0.715,
- "recall-0.05": 0.93,
- "recall-0.1": 0.99,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "wrist_left": {
- "count": 200,
- "mean": 0.024887,
- "median": 0.017495,
- "std": 0.029797,
- "sem": 0.002112,
- "min": 0.00217,
- "max": 0.27968,
- "recall-0.025": 0.685,
- "recall-0.05": 0.915,
- "recall-0.1": 0.985,
- "recall-0.15": 0.99,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "wrist_right": {
- "count": 200,
- "mean": 0.030128,
- "median": 0.022392,
- "std": 0.026076,
- "sem": 0.001848,
- "min": 0.001982,
- "max": 0.15564,
- "recall-0.025": 0.525,
- "recall-0.05": 0.855,
- "recall-0.1": 0.965,
- "recall-0.15": 0.99,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "hip_left": {
- "count": 200,
- "mean": 0.030835,
- "median": 0.028464,
- "std": 0.015695,
- "sem": 0.001113,
- "min": 0.003129,
- "max": 0.092047,
- "recall-0.025": 0.415,
- "recall-0.05": 0.885,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "hip_right": {
- "count": 200,
- "mean": 0.029373,
- "median": 0.026892,
- "std": 0.013671,
- "sem": 0.000969,
- "min": 0.003684,
- "max": 0.062972,
- "recall-0.025": 0.435,
- "recall-0.05": 0.895,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "knee_left": {
- "count": 200,
- "mean": 0.020261,
- "median": 0.013787,
- "std": 0.026966,
- "sem": 0.001912,
- "min": 0.002161,
- "max": 0.321862,
- "recall-0.025": 0.78,
- "recall-0.05": 0.96,
- "recall-0.1": 0.99,
- "recall-0.15": 0.995,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "knee_right": {
- "count": 200,
- "mean": 0.018755,
- "median": 0.013997,
- "std": 0.031466,
- "sem": 0.002231,
- "min": 0.001406,
- "max": 0.423445,
- "recall-0.025": 0.84,
- "recall-0.05": 0.955,
- "recall-0.1": 0.995,
- "recall-0.15": 0.995,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "ankle_left": {
- "count": 200,
- "mean": 0.015587,
- "median": 0.010735,
- "std": 0.026038,
- "sem": 0.001846,
- "min": 0.003313,
- "max": 0.329013,
- "recall-0.025": 0.9,
- "recall-0.05": 0.97,
- "recall-0.1": 0.99,
- "recall-0.15": 0.995,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "ankle_right": {
- "count": 199,
- "mean": 0.015906,
- "median": 0.010047,
- "std": 0.027685,
- "sem": 0.001968,
- "min": 0.000852,
- "max": 0.34465,
- "recall-0.025": 0.89,
- "recall-0.05": 0.965,
- "recall-0.1": 0.985,
- "recall-0.15": 0.99,
- "recall-0.25": 0.99,
- "recall-0.5": 0.995,
- "num_labels": 200
- },
- "joint_recalls": {
- "num_labels": 2600,
- "recall-0.025": 0.685,
- "recall-0.05": 0.92577,
- "recall-0.1": 0.98808,
- "recall-0.15": 0.99538,
- "recall-0.25": 0.99731,
- "recall-0.5": 0.99962
- }
-}
-{
- "total_parts": 2800,
- "correct_parts": 2794,
- "pcp": 0.997857
-}
-```
-
-##### whole-body
-
-```json
-{
- "img_loading": 0.0380362,
- "demosaicing": 0.000576236,
- "avg_time_2d": 0.0356966,
- "avg_time_3d": 0.000274105,
- "fps": 27.3621
-}
-{
- "triangulator_calls": 200,
- "init_time": 7.56849e-06,
- "undistort_time": 4.34473e-05,
- "project_time": 4.16e-08,
- "match_time": 4.0805e-08,
- "pairs_time": 6.84805e-07,
- "pair_scoring_time": 1.78283e-05,
- "grouping_time": 2.88577e-06,
- "full_time": 0.000115345,
- "merge_time": 2.88308e-05,
- "post_time": 4.59524e-05,
- "convert_time": 1.0688e-06,
- "total_time": 0.000264242
-}
-{
- "person_nums": {
- "total_frames": 200,
- "total_labels": 200,
- "total_preds": 200,
- "considered_empty": 0,
- "valid_preds": 200,
- "invalid_preds": 0,
- "missing": 0,
- "invalid_fraction": 0.0,
- "precision": 1.0,
- "recall": 1.0,
- "f1": 1.0,
- "non_empty": 200
- },
- "mpjpe": {
- "count": 200,
- "mean": 0.04303,
- "median": 0.039269,
- "std": 0.014132,
- "sem": 0.001002,
- "min": 0.021539,
- "max": 0.086984,
- "recall-0.025": 0.045,
- "recall-0.05": 0.745,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200,
- "ap-0.025": 0.003881,
- "ap-0.05": 0.662439,
- "ap-0.1": 1.0,
- "ap-0.15": 1.0,
- "ap-0.25": 1.0,
- "ap-0.5": 1.0
- },
- "nose": {
- "count": 200,
- "mean": 0.05,
- "median": 0.041294,
- "std": 0.036001,
- "sem": 0.002552,
- "min": 0.005973,
- "max": 0.236403,
- "recall-0.025": 0.275,
- "recall-0.05": 0.62,
- "recall-0.1": 0.895,
- "recall-0.15": 0.985,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "eye_left": {
- "count": 200,
- "mean": 0.044288,
- "median": 0.037923,
- "std": 0.028209,
- "sem": 0.002,
- "min": 0.00171,
- "max": 0.137155,
- "recall-0.025": 0.32,
- "recall-0.05": 0.635,
- "recall-0.1": 0.96,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "eye_right": {
- "count": 200,
- "mean": 0.056325,
- "median": 0.046619,
- "std": 0.038686,
- "sem": 0.002742,
- "min": 0.007166,
- "max": 0.226585,
- "recall-0.025": 0.21,
- "recall-0.05": 0.54,
- "recall-0.1": 0.88,
- "recall-0.15": 0.98,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "ear_left": {
- "count": 200,
- "mean": 0.034649,
- "median": 0.028446,
- "std": 0.025909,
- "sem": 0.001837,
- "min": 0.003826,
- "max": 0.175177,
- "recall-0.025": 0.425,
- "recall-0.05": 0.815,
- "recall-0.1": 0.975,
- "recall-0.15": 0.99,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "ear_right": {
- "count": 200,
- "mean": 0.042026,
- "median": 0.037544,
- "std": 0.026198,
- "sem": 0.001857,
- "min": 0.003791,
- "max": 0.128287,
- "recall-0.025": 0.305,
- "recall-0.05": 0.65,
- "recall-0.1": 0.975,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "shoulder_left": {
- "count": 200,
- "mean": 0.019929,
- "median": 0.01693,
- "std": 0.011985,
- "sem": 0.00085,
- "min": 0.001094,
- "max": 0.095807,
- "recall-0.025": 0.75,
- "recall-0.05": 0.96,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "shoulder_right": {
- "count": 200,
- "mean": 0.024932,
- "median": 0.022244,
- "std": 0.013747,
- "sem": 0.000975,
- "min": 0.00522,
- "max": 0.080711,
- "recall-0.025": 0.58,
- "recall-0.05": 0.935,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "elbow_left": {
- "count": 200,
- "mean": 0.020252,
- "median": 0.015771,
- "std": 0.01732,
- "sem": 0.001228,
- "min": 0.001505,
- "max": 0.105529,
- "recall-0.025": 0.775,
- "recall-0.05": 0.95,
- "recall-0.1": 0.985,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "elbow_right": {
- "count": 200,
- "mean": 0.025033,
- "median": 0.017226,
- "std": 0.025091,
- "sem": 0.001779,
- "min": 0.002717,
- "max": 0.200619,
- "recall-0.025": 0.68,
- "recall-0.05": 0.885,
- "recall-0.1": 0.975,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "wrist_left": {
- "count": 200,
- "mean": 0.027222,
- "median": 0.019391,
- "std": 0.025146,
- "sem": 0.001783,
- "min": 0.002502,
- "max": 0.164594,
- "recall-0.025": 0.64,
- "recall-0.05": 0.885,
- "recall-0.1": 0.975,
- "recall-0.15": 0.99,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "wrist_right": {
- "count": 200,
- "mean": 0.041146,
- "median": 0.025616,
- "std": 0.048429,
- "sem": 0.003433,
- "min": 0.003859,
- "max": 0.404037,
- "recall-0.025": 0.485,
- "recall-0.05": 0.78,
- "recall-0.1": 0.925,
- "recall-0.15": 0.95,
- "recall-0.25": 0.99,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "hip_left": {
- "count": 200,
- "mean": 0.030428,
- "median": 0.028178,
- "std": 0.014864,
- "sem": 0.001054,
- "min": 0.002594,
- "max": 0.072983,
- "recall-0.025": 0.4,
- "recall-0.05": 0.87,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "hip_right": {
- "count": 200,
- "mean": 0.030707,
- "median": 0.026996,
- "std": 0.016509,
- "sem": 0.00117,
- "min": 0.004434,
- "max": 0.084628,
- "recall-0.025": 0.445,
- "recall-0.05": 0.85,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "knee_left": {
- "count": 200,
- "mean": 0.020818,
- "median": 0.016714,
- "std": 0.019284,
- "sem": 0.001367,
- "min": 0.000745,
- "max": 0.165307,
- "recall-0.025": 0.75,
- "recall-0.05": 0.965,
- "recall-0.1": 0.99,
- "recall-0.15": 0.99,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "knee_right": {
- "count": 200,
- "mean": 0.02654,
- "median": 0.014401,
- "std": 0.047846,
- "sem": 0.003392,
- "min": 0.002234,
- "max": 0.348059,
- "recall-0.025": 0.775,
- "recall-0.05": 0.925,
- "recall-0.1": 0.955,
- "recall-0.15": 0.975,
- "recall-0.25": 0.98,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "ankle_left": {
- "count": 200,
- "mean": 0.016566,
- "median": 0.011593,
- "std": 0.019664,
- "sem": 0.001394,
- "min": 0.001291,
- "max": 0.139635,
- "recall-0.025": 0.845,
- "recall-0.05": 0.965,
- "recall-0.1": 0.98,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "ankle_right": {
- "count": 200,
- "mean": 0.018111,
- "median": 0.013128,
- "std": 0.021771,
- "sem": 0.001543,
- "min": 0.001292,
- "max": 0.172154,
- "recall-0.025": 0.845,
- "recall-0.05": 0.965,
- "recall-0.1": 0.98,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "foot_toe_big_left": {
- "count": 200,
- "mean": 0.029063,
- "median": 0.021991,
- "std": 0.029218,
- "sem": 0.002071,
- "min": 0.00125,
- "max": 0.217976,
- "recall-0.025": 0.58,
- "recall-0.05": 0.905,
- "recall-0.1": 0.965,
- "recall-0.15": 0.985,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "foot_toe_small_left": {
- "count": 200,
- "mean": 0.026559,
- "median": 0.019642,
- "std": 0.031111,
- "sem": 0.002205,
- "min": 0.003994,
- "max": 0.2917,
- "recall-0.025": 0.67,
- "recall-0.05": 0.935,
- "recall-0.1": 0.96,
- "recall-0.15": 0.98,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "foot_heel_left": {
- "count": 200,
- "mean": 0.02443,
- "median": 0.017401,
- "std": 0.02463,
- "sem": 0.001746,
- "min": 0.002178,
- "max": 0.21736,
- "recall-0.025": 0.68,
- "recall-0.05": 0.935,
- "recall-0.1": 0.98,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "foot_toe_big_right": {
- "count": 200,
- "mean": 0.031939,
- "median": 0.024265,
- "std": 0.031535,
- "sem": 0.002235,
- "min": 0.001342,
- "max": 0.262809,
- "recall-0.025": 0.52,
- "recall-0.05": 0.87,
- "recall-0.1": 0.96,
- "recall-0.15": 0.99,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "foot_toe_small_right": {
- "count": 200,
- "mean": 0.032333,
- "median": 0.024078,
- "std": 0.032025,
- "sem": 0.00227,
- "min": 0.00475,
- "max": 0.220805,
- "recall-0.025": 0.53,
- "recall-0.05": 0.87,
- "recall-0.1": 0.965,
- "recall-0.15": 0.98,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "foot_heel_right": {
- "count": 200,
- "mean": 0.023705,
- "median": 0.017291,
- "std": 0.020747,
- "sem": 0.001471,
- "min": 0.001192,
- "max": 0.135471,
- "recall-0.025": 0.685,
- "recall-0.05": 0.915,
- "recall-0.1": 0.98,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_right_1": {
- "count": 199,
- "mean": 0.090186,
- "median": 0.081091,
- "std": 0.042041,
- "sem": 0.002988,
- "min": 0.029641,
- "max": 0.296506,
- "recall-0.025": 0.0,
- "recall-0.05": 0.095,
- "recall-0.1": 0.71,
- "recall-0.15": 0.91,
- "recall-0.25": 0.98,
- "recall-0.5": 0.995,
- "num_labels": 200
- },
- "face_jaw_right_2": {
- "count": 200,
- "mean": 0.086496,
- "median": 0.080626,
- "std": 0.041034,
- "sem": 0.002909,
- "min": 0.022659,
- "max": 0.291609,
- "recall-0.025": 0.005,
- "recall-0.05": 0.145,
- "recall-0.1": 0.7,
- "recall-0.15": 0.905,
- "recall-0.25": 0.99,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_right_3": {
- "count": 200,
- "mean": 0.090164,
- "median": 0.080694,
- "std": 0.047646,
- "sem": 0.003378,
- "min": 0.014401,
- "max": 0.240963,
- "recall-0.025": 0.04,
- "recall-0.05": 0.185,
- "recall-0.1": 0.665,
- "recall-0.15": 0.875,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_right_4": {
- "count": 200,
- "mean": 0.090295,
- "median": 0.077929,
- "std": 0.047947,
- "sem": 0.003399,
- "min": 0.006873,
- "max": 0.243925,
- "recall-0.025": 0.035,
- "recall-0.05": 0.185,
- "recall-0.1": 0.66,
- "recall-0.15": 0.88,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_right_5": {
- "count": 200,
- "mean": 0.087022,
- "median": 0.073364,
- "std": 0.047157,
- "sem": 0.003343,
- "min": 0.004597,
- "max": 0.244694,
- "recall-0.025": 0.05,
- "recall-0.05": 0.205,
- "recall-0.1": 0.685,
- "recall-0.15": 0.875,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_right_6": {
- "count": 200,
- "mean": 0.078144,
- "median": 0.06802,
- "std": 0.040178,
- "sem": 0.002848,
- "min": 0.008041,
- "max": 0.219142,
- "recall-0.025": 0.05,
- "recall-0.05": 0.235,
- "recall-0.1": 0.755,
- "recall-0.15": 0.935,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_right_7": {
- "count": 200,
- "mean": 0.068325,
- "median": 0.056898,
- "std": 0.040372,
- "sem": 0.002862,
- "min": 0.008542,
- "max": 0.226815,
- "recall-0.025": 0.06,
- "recall-0.05": 0.425,
- "recall-0.1": 0.815,
- "recall-0.15": 0.95,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_right_8": {
- "count": 200,
- "mean": 0.056317,
- "median": 0.045115,
- "std": 0.045669,
- "sem": 0.003237,
- "min": 0.008879,
- "max": 0.483117,
- "recall-0.025": 0.19,
- "recall-0.05": 0.545,
- "recall-0.1": 0.935,
- "recall-0.15": 0.965,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_middle": {
- "count": 200,
- "mean": 0.04195,
- "median": 0.03765,
- "std": 0.025286,
- "sem": 0.001793,
- "min": 0.005106,
- "max": 0.112937,
- "recall-0.025": 0.33,
- "recall-0.05": 0.655,
- "recall-0.1": 0.96,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_left_1": {
- "count": 200,
- "mean": 0.049126,
- "median": 0.038409,
- "std": 0.031014,
- "sem": 0.002198,
- "min": 0.006884,
- "max": 0.208441,
- "recall-0.025": 0.225,
- "recall-0.05": 0.61,
- "recall-0.1": 0.935,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_left_2": {
- "count": 200,
- "mean": 0.055484,
- "median": 0.045459,
- "std": 0.034806,
- "sem": 0.002467,
- "min": 0.014189,
- "max": 0.238655,
- "recall-0.025": 0.13,
- "recall-0.05": 0.575,
- "recall-0.1": 0.89,
- "recall-0.15": 0.975,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_left_3": {
- "count": 200,
- "mean": 0.064117,
- "median": 0.052038,
- "std": 0.039353,
- "sem": 0.00279,
- "min": 0.004509,
- "max": 0.267647,
- "recall-0.025": 0.055,
- "recall-0.05": 0.465,
- "recall-0.1": 0.87,
- "recall-0.15": 0.955,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_left_4": {
- "count": 200,
- "mean": 0.070067,
- "median": 0.060842,
- "std": 0.046212,
- "sem": 0.003276,
- "min": 0.009068,
- "max": 0.489191,
- "recall-0.025": 0.035,
- "recall-0.05": 0.355,
- "recall-0.1": 0.845,
- "recall-0.15": 0.955,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_left_5": {
- "count": 199,
- "mean": 0.071107,
- "median": 0.060703,
- "std": 0.038609,
- "sem": 0.002744,
- "min": 0.002978,
- "max": 0.203766,
- "recall-0.025": 0.03,
- "recall-0.05": 0.33,
- "recall-0.1": 0.805,
- "recall-0.15": 0.935,
- "recall-0.25": 0.995,
- "recall-0.5": 0.995,
- "num_labels": 200
- },
- "face_jaw_left_6": {
- "count": 200,
- "mean": 0.071863,
- "median": 0.061698,
- "std": 0.042063,
- "sem": 0.002982,
- "min": 0.00737,
- "max": 0.248067,
- "recall-0.025": 0.06,
- "recall-0.05": 0.365,
- "recall-0.1": 0.81,
- "recall-0.15": 0.94,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_left_7": {
- "count": 200,
- "mean": 0.070767,
- "median": 0.060658,
- "std": 0.038384,
- "sem": 0.002721,
- "min": 0.007471,
- "max": 0.193507,
- "recall-0.025": 0.05,
- "recall-0.05": 0.37,
- "recall-0.1": 0.79,
- "recall-0.15": 0.95,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_jaw_left_8": {
- "count": 200,
- "mean": 0.069908,
- "median": 0.063692,
- "std": 0.037747,
- "sem": 0.002676,
- "min": 0.004256,
- "max": 0.205657,
- "recall-0.025": 0.04,
- "recall-0.05": 0.375,
- "recall-0.1": 0.805,
- "recall-0.15": 0.955,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eyebrow_right_1": {
- "count": 200,
- "mean": 0.065137,
- "median": 0.052178,
- "std": 0.046069,
- "sem": 0.003266,
- "min": 0.00491,
- "max": 0.304229,
- "recall-0.025": 0.09,
- "recall-0.05": 0.47,
- "recall-0.1": 0.85,
- "recall-0.15": 0.96,
- "recall-0.25": 0.985,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eyebrow_right_2": {
- "count": 200,
- "mean": 0.056394,
- "median": 0.044664,
- "std": 0.04334,
- "sem": 0.003072,
- "min": 0.00459,
- "max": 0.344106,
- "recall-0.025": 0.215,
- "recall-0.05": 0.53,
- "recall-0.1": 0.905,
- "recall-0.15": 0.955,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eyebrow_right_3": {
- "count": 200,
- "mean": 0.050022,
- "median": 0.037612,
- "std": 0.040997,
- "sem": 0.002906,
- "min": 0.003698,
- "max": 0.326209,
- "recall-0.025": 0.29,
- "recall-0.05": 0.65,
- "recall-0.1": 0.9,
- "recall-0.15": 0.97,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eyebrow_right_4": {
- "count": 200,
- "mean": 0.042468,
- "median": 0.033034,
- "std": 0.034806,
- "sem": 0.002467,
- "min": 0.002955,
- "max": 0.275102,
- "recall-0.025": 0.365,
- "recall-0.05": 0.74,
- "recall-0.1": 0.935,
- "recall-0.15": 0.975,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eyebrow_right_5": {
- "count": 200,
- "mean": 0.037063,
- "median": 0.029386,
- "std": 0.03015,
- "sem": 0.002137,
- "min": 0.004151,
- "max": 0.267448,
- "recall-0.025": 0.395,
- "recall-0.05": 0.79,
- "recall-0.1": 0.965,
- "recall-0.15": 0.995,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eyebrow_left_1": {
- "count": 200,
- "mean": 0.03367,
- "median": 0.024625,
- "std": 0.030311,
- "sem": 0.002149,
- "min": 0.00367,
- "max": 0.212602,
- "recall-0.025": 0.505,
- "recall-0.05": 0.825,
- "recall-0.1": 0.97,
- "recall-0.15": 0.985,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eyebrow_left_2": {
- "count": 200,
- "mean": 0.032057,
- "median": 0.025607,
- "std": 0.025639,
- "sem": 0.001818,
- "min": 0.003148,
- "max": 0.179948,
- "recall-0.025": 0.48,
- "recall-0.05": 0.825,
- "recall-0.1": 0.98,
- "recall-0.15": 0.99,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eyebrow_left_3": {
- "count": 200,
- "mean": 0.033774,
- "median": 0.026215,
- "std": 0.027979,
- "sem": 0.001983,
- "min": 0.002209,
- "max": 0.173778,
- "recall-0.025": 0.49,
- "recall-0.05": 0.8,
- "recall-0.1": 0.975,
- "recall-0.15": 0.99,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eyebrow_left_4": {
- "count": 200,
- "mean": 0.036848,
- "median": 0.028273,
- "std": 0.028712,
- "sem": 0.002035,
- "min": 0.00303,
- "max": 0.230255,
- "recall-0.025": 0.425,
- "recall-0.05": 0.76,
- "recall-0.1": 0.97,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eyebrow_left_5": {
- "count": 200,
- "mean": 0.042395,
- "median": 0.033633,
- "std": 0.029695,
- "sem": 0.002105,
- "min": 0.00347,
- "max": 0.193113,
- "recall-0.025": 0.325,
- "recall-0.05": 0.67,
- "recall-0.1": 0.95,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_nose_1": {
- "count": 200,
- "mean": 0.032583,
- "median": 0.025128,
- "std": 0.027478,
- "sem": 0.001948,
- "min": 0.004162,
- "max": 0.243484,
- "recall-0.025": 0.495,
- "recall-0.05": 0.855,
- "recall-0.1": 0.98,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_nose_2": {
- "count": 200,
- "mean": 0.037432,
- "median": 0.026723,
- "std": 0.034646,
- "sem": 0.002456,
- "min": 0.003926,
- "max": 0.21618,
- "recall-0.025": 0.43,
- "recall-0.05": 0.815,
- "recall-0.1": 0.955,
- "recall-0.15": 0.975,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_nose_3": {
- "count": 200,
- "mean": 0.039218,
- "median": 0.030531,
- "std": 0.031833,
- "sem": 0.002257,
- "min": 0.004975,
- "max": 0.206698,
- "recall-0.025": 0.38,
- "recall-0.05": 0.77,
- "recall-0.1": 0.94,
- "recall-0.15": 0.98,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_nose_4": {
- "count": 200,
- "mean": 0.042108,
- "median": 0.031621,
- "std": 0.034613,
- "sem": 0.002454,
- "min": 0.004579,
- "max": 0.224392,
- "recall-0.025": 0.385,
- "recall-0.05": 0.72,
- "recall-0.1": 0.92,
- "recall-0.15": 0.98,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_nose_5": {
- "count": 200,
- "mean": 0.050299,
- "median": 0.040057,
- "std": 0.042128,
- "sem": 0.002986,
- "min": 0.005103,
- "max": 0.397263,
- "recall-0.025": 0.26,
- "recall-0.05": 0.65,
- "recall-0.1": 0.92,
- "recall-0.15": 0.96,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_nose_6": {
- "count": 200,
- "mean": 0.044236,
- "median": 0.034263,
- "std": 0.031104,
- "sem": 0.002205,
- "min": 0.006119,
- "max": 0.187049,
- "recall-0.025": 0.31,
- "recall-0.05": 0.675,
- "recall-0.1": 0.935,
- "recall-0.15": 0.985,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_nose_7": {
- "count": 200,
- "mean": 0.037019,
- "median": 0.03075,
- "std": 0.026101,
- "sem": 0.00185,
- "min": 0.006775,
- "max": 0.153869,
- "recall-0.025": 0.405,
- "recall-0.05": 0.76,
- "recall-0.1": 0.97,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_nose_8": {
- "count": 200,
- "mean": 0.036512,
- "median": 0.029187,
- "std": 0.024736,
- "sem": 0.001753,
- "min": 0.005065,
- "max": 0.145505,
- "recall-0.025": 0.415,
- "recall-0.05": 0.76,
- "recall-0.1": 0.98,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_nose_9": {
- "count": 200,
- "mean": 0.037414,
- "median": 0.029256,
- "std": 0.028403,
- "sem": 0.002013,
- "min": 0.00169,
- "max": 0.15322,
- "recall-0.025": 0.435,
- "recall-0.05": 0.765,
- "recall-0.1": 0.955,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eye_right_1": {
- "count": 200,
- "mean": 0.05918,
- "median": 0.047236,
- "std": 0.038971,
- "sem": 0.002763,
- "min": 0.007489,
- "max": 0.235613,
- "recall-0.025": 0.15,
- "recall-0.05": 0.515,
- "recall-0.1": 0.885,
- "recall-0.15": 0.96,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eye_right_2": {
- "count": 200,
- "mean": 0.051284,
- "median": 0.043347,
- "std": 0.033688,
- "sem": 0.002388,
- "min": 0.003984,
- "max": 0.210391,
- "recall-0.025": 0.195,
- "recall-0.05": 0.605,
- "recall-0.1": 0.91,
- "recall-0.15": 0.985,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eye_right_3": {
- "count": 200,
- "mean": 0.045563,
- "median": 0.037221,
- "std": 0.031299,
- "sem": 0.002219,
- "min": 0.004218,
- "max": 0.186976,
- "recall-0.025": 0.285,
- "recall-0.05": 0.665,
- "recall-0.1": 0.94,
- "recall-0.15": 0.985,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eye_right_4": {
- "count": 200,
- "mean": 0.040261,
- "median": 0.032768,
- "std": 0.030755,
- "sem": 0.00218,
- "min": 0.003566,
- "max": 0.276559,
- "recall-0.025": 0.355,
- "recall-0.05": 0.75,
- "recall-0.1": 0.96,
- "recall-0.15": 0.99,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eye_right_5": {
- "count": 200,
- "mean": 0.042503,
- "median": 0.035272,
- "std": 0.027721,
- "sem": 0.001965,
- "min": 0.002076,
- "max": 0.177924,
- "recall-0.025": 0.29,
- "recall-0.05": 0.71,
- "recall-0.1": 0.95,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eye_right_6": {
- "count": 200,
- "mean": 0.051571,
- "median": 0.040153,
- "std": 0.037041,
- "sem": 0.002626,
- "min": 0.006639,
- "max": 0.213775,
- "recall-0.025": 0.245,
- "recall-0.05": 0.605,
- "recall-0.1": 0.9,
- "recall-0.15": 0.97,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eye_left_1": {
- "count": 200,
- "mean": 0.032026,
- "median": 0.0253,
- "std": 0.022861,
- "sem": 0.001621,
- "min": 0.005487,
- "max": 0.151369,
- "recall-0.025": 0.495,
- "recall-0.05": 0.82,
- "recall-0.1": 0.975,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eye_left_2": {
- "count": 200,
- "mean": 0.032216,
- "median": 0.025704,
- "std": 0.023708,
- "sem": 0.001681,
- "min": 0.003795,
- "max": 0.122308,
- "recall-0.025": 0.475,
- "recall-0.05": 0.82,
- "recall-0.1": 0.98,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eye_left_3": {
- "count": 200,
- "mean": 0.03404,
- "median": 0.024649,
- "std": 0.027985,
- "sem": 0.001984,
- "min": 0.001734,
- "max": 0.165697,
- "recall-0.025": 0.51,
- "recall-0.05": 0.825,
- "recall-0.1": 0.96,
- "recall-0.15": 0.99,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eye_left_4": {
- "count": 200,
- "mean": 0.037922,
- "median": 0.028656,
- "std": 0.029045,
- "sem": 0.002059,
- "min": 0.00163,
- "max": 0.169992,
- "recall-0.025": 0.425,
- "recall-0.05": 0.775,
- "recall-0.1": 0.935,
- "recall-0.15": 0.99,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eye_left_5": {
- "count": 200,
- "mean": 0.035021,
- "median": 0.027634,
- "std": 0.026689,
- "sem": 0.001892,
- "min": 0.00109,
- "max": 0.147629,
- "recall-0.025": 0.455,
- "recall-0.05": 0.775,
- "recall-0.1": 0.965,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_eye_left_6": {
- "count": 200,
- "mean": 0.033258,
- "median": 0.02609,
- "std": 0.023644,
- "sem": 0.001676,
- "min": 0.003624,
- "max": 0.125818,
- "recall-0.025": 0.475,
- "recall-0.05": 0.815,
- "recall-0.1": 0.975,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_1": {
- "count": 200,
- "mean": 0.052417,
- "median": 0.039059,
- "std": 0.045006,
- "sem": 0.00319,
- "min": 0.00469,
- "max": 0.413482,
- "recall-0.025": 0.28,
- "recall-0.05": 0.595,
- "recall-0.1": 0.9,
- "recall-0.15": 0.975,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_2": {
- "count": 200,
- "mean": 0.043331,
- "median": 0.035459,
- "std": 0.031829,
- "sem": 0.002256,
- "min": 0.004419,
- "max": 0.219084,
- "recall-0.025": 0.35,
- "recall-0.05": 0.67,
- "recall-0.1": 0.94,
- "recall-0.15": 0.985,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_3": {
- "count": 200,
- "mean": 0.038693,
- "median": 0.031125,
- "std": 0.029204,
- "sem": 0.00207,
- "min": 0.004738,
- "max": 0.194787,
- "recall-0.025": 0.39,
- "recall-0.05": 0.76,
- "recall-0.1": 0.96,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_4": {
- "count": 200,
- "mean": 0.037193,
- "median": 0.027998,
- "std": 0.030438,
- "sem": 0.002158,
- "min": 0.003016,
- "max": 0.216648,
- "recall-0.025": 0.4,
- "recall-0.05": 0.76,
- "recall-0.1": 0.965,
- "recall-0.15": 0.985,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_5": {
- "count": 200,
- "mean": 0.0362,
- "median": 0.029058,
- "std": 0.026208,
- "sem": 0.001858,
- "min": 0.006694,
- "max": 0.153436,
- "recall-0.025": 0.43,
- "recall-0.05": 0.785,
- "recall-0.1": 0.97,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_6": {
- "count": 200,
- "mean": 0.033512,
- "median": 0.027338,
- "std": 0.022872,
- "sem": 0.001621,
- "min": 0.003556,
- "max": 0.125841,
- "recall-0.025": 0.435,
- "recall-0.05": 0.815,
- "recall-0.1": 0.98,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_7": {
- "count": 200,
- "mean": 0.037067,
- "median": 0.028309,
- "std": 0.026543,
- "sem": 0.001882,
- "min": 0.002307,
- "max": 0.164978,
- "recall-0.025": 0.425,
- "recall-0.05": 0.755,
- "recall-0.1": 0.975,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_8": {
- "count": 200,
- "mean": 0.035943,
- "median": 0.027546,
- "std": 0.029331,
- "sem": 0.002079,
- "min": 0.004591,
- "max": 0.25722,
- "recall-0.025": 0.46,
- "recall-0.05": 0.765,
- "recall-0.1": 0.975,
- "recall-0.15": 0.99,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_9": {
- "count": 200,
- "mean": 0.035293,
- "median": 0.029039,
- "std": 0.02704,
- "sem": 0.001917,
- "min": 0.00276,
- "max": 0.190415,
- "recall-0.025": 0.445,
- "recall-0.05": 0.765,
- "recall-0.1": 0.98,
- "recall-0.15": 0.99,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_10": {
- "count": 200,
- "mean": 0.038797,
- "median": 0.028855,
- "std": 0.033653,
- "sem": 0.002386,
- "min": 0.005085,
- "max": 0.294249,
- "recall-0.025": 0.43,
- "recall-0.05": 0.73,
- "recall-0.1": 0.965,
- "recall-0.15": 0.99,
- "recall-0.25": 0.995,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_11": {
- "count": 200,
- "mean": 0.041176,
- "median": 0.033584,
- "std": 0.027888,
- "sem": 0.001977,
- "min": 0.006178,
- "max": 0.224664,
- "recall-0.025": 0.325,
- "recall-0.05": 0.69,
- "recall-0.1": 0.97,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_12": {
- "count": 200,
- "mean": 0.04335,
- "median": 0.035058,
- "std": 0.029542,
- "sem": 0.002094,
- "min": 0.004884,
- "max": 0.221595,
- "recall-0.025": 0.335,
- "recall-0.05": 0.66,
- "recall-0.1": 0.95,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_13": {
- "count": 199,
- "mean": 0.049791,
- "median": 0.036583,
- "std": 0.037244,
- "sem": 0.002647,
- "min": 0.001204,
- "max": 0.201367,
- "recall-0.025": 0.29,
- "recall-0.05": 0.615,
- "recall-0.1": 0.89,
- "recall-0.15": 0.98,
- "recall-0.25": 0.995,
- "recall-0.5": 0.995,
- "num_labels": 200
- },
- "face_mouth_14": {
- "count": 200,
- "mean": 0.042289,
- "median": 0.034645,
- "std": 0.03222,
- "sem": 0.002284,
- "min": 0.007891,
- "max": 0.22009,
- "recall-0.025": 0.325,
- "recall-0.05": 0.705,
- "recall-0.1": 0.955,
- "recall-0.15": 0.985,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_15": {
- "count": 200,
- "mean": 0.037423,
- "median": 0.032205,
- "std": 0.026285,
- "sem": 0.001863,
- "min": 0.003932,
- "max": 0.17102,
- "recall-0.025": 0.4,
- "recall-0.05": 0.74,
- "recall-0.1": 0.975,
- "recall-0.15": 0.99,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_16": {
- "count": 200,
- "mean": 0.033631,
- "median": 0.028634,
- "std": 0.021759,
- "sem": 0.001542,
- "min": 0.003328,
- "max": 0.118601,
- "recall-0.025": 0.42,
- "recall-0.05": 0.8,
- "recall-0.1": 0.995,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_17": {
- "count": 200,
- "mean": 0.037143,
- "median": 0.027897,
- "std": 0.026863,
- "sem": 0.001904,
- "min": 0.003264,
- "max": 0.161595,
- "recall-0.025": 0.42,
- "recall-0.05": 0.76,
- "recall-0.1": 0.97,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_18": {
- "count": 200,
- "mean": 0.032196,
- "median": 0.025563,
- "std": 0.024801,
- "sem": 0.001758,
- "min": 0.002826,
- "max": 0.200336,
- "recall-0.025": 0.48,
- "recall-0.05": 0.835,
- "recall-0.1": 0.985,
- "recall-0.15": 0.995,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_19": {
- "count": 200,
- "mean": 0.033841,
- "median": 0.02622,
- "std": 0.02801,
- "sem": 0.001986,
- "min": 0.002484,
- "max": 0.225828,
- "recall-0.025": 0.475,
- "recall-0.05": 0.785,
- "recall-0.1": 0.97,
- "recall-0.15": 0.99,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "face_mouth_20": {
- "count": 200,
- "mean": 0.03805,
- "median": 0.029733,
- "std": 0.028118,
- "sem": 0.001993,
- "min": 0.006261,
- "max": 0.225434,
- "recall-0.025": 0.43,
- "recall-0.05": 0.72,
- "recall-0.1": 0.965,
- "recall-0.15": 0.99,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "hand_wrist_left": {
- "count": 200,
- "mean": 0.034222,
- "median": 0.021707,
- "std": 0.037783,
- "sem": 0.002678,
- "min": 0.001226,
- "max": 0.181711,
- "recall-0.025": 0.575,
- "recall-0.05": 0.83,
- "recall-0.1": 0.915,
- "recall-0.15": 0.965,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "hand_wrist_right": {
- "count": 200,
- "mean": 0.042875,
- "median": 0.023659,
- "std": 0.056983,
- "sem": 0.004039,
- "min": 0.003907,
- "max": 0.386514,
- "recall-0.025": 0.53,
- "recall-0.05": 0.785,
- "recall-0.1": 0.905,
- "recall-0.15": 0.95,
- "recall-0.25": 0.975,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "hip_middle": {
- "count": 200,
- "mean": 0.029232,
- "median": 0.025708,
- "std": 0.015173,
- "sem": 0.001076,
- "min": 0.002008,
- "max": 0.099106,
- "recall-0.025": 0.47,
- "recall-0.05": 0.875,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "shoulder_middle": {
- "count": 200,
- "mean": 0.018579,
- "median": 0.016433,
- "std": 0.009356,
- "sem": 0.000663,
- "min": 0.002107,
- "max": 0.054166,
- "recall-0.025": 0.78,
- "recall-0.05": 0.995,
- "recall-0.1": 1.0,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "head": {
- "count": 200,
- "mean": 0.031422,
- "median": 0.028525,
- "std": 0.019139,
- "sem": 0.001357,
- "min": 0.003049,
- "max": 0.112382,
- "recall-0.025": 0.465,
- "recall-0.05": 0.855,
- "recall-0.1": 0.99,
- "recall-0.15": 1.0,
- "recall-0.25": 1.0,
- "recall-0.5": 1.0,
- "num_labels": 200
- },
- "body_errors": {
- "body": {
- "count": 5200,
- "mean": 0.029855,
- "median": 0.023667,
- "std": 0.024984,
- "sem": 0.001771,
- "min": 0.002839,
- "max": 0.174979,
- "num_labels": 5200
- },
- "face": {
- "count": 13597,
- "mean": 0.048086,
- "median": 0.039195,
- "std": 0.032977,
- "sem": 0.002338,
- "min": 0.005486,
- "max": 0.224024,
- "num_labels": 13600
- },
- "hand": {
- "count": 400,
- "mean": 0.038549,
- "median": 0.022683,
- "std": 0.047383,
- "sem": 0.003358,
- "min": 0.002566,
- "max": 0.284113,
- "num_labels": 400
- }
- },
- "joint_recalls": {
- "num_labels": 19200,
- "recall-0.025": 0.38266,
- "recall-0.05": 0.70099,
- "recall-0.1": 0.92948,
- "recall-0.15": 0.97917,
- "recall-0.25": 0.99813,
- "recall-0.5": 0.99984
- }
-}
-{
- "total_parts": 2800,
- "correct_parts": 2791,
- "pcp": 0.996786
-}
-```
diff --git a/extras/jetson/docker-compose-2d.yml b/extras/jetson/docker-compose-2d.yml
deleted file mode 100644
index 2310d33..0000000
--- a/extras/jetson/docker-compose-2d.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-services:
-
- test_node:
- image: rapidposetriangulation_ros2d
- network_mode: "host"
- ipc: "host"
- runtime: nvidia
- privileged: true
- volumes:
- - ../../:/RapidPoseTriangulation/
- - ../../skelda/:/skelda/
- - /tmp/.X11-unix:/tmp/.X11-unix
- - /dev/shm:/dev/shm
- environment:
- - CAMID
- - DISPLAY
- - QT_X11_NO_MITSHM=1
- - "PYTHONUNBUFFERED=1"
- command: /bin/bash -i -c 'sleep infinity'
-
- estimator:
- image: rapidposetriangulation_ros2d
- network_mode: "host"
- ipc: "host"
- runtime: nvidia
- privileged: true
- volumes:
- - ../../:/RapidPoseTriangulation/
- - ../../skelda/:/skelda/
- - /tmp/.X11-unix:/tmp/.X11-unix
- - /dev/shm:/dev/shm
- environment:
- - CAMID
- - DISPLAY
- - QT_X11_NO_MITSHM=1
- - "PYTHONUNBUFFERED=1"
- command: /bin/bash -i -c 'export ROS_DOMAIN_ID=18 && ros2 run rpt2d_wrapper_cpp rpt2d_wrapper'
diff --git a/extras/jetson/dockerfile b/extras/jetson/dockerfile
deleted file mode 100644
index e245a42..0000000
--- a/extras/jetson/dockerfile
+++ /dev/null
@@ -1,25 +0,0 @@
-FROM dustynv/onnxruntime:1.20-r36.4.0
-
-ARG DEBIAN_FRONTEND=noninteractive
-ENV LANG=C.UTF-8
-ENV LC_ALL=C.UTF-8
-WORKDIR /
-
-RUN apt-get update && apt-get install -y --no-install-recommends feh
-RUN apt-get update && apt-get install -y --no-install-recommends python3-opencv
-RUN apt-get update && apt-get install -y --no-install-recommends libatlas-base-dev
-
-# Show matplotlib images
-RUN apt-get update && apt-get install -y --no-install-recommends python3-tk
-
-# Install build dependencies
-RUN apt-get update && apt-get install -y --no-install-recommends build-essential
-RUN apt-get update && apt-get install -y --no-install-recommends libopencv-dev
-RUN pip3 install --no-cache-dir uv
-
-RUN pip3 install --no-cache-dir scipy
-COPY ./skelda/ /skelda/
-RUN pip3 install --no-cache-dir -e /skelda/
-
-WORKDIR /RapidPoseTriangulation/
-CMD ["/bin/bash"]
diff --git a/extras/mmdeploy/README.md b/extras/mmdeploy/README.md
deleted file mode 100644
index ab35740..0000000
--- a/extras/mmdeploy/README.md
+++ /dev/null
@@ -1,131 +0,0 @@
-# Exporting MMPose models
-
-```bash
-docker build --progress=plain -f extras/mmdeploy/dockerfile -t rpt_mmdeploy .
-
-./extras/mmdeploy/run_container.sh
-```
-
-
-
-## ONNX
-
-```bash
-cd /mmdeploy/
-export withFP16="_fp16"
-cp /RapidPoseTriangulation/extras/mmdeploy/configs/detection_onnxruntime_static-320x320"$withFP16".py configs/mmdet/detection/
-
-python3 ./tools/deploy.py \
- configs/mmdet/detection/detection_onnxruntime_static-320x320"$withFP16".py \
- /mmpose/projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \
- https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \
- /mmpose/projects/rtmpose/examples/onnxruntime/human-pose.jpeg \
- --work-dir work_dir \
- --show
-mv /mmdeploy/work_dir/end2end.onnx /RapidPoseTriangulation/extras/mmdeploy/exports/rtmdet-nano_1x3x320x320"$withFP16".onnx
-
-python3 ./tools/deploy.py \
- configs/mmdet/detection/detection_onnxruntime_static-320x320"$withFP16".py \
- /mmpose/projects/rtmpose/rtmdet/person/rtmdet_m_640-8xb32_coco-person.py \
- https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth \
- /mmpose/projects/rtmpose/examples/onnxruntime/human-pose.jpeg \
- --work-dir work_dir \
- --show
-mv /mmdeploy/work_dir/end2end.onnx /RapidPoseTriangulation/extras/mmdeploy/exports/rtmdet-m_1x3x320x320"$withFP16".onnx
-```
-
-```bash
-cd /mmdeploy/
-export withFP16="_fp16"
-cp /RapidPoseTriangulation/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_static-384x288"$withFP16".py configs/mmpose/
-cp /RapidPoseTriangulation/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_dynamic-384x288"$withFP16".py configs/mmpose/
-
-python3 ./tools/deploy.py \
- configs/mmpose/pose-detection_simcc_onnxruntime_static-384x288"$withFP16".py \
- /mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-384x288.py \
- https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-384x288-65e718c4_20230504.pth \
- /mmpose/projects/rtmpose/examples/onnxruntime/human-pose.jpeg \
- --work-dir work_dir \
- --show
-mv /mmdeploy/work_dir/end2end.onnx /RapidPoseTriangulation/extras/mmdeploy/exports/rtmpose-m_1x3x384x288"$withFP16".onnx
-
-python3 ./tools/deploy.py \
- configs/mmpose/pose-detection_simcc_onnxruntime_dynamic-384x288"$withFP16".py \
- /mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-384x288.py \
- https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-384x288-65e718c4_20230504.pth \
- /mmpose/projects/rtmpose/examples/onnxruntime/human-pose.jpeg \
- --work-dir work_dir \
- --show
-mv /mmdeploy/work_dir/end2end.onnx /RapidPoseTriangulation/extras/mmdeploy/exports/rtmpose-m_Bx3x384x288"$withFP16".onnx
-
-python3 ./tools/deploy.py \
- configs/mmpose/pose-detection_simcc_onnxruntime_static-384x288"$withFP16".py \
- /mmpose/projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py \
- https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-384x288-2438fd99_20230728.pth \
- /mmpose/projects/rtmpose/examples/onnxruntime/human-pose.jpeg \
- --work-dir work_dir \
- --show
-mv /mmdeploy/work_dir/end2end.onnx /RapidPoseTriangulation/extras/mmdeploy/exports/rtmpose-l_wb_1x3x384x288"$withFP16".onnx
-
-python3 ./tools/deploy.py \
- configs/mmpose/pose-detection_simcc_onnxruntime_dynamic-384x288"$withFP16".py \
- /mmpose/projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py \
- https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-384x288-2438fd99_20230728.pth \
- /mmpose/projects/rtmpose/examples/onnxruntime/human-pose.jpeg \
- --work-dir work_dir \
- --show
-mv /mmdeploy/work_dir/end2end.onnx /RapidPoseTriangulation/extras/mmdeploy/exports/rtmpose-l_wb_Bx3x384x288"$withFP16".onnx
-```
-
-```bash
-python3 /RapidPoseTriangulation/extras/mmdeploy/make_extra_graphs_pt.py
-python3 /RapidPoseTriangulation/extras/mmdeploy/make_extra_graphs_tf.py
-```
-
-```bash
-python3 /RapidPoseTriangulation/extras/mmdeploy/add_extra_steps.py
-```
-
-
-
-## TensorRT
-
-Run this directly in the inference container (the TensorRT versions need to be the same)
-
-```bash
-export withFP16="_fp16"
-
-trtexec --fp16 \
- --onnx=/RapidPoseTriangulation/extras/mmdeploy/exports/rtmdet-nano_1x320x320x3"$withFP16"_extra-steps.onnx \
- --saveEngine=end2end.engine
-
-mv ./end2end.engine /RapidPoseTriangulation/extras/mmdeploy/exports/rtmdet-nano_1x320x320x3"$withFP16"_extra-steps.engine
-
-trtexec --fp16 \
- --onnx=/RapidPoseTriangulation/extras/mmdeploy/exports/rtmpose-m_Bx384x288x3"$withFP16"_extra-steps.onnx \
- --saveEngine=end2end.engine \
- --minShapes=image_input:1x384x288x3 \
- --optShapes=image_input:1x384x288x3 \
- --maxShapes=image_input:1x384x288x3
-
-mv ./end2end.engine /RapidPoseTriangulation/extras/mmdeploy/exports/rtmpose-m_1x384x288x3"$withFP16"_extra-steps.engine
-```
-
-
-
-## Benchmark
-
-```bash
-cd /mmdeploy/
-export withFP16="_fp16"
-
-python3 ./tools/profiler.py \
- configs/mmpose/pose-detection_simcc_onnxruntime_static-384x288"$withFP16".py \
- /mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-384x288.py \
- /RapidPoseTriangulation/extras/mmdeploy/testimages/ \
- --model /RapidPoseTriangulation/extras/mmdeploy/exports/rtmpose-m_1x3x384x288"$withFP16".onnx \
- --shape 384x288 \
- --device cuda \
- --warmup 50 \
- --num-iter 200
-```
diff --git a/extras/mmdeploy/add_extra_steps.py b/extras/mmdeploy/add_extra_steps.py
deleted file mode 100644
index e8b9740..0000000
--- a/extras/mmdeploy/add_extra_steps.py
+++ /dev/null
@@ -1,233 +0,0 @@
-import re
-
-import numpy as np
-import onnx
-from onnx import TensorProto, helper, numpy_helper
-
-# ==================================================================================================
-
-base_path = "/RapidPoseTriangulation/extras/mmdeploy/exports/"
-det_model_path1 = base_path + "rtmdet-nano_1x3x320x320.onnx"
-det_model_path2 = base_path + "rtmdet-m_1x3x320x320.onnx"
-pose_model_path1 = base_path + "rtmpose-m_Bx3x384x288.onnx"
-pose_model_path2 = base_path + "rtmpose-m_1x3x384x288.onnx"
-pose_model_path3 = base_path + "rtmpose-l_wb_Bx3x384x288.onnx"
-pose_model_path4 = base_path + "rtmpose-l_wb_1x3x384x288.onnx"
-
-norm_mean = -1 * (np.array([0.485, 0.456, 0.406]) * 255)
-norm_std = 1.0 / (np.array([0.229, 0.224, 0.225]) * 255)
-
-
-# ==================================================================================================
-
-
-def add_steps_to_onnx(model_path):
-
- # Load existing model
- model = onnx.load(model_path)
- graph = model.graph
-
- mean = norm_mean.astype(np.float32)
- std = norm_std.astype(np.float32)
-
- mean = np.reshape(mean, (1, 3, 1, 1)).astype(np.float32)
- std = np.reshape(std, (1, 3, 1, 1)).astype(np.float32)
-
- use_fp16 = bool("fp16" in model_path)
- if use_fp16:
- mean = mean.astype(np.float16)
- std = std.astype(np.float16)
-
- # Add the initializers to the graph
- mean_initializer = numpy_helper.from_array(mean, name="norm_mean")
- std_initializer = numpy_helper.from_array(std, name="norm_std")
- graph.initializer.extend([mean_initializer, std_initializer])
-
- # Define layer names, assuming the first input is the image tensor
- input_name = graph.input[0].name
-
- # Cast to internal type
- # This has to be the first node, because tensorrt does not support uint8 layers
- cast_type = 10 if use_fp16 else 1
- casted_output = "casted_output"
- cast_node = helper.make_node(
- "Cast",
- inputs=[input_name],
- outputs=[casted_output],
- to=cast_type,
- name="Cast_Input",
- )
-
- # Node to transpose
- transpose_output = "transpose_output"
- transpose_node = helper.make_node(
- "Transpose",
- inputs=[casted_output],
- outputs=[transpose_output],
- perm=[0, 3, 1, 2],
- name="Transpose",
- )
-
- # Node to add mean
- mean_added_output = "mean_added_output"
- mean_add_node = helper.make_node(
- "Add",
- inputs=[transpose_output, "norm_mean"],
- outputs=[mean_added_output],
- name="Mean_Addition",
- )
-
- # Node to multiply by std
- std_mult_output = "std_mult_output"
- std_mul_node = helper.make_node(
- "Mul",
- inputs=[mean_added_output, "norm_std"],
- outputs=[std_mult_output],
- name="Std_Multiplication",
- )
-
- # Replace original input of the model with the output of normalization
- for node in graph.node:
- for idx, input_name_in_node in enumerate(node.input):
- if input_name_in_node == input_name:
- node.input[idx] = std_mult_output
-
- # Add the new nodes to the graph
- graph.node.insert(0, cast_node)
- graph.node.insert(1, transpose_node)
- graph.node.insert(2, mean_add_node)
- graph.node.insert(3, std_mul_node)
-
- # Transpose the input shape
- input_shape = graph.input[0].type.tensor_type.shape.dim
- dims = [dim.dim_value for dim in input_shape]
- for i, j in enumerate([0, 3, 1, 2]):
- input_shape[j].dim_value = dims[i]
-
- # Set the batch size to a defined string
- input_shape = graph.input[0].type.tensor_type.shape.dim
- if input_shape[0].dim_value == 0:
- input_shape[0].dim_param = "batch_size"
-
- # Rename the input tensor
- main_input_image_name = model.graph.input[0].name
- for node in model.graph.node:
- for idx, name in enumerate(node.input):
- if name == main_input_image_name:
- node.input[idx] = "image_input"
- model.graph.input[0].name = "image_input"
-
- # Set input image type to int8
- model.graph.input[0].type.tensor_type.elem_type = TensorProto.UINT8
-
- # Cast all outputs to fp32 to avoid half precision issues in cpp code
- for output in graph.output:
- orig_output_name = output.name
- internal_output_name = orig_output_name + "_internal"
-
- # Rename the output tensor
- for node in model.graph.node:
- for idx, name in enumerate(node.output):
- if name == orig_output_name:
- node.output[idx] = internal_output_name
-
- # Insert a Cast node that casts the internal output to fp32
- cast_fp32_name = orig_output_name
- cast_node_output = helper.make_node(
- "Cast",
- inputs=[internal_output_name],
- outputs=[cast_fp32_name],
- to=1,
- name="Cast_Output_" + orig_output_name,
- )
- # Append the cast node to the graph
- graph.node.append(cast_node_output)
-
- # Update the output's data type info
- output.type.tensor_type.elem_type = TensorProto.FLOAT
-
- # Merge the two outputs
- if "det" in model_path:
- r1_output = "dets"
- r2_output = "labels"
- out_name = "bboxes"
- out_dim = 6
- if "pose" in model_path:
- r1_output = "kpts"
- r2_output = "scores"
- out_name = "keypoints"
- out_dim = 3
- if "det" in model_path or "pose" in model_path:
- # Node to expand
- r2_expanded = r2_output + "_expanded"
- unsqueeze_node = helper.make_node(
- "Unsqueeze",
- inputs=[r2_output],
- outputs=[r2_expanded],
- axes=[2],
- name="Unsqueeze",
- )
-
- # Node to concatenate
- r12_merged = out_name
- concat_node = helper.make_node(
- "Concat",
- inputs=[r1_output, r2_expanded],
- outputs=[r12_merged],
- axis=2,
- name="Merged",
- )
-
- # Define the new concatenated output
- merged_output = helper.make_tensor_value_info(
- r12_merged,
- TensorProto.FLOAT,
- [
- (
- graph.input[0].type.tensor_type.shape.dim[0].dim_value
- if graph.input[0].type.tensor_type.shape.dim[0].dim_value > 0
- else None
- ),
- (
- graph.output[0].type.tensor_type.shape.dim[1].dim_value
- if graph.output[0].type.tensor_type.shape.dim[1].dim_value > 0
- else None
- ),
- out_dim,
- ],
- )
-
- # Update the graph
- graph.node.append(unsqueeze_node)
- graph.node.append(concat_node)
- graph.output.pop()
- graph.output.pop()
- graph.output.append(merged_output)
-
- path = re.sub(r"(x)(\d+)x(\d+)x(\d+)", r"\1\3x\4x\2", model_path)
- path = path.replace(".onnx", "_extra-steps.onnx")
- onnx.save(model, path)
-
-
-# ==================================================================================================
-
-
-def main():
- add_steps_to_onnx(det_model_path1)
- add_steps_to_onnx(det_model_path2)
- add_steps_to_onnx(pose_model_path1)
- add_steps_to_onnx(pose_model_path2)
- add_steps_to_onnx(pose_model_path3)
- add_steps_to_onnx(pose_model_path4)
- add_steps_to_onnx(det_model_path1.replace(".onnx", "_fp16.onnx"))
- add_steps_to_onnx(det_model_path2.replace(".onnx", "_fp16.onnx"))
- add_steps_to_onnx(pose_model_path1.replace(".onnx", "_fp16.onnx"))
- add_steps_to_onnx(pose_model_path2.replace(".onnx", "_fp16.onnx"))
- add_steps_to_onnx(pose_model_path3.replace(".onnx", "_fp16.onnx"))
- add_steps_to_onnx(pose_model_path4.replace(".onnx", "_fp16.onnx"))
-
-
-# ==================================================================================================
-
-if __name__ == "__main__":
- main()
diff --git a/extras/mmdeploy/configs/detection_onnxruntime_static-320x320.py b/extras/mmdeploy/configs/detection_onnxruntime_static-320x320.py
deleted file mode 100644
index d7d5b57..0000000
--- a/extras/mmdeploy/configs/detection_onnxruntime_static-320x320.py
+++ /dev/null
@@ -1,18 +0,0 @@
-_base_ = ["../_base_/base_static.py", "../../_base_/backends/onnxruntime.py"]
-
-onnx_config = dict(
- input_shape=[320, 320],
-)
-
-codebase_config = dict(
- # For later TensorRT inference, the number of output boxes needs to be as stable as possible,
- # because a drop in the box count leads to a re-optimization which takes a lot of time,
- # therefore reduce the maximum number of output boxes to the smallest usable value and sort out
- # low confidence boxes outside the model.
- post_processing=dict(
- score_threshold=0.0,
- confidence_threshold=0.0,
- iou_threshold=0.5,
- max_output_boxes_per_class=10,
- ),
-)
diff --git a/extras/mmdeploy/configs/detection_onnxruntime_static-320x320_fp16.py b/extras/mmdeploy/configs/detection_onnxruntime_static-320x320_fp16.py
deleted file mode 100644
index 1dd243b..0000000
--- a/extras/mmdeploy/configs/detection_onnxruntime_static-320x320_fp16.py
+++ /dev/null
@@ -1,18 +0,0 @@
-_base_ = ["../_base_/base_static.py", "../../_base_/backends/onnxruntime-fp16.py"]
-
-onnx_config = dict(
- input_shape=[320, 320],
-)
-
-codebase_config = dict(
- # For later TensorRT inference, the number of output boxes needs to be as stable as possible,
- # because a drop in the box count leads to a re-optimization which takes a lot of time,
- # therefore reduce the maximum number of output boxes to the smallest usable value and sort out
- # low confidence boxes outside the model.
- post_processing=dict(
- score_threshold=0.0,
- confidence_threshold=0.0,
- iou_threshold=0.5,
- max_output_boxes_per_class=10,
- ),
-)
diff --git a/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_dynamic-384x288.py b/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_dynamic-384x288.py
deleted file mode 100644
index 3d52547..0000000
--- a/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_dynamic-384x288.py
+++ /dev/null
@@ -1,19 +0,0 @@
-_base_ = ["./pose-detection_static.py", "../_base_/backends/onnxruntime.py"]
-
-onnx_config = dict(
- input_shape=[288, 384],
- output_names=["kpts", "scores"],
- dynamic_axes={
- "input": {
- 0: "batch",
- },
- "kpts": {
- 0: "batch",
- },
- "scores": {
- 0: "batch",
- },
- },
-)
-
-codebase_config = dict(export_postprocess=True) # export get_simcc_maximum
diff --git a/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_dynamic-384x288_fp16.py b/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_dynamic-384x288_fp16.py
deleted file mode 100644
index fe0ca45..0000000
--- a/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_dynamic-384x288_fp16.py
+++ /dev/null
@@ -1,19 +0,0 @@
-_base_ = ["./pose-detection_static.py", "../_base_/backends/onnxruntime-fp16.py"]
-
-onnx_config = dict(
- input_shape=[288, 384],
- output_names=["kpts", "scores"],
- dynamic_axes={
- "input": {
- 0: "batch",
- },
- "kpts": {
- 0: "batch",
- },
- "scores": {
- 0: "batch",
- },
- },
-)
-
-codebase_config = dict(export_postprocess=True) # export get_simcc_maximum
diff --git a/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_static-384x288.py b/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_static-384x288.py
deleted file mode 100644
index bfa43b4..0000000
--- a/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_static-384x288.py
+++ /dev/null
@@ -1,8 +0,0 @@
-_base_ = ["./pose-detection_static.py", "../_base_/backends/onnxruntime.py"]
-
-onnx_config = dict(
- input_shape=[288, 384],
- output_names=["kpts", "scores"],
-)
-
-codebase_config = dict(export_postprocess=True) # export get_simcc_maximum
diff --git a/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_static-384x288_fp16.py b/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_static-384x288_fp16.py
deleted file mode 100644
index 6263dac..0000000
--- a/extras/mmdeploy/configs/pose-detection_simcc_onnxruntime_static-384x288_fp16.py
+++ /dev/null
@@ -1,8 +0,0 @@
-_base_ = ["./pose-detection_static.py", "../_base_/backends/onnxruntime-fp16.py"]
-
-onnx_config = dict(
- input_shape=[288, 384],
- output_names=["kpts", "scores"],
-)
-
-codebase_config = dict(export_postprocess=True) # export get_simcc_maximum
diff --git a/extras/mmdeploy/dockerfile b/extras/mmdeploy/dockerfile
deleted file mode 100644
index 313be15..0000000
--- a/extras/mmdeploy/dockerfile
+++ /dev/null
@@ -1,41 +0,0 @@
-FROM openmmlab/mmdeploy:ubuntu20.04-cuda11.8-mmdeploy1.3.1
-
-ARG DEBIAN_FRONTEND=noninteractive
-ENV LANG=C.UTF-8
-ENV LC_ALL=C.UTF-8
-WORKDIR /
-
-RUN apt-get update && apt-get install -y --no-install-recommends feh
-
-RUN git clone https://github.com/open-mmlab/mmdeploy.git --depth=1
-RUN cd mmdeploy/; python3 tools/scripts/build_ubuntu_x64_ort.py
-
-# Install MMPose
-ENV FORCE_CUDA="1"
-ENV MMCV_WITH_OPS=1
-RUN pip3 install --upgrade --no-cache-dir openmim
-RUN mim install mmengine
-RUN mim install "mmcv>=2,<2.2.0"
-RUN mim install "mmdet>=3"
-RUN mim install "mmpose>=1.1.0"
-# Fix an error when importing mmpose
-RUN pip3 install --upgrade --no-cache-dir "numpy<2" scipy
-RUN git clone --depth=1 --branch=main https://github.com/open-mmlab/mmpose.git
-
-RUN echo 'export PYTHONPATH=/mmdeploy/build/lib:$PYTHONPATH' >> ~/.bashrc
-RUN echo 'export LD_LIBRARY_PATH=/mmdeploy/../mmdeploy-dep/onnxruntime-linux-x64-1.8.1/lib/:$LD_LIBRARY_PATH' >> ~/.bashrc
-
-# Show images
-RUN apt-get update && apt-get install -y --no-install-recommends python3-tk
-
-# Tool for fp16 conversion
-RUN pip3 install --upgrade --no-cache-dir onnxconverter_common
-
-# Fix an error when profiling
-RUN pip3 install --upgrade --no-cache-dir "onnxruntime-gpu<1.17"
-
-RUN pip3 install --upgrade --no-cache-dir tensorflow
-RUN pip3 install --upgrade --no-cache-dir tf2onnx
-
-WORKDIR /mmdeploy/
-CMD ["/bin/bash"]
diff --git a/extras/mmdeploy/exports/.gitignore b/extras/mmdeploy/exports/.gitignore
deleted file mode 100644
index d6b7ef3..0000000
--- a/extras/mmdeploy/exports/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore
diff --git a/extras/mmdeploy/make_extra_graphs_pt.py b/extras/mmdeploy/make_extra_graphs_pt.py
deleted file mode 100644
index 0a920f7..0000000
--- a/extras/mmdeploy/make_extra_graphs_pt.py
+++ /dev/null
@@ -1,338 +0,0 @@
-import cv2
-import torch
-import torch.nn as nn
-import torch.nn.functional as F
-from torchvision.ops import roi_align
-
-# ==================================================================================================
-
-base_path = "/RapidPoseTriangulation/extras/mmdeploy/exports/"
-det_target_size = (320, 320)
-pose_target_size = (384, 288)
-
-# ==================================================================================================
-
-
-class Letterbox(nn.Module):
- def __init__(self, target_size, fill_value=128):
- """Resize and pad image while keeping aspect ratio"""
- super(Letterbox, self).__init__()
-
- self.target_size = target_size
- self.fill_value = fill_value
-
- def calc_params(self, ishape):
- ih, iw = ishape[1], ishape[2]
- th, tw = self.target_size
-
- scale = torch.min(tw / iw, th / ih)
- nw = torch.round(iw * scale)
- nh = torch.round(ih * scale)
-
- pad_w = tw - nw
- pad_h = th - nh
- pad_left = pad_w // 2
- pad_top = pad_h // 2
- pad_right = pad_w - pad_left
- pad_bottom = pad_h - pad_top
- paddings = (pad_left, pad_right, pad_top, pad_bottom)
-
- return paddings, scale, (nw, nh)
-
- def forward(self, img):
- paddings, _, (nw, nh) = self.calc_params(img.shape)
-
- # Resize the image
- img = img.to(torch.float32)
- img = img.permute(0, 3, 1, 2)
- img = F.interpolate(
- img,
- size=(nh, nw),
- mode="bilinear",
- align_corners=False,
- )
- img = img.permute(0, 2, 3, 1)
- img = img.round()
-
- # Pad the image
- img = F.pad(
- img.permute(0, 3, 1, 2),
- pad=paddings,
- mode="constant",
- value=self.fill_value,
- )
- img = img.permute(0, 2, 3, 1)
-
- return img
-
-
-# ==================================================================================================
-
-
-class BoxCrop(nn.Module):
- def __init__(self, target_size):
- """Crop bounding box from image"""
- super(BoxCrop, self).__init__()
-
- self.target_size = target_size
- self.padding_scale = 1.25
-
- def calc_params(self, bbox):
- start_x, start_y, end_x, end_y = bbox[0, 0], bbox[0, 1], bbox[0, 2], bbox[0, 3]
- target_h, target_w = self.target_size
-
- # Calculate original bounding box width, height and center
- bbox_w = end_x - start_x
- bbox_h = end_y - start_y
- center_x = (start_x + end_x) / 2.0
- center_y = (start_y + end_y) / 2.0
-
- # Calculate the aspect ratios
- bbox_aspect = bbox_w / bbox_h
- target_aspect = target_w / target_h
-
- # Adjust the scaled bounding box to match the target aspect ratio
- if bbox_aspect > target_aspect:
- adjusted_h = bbox_w / target_aspect
- adjusted_w = bbox_w
- else:
- adjusted_w = bbox_h * target_aspect
- adjusted_h = bbox_h
-
- # Scale the bounding box by the padding_scale
- scaled_bbox_w = adjusted_w * self.padding_scale
- scaled_bbox_h = adjusted_h * self.padding_scale
-
- # Calculate scaled bounding box coordinates
- new_start_x = center_x - scaled_bbox_w / 2.0
- new_start_y = center_y - scaled_bbox_h / 2.0
- new_end_x = center_x + scaled_bbox_w / 2.0
- new_end_y = center_y + scaled_bbox_h / 2.0
-
- # Define the new box coordinates
- new_box = torch.stack((new_start_x, new_start_y, new_end_x, new_end_y), dim=0)
- new_box = new_box.unsqueeze(0)
- scale = torch.stack(
- ((target_w / scaled_bbox_w), (target_h / scaled_bbox_h)), dim=0
- )
-
- return scale, new_box
-
- def forward(self, img, bbox):
- _, bbox = self.calc_params(bbox)
-
- batch_indices = torch.zeros(bbox.shape[0], 1)
- rois = torch.cat([batch_indices, bbox], dim=1)
-
- # Resize and crop
- img = img.to(torch.float32)
- img = img.permute(0, 3, 1, 2)
- img = roi_align(
- img,
- rois,
- output_size=self.target_size,
- spatial_scale=1.0,
- sampling_ratio=0,
- )
- img = img.permute(0, 2, 3, 1)
- img = img.round()
-
- return img
-
-
-# ==================================================================================================
-
-
-class DetPreprocess(nn.Module):
- def __init__(self, target_size, fill_value=114):
- super(DetPreprocess, self).__init__()
- self.letterbox = Letterbox(target_size, fill_value)
-
- def forward(self, img):
- # img: torch.Tensor of shape [batch, H, W, C], dtype=torch.uint8
- img = self.letterbox(img)
- return img
-
-
-# ==================================================================================================
-
-
-class DetPostprocess(nn.Module):
- def __init__(self, target_size):
- super(DetPostprocess, self).__init__()
-
- self.target_size = target_size
- self.letterbox = Letterbox(target_size)
-
- def forward(self, img, boxes):
- paddings, scale, _ = self.letterbox.calc_params(img.shape)
-
- boxes = boxes.float()
- boxes[:, :, 0] -= paddings[0]
- boxes[:, :, 2] -= paddings[0]
- boxes[:, :, 1] -= paddings[2]
- boxes[:, :, 3] -= paddings[2]
-
- zero = torch.tensor(0)
- boxes = torch.max(boxes, zero)
-
- th, tw = self.target_size
- pad_w = paddings[0] + paddings[1]
- pad_h = paddings[2] + paddings[3]
- max_w = tw - pad_w - 1
- max_h = th - pad_h - 1
- b0 = boxes[:, :, 0]
- b1 = boxes[:, :, 1]
- b2 = boxes[:, :, 2]
- b3 = boxes[:, :, 3]
- b0 = torch.min(b0, max_w)
- b1 = torch.min(b1, max_h)
- b2 = torch.min(b2, max_w)
- b3 = torch.min(b3, max_h)
- boxes[:, :, 0] = b0
- boxes[:, :, 1] = b1
- boxes[:, :, 2] = b2
- boxes[:, :, 3] = b3
-
- boxes[:, :, 0:4] /= scale
- return boxes
-
-
-# ==================================================================================================
-
-
-class PosePreprocess(nn.Module):
- def __init__(self, target_size, fill_value=114):
- super(PosePreprocess, self).__init__()
- self.boxcrop = BoxCrop(target_size)
-
- def forward(self, img, bbox):
- # img: torch.Tensor of shape [1, H, W, C], dtype=torch.uint8
- # bbox: torch.Tensor of shape [1, 4], dtype=torch.float32
- img = self.boxcrop(img, bbox)
- return img
-
-
-# ==================================================================================================
-
-
-class PosePostprocess(nn.Module):
- def __init__(self, target_size):
- super(PosePostprocess, self).__init__()
- self.boxcrop = BoxCrop(target_size)
- self.target_size = target_size
-
- def forward(self, img, bbox, keypoints):
- scale, bbox = self.boxcrop.calc_params(bbox)
-
- kp = keypoints.float()
- kp[:, :, 0:2] /= scale
- kp[:, :, 0] += bbox[0, 0]
- kp[:, :, 1] += bbox[0, 1]
-
- zero = torch.tensor(0)
- kp = torch.max(kp, zero)
-
- max_w = img.shape[2] - 1
- max_h = img.shape[1] - 1
- k0 = kp[:, :, 0]
- k1 = kp[:, :, 1]
- k0 = torch.min(k0, max_w)
- k1 = torch.min(k1, max_h)
- kp[:, :, 0] = k0
- kp[:, :, 1] = k1
-
- return kp
-
-
-# ==================================================================================================
-
-
-def main():
-
- img_path = "/RapidPoseTriangulation/scripts/../data/h1/54138969-img_003201.jpg"
- image = cv2.imread(img_path, 3)
- image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
-
- # Initialize the DetPreprocess module
- preprocess_model = DetPreprocess(target_size=det_target_size)
- det_dummy_input_a0 = torch.from_numpy(image).unsqueeze(0)
-
- # Export to ONNX
- torch.onnx.export(
- preprocess_model,
- det_dummy_input_a0,
- base_path + "det_preprocess.onnx",
- opset_version=11,
- input_names=["input_image"],
- output_names=["preprocessed_image"],
- dynamic_axes={
- "input_image": {0: "batch_size", 1: "height", 2: "width"},
- "preprocessed_image": {0: "batch_size"},
- },
- )
-
- # Initialize the DetPostprocess module
- postprocess_model = DetPostprocess(target_size=det_target_size)
- det_dummy_input_b0 = torch.from_numpy(image).unsqueeze(0)
- det_dummy_input_b1 = torch.rand(1, 10, 5)
-
- # Export to ONNX
- torch.onnx.export(
- postprocess_model,
- (det_dummy_input_b0, det_dummy_input_b1),
- base_path + "det_postprocess.onnx",
- opset_version=11,
- input_names=["input_image", "boxes"],
- output_names=["output_boxes"],
- dynamic_axes={
- "input_image": {0: "batch_size", 1: "height", 2: "width"},
- "boxes": {0: "batch_size", 1: "num_boxes"},
- "output_boxes": {0: "batch_size", 1: "num_boxes"},
- },
- )
-
- # Initialize the PosePreprocess module
- preprocess_model = PosePreprocess(target_size=pose_target_size)
- det_dummy_input_c0 = torch.from_numpy(image).unsqueeze(0)
- det_dummy_input_c1 = torch.tensor([[352, 339, 518, 594]]).to(torch.int32)
-
- # Export to ONNX
- torch.onnx.export(
- preprocess_model,
- (det_dummy_input_c0, det_dummy_input_c1),
- base_path + "pose_preprocess.onnx",
- opset_version=11,
- input_names=["input_image", "bbox"],
- output_names=["preprocessed_image"],
- dynamic_axes={
- "input_image": {0: "batch_size", 1: "height", 2: "width"},
- "preprocessed_image": {0: "batch_size"},
- },
- )
-
- # Initialize the PosePostprocess module
- postprocess_model = PosePostprocess(target_size=pose_target_size)
- det_dummy_input_d0 = torch.from_numpy(image).unsqueeze(0)
- det_dummy_input_d1 = torch.tensor([[352, 339, 518, 594]]).to(torch.int32)
- det_dummy_input_d2 = torch.rand(1, 17, 2)
-
- # Export to ONNX
- torch.onnx.export(
- postprocess_model,
- (det_dummy_input_d0, det_dummy_input_d1, det_dummy_input_d2),
- base_path + "pose_postprocess.onnx",
- opset_version=11,
- input_names=["input_image", "bbox", "keypoints"],
- output_names=["output_keypoints"],
- dynamic_axes={
- "input_image": {0: "batch_size", 1: "height", 2: "width"},
- "output_keypoints": {0: "batch_size"},
- },
- )
-
-
-# ==================================================================================================
-
-if __name__ == "__main__":
- main()
diff --git a/extras/mmdeploy/make_extra_graphs_tf.py b/extras/mmdeploy/make_extra_graphs_tf.py
deleted file mode 100644
index 3cf1d27..0000000
--- a/extras/mmdeploy/make_extra_graphs_tf.py
+++ /dev/null
@@ -1,276 +0,0 @@
-import cv2
-
-import numpy as np
-import tensorflow as tf
-import tf2onnx
-
-# ==================================================================================================
-
-base_path = "/RapidPoseTriangulation/extras/mmdeploy/exports/"
-det_target_size = (320, 320)
-
-# ==================================================================================================
-
-
-class BayerToRGB(tf.keras.layers.Layer):
- """Convert Bayer image to RGB
- See: https://stanford.edu/class/ee367/reading/Demosaicing_ICASSP04.pdf
- See: https://github.com/cheind/pytorch-debayer/blob/master/debayer/modules.py#L231
- """
-
- def __init__(self):
- super().__init__()
- self.layout = "RGGB"
- self.max_val = 255.0
-
- self.kernels = tf.constant(
- np.array(
- [
- # G at R/B locations
- [
- [0, 0, -1, 0, 0],
- [0, 0, 2, 0, 0],
- [-1, 2, 4, 2, -1],
- [0, 0, 2, 0, 0],
- [0, 0, -1, 0, 0],
- ],
- # R/B at G in R/B rows and B/R columns
- [
- [0, 0, 0.5, 0, 0],
- [0, -1, 0, -1, 0],
- [-1, 4, 5, 4, -1],
- [0, -1, 0, -1, 0],
- [0, 0, 0.5, 0, 0],
- ],
- # R/B at G in B/R rows and R/B columns
- [
- [0, 0, 0.5, 0, 0],
- [0, -1, 4, -1, 0],
- [-1, 0, 5, 0, -1],
- [0, -1, 4, -1, 0],
- [0, 0, 0.5, 0, 0],
- ],
- # R/B at B/R in B/R rows and B/R columns
- [
- [0, 0, -1.5, 0, 0],
- [0, 2, 0, 2, 0],
- [-1.5, 0, 6, 0, -1.5],
- [0, 2, 0, 2, 0],
- [0, 0, -1.5, 0, 0],
- ],
- ],
- dtype=np.float32,
- )
- .reshape(1, 4, 5, 5)
- .transpose(2, 3, 0, 1)
- / 8.0
- )
- self.index = tf.constant(
- np.array(
- # Describes the kernel indices that calculate the corresponding RGB values for
- # the 2x2 layout (RGGB) sub-structure
- [
- # Destination R
- [
- [4, 1], # identity, R at G in R row B column
- [2, 3], # R at G in B row R column, R at B in B row R column
- ],
- # Destination G
- [
- [0, 4],
- [4, 0],
- ],
- # Destination B
- [
- [3, 2],
- [1, 4],
- ],
- ]
- ).reshape(1, 3, 2, 2)
- )
-
- def call(self, img):
- H, W = tf.shape(img)[1], tf.shape(img)[2]
-
- # Pad the image
- tpad = img[:, 0:2, :, :]
- bpad = img[:, H - 2 : H, :, :]
- ipad = tf.concat([tpad, img, bpad], axis=1)
- lpad = ipad[:, :, 0:2, :]
- rpad = ipad[:, :, W - 2 : W, :]
- ipad = tf.concat([lpad, ipad, rpad], axis=2)
-
- # Convolve with kernels
- planes = tf.nn.conv2d(ipad, self.kernels, strides=[1, 1, 1, 1], padding="VALID")
-
- # Concatenate identity kernel
- planes = tf.concat([planes, img], axis=-1)
-
- # Gather values
- index_repeated = tf.tile(self.index, multiples=[1, 1, H // 2, W // 2])
- index_repeated = tf.transpose(index_repeated, perm=[0, 2, 3, 1])
- row_indices, col_indices = tf.meshgrid(tf.range(H), tf.range(W), indexing="ij")
- index_tensor = tf.stack([row_indices, col_indices], axis=-1)
- index_tensor = tf.expand_dims(index_tensor, axis=0)
- index_tensor = tf.expand_dims(index_tensor, axis=-2)
- index_tensor = tf.repeat(index_tensor, repeats=3, axis=-2)
- index_repeated = tf.expand_dims(index_repeated, axis=-1)
- indices = tf.concat([tf.cast(index_tensor, tf.int64), index_repeated], axis=-1)
- rgb = tf.gather_nd(planes, indices, batch_dims=1)
-
- if self.max_val == 255.0:
- # Make value range valid again
- rgb = tf.round(rgb)
-
- return rgb
-
-
-# ==================================================================================================
-
-
-def bayer_resize(img, size):
- """Resize a Bayer image by splitting color channels"""
-
- # Split the image into 4 channels
- r = img[:, 0::2, 0::2, 0]
- g1 = img[:, 0::2, 1::2, 0]
- g2 = img[:, 1::2, 0::2, 0]
- b = img[:, 1::2, 1::2, 0]
- bsplit = tf.stack([r, g1, g2, b], axis=-1)
-
- # Resize the image
- # Make sure the target size is divisible by 2
- size = (size[0] // 2, size[1] // 2)
- bsized = tf.image.resize(bsplit, size=size, method="bilinear")
-
- # Create a bayer image again
- img = tf.nn.depth_to_space(bsized, block_size=2)
-
- return img
-
-
-# ==================================================================================================
-
-
-class Letterbox(tf.keras.layers.Layer):
- def __init__(self, target_size, fill_value=128):
- """Resize and pad image while keeping aspect ratio"""
- super(Letterbox, self).__init__()
-
- self.b2rgb = BayerToRGB()
- self.target_size = target_size
- self.fill_value = fill_value
-
- def calc_params(self, ishape):
- img_h, img_w = ishape[1], ishape[2]
- target_h, target_w = self.target_size
-
- scale = tf.minimum(target_w / img_w, target_h / img_h)
- new_w = tf.round(tf.cast(img_w, scale.dtype) * scale)
- new_h = tf.round(tf.cast(img_h, scale.dtype) * scale)
- new_w = tf.cast(new_w, tf.int32)
- new_h = tf.cast(new_h, tf.int32)
- new_w = new_w - (new_w % 2)
- new_h = new_h - (new_h % 2)
-
- pad_w = target_w - new_w
- pad_h = target_h - new_h
- pad_left = tf.cast(tf.floor(tf.cast(pad_w, tf.float32) / 2.0), tf.int32)
- pad_top = tf.cast(tf.floor(tf.cast(pad_h, tf.float32) / 2.0), tf.int32)
- pad_right = pad_w - pad_left
- pad_bottom = pad_h - pad_top
- paddings = [pad_top, pad_bottom, pad_left, pad_right]
-
- return paddings, scale, (new_w, new_h)
-
- def call(self, img):
- paddings, _, (nw, nh) = self.calc_params(tf.shape(img))
-
- # Resize the image and convert to RGB
- img = bayer_resize(img, (nh, nw))
- img = self.b2rgb(img)
-
- # Pad the image
- pad_top, pad_bottom, pad_left, pad_right = paddings
- img = tf.pad(
- img,
- paddings=[[0, 0], [pad_top, pad_bottom], [pad_left, pad_right], [0, 0]],
- mode="CONSTANT",
- constant_values=self.fill_value,
- )
-
- return img
-
-
-# ==================================================================================================
-
-
-class DetPreprocess(tf.keras.layers.Layer):
- def __init__(self, target_size, fill_value=114):
- super(DetPreprocess, self).__init__()
- self.letterbox = Letterbox(target_size, fill_value)
-
- def call(self, img):
- """img: tf.Tensor of shape [batch, H, W, C], dtype=tf.uint8"""
-
- # Cast to float32 since TensorRT does not support uint8 layers
- img = tf.cast(img, tf.float32)
-
- img = self.letterbox(img)
- return img
-
-
-# ==================================================================================================
-
-
-def rgb2bayer(img):
- bayer = np.zeros((img.shape[0], img.shape[1]), dtype=img.dtype)
- bayer[0::2, 0::2] = img[0::2, 0::2, 0]
- bayer[0::2, 1::2] = img[0::2, 1::2, 1]
- bayer[1::2, 0::2] = img[1::2, 0::2, 1]
- bayer[1::2, 1::2] = img[1::2, 1::2, 2]
- return bayer
-
-
-# ==================================================================================================
-
-
-def main():
-
- img_path = "/RapidPoseTriangulation/scripts/../data/h1/54138969-img_003201.jpg"
- image = cv2.imread(img_path, 3)
- image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
- image = rgb2bayer(image)
- image = np.expand_dims(image, axis=-1)
- image = np.asarray(image, dtype=np.uint8)
-
- # Initialize the DetPreprocess module
- preprocess_model = tf.keras.Sequential()
- preprocess_model.add(DetPreprocess(target_size=det_target_size))
- det_dummy_input_a0 = tf.convert_to_tensor(
- np.expand_dims(image, axis=0), dtype=tf.uint8
- )
- det_dummy_output_a0 = preprocess_model(det_dummy_input_a0)
- print("\n", det_dummy_output_a0.shape, "\n")
-
- output_a0 = det_dummy_output_a0.numpy()
- output_a0 = np.squeeze(output_a0, axis=0)
- output_a0 = np.asarray(output_a0, dtype=np.uint8)
- output_a0 = cv2.cvtColor(output_a0, cv2.COLOR_RGB2BGR)
- cv2.imwrite(base_path + "det_preprocess.jpg", output_a0)
-
- # Export to ONNX
- input_signature = [tf.TensorSpec([None, None, None, 1], tf.uint8, name="x")]
- _, _ = tf2onnx.convert.from_keras(
- preprocess_model,
- input_signature,
- opset=11,
- output_path=base_path + "det_preprocess.onnx",
- target=["tensorrt"],
- )
-
-
-# ==================================================================================================
-
-if __name__ == "__main__":
- main()
diff --git a/extras/mmdeploy/run_container.sh b/extras/mmdeploy/run_container.sh
deleted file mode 100755
index 7353774..0000000
--- a/extras/mmdeploy/run_container.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/bash
-
-xhost +
-docker run --privileged --rm --network host -it \
- --gpus all --shm-size=16g --ulimit memlock=-1 --ulimit stack=67108864 \
- --volume "$(pwd)"/:/RapidPoseTriangulation/ \
- --volume /tmp/.X11-unix:/tmp/.X11-unix \
- --env DISPLAY --env QT_X11_NO_MITSHM=1 \
- rpt_mmdeploy
diff --git a/extras/mmdeploy/testimages/human-pose.jpeg b/extras/mmdeploy/testimages/human-pose.jpeg
deleted file mode 100644
index 8de4015..0000000
Binary files a/extras/mmdeploy/testimages/human-pose.jpeg and /dev/null differ
diff --git a/extras/mmpose/README.md b/extras/mmpose/README.md
deleted file mode 100644
index c731136..0000000
--- a/extras/mmpose/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Finetuning MMPose models
-
-See:
-
-
-
-```bash
-docker build --progress=plain -f extras/mmpose/dockerfile -t rpt_mmpose .
-
-./extras/mmpose/run_container.sh
-```
-
-```bash
-cd /mmpose/
-export CUDA_VISIBLE_DEVICES=0
-
-python3 ./tools/train.py \
- /RapidPoseTriangulation/extras/mmpose/configs/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py \
- --amp \
- --cfg-options \
- load_from=https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco-wholebody_pt-aic-coco_270e-384x288-eaeb96c8_20230125.pth \
- base_lr=0.00004
-```
diff --git a/extras/mmpose/configs/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py b/extras/mmpose/configs/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py
deleted file mode 100644
index 9af4ae2..0000000
--- a/extras/mmpose/configs/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py
+++ /dev/null
@@ -1,235 +0,0 @@
-_base_ = ['mmpose::_base_/default_runtime.py']
-
-val_interval=1
-max_epochs = 3
-
-# common setting
-num_keypoints = 133
-input_size = (288, 384)
-
-# runtime
-stage2_num_epochs = 30
-base_lr = 4e-3
-train_batch_size = 32
-val_batch_size = 32
-
-train_cfg = dict(max_epochs=max_epochs, val_interval=val_interval)
-randomness = dict(seed=21)
-
-# optimizer
-optim_wrapper = dict(
- type='OptimWrapper',
- optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),
- clip_grad=dict(max_norm=35, norm_type=2),
- paramwise_cfg=dict(
- norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))
-
-# learning rate
-param_scheduler = [
- dict(
- type='LinearLR',
- start_factor=1.0e-5,
- by_epoch=False,
- begin=0,
- end=1000),
- dict(
- type='CosineAnnealingLR',
- eta_min=base_lr * 0.05,
- begin=max_epochs // 2,
- end=max_epochs,
- T_max=max_epochs // 2,
- by_epoch=True,
- convert_to_iter_based=True),
-]
-
-# automatically scaling LR based on the actual training batch size
-auto_scale_lr = dict(base_batch_size=512)
-
-# codec settings
-codec = dict(
- type='SimCCLabel',
- input_size=input_size,
- sigma=(6., 6.93),
- simcc_split_ratio=2.0,
- normalize=False,
- use_dark=False)
-
-# model settings
-model = dict(
- type='TopdownPoseEstimator',
- data_preprocessor=dict(
- type='PoseDataPreprocessor',
- mean=[123.675, 116.28, 103.53],
- std=[58.395, 57.12, 57.375],
- bgr_to_rgb=True),
- backbone=dict(
- _scope_='mmdet',
- type='CSPNeXt',
- arch='P5',
- expand_ratio=0.5,
- deepen_factor=1.,
- widen_factor=1.,
- out_indices=(4, ),
- channel_attention=True,
- norm_cfg=dict(type='SyncBN'),
- act_cfg=dict(type='SiLU'),
- init_cfg=dict(
- type='Pretrained',
- prefix='backbone.',
- checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'
- 'rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth' # noqa
- )),
- head=dict(
- type='RTMCCHead',
- in_channels=1024,
- out_channels=num_keypoints,
- input_size=codec['input_size'],
- in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),
- simcc_split_ratio=codec['simcc_split_ratio'],
- final_layer_kernel_size=7,
- gau_cfg=dict(
- hidden_dims=256,
- s=128,
- expansion_factor=2,
- dropout_rate=0.,
- drop_path=0.,
- act_fn='SiLU',
- use_rel_bias=False,
- pos_enc=False),
- loss=dict(
- type='KLDiscretLoss',
- use_target_weight=True,
- beta=10.,
- label_softmax=True),
- decoder=codec),
- test_cfg=dict(flip_test=True, ))
-
-# base dataset settings
-dataset_type = 'CocoWholeBodyDataset'
-data_mode = 'topdown'
-data_root = 'data/coco/'
-
-backend_args = dict(backend='local')
-
-# pipelines
-train_pipeline = [
- dict(type='LoadImage', backend_args=backend_args),
- dict(type='GetBBoxCenterScale'),
- dict(type='RandomFlip', direction='horizontal'),
- dict(type='RandomHalfBody'),
- dict(
- type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),
- dict(type='TopdownAffine', input_size=codec['input_size']),
- dict(type='mmdet.YOLOXHSVRandomAug'),
- dict(
- type='Albumentation',
- transforms=[
- dict(type='Blur', p=0.1),
- dict(type='MedianBlur', p=0.1),
- dict(
- type='CoarseDropout',
- max_holes=1,
- max_height=0.4,
- max_width=0.4,
- min_holes=1,
- min_height=0.2,
- min_width=0.2,
- p=1.0),
- ]),
- dict(type='GenerateTarget', encoder=codec),
- dict(type='PackPoseInputs')
-]
-val_pipeline = [
- dict(type='LoadImage', backend_args=backend_args),
- dict(type='GetBBoxCenterScale'),
- dict(type='TopdownAffine', input_size=codec['input_size']),
- dict(type='PackPoseInputs')
-]
-
-train_pipeline_stage2 = [
- dict(type='LoadImage', backend_args=backend_args),
- dict(type='GetBBoxCenterScale'),
- dict(type='RandomFlip', direction='horizontal'),
- dict(type='RandomHalfBody'),
- dict(
- type='RandomBBoxTransform',
- shift_factor=0.,
- scale_factor=[0.75, 1.25],
- rotate_factor=60),
- dict(type='TopdownAffine', input_size=codec['input_size']),
- dict(type='mmdet.YOLOXHSVRandomAug'),
- dict(
- type='Albumentation',
- transforms=[
- dict(type='Blur', p=0.1),
- dict(type='MedianBlur', p=0.1),
- dict(
- type='CoarseDropout',
- max_holes=1,
- max_height=0.4,
- max_width=0.4,
- min_holes=1,
- min_height=0.2,
- min_width=0.2,
- p=0.5),
- ]),
- dict(type='GenerateTarget', encoder=codec),
- dict(type='PackPoseInputs')
-]
-
-# data loaders
-train_dataloader = dict(
- batch_size=train_batch_size,
- num_workers=10,
- persistent_workers=True,
- sampler=dict(type='DefaultSampler', shuffle=True),
- dataset=dict(
- type=dataset_type,
- data_root=data_root,
- data_mode=data_mode,
- ann_file='annotations/coco_wholebody_train_v1.0.json',
- data_prefix=dict(img='train2017/'),
- pipeline=train_pipeline,
- ))
-val_dataloader = dict(
- batch_size=val_batch_size,
- num_workers=10,
- persistent_workers=True,
- drop_last=False,
- sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),
- dataset=dict(
- type=dataset_type,
- data_root=data_root,
- data_mode=data_mode,
- ann_file='annotations/coco_wholebody_val_v1.0.json',
- data_prefix=dict(img='val2017/'),
- test_mode=True,
- # bbox_file='data/coco/person_detection_results/'
- # 'COCO_val2017_detections_AP_H_56_person.json',
- pipeline=val_pipeline,
- ))
-test_dataloader = val_dataloader
-
-# hooks
-default_hooks = dict(
- checkpoint=dict(
- save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))
-
-custom_hooks = [
- dict(
- type='EMAHook',
- ema_type='ExpMomentumEMA',
- momentum=0.0002,
- update_buffers=True,
- priority=49),
- dict(
- type='mmdet.PipelineSwitchHook',
- switch_epoch=max_epochs - stage2_num_epochs,
- switch_pipeline=train_pipeline_stage2)
-]
-
-# evaluators
-val_evaluator = dict(
- type='CocoWholeBodyMetric',
- ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')
-test_evaluator = val_evaluator
diff --git a/extras/mmpose/dockerfile b/extras/mmpose/dockerfile
deleted file mode 100644
index 455ba87..0000000
--- a/extras/mmpose/dockerfile
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM rpt_mmdeploy
-
-RUN apt-get update && apt-get install -y --no-install-recommends nano
-RUN pip3 install --upgrade --no-cache-dir "albumentations<1.4"
-
-RUN sed -i '94i\ self.runner.val_loop.run()' /usr/local/lib/python3.8/dist-packages/mmengine/runner/loops.py
-
-WORKDIR /mmpose/
-CMD ["/bin/bash"]
diff --git a/extras/mmpose/run_container.sh b/extras/mmpose/run_container.sh
deleted file mode 100755
index 2b0ed92..0000000
--- a/extras/mmpose/run_container.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#! /bin/bash
-
-xhost +
-docker run --privileged --rm --network host -it \
- --gpus all --shm-size=16g --ulimit memlock=-1 --ulimit stack=67108864 \
- --volume "$(pwd)"/:/RapidPoseTriangulation/ \
- --volume "$(pwd)"/../datasets/coco2017/annotations/:/mmpose/data/coco/annotations/ \
- --volume "$(pwd)"/../datasets/coco2017/images/:/mmpose/data/coco/ \
- --volume /tmp/.X11-unix:/tmp/.X11-unix \
- --env DISPLAY --env QT_X11_NO_MITSHM=1 \
- rpt_mmpose
diff --git a/extras/ros/README.md b/extras/ros/README.md
index 757fbdd..e1b3d11 100644
--- a/extras/ros/README.md
+++ b/extras/ros/README.md
@@ -1,13 +1,12 @@
-# ROS-Wrapper
+# ROS Wrapper
-Run pose estimator with ros topics as inputs and publish detected poses.
+Run the 3D triangulator with ROS topics as inputs and publish detected poses.
- Build container:
```bash
- docker build --progress=plain -t rapidposetriangulation_ros2d -f extras/ros/dockerfile_2d .
docker build --progress=plain -t rapidposetriangulation_ros3d -f extras/ros/dockerfile_3d .
```
@@ -16,7 +15,6 @@ Run pose estimator with ros topics as inputs and publish detected poses.
- Run and test:
```bash
- xhost + && export CAMID="camera01" && docker compose -f extras/ros/docker-compose-2d.yml up
xhost + && docker compose -f extras/ros/docker-compose-3d.yml up
docker exec -it ros-test_node-1 bash
diff --git a/extras/ros/docker-compose-2d.yml b/extras/ros/docker-compose-2d.yml
deleted file mode 100644
index ba79b9f..0000000
--- a/extras/ros/docker-compose-2d.yml
+++ /dev/null
@@ -1,71 +0,0 @@
-services:
-
- test_node:
- image: rapidposetriangulation_ros2d
- network_mode: "host"
- ipc: "host"
- runtime: nvidia
- privileged: true
- volumes:
- - ../../:/RapidPoseTriangulation/
- - ../../skelda/:/skelda/
- - /tmp/.X11-unix:/tmp/.X11-unix
- - /dev/shm:/dev/shm
- environment:
- - CAMID
- - DISPLAY
- - QT_X11_NO_MITSHM=1
- - "PYTHONUNBUFFERED=1"
- command: /bin/bash -i -c 'sleep infinity'
-
- estimator:
- image: rapidposetriangulation_ros2d
- network_mode: "host"
- ipc: "host"
- runtime: nvidia
- privileged: true
- volumes:
- - ../../:/RapidPoseTriangulation/
- - ../../skelda/:/skelda/
- - /tmp/.X11-unix:/tmp/.X11-unix
- - /dev/shm:/dev/shm
- environment:
- - CAMID
- - DISPLAY
- - QT_X11_NO_MITSHM=1
- - "PYTHONUNBUFFERED=1"
- command: /bin/bash -i -c 'export ROS_DOMAIN_ID=18 && ros2 run rpt2d_wrapper_cpp rpt2d_wrapper'
-
- pose_visualizer:
- image: rapidposetriangulation_ros2d
- network_mode: "host"
- ipc: "host"
- runtime: nvidia
- privileged: true
- volumes:
- - ../../:/RapidPoseTriangulation/
- - ../../skelda/:/skelda/
- - /tmp/.X11-unix:/tmp/.X11-unix
- - /dev/shm:/dev/shm
- environment:
- - CAMID
- - DISPLAY
- - QT_X11_NO_MITSHM=1
- - "PYTHONUNBUFFERED=1"
- command: /bin/bash -i -c 'sleep 2 && export ROS_DOMAIN_ID=18 && ros2 run pose2d_visualizer pose2d_visualizer $CAMID'
-
- pose_viewer:
- image: rapidposetriangulation_ros2d
- network_mode: "host"
- ipc: "host"
- runtime: nvidia
- privileged: true
- volumes:
- - /tmp/.X11-unix:/tmp/.X11-unix
- - /dev/shm:/dev/shm
- environment:
- - CAMID
- - DISPLAY
- - QT_X11_NO_MITSHM=1
- - "PYTHONUNBUFFERED=1"
- command: /bin/bash -i -c 'sleep 2 && export ROS_DOMAIN_ID=18 && ros2 run image_view image_view --ros-args --remap image:=/$CAMID/img_with_pose -p autosize:=True -p window_name:=MyPoseImage'
diff --git a/extras/ros/docker-compose-3d.yml b/extras/ros/docker-compose-3d.yml
index b6266bf..7989b27 100644
--- a/extras/ros/docker-compose-3d.yml
+++ b/extras/ros/docker-compose-3d.yml
@@ -7,7 +7,6 @@ services:
privileged: true
volumes:
- ../../:/RapidPoseTriangulation/
- - ../../skelda/:/skelda/
- /tmp/.X11-unix:/tmp/.X11-unix
- /dev/shm:/dev/shm
environment:
@@ -23,7 +22,6 @@ services:
privileged: true
volumes:
- ../../:/RapidPoseTriangulation/
- - ../../skelda/:/skelda/
- /tmp/.X11-unix:/tmp/.X11-unix
- /dev/shm:/dev/shm
environment:
diff --git a/extras/ros/dockerfile_2d b/extras/ros/dockerfile_2d
deleted file mode 100644
index fe72c48..0000000
--- a/extras/ros/dockerfile_2d
+++ /dev/null
@@ -1,67 +0,0 @@
-FROM rapidposetriangulation
-WORKDIR /
-
-# Install ROS2
-# https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html
-RUN apt-get update && apt-get install -y --no-install-recommends locales
-RUN locale-gen en_US en_US.UTF-8 && update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
-RUN apt-get update && apt-get install -y --no-install-recommends software-properties-common
-RUN add-apt-repository universe
-RUN apt-get update && apt-get install -y --no-install-recommends curl
-RUN curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
-RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" > /etc/apt/sources.list.d/ros2.list
-RUN apt-get update && apt-get install -y --no-install-recommends ros-humble-ros-base python3-argcomplete
-RUN apt-get update && apt-get install -y --no-install-recommends ros-dev-tools
-RUN echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
-
-# Fix ros package building error
-RUN pip3 install --no-cache-dir "setuptools<=58.2.0"
-
-# Create ROS2 workspace for basic packages
-RUN mkdir -p /project/base/src/
-RUN cd /project/base/; colcon build
-RUN echo "source /project/base/install/setup.bash" >> ~/.bashrc
-
-# Install opencv and cv_bridge
-RUN apt-get update && apt-get install -y --no-install-recommends libboost-dev
-RUN apt-get update && apt-get install -y --no-install-recommends libboost-python-dev
-RUN apt-get update && apt-get install -y --no-install-recommends libopencv-dev
-RUN cd /project/base/src/; git clone --branch humble --depth=1 https://github.com/ros-perception/vision_opencv.git
-RUN /bin/bash -i -c 'cd /project/base/; colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release'
-
-# Install ROS2 image viewer
-RUN cd /project/base/src/; git clone --branch=humble --depth=1 https://github.com/ros-perception/image_pipeline.git
-RUN cd /project/base/src/; git clone --branch=humble --depth=1 https://github.com/ros-perception/image_common.git
-RUN /bin/bash -i -c 'cd /project/base/; colcon build --symlink-install --packages-select camera_calibration_parsers image_transport image_view --cmake-args -DCMAKE_BUILD_TYPE=Release'
-
-# Fix module not found error when displaying images
-RUN apt-get update && apt-get install -y --no-install-recommends libcanberra-gtk-module libcanberra-gtk3-module
-
-# Create ROS2 workspace for project packages
-RUN mkdir -p /project/dev_ws/src/
-RUN cd /project/dev_ws/; colcon build
-RUN echo "source /project/dev_ws/install/setup.bash" >> ~/.bashrc
-
-# Copy modules
-COPY ./extras/include/ /RapidPoseTriangulation/extras/include/
-COPY ./scripts/ /RapidPoseTriangulation/scripts/
-COPY ./extras/ros/rpt_msgs/ /RapidPoseTriangulation/extras/ros/rpt_msgs/
-COPY ./extras/ros/pose2d_visualizer/ /RapidPoseTriangulation/extras/ros/pose2d_visualizer/
-COPY ./extras/ros/rpt2d_wrapper_cpp/ /RapidPoseTriangulation/extras/ros/rpt2d_wrapper_cpp/
-
-# Link and build as ros package
-RUN ln -s /RapidPoseTriangulation/extras/ros/rpt_msgs/ /project/dev_ws/src/
-RUN ln -s /RapidPoseTriangulation/extras/ros/pose2d_visualizer/ /project/dev_ws/src/
-RUN ln -s /RapidPoseTriangulation/extras/ros/rpt2d_wrapper_cpp/ /project/dev_ws/src/
-RUN /bin/bash -i -c 'cd /project/dev_ws/; colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release'
-
-# Update ros packages -> autocompletion and check
-RUN /bin/bash -i -c 'ros2 pkg list'
-
-# Clear cache to save space, only has an effect if image is squashed
-RUN apt-get autoremove -y \
- && apt-get clean \
- && rm -rf /var/lib/apt/lists/*
-
-WORKDIR /RapidPoseTriangulation/
-CMD ["/bin/bash"]
diff --git a/extras/ros/pose2d_visualizer/package.xml b/extras/ros/pose2d_visualizer/package.xml
deleted file mode 100644
index 99c3f33..0000000
--- a/extras/ros/pose2d_visualizer/package.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
- pose2d_visualizer
- 0.0.0
- TODO: Package description
- root
- TODO: License declaration
-
- rpt_msgs
-
- ament_copyright
- ament_flake8
- ament_pep257
- python3-pytest
-
-
- ament_python
-
-
diff --git a/extras/ros/pose2d_visualizer/pose2d_visualizer/__init__.py b/extras/ros/pose2d_visualizer/pose2d_visualizer/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/extras/ros/pose2d_visualizer/pose2d_visualizer/pose2d_visualizer.py b/extras/ros/pose2d_visualizer/pose2d_visualizer/pose2d_visualizer.py
deleted file mode 100644
index 7c717b2..0000000
--- a/extras/ros/pose2d_visualizer/pose2d_visualizer/pose2d_visualizer.py
+++ /dev/null
@@ -1,158 +0,0 @@
-import sys
-import threading
-import time
-
-import cv2
-from matplotlib import pyplot as plt
-import numpy as np
-import rclpy
-from cv_bridge import CvBridge
-from rclpy.qos import QoSHistoryPolicy, QoSProfile, QoSReliabilityPolicy
-from sensor_msgs.msg import Image
-
-from rpt_msgs.msg import Poses
-from skelda import utils_view
-
-# ==================================================================================================
-
-bridge = CvBridge()
-node = None
-publisher_img = None
-
-img_input_topic = "/{}/pylon_ros2_camera_node/image_raw"
-pose_input_topic = "/poses/{}"
-img_output_topic = "/{}/img_with_pose"
-
-last_input_image = None
-lock = threading.Lock()
-
-# ==================================================================================================
-
-
-def bayer2rgb(bayer):
- img = cv2.cvtColor(bayer, cv2.COLOR_BayerBG2RGB)
- return img
-
-
-# ==================================================================================================
-
-
-def callback_images(image_data):
- global last_input_image, lock
-
- # Convert into cv images from image string
- if image_data.encoding == "bayer_rggb8":
- bayer_image = bridge.imgmsg_to_cv2(image_data, "bayer_rggb8")
- color_image = bayer2rgb(bayer_image)
- elif image_data.encoding == "mono8":
- gray_image = bridge.imgmsg_to_cv2(image_data, "mono8")
- color_image = cv2.cvtColor(gray_image, cv2.COLOR_GRAY2RGB)
- elif image_data.encoding == "rgb8":
- color_image = bridge.imgmsg_to_cv2(image_data, "rgb8")
- else:
- raise ValueError("Unknown image encoding:", image_data.encoding)
-
- time_stamp = image_data.header.stamp.sec + image_data.header.stamp.nanosec / 1.0e9
-
- with lock:
- last_input_image = (color_image, time_stamp)
-
-
-# ==================================================================================================
-
-
-def callback_poses(pose_data):
- global last_input_image, lock
-
- ptime = time.time()
- if last_input_image is None:
- return
-
- # Extract pose data
- joint_names = pose_data.joint_names
- bodies2D = np.array(pose_data.bodies_flat).reshape(pose_data.bodies_shape).tolist()
-
- # Collect inputs
- images_2d = []
- timestamps = []
- with lock:
- img = np.copy(last_input_image[0])
- ts = last_input_image[1]
- images_2d.append(img)
- timestamps.append(ts)
-
- # Visualize 2D poses
- colors = plt.cm.hsv(np.linspace(0, 1, len(bodies2D), endpoint=False)).tolist()
- colors = [[int(c[0] * 255), int(c[1] * 255), int(c[2] * 255)] for c in colors]
- for i, body in enumerate(bodies2D):
- color = list(reversed(colors[i]))
- img = utils_view.draw_body_in_image(img, body, joint_names, color)
-
- # Publish image with poses
- publish(img)
-
- msg = "Visualization time: {:.3f}s"
- print(msg.format(time.time() - ptime))
-
-
-# ==================================================================================================
-
-
-def publish(img):
- # Publish image data
- msg = bridge.cv2_to_imgmsg(img, "rgb8")
- publisher_img.publish(msg)
-
-
-# ==================================================================================================
-
-
-def main():
- global node, publisher_img
-
- # Start node
- rclpy.init(args=sys.argv)
- cam_id = sys.argv[1]
- node = rclpy.create_node("pose2d_visualizer")
-
- # Quality of service settings
- qos_profile = QoSProfile(
- reliability=QoSReliabilityPolicy.RELIABLE,
- history=QoSHistoryPolicy.KEEP_LAST,
- depth=1,
- )
-
- # Create subscribers
- _ = node.create_subscription(
- Image,
- img_input_topic.format(cam_id),
- callback_images,
- qos_profile,
- )
- _ = node.create_subscription(
- Poses,
- pose_input_topic.format(cam_id),
- callback_poses,
- qos_profile,
- )
-
- # Create publishers
- publisher_img = node.create_publisher(
- Image,
- img_output_topic.format(cam_id),
- qos_profile,
- )
-
- node.get_logger().info("Finished initialization of pose visualizer")
-
- # Run ros update thread
- rclpy.spin(node)
-
- node.destroy_node()
- rclpy.shutdown()
-
-
-# ==================================================================================================
-
-if __name__ == "__main__":
- main()
diff --git a/extras/ros/pose2d_visualizer/resource/pose2d_visualizer b/extras/ros/pose2d_visualizer/resource/pose2d_visualizer
deleted file mode 100644
index e69de29..0000000
diff --git a/extras/ros/pose2d_visualizer/setup.cfg b/extras/ros/pose2d_visualizer/setup.cfg
deleted file mode 100644
index 5522611..0000000
--- a/extras/ros/pose2d_visualizer/setup.cfg
+++ /dev/null
@@ -1,4 +0,0 @@
-[develop]
-script_dir=$base/lib/pose2d_visualizer
-[install]
-install_scripts=$base/lib/pose2d_visualizer
diff --git a/extras/ros/pose2d_visualizer/setup.py b/extras/ros/pose2d_visualizer/setup.py
deleted file mode 100644
index ea0f365..0000000
--- a/extras/ros/pose2d_visualizer/setup.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from setuptools import setup
-
-package_name = "pose2d_visualizer"
-
-setup(
- name=package_name,
- version="0.0.0",
- packages=[package_name],
- data_files=[
- ("share/ament_index/resource_index/packages", ["resource/" + package_name]),
- ("share/" + package_name, ["package.xml"]),
- ],
- install_requires=["setuptools"],
- zip_safe=True,
- maintainer="root",
- maintainer_email="root@todo.todo",
- description="TODO: Package description",
- license="TODO: License declaration",
- tests_require=["pytest"],
- entry_points={
- "console_scripts": ["pose2d_visualizer = pose2d_visualizer.pose2d_visualizer:main"],
- },
-)
diff --git a/extras/ros/pose2d_visualizer/test/test_copyright.py b/extras/ros/pose2d_visualizer/test/test_copyright.py
deleted file mode 100644
index 8f18fa4..0000000
--- a/extras/ros/pose2d_visualizer/test/test_copyright.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2015 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_copyright.main import main
-
-
-# Remove the `skip` decorator once the source file(s) have a copyright header
-@pytest.mark.skip(
- reason="No copyright header has been placed in the generated source file."
-)
-@pytest.mark.copyright
-@pytest.mark.linter
-def test_copyright():
- rc = main(argv=[".", "test"])
- assert rc == 0, "Found errors"
diff --git a/extras/ros/pose2d_visualizer/test/test_flake8.py b/extras/ros/pose2d_visualizer/test/test_flake8.py
deleted file mode 100644
index f494570..0000000
--- a/extras/ros/pose2d_visualizer/test/test_flake8.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2017 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_flake8.main import main_with_errors
-
-
-@pytest.mark.flake8
-@pytest.mark.linter
-def test_flake8():
- rc, errors = main_with_errors(argv=[])
- assert rc == 0, "Found %d code style errors / warnings:\n" % len(
- errors
- ) + "\n".join(errors)
diff --git a/extras/ros/pose2d_visualizer/test/test_pep257.py b/extras/ros/pose2d_visualizer/test/test_pep257.py
deleted file mode 100644
index 4eddb46..0000000
--- a/extras/ros/pose2d_visualizer/test/test_pep257.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2015 Open Source Robotics Foundation, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import pytest
-from ament_pep257.main import main
-
-
-@pytest.mark.linter
-@pytest.mark.pep257
-def test_pep257():
- rc = main(argv=[".", "test"])
- assert rc == 0, "Found code style errors / warnings"
diff --git a/extras/ros/rpt2d_wrapper_cpp/CMakeLists.txt b/extras/ros/rpt2d_wrapper_cpp/CMakeLists.txt
deleted file mode 100644
index 6b4f8c3..0000000
--- a/extras/ros/rpt2d_wrapper_cpp/CMakeLists.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-cmake_minimum_required(VERSION 3.5)
-project(rpt2d_wrapper_cpp)
-
-# Default to C99
-if(NOT CMAKE_C_STANDARD)
- set(CMAKE_C_STANDARD 99)
-endif()
-
-# Default to C++17
-if(NOT CMAKE_CXX_STANDARD)
- set(CMAKE_CXX_STANDARD 17)
-endif()
-
-if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
- add_compile_options(-Wall -Wextra -Wpedantic)
-endif()
-
-# find dependencies
-find_package(ament_cmake REQUIRED)
-find_package(rclcpp REQUIRED)
-find_package(rpt_msgs REQUIRED)
-find_package(sensor_msgs REQUIRED)
-find_package(cv_bridge REQUIRED)
-find_package(OpenCV REQUIRED)
-
-### 3) ONNX Runtime
-# for desktop
-include_directories(/onnxruntime/include/
- /onnxruntime/include/onnxruntime/core/session/
- /onnxruntime/include/onnxruntime/core/providers/tensorrt/)
-link_directories(/onnxruntime/build/Linux/Release/)
-# for jetson
-include_directories(/usr/local/include/onnxruntime/)
-link_directories(/usr/local/lib/)
-
-add_executable(rpt2d_wrapper src/rpt2d_wrapper.cpp)
-ament_target_dependencies(rpt2d_wrapper rclcpp sensor_msgs rpt_msgs cv_bridge)
-target_include_directories(rpt2d_wrapper PUBLIC
- $
- $)
-
-target_link_libraries(rpt2d_wrapper
- ${OpenCV_LIBS}
- onnxruntime_providers_tensorrt
- onnxruntime_providers_shared
- onnxruntime_providers_cuda
- onnxruntime
-)
-
-set_target_properties(rpt2d_wrapper PROPERTIES
- BUILD_WITH_INSTALL_RPATH TRUE
- INSTALL_RPATH "/onnxruntime/build/Linux/Release"
-)
-
-install(TARGETS rpt2d_wrapper
- DESTINATION lib/${PROJECT_NAME})
-
-if(BUILD_TESTING)
- find_package(ament_lint_auto REQUIRED)
- # the following line skips the linter which checks for copyrights
- # uncomment the line when a copyright and license is not present in all source files
- #set(ament_cmake_copyright_FOUND TRUE)
- # the following line skips cpplint (only works in a git repo)
- # uncomment the line when this package is not in a git repo
- #set(ament_cmake_cpplint_FOUND TRUE)
- ament_lint_auto_find_test_dependencies()
-endif()
-
-ament_package()
diff --git a/extras/ros/rpt2d_wrapper_cpp/package.xml b/extras/ros/rpt2d_wrapper_cpp/package.xml
deleted file mode 100644
index 7a40658..0000000
--- a/extras/ros/rpt2d_wrapper_cpp/package.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
- rpt2d_wrapper_cpp
- 0.0.0
- TODO: Package description
- root
- TODO: License declaration
-
- ament_cmake
-
- rclcpp
- rpt_msgs
- sensor_msgs
-
- cv_bridge
- OpenCV
-
- ament_lint_auto
- ament_lint_common
-
-
- ament_cmake
-
-
diff --git a/extras/ros/rpt2d_wrapper_cpp/src/rpt2d_wrapper.cpp b/extras/ros/rpt2d_wrapper_cpp/src/rpt2d_wrapper.cpp
deleted file mode 100644
index 0d2ed12..0000000
--- a/extras/ros/rpt2d_wrapper_cpp/src/rpt2d_wrapper.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-
-// ROS2
-#include
-#include
-
-// OpenCV / cv_bridge
-#include
-#include
-
-// JSON library
-#include "/RapidPoseTriangulation/extras/include/nlohmann/json.hpp"
-using json = nlohmann::json;
-
-#include "rpt_msgs/msg/poses.hpp"
-#include "/RapidPoseTriangulation/scripts/utils_2d_pose.hpp"
-#include "/RapidPoseTriangulation/scripts/utils_pipeline.hpp"
-
-// =================================================================================================
-
-static const std::string img_input_topic = "/{}/pylon_ros2_camera_node/image_raw";
-static const std::string pose_out_topic = "/poses/{}";
-
-static const float min_bbox_score = 0.4;
-static const float min_bbox_area = 0.1 * 0.1;
-static const bool batch_poses = true;
-
-static const std::map whole_body = {
- {"foots", true},
- {"face", true},
- {"hands", true},
-};
-
-// =================================================================================================
-// =================================================================================================
-
-class Rpt2DWrapperNode : public rclcpp::Node
-{
-public:
- Rpt2DWrapperNode(const std::string &cam_id)
- : Node("rpt2d_wrapper_" + cam_id)
- {
- this->is_busy = false;
- std::string img_topic = std::string(img_input_topic)
- .replace(img_input_topic.find("{}"), 2, cam_id);
- std::string pose_topic = std::string(pose_out_topic)
- .replace(pose_out_topic.find("{}"), 2, cam_id);
-
- // QoS
- rclcpp::QoS qos_profile(1);
- qos_profile.reliable();
- qos_profile.keep_last(1);
-
- // Setup subscriber
- image_sub_ = this->create_subscription(
- img_topic, qos_profile,
- std::bind(&Rpt2DWrapperNode::callback_images, this, std::placeholders::_1));
-
- // Setup publisher
- pose_pub_ = this->create_publisher(pose_topic, qos_profile);
-
- // Load model
- bool use_wb = utils_pipeline::use_whole_body(whole_body);
- this->kpt_model = std::make_unique(
- use_wb, min_bbox_score, min_bbox_area, batch_poses);
-
- RCLCPP_INFO(this->get_logger(), "Finished initialization of pose estimator.");
- }
-
-private:
- rclcpp::Subscription::SharedPtr image_sub_;
- rclcpp::Publisher::SharedPtr pose_pub_;
- std::atomic is_busy;
-
- // Pose model pointer
- std::unique_ptr kpt_model;
- const std::vector joint_names_2d = utils_pipeline::get_joint_names(whole_body);
-
- void callback_images(const sensor_msgs::msg::Image::SharedPtr msg);
-
- std::vector>> call_model(const cv::Mat &image);
-};
-
-// =================================================================================================
-
-void Rpt2DWrapperNode::callback_images(const sensor_msgs::msg::Image::SharedPtr msg)
-{
- if (this->is_busy)
- {
- RCLCPP_WARN(this->get_logger(), "Skipping frame, still processing...");
- return;
- }
- this->is_busy = true;
- auto ts_image = std::chrono::high_resolution_clock::now();
-
- // Load or convert image to Bayer format
- cv::Mat bayer_image;
- try
- {
- if (msg->encoding == "mono8")
- {
- cv_bridge::CvImageConstPtr cv_ptr = cv_bridge::toCvShare(msg, msg->encoding);
- bayer_image = cv_ptr->image;
- }
- else if (msg->encoding == "bayer_rggb8")
- {
- cv_bridge::CvImageConstPtr cv_ptr = cv_bridge::toCvShare(msg, msg->encoding);
- bayer_image = cv_ptr->image;
- }
- else if (msg->encoding == "rgb8")
- {
- cv_bridge::CvImageConstPtr cv_ptr = cv_bridge::toCvShare(msg, "rgb8");
- cv::Mat color_image = cv_ptr->image;
- bayer_image = utils_pipeline::rgb2bayer(color_image);
- }
- else
- {
- throw std::runtime_error("Unknown image encoding: " + msg->encoding);
- }
- }
- catch (const std::exception &e)
- {
- RCLCPP_ERROR(this->get_logger(), "cv_bridge exception: %s", e.what());
- return;
- }
-
- // Call model
- const auto &valid_poses = this->call_model(bayer_image);
-
- // Calculate timings
- double time_stamp = msg->header.stamp.sec + msg->header.stamp.nanosec / 1.0e9;
- auto ts_image_sec = std::chrono::duration(ts_image.time_since_epoch()).count();
- auto ts_pose = std::chrono::high_resolution_clock::now();
- double ts_pose_sec = std::chrono::duration(ts_pose.time_since_epoch()).count();
- double z_trigger_image = ts_image_sec - time_stamp;
- double z_trigger_pose = ts_pose_sec - time_stamp;
- double z_image_pose = ts_pose_sec - ts_image_sec;
- json jdata;
- jdata["timestamps"] = {
- {"trigger", time_stamp},
- {"image", ts_image_sec},
- {"pose2d", ts_pose_sec},
- {"z-trigger-image", z_trigger_image},
- {"z-image-pose2d", z_image_pose},
- {"z-trigger-pose2d", z_trigger_pose}};
-
- // Publish message
- auto pose_msg = rpt_msgs::msg::Poses();
- pose_msg.header = msg->header;
- std::vector bshape = {(int)valid_poses.size(), (int)joint_names_2d.size(), 3};
- pose_msg.bodies_shape = bshape;
- pose_msg.bodies_flat.reserve(bshape[0] * bshape[1] * bshape[2]);
- for (int32_t i = 0; i < bshape[0]; i++)
- {
- for (int32_t j = 0; j < bshape[1]; j++)
- {
- for (int32_t k = 0; k < bshape[2]; k++)
- {
- pose_msg.bodies_flat.push_back(valid_poses[i][j][k]);
- }
- }
- }
- pose_msg.joint_names = joint_names_2d;
- pose_msg.extra_data = jdata.dump();
- pose_pub_->publish(pose_msg);
-
- // Print info
- double elapsed_time = std::chrono::duration(
- std::chrono::high_resolution_clock::now() - ts_image)
- .count();
- std::cout << "Detected persons: " << valid_poses.size()
- << " - Prediction time: " << elapsed_time << "s" << std::endl;
-
- this->is_busy = false;
-}
-
-// =================================================================================================
-
-std::vector>> Rpt2DWrapperNode::call_model(const cv::Mat &image)
-{
- // Create image vector
- cv::Mat rgb_image = utils_pipeline::bayer2rgb(image);
- std::vector images_2d = {rgb_image};
-
- // Predict 2D poses
- auto poses_2d_all = kpt_model->predict(images_2d);
- auto poses_2d_upd = utils_pipeline::update_keypoints(
- poses_2d_all, joint_names_2d, whole_body);
- auto &poses_2d = poses_2d_upd[0];
-
- // Drop persons with no joints
- std::vector>> valid_poses;
- for (auto &person : poses_2d)
- {
- float sum_conf = 0.0;
- for (auto &kp : person)
- {
- sum_conf += kp[2];
- }
- if (sum_conf > 0.0)
- {
- valid_poses.push_back(person);
- }
- }
-
- // Round poses to 3 decimal places
- for (auto &person : valid_poses)
- {
- for (auto &kp : person)
- {
- kp[0] = std::round(kp[0] * 1000.0) / 1000.0;
- kp[1] = std::round(kp[1] * 1000.0) / 1000.0;
- kp[2] = std::round(kp[2] * 1000.0) / 1000.0;
- }
- }
-
- return valid_poses;
-}
-
-// =================================================================================================
-// =================================================================================================
-
-int main(int argc, char **argv)
-{
- rclcpp::init(argc, argv);
- const std::string cam_id = std::getenv("CAMID");
-
- auto node = std::make_shared(cam_id);
- rclcpp::spin(node);
-
- rclcpp::shutdown();
- return 0;
-}
diff --git a/pyproject.toml b/pyproject.toml
index ec652a3..c940f7e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -22,4 +22,4 @@ wheel.packages = ["src/rpt"]
[tool.isort]
profile = "black"
-known_first_party = "rpt,draw_utils,test_triangulate,utils_2d_pose,triangulate_poses"
+known_first_party = "rpt"
diff --git a/run_container.sh b/run_container.sh
index 15f2fb9..c72bbab 100755
--- a/run_container.sh
+++ b/run_container.sh
@@ -5,7 +5,6 @@ docker run --privileged --rm --network host -it \
--runtime nvidia --shm-size=16g --ulimit memlock=-1 --ulimit stack=67108864 \
--volume "$(pwd)"/:/RapidPoseTriangulation/ \
--volume "$(pwd)"/../datasets/:/datasets/ \
- --volume "$(pwd)"/skelda/:/skelda/ \
--volume /tmp/.X11-unix:/tmp/.X11-unix \
--env DISPLAY --env QT_X11_NO_MITSHM=1 \
rapidposetriangulation
diff --git a/scripts/test_skelda_dataset.cpp b/scripts/test_skelda_dataset.cpp
deleted file mode 100644
index 99c4602..0000000
--- a/scripts/test_skelda_dataset.cpp
+++ /dev/null
@@ -1,327 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-// OpenCV
-#include
-
-// JSON library
-#include "/RapidPoseTriangulation/extras/include/nlohmann/json.hpp"
-using json = nlohmann::json;
-
-#include "/RapidPoseTriangulation/rpt/camera.hpp"
-#include "/RapidPoseTriangulation/rpt/interface.hpp"
-#include "/RapidPoseTriangulation/rpt/tracker.hpp"
-#include "/RapidPoseTriangulation/scripts/utils_2d_pose.hpp"
-#include "/RapidPoseTriangulation/scripts/utils_pipeline.hpp"
-
-// =================================================================================================
-
-static const std::string path_data = "/tmp/rpt/all.json";
-static const std::string path_cfg = "/tmp/rpt/config.json";
-
-// =================================================================================================
-
-std::vector load_images(json &item)
-{
- // Load images
- std::vector images;
- for (size_t j = 0; j < item["imgpaths"].size(); j++)
- {
- auto ipath = item["imgpaths"][j].get();
- cv::Mat image = cv::imread(ipath, cv::IMREAD_COLOR);
- cv::cvtColor(image, image, cv::COLOR_BGR2RGB);
- images.push_back(image);
- }
-
- if (item["dataset_name"] == "human36m")
- {
- // Since the images don't have the same shape, rescale some of them
- for (size_t i = 0; i < images.size(); i++)
- {
- cv::Mat &img = images[i];
- cv::Size ishape = img.size();
- if (ishape != cv::Size(1000, 1000))
- {
- auto cam = item["cameras"][i];
- cam["K"][1][1] = cam["K"][1][1].get() * (1000.0 / ishape.height);
- cam["K"][1][2] = cam["K"][1][2].get() * (1000.0 / ishape.height);
- cam["K"][0][0] = cam["K"][0][0].get() * (1000.0 / ishape.width);
- cam["K"][0][2] = cam["K"][0][2].get() * (1000.0 / ishape.width);
- cv::resize(img, img, cv::Size(1000, 1000));
- images[i] = img;
- }
- }
- }
-
- // Convert image format to Bayer encoding to simulate real camera input
- // This also resulted in notably better MPJPE results in most cases, presumably since the
- // demosaicing algorithm from OpenCV is better than the default one from the cameras
- for (size_t i = 0; i < images.size(); i++)
- {
- cv::Mat &img = images[i];
- cv::Mat bayer_image = utils_pipeline::rgb2bayer(img);
- images[i] = std::move(bayer_image);
- }
-
- return images;
-}
-
-// =================================================================================================
-
-std::string read_file(const std::string &path)
-{
- std::ifstream file_stream(path);
- if (!file_stream.is_open())
- {
- throw std::runtime_error("Unable to open file: " + path);
- }
-
- std::stringstream buffer;
- buffer << file_stream.rdbuf();
- return buffer.str();
-}
-
-void write_file(const std::string &path, const std::string &content)
-{
- std::ofstream file_stream(path, std::ios::out | std::ios::binary);
- if (!file_stream.is_open())
- {
- throw std::runtime_error("Unable to open file for writing: " + path);
- }
-
- file_stream << content;
-
- if (!file_stream)
- {
- throw std::runtime_error("Error occurred while writing to file: " + path);
- }
- file_stream.close();
-}
-
-// =================================================================================================
-
-int main(int argc, char **argv)
-{
- // Load the files
- auto dataset = json::parse(read_file(path_data));
- auto config = json::parse(read_file(path_cfg));
-
- // Load the configuration
- const std::map whole_body = config["whole_body"];
- const float min_bbox_score = config["min_bbox_score"];
- const float min_bbox_area = config["min_bbox_area"];
- const bool batch_poses = config["batch_poses"];
- const std::vector joint_names_2d = utils_pipeline::get_joint_names(whole_body);
- const float min_match_score = config["min_match_score"];
- const size_t min_group_size = config["min_group_size"];
- const int take_interval = config["take_interval"];
- const float ifps = config["fps"];
- const float max_movement_speed = config["max_movement_speed"];
- const float max_track_distance = config["max_track_distance"];
-
- // Load 2D model
- bool use_wb = utils_pipeline::use_whole_body(whole_body);
- std::unique_ptr kpt_model =
- std::make_unique(
- use_wb, min_bbox_score, min_bbox_area, batch_poses);
-
- // Load 3D models
- std::unique_ptr tri_model = std::make_unique(
- min_match_score, min_group_size);
- std::unique_ptr pose_tracker = std::make_unique(
- max_movement_speed, max_track_distance);
-
- // Timers
- size_t time_count = dataset.size();
- std::vector times_image;
- std::vector times_debayer;
- std::vector times_pose2d;
- std::vector times_pose3d;
- std::vector times_tracks;
- times_image.reserve(time_count);
- times_debayer.reserve(time_count);
- times_pose2d.reserve(time_count);
- times_pose3d.reserve(time_count);
- times_tracks.reserve(time_count);
- size_t print_steps = (size_t)std::floor((float)time_count / 100.0f);
- print_steps = std::max((size_t)1, print_steps);
-
- std::cout << "Running predictions: |";
- size_t bar_width = (size_t)std::ceil((float)time_count / (float)print_steps);
- for (size_t i = 0; i < bar_width; i++)
- {
- std::cout << "-";
- }
- std::cout << "|" << std::endl;
-
- // Calculate 2D poses [items, views, persons, joints, 3]
- std::vector>>>> all_poses_2d;
- std::cout << "Calculating 2D poses: |";
- for (size_t i = 0; i < dataset.size(); i++)
- {
- if (i % print_steps == 0)
- {
- std::cout << "#" << std::flush;
- }
- std::chrono::duration elapsed;
- auto &item = dataset[i];
-
- // Load images
- auto stime = std::chrono::high_resolution_clock::now();
- std::vector images = load_images(item);
- elapsed = std::chrono::high_resolution_clock::now() - stime;
- times_image.push_back(elapsed.count());
-
- // Demosaic images
- stime = std::chrono::high_resolution_clock::now();
- for (size_t i = 0; i < images.size(); i++)
- {
- cv::Mat &img = images[i];
- cv::Mat rgb = utils_pipeline::bayer2rgb(img);
- images[i] = std::move(rgb);
- }
- elapsed = std::chrono::high_resolution_clock::now() - stime;
- times_debayer.push_back(elapsed.count());
-
- // Predict 2D poses
- stime = std::chrono::high_resolution_clock::now();
- auto poses_2d_all = kpt_model->predict(images);
- auto poses_2d_upd = utils_pipeline::update_keypoints(
- poses_2d_all, joint_names_2d, whole_body);
- elapsed = std::chrono::high_resolution_clock::now() - stime;
- times_pose2d.push_back(elapsed.count());
-
- all_poses_2d.push_back(std::move(poses_2d_upd));
- }
- std::cout << "|" << std::endl;
-
- // Calculate 3D poses [items, persons, joints, 4]
- std::vector>>> all_poses_3d;
- std::vector all_ids;
- std::string old_scene = "";
- int old_id = -1;
- std::cout << "Calculating 3D poses: |";
- for (size_t i = 0; i < dataset.size(); i++)
- {
- if (i % print_steps == 0)
- {
- std::cout << "#" << std::flush;
- }
- std::chrono::duration elapsed;
- auto &item = dataset[i];
- auto &poses_2d = all_poses_2d[i];
-
- if (old_scene != item["scene"] || old_id + take_interval != item["index"])
- {
- // Reset last poses if scene changes
- tri_model->reset();
- pose_tracker->reset();
- old_scene = item["scene"];
- }
-
- auto stime = std::chrono::high_resolution_clock::now();
- std::vector cameras;
- for (size_t j = 0; j < item["cameras"].size(); j++)
- {
- auto &cam = item["cameras"][j];
- Camera camera;
- camera.name = cam["name"].get();
- camera.K = cam["K"].get, 3>>();
- camera.DC = cam["DC"].get>();
- camera.R = cam["R"].get, 3>>();
- camera.T = cam["T"].get, 3>>();
- camera.width = cam["width"].get();
- camera.height = cam["height"].get();
- camera.type = cam["type"].get();
- cameras.push_back(camera);
- }
- std::array, 2> roomparams = {
- item["room_size"].get>(),
- item["room_center"].get>()};
-
- PoseBatch2D pose_batch_2d = PoseBatch2D::from_nested(poses_2d);
- auto poses_3d = tri_model->triangulate_poses(
- pose_batch_2d, cameras, roomparams, joint_names_2d).to_nested();
- elapsed = std::chrono::high_resolution_clock::now() - stime;
- times_pose3d.push_back(elapsed.count());
-
- if (ifps <= 0)
- {
- // Disable pose tracking if frame rate is too low
- times_tracks.push_back(0.0);
- }
- else
- {
- stime = std::chrono::high_resolution_clock::now();
- double ts = ((int)item["index"]) / ifps;
- auto pose_tracks = pose_tracker->track_poses(poses_3d, joint_names_2d, ts);
- std::vector>> poses_3d_refined;
- for (size_t j = 0; j < pose_tracks.size(); j++)
- {
- auto &pose = std::get<1>(pose_tracks[j]);
- poses_3d_refined.push_back(pose);
- }
- poses_3d = poses_3d_refined;
- elapsed = std::chrono::high_resolution_clock::now() - stime;
- times_tracks.push_back(elapsed.count());
- }
-
- all_poses_3d.push_back(std::move(poses_3d));
- all_ids.push_back(item["id"].get());
- old_id = item["index"];
- }
- std::cout << "|" << std::endl;
-
- // Print timing stats
- std::cout << "\nMetrics:" << std::endl;
- size_t warmup = std::min((size_t)10, time_count - 1);
- double time_image = 0.0;
- double time_debayer = 0.0;
- double time_pose2d = 0.0;
- double time_pose3d = 0.0;
- double time_tracks = 0.0;
- for (size_t i = warmup; i < time_count; i++)
- {
- time_image += times_image[i];
- time_debayer += times_debayer[i];
- time_pose2d += times_pose2d[i];
- time_pose3d += times_pose3d[i];
- time_tracks += times_tracks[i];
- }
- double avg_time_image = time_image / (time_count - warmup);
- double avg_time_debayer = time_debayer / (time_count - warmup);
- double avg_time_pose2d = time_pose2d / (time_count - warmup);
- double avg_time_pose3d = time_pose3d / (time_count - warmup);
- double avg_time_tracks = time_tracks / (time_count - warmup);
- double fps = 1.0 / (avg_time_debayer + avg_time_pose2d + avg_time_pose3d + avg_time_tracks);
- std::cout << "{\n"
- << " \"img_loading\": " << avg_time_image << ",\n"
- << " \"demosaicing\": " << avg_time_debayer << ",\n"
- << " \"avg_time_2d\": " << avg_time_pose2d << ",\n"
- << " \"avg_time_3d\": " << avg_time_pose3d << ",\n"
- << " \"time_tracks\": " << avg_time_tracks << ",\n"
- << " \"fps\": " << fps << "\n"
- << "}" << std::endl;
- tri_model->print_stats();
-
- // Store the results as json
- json all_results;
- all_results["all_ids"] = all_ids;
- all_results["all_poses_2d"] = all_poses_2d;
- all_results["all_poses_3d"] = all_poses_3d;
- all_results["joint_names_2d"] = joint_names_2d;
- all_results["joint_names_3d"] = joint_names_2d;
-
- // Save the results
- std::string path_results = "/tmp/rpt/results.json";
- write_file(path_results, all_results.dump(0));
-
- return 0;
-}
diff --git a/scripts/test_skelda_dataset.py b/scripts/test_skelda_dataset.py
deleted file mode 100644
index 00381c3..0000000
--- a/scripts/test_skelda_dataset.py
+++ /dev/null
@@ -1,513 +0,0 @@
-import json
-import os
-
-import numpy as np
-
-import utils_pipeline
-from skelda import evals
-from skelda.writers import json_writer
-
-# ==================================================================================================
-
-whole_body = {
- "foots": False,
- "face": False,
- "hands": False,
-}
-
-dataset_use = "human36m"
-# dataset_use = "panoptic"
-# dataset_use = "mvor"
-# dataset_use = "shelf"
-# dataset_use = "campus"
-# dataset_use = "ikeaasm"
-# dataset_use = "chi3d"
-# dataset_use = "tsinghua"
-# dataset_use = "human36m_wb"
-# dataset_use = "egohumans_tagging"
-# dataset_use = "egohumans_legoassemble"
-# dataset_use = "egohumans_fencing"
-# dataset_use = "egohumans_basketball"
-# dataset_use = "egohumans_volleyball"
-# dataset_use = "egohumans_badminton"
-# dataset_use = "egohumans_tennis"
-
-
-# Describes the minimum area as fraction of the image size for a 2D bounding box to be considered
-# If the persons are small in the image, use a lower value
-default_min_bbox_area = 0.1 * 0.1
-
-# Describes how confident a 2D bounding box needs to be to be considered
-# If the persons are small in the image, or poorly recognizable, use a lower value
-default_min_bbox_score = 0.3
-
-# Describes how good two 2D poses need to match each other to create a valid triangulation
-# If the quality of the 2D detections is poor, use a lower value
-default_min_match_score = 0.94
-
-# Describes the minimum number of camera pairs that need to detect the same person
-# If the number of cameras is high, and the views are not occluded, use a higher value
-default_min_group_size = 1
-
-# Batch poses per image for faster processing
-# If most of the time only one person is in a image, disable it, because it is slightly slower then
-default_batch_poses = True
-
-# Approach speed of EN ISO 13855 with 2000 mm/sec for hand speed
-# and an additional factor to compensate for noise-based jumps
-default_max_movement_speed = 2.0 * 1.5
-
-# The size of an A4 sheet of paper which is assumed to fit between two different persons
-# and additionally the distance a person can move between two frames (here at 10 fps)
-default_max_track_distance = 0.3 + default_max_movement_speed / 10
-
-
-datasets = {
- "human36m": {
- "path": "/datasets/human36m/skelda/pose_test.json",
- "take_interval": 5,
- "fps": 50,
- "min_match_score": 0.95,
- "min_group_size": 1,
- "min_bbox_score": 0.4,
- "min_bbox_area": 0.1 * 0.1,
- "batch_poses": False,
- "max_movement_speed": 2.0 * 1.5,
- "max_track_distance": 0.3 + default_max_movement_speed / (50 / 5),
- },
- "panoptic": {
- "path": "/datasets/panoptic/skelda/test.json",
- "cams": ["00_03", "00_06", "00_12", "00_13", "00_23"],
- # "cams": ["00_03", "00_06", "00_12"],
- # "cams": ["00_03", "00_06", "00_12", "00_13", "00_23", "00_15", "00_10"],
- # "cams": ["00_03", "00_06", "00_12", "00_13", "00_23", "00_15", "00_10", "00_21", "00_09", "00_01"],
- # "cams": [],
- "take_interval": 3,
- "fps": 30,
- "min_match_score": 0.95,
- "use_scenes": ["160906_pizza1", "160422_haggling1", "160906_ian5"],
- "min_group_size": 1,
- # "min_group_size": 1,
- # "min_group_size": 1,
- # "min_group_size": 2,
- # "min_group_size": 11,
- "min_bbox_area": 0.05 * 0.05,
- "max_track_distance": 0.3 + default_max_movement_speed / (30 / 3),
- },
- "mvor": {
- "path": "/datasets/mvor/skelda/all.json",
- "take_interval": 1,
- "fps": -1,
- "min_match_score": 0.81,
- "min_bbox_score": 0.25,
- },
- "campus": {
- "path": "/datasets/campus/skelda/test.json",
- "fps": 25,
- "take_interval": 1,
- "min_match_score": 0.91,
- "min_bbox_score": 0.5,
- "max_track_distance": 0.3 + default_max_movement_speed / 25,
- },
- "shelf": {
- "path": "/datasets/shelf/skelda/test.json",
- "take_interval": 1,
- "fps": 25,
- "min_match_score": 0.95,
- "min_group_size": 3,
- "max_track_distance": 0.3 + default_max_movement_speed / 25,
- },
- "ikeaasm": {
- "path": "/datasets/ikeaasm/skelda/test.json",
- "take_interval": 2,
- "fps": -1,
- "min_match_score": 0.81,
- "min_bbox_score": 0.20,
- },
- "chi3d": {
- "path": "/datasets/chi3d/skelda/all.json",
- "take_interval": 5,
- "fps": 50,
- "min_match_score": 0.92,
- "min_bbox_area": 0.2 * 0.2,
- "max_track_distance": 0.3 + default_max_movement_speed / (50 / 5),
- },
- "tsinghua": {
- "path": "/datasets/tsinghua/skelda/test.json",
- "take_interval": 3,
- "fps": 30,
- "min_match_score": 0.95,
- "min_group_size": 2,
- "max_track_distance": 0.3 + default_max_movement_speed / (30 / 3),
- },
- "human36m_wb": {
- "path": "/datasets/human36m/skelda/wb/test.json",
- "take_interval": 100,
- "fps": -1,
- "min_bbox_score": 0.4,
- "batch_poses": False,
- },
- "egohumans_tagging": {
- "path": "/datasets/egohumans/skelda/all.json",
- "take_interval": 2,
- "fps": 20,
- "subset": "tagging",
- "min_match_score": 0.89,
- "min_group_size": 1,
- "min_bbox_score": 0.2,
- "min_bbox_area": 0.05 * 0.05,
- "max_movement_speed": 4.0 * 1.5,
- "max_track_distance": 0.3 + (4.0 * 1.5) / (20 / 2),
- },
- "egohumans_legoassemble": {
- "path": "/datasets/egohumans/skelda/all.json",
- "take_interval": 2,
- "fps": 20,
- "subset": "legoassemble",
- "min_group_size": 2,
- "max_track_distance": 0.3 + default_max_movement_speed / (20 / 2),
- },
- "egohumans_fencing": {
- "path": "/datasets/egohumans/skelda/all.json",
- "take_interval": 2,
- "fps": 20,
- "subset": "fencing",
- "min_group_size": 7,
- "min_bbox_score": 0.5,
- "min_bbox_area": 0.05 * 0.05,
- "max_track_distance": 0.3 + default_max_movement_speed / (20 / 2),
- },
- "egohumans_basketball": {
- "path": "/datasets/egohumans/skelda/all.json",
- "take_interval": 2,
- "fps": 20,
- "subset": "basketball",
- "min_group_size": 4,
- "min_bbox_score": 0.25,
- "min_bbox_area": 0.025 * 0.025,
- "max_movement_speed": 4.0 * 1.5,
- "max_track_distance": 0.3 + (4.0 * 1.5) / (20 / 2),
- },
- "egohumans_volleyball": {
- "path": "/datasets/egohumans/skelda/all.json",
- "take_interval": 2,
- "fps": 20,
- "subset": "volleyball",
- "min_match_score": 0.95,
- "min_group_size": 7,
- "min_bbox_score": 0.20,
- "min_bbox_area": 0.05 * 0.05,
- "max_movement_speed": 4.0 * 1.5,
- "max_track_distance": 0.3 + (4.0 * 1.5) / (20 / 2),
- },
- "egohumans_badminton": {
- "path": "/datasets/egohumans/skelda/all.json",
- "take_interval": 2,
- "fps": 20,
- "subset": "badminton",
- "min_group_size": 7,
- "min_bbox_score": 0.25,
- "min_bbox_area": 0.05 * 0.05,
- "max_movement_speed": 4.0 * 1.5,
- "max_track_distance": 0.3 + (4.0 * 1.5) / (20 / 2),
- },
- "egohumans_tennis": {
- "path": "/datasets/egohumans/skelda/all.json",
- "take_interval": 2,
- "fps": 20,
- "subset": "tennis",
- "min_group_size": 11,
- "min_bbox_area": 0.025 * 0.025,
- "max_movement_speed": 4.0 * 1.5,
- "max_track_distance": 0.3 + (4.0 * 1.5) / (20 / 2),
- },
-}
-
-joint_names_2d = utils_pipeline.get_joint_names(whole_body)
-joint_names_3d = list(joint_names_2d)
-eval_joints = [
- "head",
- "shoulder_left",
- "shoulder_right",
- "elbow_left",
- "elbow_right",
- "wrist_left",
- "wrist_right",
- "hip_left",
- "hip_right",
- "knee_left",
- "knee_right",
- "ankle_left",
- "ankle_right",
-]
-if dataset_use == "human36m":
- eval_joints[eval_joints.index("head")] = "nose"
-if dataset_use == "panoptic":
- eval_joints[eval_joints.index("head")] = "nose"
-if dataset_use == "human36m_wb":
- if utils_pipeline.use_whole_body(whole_body):
- eval_joints = list(joint_names_2d)
- else:
- eval_joints[eval_joints.index("head")] = "nose"
-
-# output_dir = "/RapidPoseTriangulation/data/testoutput/"
-output_dir = ""
-
-# pred_export_path = f"/datasets/predictions/{dataset_use}/RapidPoseTriangulation.json"
-pred_export_path = ""
-
-
-# ==================================================================================================
-
-
-def load_labels(dataset: dict):
- """Load labels by dataset description"""
-
- if "panoptic" in dataset:
- labels = utils_pipeline.load_json(dataset["panoptic"]["path"])
- labels = [lb for i, lb in enumerate(labels) if i % 1500 < 90]
-
- # Filter by maximum number of persons
- labels = [l for l in labels if len(l["bodies3D"]) <= 10]
-
- # Filter scenes
- if "use_scenes" in dataset["panoptic"]:
- labels = [
- l for l in labels if l["scene"] in dataset["panoptic"]["use_scenes"]
- ]
-
- # Filter cameras
- if not "cameras_depth" in labels[0] and len(dataset["panoptic"]["cams"]) > 0:
- for label in labels:
- for i, cam in reversed(list(enumerate(label["cameras"]))):
- if cam["name"] not in dataset["panoptic"]["cams"]:
- label["cameras"].pop(i)
- label["imgpaths"].pop(i)
-
- elif "human36m" in dataset:
- labels = utils_pipeline.load_json(dataset["human36m"]["path"])
- labels = [lb for lb in labels if lb["subject"] == "S9"]
- labels = [lb for i, lb in enumerate(labels) if i % 4000 < 150]
-
- elif "mvor" in dataset:
- labels = utils_pipeline.load_json(dataset["mvor"]["path"])
-
- # Rename keys
- for label in labels:
- label["cameras_color"] = label["cameras"]
- label["imgpaths_color"] = label["imgpaths"]
-
- elif "ikeaasm" in dataset:
- labels = utils_pipeline.load_json(dataset["ikeaasm"]["path"])
- cams0 = str(labels[0]["cameras"])
- labels = [lb for lb in labels if str(lb["cameras"]) == cams0]
-
- elif "shelf" in dataset:
- labels = utils_pipeline.load_json(dataset["shelf"]["path"])
- labels = [lb for lb in labels if "test" in lb["splits"]]
-
- elif "campus" in dataset:
- labels = utils_pipeline.load_json(dataset["campus"]["path"])
- labels = [lb for lb in labels if "test" in lb["splits"]]
-
- elif "tsinghua" in dataset:
- labels = utils_pipeline.load_json(dataset["tsinghua"]["path"])
- labels = [lb for lb in labels if "test" in lb["splits"]]
- labels = [lb for lb in labels if lb["seq"] == "seq_1"]
- labels = [lb for i, lb in enumerate(labels) if i % 300 < 90]
-
- for label in labels:
- label["bodyids"] = list(range(len(label["bodies3D"])))
-
- elif "chi3d" in dataset:
- labels = utils_pipeline.load_json(dataset["chi3d"]["path"])
- labels = [lb for lb in labels if lb["setup"] == "s03"]
- labels = [lb for i, lb in enumerate(labels) if i % 2000 < 150]
-
- elif "human36m_wb" in dataset:
- labels = utils_pipeline.load_json(dataset["human36m_wb"]["path"])
-
- elif any(("egohumans" in key for key in dataset)):
- labels = utils_pipeline.load_json(dataset[dataset_use]["path"])
- labels = [lb for lb in labels if "test" in lb["splits"]]
- labels = [lb for lb in labels if dataset[dataset_use]["subset"] in lb["seq"]]
- if dataset[dataset_use]["subset"] in ["volleyball", "tennis"]:
- labels = [lb for i, lb in enumerate(labels) if i % 150 < 60]
-
- else:
- raise ValueError("Dataset not available")
-
- # Optionally drop samples to speed up train/eval
- if "take_interval" in dataset:
- take_interval = dataset["take_interval"]
- if take_interval > 1:
- labels = [l for i, l in enumerate(labels) if i % take_interval == 0]
-
- # Add default values
- for label in labels:
- if "scene" not in label:
- label["scene"] = "default"
- for cam in label["cameras"]:
- if not "type" in cam:
- cam["type"] = "pinhole"
-
- return labels
-
-
-# ==================================================================================================
-
-
-def main():
- global joint_names_3d, eval_joints
-
- print("Loading dataset ...")
- labels = load_labels(
- {
- dataset_use: datasets[dataset_use],
- "take_interval": datasets[dataset_use]["take_interval"],
- }
- )
-
- # Print a dataset sample for debugging
- print("Amount of samples:", len(labels))
- print(labels[0])
-
- # Save dataset
- tmp_export_dir = "/tmp/rpt/"
- for label in labels:
- if "splits" in label:
- label.pop("splits")
- json_writer.save_dataset(labels, tmp_export_dir)
-
- # Load dataset specific parameters
- min_match_score = datasets[dataset_use].get(
- "min_match_score", default_min_match_score
- )
- min_group_size = datasets[dataset_use].get("min_group_size", default_min_group_size)
- min_bbox_score = datasets[dataset_use].get("min_bbox_score", default_min_bbox_score)
- min_bbox_area = datasets[dataset_use].get("min_bbox_area", default_min_bbox_area)
- batch_poses = datasets[dataset_use].get("batch_poses", default_batch_poses)
- max_movement_speed = datasets[dataset_use].get(
- "max_movement_speed", default_max_movement_speed
- )
- max_track_distance = datasets[dataset_use].get(
- "max_track_distance", default_max_track_distance
- )
-
- # Save config
- config_path = tmp_export_dir + "config.json"
- config = {
- "min_match_score": min_match_score,
- "min_group_size": min_group_size,
- "min_bbox_score": min_bbox_score,
- "min_bbox_area": min_bbox_area,
- "batch_poses": batch_poses,
- "max_movement_speed": max_movement_speed,
- "max_track_distance": max_track_distance,
- "whole_body": whole_body,
- "take_interval": datasets[dataset_use]["take_interval"],
- "fps": datasets[dataset_use]["fps"],
- }
- utils_pipeline.save_json(config, config_path)
-
- # Call the CPP binary
- os.system("/RapidPoseTriangulation/scripts/test_skelda_dataset.bin")
-
- # Load the results
- print("Loading exports ...")
- res_path = tmp_export_dir + "results.json"
- results = utils_pipeline.load_json(res_path)
- all_poses_3d = results["all_poses_3d"]
- all_poses_2d = results["all_poses_2d"]
- all_ids = results["all_ids"]
- joint_names_3d = results["joint_names_3d"]
-
- # # Visualize labels and predictions
- # from skelda import utils_view
- # for i in range(0, len(labels), 1):
- # posesL = []
- # posesR = []
- # jnames = []
- # for j in labels[i]["joints"]:
- # if "->" in j:
- # jnames.append(j.split("->")[-1])
- # else:
- # jnames.append(j)
- # for j in range(len(labels[i]["bodies3D"])):
- # pose = []
- # for k in range(len(eval_joints)):
- # n = eval_joints[k]
- # pose.append(labels[i]["bodies3D"][j][jnames.index(n)])
- # posesL.append(pose)
- # for j in range(len(all_poses_3d[i])):
- # pose = []
- # for k in range(len(eval_joints)):
- # n = eval_joints[k]
- # pose.append(all_poses_3d[i][j][joint_names_3d.index(n)])
- # posesR.append(pose)
- # poses_3d = posesL + posesR
- # sample = labels[i]
- # sample["bodies3D"] = np.array(poses_3d).round(3).tolist()
- # sample["joints"] = eval_joints
- # sample["num_persons"] = len(poses_3d)
- # print(sample)
- # utils_view.draw_sample_3d(sample)
- # utils_view.draw_many_images(
- # sample["imgpaths"],
- # sample["cameras"],
- # [],
- # all_poses_2d[i],
- # joint_names_3d,
- # "2D detections",
- # )
- # utils_view.show_plots()
-
- if pred_export_path != "":
- # Export predictions
- print("\nExporting predictions ...")
- all_poses_3d = [np.array(poses).round(3).tolist() for poses in all_poses_3d]
- data = {
- "poses3D": all_poses_3d,
- "ids": all_ids,
- "joint_names": joint_names_3d,
- }
- os.makedirs(os.path.dirname(pred_export_path), exist_ok=True)
- with open(pred_export_path, "w") as file:
- json.dump(data, file, indent=0)
-
- # Run evaluation
- _ = evals.mpjpe.run_eval(
- labels,
- all_poses_3d,
- all_ids,
- joint_names_net=joint_names_3d,
- joint_names_use=eval_joints,
- save_error_imgs=output_dir,
- debug_2D_preds=all_poses_2d,
- )
- _ = evals.pcp.run_eval(
- labels,
- all_poses_3d,
- all_ids,
- joint_names_net=joint_names_3d,
- joint_names_use=eval_joints,
- replace_head_with_nose=True,
- )
-
- if dataset_use == "shelf":
- # Also run old-style evaluation for shelf dataset
- odir = os.path.join(output_dir, "pcp/") if output_dir != "" else ""
- _ = evals.campus_shelf.run_eval(
- labels,
- all_poses_3d,
- all_ids,
- joint_names_net=joint_names_3d,
- save_error_imgs=odir,
- debug_2D_preds=all_poses_2d,
- )
-
-
-# ==================================================================================================
-
-if __name__ == "__main__":
- main()
diff --git a/scripts/test_triangulate.py b/scripts/test_triangulate.py
deleted file mode 100644
index 207ac84..0000000
--- a/scripts/test_triangulate.py
+++ /dev/null
@@ -1,144 +0,0 @@
-import copy
-import json
-import os
-
-import numpy as np
-
-import utils_pipeline
-from skelda import utils_pose, utils_view
-from skelda.writers import json_writer
-
-# ==================================================================================================
-
-filepath = os.path.dirname(os.path.realpath(__file__)) + "/"
-test_img_dir = filepath + "../data/"
-
-whole_body = {
- "foots": False,
- "face": False,
- "hands": False,
-}
-config = {
- "min_match_score": 0.94,
- "min_group_size": 1,
- "min_bbox_score": 0.3,
- "min_bbox_area": 0.1 * 0.1,
- "batch_poses": True,
- "whole_body": whole_body,
- "take_interval": 1,
- "fps": -1,
- "max_movement_speed": 0,
- "max_track_distance": 0,
-}
-
-joint_names_2d = utils_pipeline.get_joint_names(whole_body)
-joint_names_3d = list(joint_names_2d)
-
-
-# ==================================================================================================
-
-
-def update_sample(sample, new_dir=""):
- sample = copy.deepcopy(sample)
-
- # Rename image paths
- sample["imgpaths"] = [
- os.path.join(new_dir, os.path.basename(v)) for v in sample["imgpaths"]
- ]
-
- # Add placeholders for missing keys
- if not "scene" in sample:
- sample["scene"] = "default"
- if not "id" in sample:
- sample["id"] = "0"
- if not "index" in sample:
- sample["index"] = 0
- for cam in sample["cameras"]:
- if not "type" in cam:
- cam["type"] = "pinhole"
-
- return sample
-
-
-# ==================================================================================================
-
-
-def main():
-
- for dirname in sorted(os.listdir(test_img_dir)):
- dirpath = os.path.join(test_img_dir, dirname)
-
- if not os.path.isdir(dirpath):
- continue
-
- if (dirname[0] not in ["p", "h", "e", "q"]) or len(dirname) != 2:
- continue
-
- # Load sample infos
- print("\n" + dirpath)
- with open(os.path.join(dirpath, "sample.json"), "r", encoding="utf-8") as file:
- sample = json.load(file)
- sample = update_sample(sample, dirpath)
-
- if len(sample["imgpaths"]) == 1:
- # At least two images are required
- continue
-
- # Save dataset
- labels = [sample]
- tmp_export_dir = "/tmp/rpt/"
- for label in labels:
- if "splits" in label:
- label.pop("splits")
- json_writer.save_dataset(labels, tmp_export_dir)
-
- # Save config
- config_path = tmp_export_dir + "config.json"
- utils_pipeline.save_json(config, config_path)
-
- # Call the CPP binary
- os.system("/RapidPoseTriangulation/scripts/test_skelda_dataset.bin")
-
- # Load the results
- print("Loading exports ...")
- res_path = tmp_export_dir + "results.json"
- results = utils_pipeline.load_json(res_path)
- poses_3d = results["all_poses_3d"][0]
- poses_2d = results["all_poses_2d"][0]
- joint_names_3d = results["joint_names_3d"]
-
- # Visualize the 2D results
- fig1 = utils_view.draw_many_images(
- sample["imgpaths"], [], [], poses_2d, joint_names_2d, "2D detections"
- )
- fig1.savefig(os.path.join(dirpath, "2d-k.png"), dpi=fig1.dpi)
-
- # Visualize the 3D results
- print("Detected 3D poses:")
- poses_3d = np.array(poses_3d)
- print(poses_3d.round(3))
- if len(poses_3d) == 0:
- utils_view.show_plots()
- continue
- camparams = sample["cameras"]
- roomparams = {
- "room_size": sample["room_size"],
- "room_center": sample["room_center"],
- }
- poses_2d_proj = []
- for cam in camparams:
- poses_2d_cam, _ = utils_pose.project_poses(poses_3d, cam)
- poses_2d_proj.append(poses_2d_cam)
- fig2 = utils_view.draw_poses3d(poses_3d, joint_names_3d, roomparams, camparams)
- fig3 = utils_view.draw_many_images(
- sample["imgpaths"], [], [], poses_2d_proj, joint_names_3d, "2D projections"
- )
- fig2.savefig(os.path.join(dirpath, "3d-p.png"), dpi=fig2.dpi)
- fig3.savefig(os.path.join(dirpath, "2d-p.png"), dpi=fig3.dpi)
- utils_view.show_plots()
-
-
-# ==================================================================================================
-
-if __name__ == "__main__":
- main()
diff --git a/scripts/utils_2d_pose.hpp b/scripts/utils_2d_pose.hpp
deleted file mode 100644
index 85b66a8..0000000
--- a/scripts/utils_2d_pose.hpp
+++ /dev/null
@@ -1,1161 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-// =================================================================================================
-// =================================================================================================
-
-namespace utils_2d_pose
-{
-
- class BaseModel
- {
- public:
- explicit BaseModel(const std::string &model_path, int warmup_iterations);
- virtual ~BaseModel() = default;
-
- std::vector>> call_by_image(
- const std::vector &images);
-
- protected:
- static Ort::Env &get_env()
- {
- // Static method to create or retrieve a single global Ort::Env
- static Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "tensorrt_model_env");
- // static Ort::Env env(ORT_LOGGING_LEVEL_VERBOSE, "tensorrt_model_env");
- return env;
- }
-
- // Initialize ONNX Runtime session with TensorRT provider
- void init_onnx_runtime(const std::string &model_path);
-
- // Generate random input data, run forward pass
- void warmup(int epoch);
-
- // Actually run the session with given input tensors
- std::vector call_model(const std::vector &inputs);
-
- // Utility to check if a string ends with a given suffix
- bool ends_with(const std::string &str, const std::string &suffix)
- {
- if (str.size() < suffix.size())
- return false;
- return (str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0);
- }
-
- protected:
- Ort::SessionOptions session_options;
- std::unique_ptr session;
- Ort::AllocatorWithDefaultOptions allocator;
-
- std::vector input_names;
- std::vector> input_shapes;
- std::vector input_types;
- std::vector output_names;
- std::vector input_name_ptrs;
- std::vector output_name_ptrs;
- };
-
- // =============================================================================================
-
- BaseModel::BaseModel(const std::string &model_path, int warmup_iterations)
- {
- if (!std::filesystem::exists(model_path))
- {
- throw std::runtime_error("File not found: " + model_path);
- }
-
- if (!ends_with(model_path, ".onnx"))
- {
- throw std::runtime_error("Only .onnx models are supported: " + model_path);
- }
-
- std::cout << "Loading model: " << model_path << std::endl;
- init_onnx_runtime(model_path);
-
- if (warmup_iterations > 0)
- {
- std::cout << "Running warmup ...\n";
- warmup((int)warmup_iterations / 2);
- warmup((int)warmup_iterations / 2);
- }
- }
-
- // =============================================================================================
-
- void BaseModel::init_onnx_runtime(const std::string &model_path)
- {
- // 0) Create env
- Ort::Env &env = get_env();
-
- session_options = Ort::SessionOptions();
- session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);
-
- // 1) Create TensorRT provider options
- OrtTensorRTProviderOptionsV2 *tensorrt_options = nullptr;
- Ort::ThrowOnError(Ort::GetApi().CreateTensorRTProviderOptions(&tensorrt_options));
-
- // 2) Configure runtime options
- tensorrt_options->trt_max_workspace_size = 2147483647;
- tensorrt_options->trt_engine_cache_enable = 1;
- tensorrt_options->trt_engine_cache_path = "/RapidPoseTriangulation/data/trt_cache/";
- if (model_path.find("_fp16") != std::string::npos)
- {
- tensorrt_options->trt_fp16_enable = 1;
- }
- else
- {
- tensorrt_options->trt_fp16_enable = 0;
- }
- if (model_path.find("_Bx") != std::string::npos)
- {
- tensorrt_options->trt_profile_min_shapes = "image_input:1x384x288x3";
- tensorrt_options->trt_profile_max_shapes = "image_input:10x384x288x3";
- tensorrt_options->trt_profile_opt_shapes = "image_input:3x384x288x3";
- }
-
- // 3) Append to session options
- Ort::ThrowOnError(
- Ort::GetApi().SessionOptionsAppendExecutionProvider_TensorRT_V2(
- static_cast(session_options),
- tensorrt_options));
-
- // 4) Create the session
- session = std::make_unique(env, model_path.c_str(), session_options);
-
- // 5) Gather input info
- size_t num_inputs = session->GetInputCount();
- for (size_t i = 0; i < num_inputs; i++)
- {
- Ort::AllocatedStringPtr iname = session->GetInputNameAllocated(i, allocator);
- input_names.push_back(iname.get());
-
- Ort::TypeInfo type_info = session->GetInputTypeInfo(i);
- auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
-
- input_shapes.push_back(tensor_info.GetShape());
- input_types.push_back(tensor_info.GetElementType());
- }
-
- // Gather output info to avoid "At least one output should be requested."
- size_t num_outputs = session->GetOutputCount();
- for (size_t i = 0; i < num_outputs; i++)
- {
- Ort::AllocatedStringPtr oname = session->GetOutputNameAllocated(i, allocator);
- output_names.push_back(oname.get());
- }
-
- // Build array of input name C-strings
- input_name_ptrs.resize(input_names.size());
- for (size_t i = 0; i < input_names.size(); i++)
- {
- input_name_ptrs[i] = input_names[i].c_str();
- }
-
- // Build array of output name C-strings
- output_name_ptrs.resize(output_names.size());
- for (size_t i = 0; i < output_names.size(); i++)
- {
- output_name_ptrs[i] = output_names[i].c_str();
- }
- }
-
- // =============================================================================================
-
- void BaseModel::warmup(int epoch)
- {
- std::vector use_batch_sizes = {4, 10, 5, 1, 9, 3, 7, 2, 8, 4, 6, 1, 3, 7, 2};
-
- std::cout << "Warmup: ";
- for (int e = 0; e < epoch; e++)
- {
- // Extract the 4D shape.
- auto shape = input_shapes[0];
- int batch_size = static_cast(shape[0]);
- int height = static_cast(shape[1]);
- int width = static_cast(shape[2]);
- int channels = static_cast(shape[3]);
-
- // We'll only handle batch=1 in this example
- if (batch_size != 1)
- {
- batch_size = use_batch_sizes[e % use_batch_sizes.size()];
- }
-
- std::vector images;
- for (int i = 0; i < batch_size; i++)
- {
- // Create a multi-channel Mat of shape (Height, Width, Channels)
- cv::Mat img(height, width, CV_8UC(channels));
- if (channels == 1)
- {
- cv::randu(img, 0, 256);
- }
- else if (channels == 3)
- {
- cv::randu(img, cv::Scalar(0, 0, 0), cv::Scalar(256, 256, 256));
- }
- else
- {
- throw std::runtime_error("Unsupported number of channels for warmup.");
- }
-
- images.push_back(std::move(img));
- }
-
- // Call the model
- auto outputs = call_by_image(images);
- std::cout << "#";
- }
-
- std::cout << std::endl;
- }
-
- // =============================================================================================
-
- std::vector>> BaseModel::call_by_image(
- const std::vector &images)
- {
- size_t batch_size = images.size();
- int height = images[0].rows;
- int width = images[0].cols;
- int channels = images[0].channels();
-
- // Flatten into single vector
- size_t single_img_size = height * width * channels;
- size_t total_elems = batch_size * single_img_size;
- std::vector batch_data(total_elems);
- for (size_t b = 0; b < batch_size; b++)
- {
- auto &img = images[b];
- if (img.rows != height || img.cols != width || img.channels() != channels)
- {
- throw std::runtime_error("All images must have the same dimensions!");
- }
- std::memcpy(batch_data.data() + b * single_img_size, img.data, single_img_size);
- }
-
- // Create an onnx tensor
- auto mem_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
- std::vector shape = {
- static_cast(batch_size),
- static_cast(height),
- static_cast(width),
- static_cast(channels),
- };
- Ort::Value input_tensor = Ort::Value::CreateTensor(
- mem_info,
- batch_data.data(),
- total_elems,
- shape.data(),
- shape.size());
-
- // Call model
- std::vector input_tensors;
- input_tensors.push_back(std::move(input_tensor));
- auto outputs = call_model(input_tensors);
-
- // Get pointer to ouput tensor
- const float *tensor_data = outputs[0].GetTensorData();
- auto data_info = outputs[0].GetTensorTypeAndShapeInfo();
- auto shape0 = data_info.GetShape();
- size_t B = (size_t)shape0[0];
- size_t N = (size_t)shape0[1];
- size_t C = (size_t)shape0[2];
-
- // Convert to vector of values
- std::vector>> data;
- data.reserve(B);
- for (size_t i = 0; i < B; i++)
- {
- std::vector> item;
- item.reserve(N);
- for (size_t j = 0; j < N; j++)
- {
- std::vector values;
- values.reserve(C);
- for (size_t k = 0; k < C; k++)
- {
- values.push_back(tensor_data[i * N * C + j * C + k]);
- }
- item.push_back(values);
- }
- data.push_back(item);
- }
-
- return data;
- }
-
- // =============================================================================================
-
- std::vector BaseModel::call_model(const std::vector &inputs)
- {
- if (inputs.size() != input_names.size())
- {
- throw std::runtime_error("Number of input tensors does not match model's input count.");
- }
-
- // Actually run the model, requesting all known outputs
- return session->Run(
- Ort::RunOptions{nullptr},
- input_name_ptrs.data(),
- inputs.data(),
- inputs.size(),
- output_name_ptrs.data(),
- output_name_ptrs.size());
- }
-
- // =============================================================================================
- // =============================================================================================
-
- class LetterBox
- {
- public:
- LetterBox(const std::array &target_size, int fill_value = 0)
- {
- this->target_size = target_size;
- this->fill_value = fill_value;
- }
-
- std::tuple, double, std::array> calc_params(
- const cv::Mat &image) const;
- cv::Mat resize_image(const cv::Mat &image) const;
-
- private:
- std::array target_size;
- int fill_value;
- };
-
- // =============================================================================================
-
- std::tuple, double, std::array> LetterBox::calc_params(
- const cv::Mat &image) const
- {
- // Original dimensions
- int img_h = image.rows;
- int img_w = image.cols;
-
- // Target dimensions
- int target_h = static_cast(target_size[0]);
- int target_w = static_cast(target_size[1]);
-
- // Scale factor
- double scale = std::min(
- static_cast(target_w) / static_cast(img_w),
- static_cast(target_h) / static_cast(img_h));
-
- // Compute new width/height (round to nearest int)
- int new_w = static_cast(std::round(img_w * scale));
- int new_h = static_cast(std::round(img_h * scale));
-
- // Calculate padding
- int pad_w = target_w - new_w;
- int pad_h = target_h - new_h;
-
- int pad_left = pad_w / 2;
- int pad_top = pad_h / 2;
- int pad_right = pad_w - pad_left;
- int pad_bottom = pad_h - pad_top;
-
- std::array paddings = {pad_left, pad_right, pad_top, pad_bottom};
- std::array new_size = {(size_t)new_w, (size_t)new_h};
-
- return {paddings, scale, new_size};
- }
-
- // =============================================================================================
-
- cv::Mat LetterBox::resize_image(const cv::Mat &image) const
- {
- // 1) Compute letterbox params
- auto [paddings, scale, new_sz] = calc_params(image);
- int pad_left = paddings[0];
- int pad_right = paddings[1];
- int pad_top = paddings[2];
- int pad_bottom = paddings[3];
-
- // 2) Resize using nearest-neighbor interpolation
- cv::Mat resized_img;
- cv::Size cv_new_sz = cv::Size(new_sz[0], new_sz[1]);
- cv::resize(image, resized_img, cv_new_sz, /*fx=*/0, /*fy=*/0, cv::INTER_NEAREST);
-
- // 3) Pad if needed
- if (pad_left == 0 && pad_right == 0 && pad_top == 0 && pad_bottom == 0)
- {
- // No padding required
- return resized_img;
- }
- else
- {
- cv::Mat final_img;
- cv::Scalar fill_color(fill_value, fill_value, fill_value);
-
- cv::copyMakeBorder(
- resized_img, final_img,
- pad_top, pad_bottom,
- pad_left, pad_right,
- cv::BORDER_CONSTANT,
- fill_color);
- return final_img;
- }
- }
-
- // =============================================================================================
- // =============================================================================================
-
- class BoxCrop
- {
- public:
- BoxCrop(const std::array &target_size,
- float padding_scale = 1.0f,
- int fill_value = 0)
- {
- this->target_size = target_size;
- this->padding_scale = padding_scale;
- this->fill_value = fill_value;
- }
-
- std::tuple, float, std::array, std::array>
- calc_params(const cv::Mat &image, const std::array &bbox) const;
-
- cv::Mat crop_resize_box(const cv::Mat &image,
- const std::array &bbox) const;
-
- private:
- std::array target_size;
- float padding_scale;
- int fill_value;
- };
-
- // =============================================================================================
-
- std::tuple, float, std::array, std::array>
- BoxCrop::calc_params(const cv::Mat &image, const std::array &bbox) const
- {
- // Extract some params
- int img_h = image.rows;
- int img_w = image.cols;
- int target_h = target_size[0];
- int target_w = target_size[1];
-
- // Round the bounding box coordinates
- float start_x = std::floor(bbox[0]);
- float start_y = std::floor(bbox[1]);
- float end_x = std::ceil(bbox[2]);
- float end_y = std::ceil(bbox[3]);
-
- // Calculate original bounding box center
- float center_x = 0.5f * (start_x + end_x);
- float center_y = 0.5f * (start_y + end_y);
-
- // Scale the bounding box by the padding_scale
- float bbox_w = end_x - start_x;
- float bbox_h = end_y - start_y;
- float scaled_w = bbox_w * padding_scale;
- float scaled_h = bbox_h * padding_scale;
-
- // Calculate the aspect ratios
- float bbox_aspect = scaled_w / scaled_h;
- float target_aspect = static_cast(target_w) / static_cast(target_h);
-
- // Adjust the scaled bounding box to match the target aspect ratio
- float adjusted_w, adjusted_h;
- if (bbox_aspect > target_aspect)
- {
- adjusted_w = scaled_w;
- adjusted_h = scaled_w / target_aspect;
- }
- else
- {
- adjusted_h = scaled_h;
- adjusted_w = scaled_h * target_aspect;
- }
-
- // Calculate scaled bounding box coordinates
- float new_start_xf = center_x - 0.5f * adjusted_w;
- float new_start_yf = center_y - 0.5f * adjusted_h;
- float new_end_xf = center_x + 0.5f * adjusted_w;
- float new_end_yf = center_y + 0.5f * adjusted_h;
-
- // Round the box coordinates
- int start_xi = static_cast(std::floor(new_start_xf));
- int start_yi = static_cast(std::floor(new_start_yf));
- int end_xi = static_cast(std::ceil(new_end_xf));
- int end_yi = static_cast(std::ceil(new_end_yf));
-
- // Define the new box coordinates
- int new_start_x = std::max(0, start_xi);
- int new_start_y = std::max(0, start_yi);
- int new_end_x = std::min(img_w - 1, end_xi);
- int new_end_y = std::min(img_h - 1, end_yi);
- std::array new_box{new_start_x, new_start_y, new_end_x, new_end_y};
-
- // Calculate resized crop size
- int clipped_w = new_box[2] - new_box[0];
- int clipped_h = new_box[3] - new_box[1];
- float scale_w = static_cast(target_w) / static_cast(clipped_w);
- float scale_h = static_cast(target_h) / static_cast(clipped_h);
- float scale = std::min(scale_w, scale_h);
- int new_w = static_cast(std::round(clipped_w * scale));
- int new_h = static_cast(std::round(clipped_h * scale));
-
- // Calculate paddings
- int pad_w = target_w - new_w;
- int pad_h = target_h - new_h;
- int pad_left = 0;
- int pad_right = 0;
- int pad_top = 0;
- int pad_bottom = 0;
- if (pad_w > 0)
- {
- if (start_xi < 0)
- {
- pad_left = pad_w;
- pad_right = 0;
- }
- else if (end_xi > img_w)
- {
- pad_left = 0;
- pad_right = pad_w;
- }
- else
- {
- // Can be caused by bbox rounding
- pad_left = pad_w / 2;
- pad_right = pad_w - pad_left;
- }
- }
- if (pad_h > 0)
- {
- if (start_yi < 0)
- {
- pad_top = pad_h;
- pad_bottom = 0;
- }
- else if (end_yi > img_h)
- {
- pad_top = 0;
- pad_bottom = pad_h;
- }
- else
- {
- // Can be caused by bbox rounding
- pad_top = pad_h / 2;
- pad_bottom = pad_h - pad_top;
- }
- }
- std::array paddings{pad_left, pad_right, pad_top, pad_bottom};
-
- return {paddings, scale, new_box, {(size_t)new_w, (size_t)new_h}};
- }
-
- // =============================================================================================
-
- cv::Mat BoxCrop::crop_resize_box(const cv::Mat &image,
- const std::array &bbox) const
- {
- auto [paddings, _, new_box, new_size] = calc_params(image, bbox);
-
- // Extract the bounding box
- int x1 = new_box[0];
- int y1 = new_box[1];
- int x2 = new_box[2];
- int y2 = new_box[3];
- cv::Rect roi(x1, y1, x2 - x1, y2 - y1);
- cv::Mat cropped_img = image(roi);
-
- // Resize the image
- cv::Size new_size_cv = cv::Size(new_size[0], new_size[1]);
- cv::Mat resized_img;
- cv::resize(cropped_img, resized_img, new_size_cv, 0, 0, cv::INTER_NEAREST);
-
- // Optionally pad the image
- int pad_left = paddings[0];
- int pad_right = paddings[1];
- int pad_top = paddings[2];
- int pad_bottom = paddings[3];
- if (pad_left == 0 && pad_right == 0 && pad_top == 0 && pad_bottom == 0)
- {
- // No padding
- return resized_img;
- }
- else
- {
- cv::Mat final_img;
- cv::Scalar fill_color(fill_value, fill_value, fill_value);
- cv::copyMakeBorder(
- resized_img,
- final_img,
- pad_top,
- pad_bottom,
- pad_left,
- pad_right,
- cv::BORDER_CONSTANT,
- fill_color);
- return final_img;
- }
- }
-
- // =============================================================================================
- // =============================================================================================
-
- class RTMDet : public BaseModel
- {
- public:
- RTMDet(const std::string &model_path,
- float conf_threshold,
- float min_area_fraction,
- int warmup = 30)
- : BaseModel(model_path, warmup)
- {
- this->target_size = {320, 320};
- this->conf_threshold = conf_threshold;
-
- float img_area = target_size[0] * target_size[1];
- this->min_area = img_area * min_area_fraction;
-
- this->letterbox = std::make_unique(target_size, 114);
- }
-
- std::vector> call(const cv::Mat &image);
-
- private:
- std::array target_size;
- float conf_threshold;
- float min_area;
- std::unique_ptr letterbox;
-
- cv::Mat preprocess(const cv::Mat &image);
- std::vector> postprocess(
- const std::vector>> &result,
- const cv::Mat &image);
-
- void clip_boxes(std::vector> &boxes,
- const cv::Mat &image) const;
- };
-
- // =============================================================================================
-
- std::vector> RTMDet::call(const cv::Mat &image)
- {
- cv::Mat preprocessed = preprocess(image);
- std::vector inputs = {preprocessed};
- auto results = call_by_image(inputs);
- auto outputs = postprocess(results, image);
- return outputs;
- }
-
- // =============================================================================================
-
- cv::Mat RTMDet::preprocess(const cv::Mat &image)
- {
- cv::Mat resized = letterbox->resize_image(image);
- return resized;
- }
-
- // =============================================================================================
-
- std::vector> RTMDet::postprocess(
- const std::vector>> &result,
- const cv::Mat &image)
- {
- // Expected result shape: [B, N, 6] => (x1,y1,x2,y2,score,class)
-
- // Convert to vector of boxes
- std::vector> boxes;
- for (auto &item : result[0])
- {
- float x1 = item[0];
- float y1 = item[1];
- float x2 = item[2];
- float y2 = item[3];
- float score = item[4];
- float cls = item[5];
- boxes.push_back({x1, y1, x2, y2, score, cls});
- }
-
- if (boxes.empty())
- {
- return {};
- }
-
- // Filter by confidence + area
- for (int i = boxes.size() - 1; i >= 0; i--)
- {
- auto &b = boxes[i];
- if (b[4] < conf_threshold)
- {
- boxes.erase(boxes.begin() + i);
- continue;
- }
-
- float area = (b[2] - b[0]) * (b[3] - b[1]);
- if (area < min_area)
- {
- boxes.erase(boxes.begin() + i);
- }
- }
-
- if (boxes.empty())
- {
- return {};
- }
-
- // Shift by letterbox padding and scale back
- clip_boxes(boxes, image);
-
- return boxes;
- }
-
- // =============================================================================================
-
- void RTMDet::clip_boxes(std::vector> &boxes,
- const cv::Mat &image) const
- {
- // Get paddings, scale from letterbox
- auto [paddings, scale, _] = letterbox->calc_params(image);
- int pad_left = paddings[0];
- int pad_right = paddings[1];
- int pad_top = paddings[2];
- int pad_bottom = paddings[3];
-
- // The effective region in the letterboxed image
- float letter_w = static_cast(target_size[1] - (pad_left + pad_right));
- float letter_h = static_cast(target_size[0] - (pad_top + pad_bottom));
-
- for (auto &b : boxes)
- {
- float &x1 = b[0];
- float &y1 = b[1];
- float &x2 = b[2];
- float &y2 = b[3];
-
- // Shift by left/top
- x1 -= pad_left;
- x2 -= pad_left;
- y1 -= pad_top;
- y2 -= pad_top;
-
- // Clamp to letterbox region
- x1 = std::max(0.f, std::min(x1, letter_w - 1.0f));
- x2 = std::max(0.f, std::min(x2, letter_w - 1.0f));
- y1 = std::max(0.f, std::min(y1, letter_h - 1.0f));
- y2 = std::max(0.f, std::min(y2, letter_h - 1.0f));
-
- // Scale back to original resolution
- x1 /= scale;
- x2 /= scale;
- y1 /= scale;
- y2 /= scale;
- }
- }
-
- // =============================================================================================
- // =============================================================================================
-
- class RTMPose : public BaseModel
- {
- public:
- RTMPose(const std::string &model_path,
- int warmup = 30)
- : BaseModel(model_path, warmup)
- {
- this->target_size = {384, 288};
- this->boxcrop = std::make_unique(target_size, 1.25f, 114);
- }
-
- std::vector>> call(const cv::Mat &image,
- const std::vector> &bboxes);
-
- private:
- std::array target_size;
- std::unique_ptr boxcrop;
-
- std::vector preprocess(
- const cv::Mat &image,
- const std::vector> &bboxes);
- std::vector>> postprocess(
- const std::vector>> &result,
- const cv::Mat &image,
- const std::vector> &bboxes);
-
- void clip_keypoints(std::vector> &kp,
- const cv::Mat &image,
- const std::array &bbox) const;
- };
-
- // =============================================================================================
-
- std::vector>> RTMPose::call(
- const cv::Mat &image, const std::vector> &bboxes)
- {
- std::vector inputs = preprocess(image, bboxes);
- auto results = call_by_image(inputs);
- auto outputs = postprocess(results, image, bboxes);
- return outputs;
- }
-
- // =============================================================================================
-
- std::vector RTMPose::preprocess(
- const cv::Mat &image, const std::vector> &bboxes)
- {
- std::vector crops;
- for (auto &bbox : bboxes)
- {
- cv::Mat cropped = boxcrop->crop_resize_box(image, bbox);
- crops.push_back(std::move(cropped));
- }
-
- return crops;
- }
-
- // =============================================================================================
-
- std::vector>> RTMPose::postprocess(
- const std::vector>> &result,
- const cv::Mat &image,
- const std::vector> &bboxes)
- {
- // Expected result shape: [B, N, 3] => (x,y,score)
- std::vector>> keypoints;
- for (size_t i = 0; i < result.size(); i++)
- {
- // Convert to vector of keypoints
- std::vector> kpts;
- for (auto &item : result[i])
- {
- float x = item[0];
- float y = item[1];
- float score = item[2];
-
- kpts.push_back({x, y, score});
- }
-
- if (!kpts.empty())
- {
- // Shift by boxcrop padding and scale back
- clip_keypoints(kpts, image, bboxes[i]);
- keypoints.push_back(std::move(kpts));
- }
- }
-
- return keypoints;
- }
-
- // =============================================================================================
-
- void RTMPose::clip_keypoints(std::vector> &kpts,
- const cv::Mat &image,
- const std::array &bbox) const
- {
- // Get paddings, scale from boxcrop
- auto [paddings, scale, box, _] = boxcrop->calc_params(image, bbox);
- int pad_left = paddings[0];
- int pad_top = paddings[2];
- int box_left = box[0];
- int box_top = box[1];
-
- for (auto &kp : kpts)
- {
- float &x = kp[0];
- float &y = kp[1];
-
- // Shift by left/top
- x -= pad_left;
- y -= pad_top;
-
- x /= scale;
- y /= scale;
-
- x += box_left;
- y += box_top;
- }
- }
-
- // =============================================================================================
- // =============================================================================================
-
- class TopDown
- {
- public:
- TopDown(const std::string &det_model_path,
- const std::string &pose_model_path,
- float box_conf_threshold,
- float box_min_area,
- bool batch_poses = false,
- int warmup = 30)
- {
- this->batch_poses = batch_poses;
-
- this->det_model = std::make_unique(
- det_model_path, box_conf_threshold, box_min_area, warmup);
- this->pose_model = std::make_unique(pose_model_path, warmup);
- }
-
- std::vector>> predict(const cv::Mat &image);
-
- private:
- std::unique_ptr det_model;
- std::unique_ptr pose_model;
- bool batch_poses;
-
- void merge_close_poses(
- std::vector>> &poses,
- std::array image_size);
- };
-
- // =============================================================================================
-
- std::vector>> TopDown::predict(const cv::Mat &image)
- {
- auto bboxes = det_model->call(image);
-
- // Drop boxes with non-person class
- for (int i = bboxes.size() - 1; i >= 0; i--)
- {
- if (static_cast(bboxes[i][5]) != 0)
- {
- bboxes.erase(bboxes.begin() + i);
- }
- }
-
- std::vector>> poses;
- if (this->batch_poses)
- {
- if (!bboxes.empty())
- {
- poses = std::move(pose_model->call(image, bboxes));
- }
- }
- else
- {
- for (size_t i = 0; i < bboxes.size(); i++)
- {
- auto kpts = pose_model->call(image, {bboxes[i]});
- poses.push_back(std::move(kpts[0]));
- }
- }
-
- // Sometimes the detection model predicts multiple boxes with different shapes for the same
- // person. They then result in strongly overlapping poses, which are merged here.
- merge_close_poses(poses, {(size_t)image.cols, (size_t)image.rows});
-
- // Clip keypoints far outside the image
- float mask_offset = (image.cols + image.rows) / 10.0;
- for (size_t i = 0; i < poses.size(); ++i)
- {
- for (size_t j = 0; j < poses[i].size(); ++j)
- {
- auto &kp = poses[i][j];
- if (kp[0] < -mask_offset)
- {
- kp[0] = -mask_offset;
- kp[2] = 0.001;
- }
- if (kp[1] < -mask_offset)
- {
- kp[1] = -mask_offset;
- kp[2] = 0.001;
- }
- if (kp[0] >= image.cols + mask_offset)
- {
- kp[0] = image.cols + mask_offset;
- kp[2] = 0.001;
- }
- if (kp[1] >= image.rows + mask_offset)
- {
- kp[1] = image.rows + mask_offset;
- kp[2] = 0.001;
- }
- }
- }
-
- return poses;
- }
-
- // =============================================================================================
-
- void TopDown::merge_close_poses(
- std::vector>> &poses,
- std::array image_size)
- {
- // Joint ids in COCO order
- const size_t num_overlaps = 5;
- const std::map joint_indices = {
- {"nose", 0},
- {"left_shoulder", 5},
- {"right_shoulder", 6},
- {"left_hip", 11},
- {"right_hip", 12},
- {"left_elbow", 7},
- {"right_elbow", 8},
- };
-
- if (poses.size() < 2)
- {
- return;
- }
-
- // Calculate pixel threshold based on image size
- size_t min_dim = std::min(image_size[0], image_size[1]);
- float pixel_threshold = 0.025f * min_dim;
-
- // Merge poses if enough joints are close
- std::vector>> merged_poses;
- merged_poses.reserve(poses.size());
- for (auto &opose : poses)
- {
- bool merged = false;
- for (auto &mpose : merged_poses)
- {
- size_t close_count = 0;
- for (auto &kv : joint_indices)
- {
- size_t joint_id = kv.second;
- float x1 = opose[joint_id][0];
- float y1 = opose[joint_id][1];
- float c1 = opose[joint_id][2];
-
- float x2 = mpose[joint_id][0];
- float y2 = mpose[joint_id][1];
- float c2 = mpose[joint_id][2];
-
- if (c1 > 0.0f && c2 > 0.0f)
- {
- float dx = x1 - x2;
- float dy = y1 - y2;
- float dist_sq = dx * dx + dy * dy;
- if (dist_sq <= pixel_threshold * pixel_threshold)
- {
- ++close_count;
- }
- }
- }
-
- if (close_count >= num_overlaps)
- {
- // Merge new pose with existing one
- for (size_t j = 0; j < mpose.size(); ++j)
- {
- if (opose[j][2] > mpose[j][2])
- {
- mpose[j] = std::move(opose[j]);
- }
- }
- merged = true;
- break;
- }
- }
- if (!merged)
- {
- // Not mergeable, add as new pose
- merged_poses.push_back(std::move(opose));
- }
- }
-
- // Replace original poses with merged ones
- poses = std::move(merged_poses);
- }
-
- // =============================================================================================
- // =============================================================================================
-
- class PosePredictor
- {
- public:
- PosePredictor(bool whole_body,
- float min_bbox_score,
- float min_bbox_area,
- bool batch_poses = false)
- {
- std::string base_path = "/RapidPoseTriangulation/extras/mmdeploy/exports/";
-
- std::string path_det_n1 = base_path + "rtmdet-nano_1x320x320x3_fp16_extra-steps.onnx";
- std::string path_det_m1 = base_path + "rtmdet-m_1x320x320x3_fp16_extra-steps.onnx";
-
- std::string path_pose_m1 = base_path + "rtmpose-m_1x384x288x3_fp16_extra-steps.onnx";
- std::string path_pose_mb = base_path + "rtmpose-m_Bx384x288x3_fp16_extra-steps.onnx";
- std::string path_pose_w1 = base_path + "rtmpose-l_wb_1x384x288x3_fp16_extra-steps.onnx";
- std::string path_pose_wb = base_path + "rtmpose-l_wb_Bx384x288x3_fp16_extra-steps.onnx";
-
- this->num_joints = whole_body ? 133 : 17;
- std::string path_det;
- std::string path_pose;
- if (!whole_body)
- {
- path_det = path_det_n1;
- if (!batch_poses)
- {
- path_pose = path_pose_m1;
- }
- else
- {
- path_pose = path_pose_mb;
- }
- }
- else
- {
- path_det = path_det_m1;
- if (!batch_poses)
- {
- path_pose = path_pose_w1;
- }
- else
- {
- path_pose = path_pose_wb;
- }
- }
-
- std::cout << "Loading 2D" + std::string(whole_body ? "-WB" : "") + " models ..."
- << std::endl;
-
- this->topdown_model = std::make_unique(
- path_det, path_pose, min_bbox_score, min_bbox_area, batch_poses, 30);
-
- std::cout << "Loaded models \n"
- << std::endl;
- }
-
- std::vector>>> predict(
- const std::vector &images);
-
- private:
- std::unique_ptr topdown_model;
- size_t num_joints;
- };
-
- // =============================================================================================
-
- std::vector>>> PosePredictor::predict(
- const std::vector &images)
- {
- std::vector>>> keypoints;
- for (auto &img : images)
- {
- auto kpts = topdown_model->predict(img);
-
- if (!kpts.empty())
- {
- keypoints.push_back(std::move(kpts));
- }
- else
- {
- // create zero keypoints
- std::vector>> zero_keypoints;
- zero_keypoints.resize(1);
- zero_keypoints[0].resize(num_joints, {0.0f, 0.0f, 0.0f});
- keypoints.push_back(std::move(zero_keypoints));
- }
- }
- return keypoints;
- }
-}
diff --git a/scripts/utils_pipeline.hpp b/scripts/utils_pipeline.hpp
deleted file mode 100644
index 8744c2a..0000000
--- a/scripts/utils_pipeline.hpp
+++ /dev/null
@@ -1,316 +0,0 @@
-#pragma once
-
-#include
-#include
-
-#include
-
-// =================================================================================================
-
-namespace utils_pipeline
-{
- bool use_whole_body(const std::map &whole_body)
- {
- for (const auto &pair : whole_body)
- {
- if (pair.second)
- {
- return true;
- }
- }
- return false;
- }
-
- // =============================================================================================
-
- std::vector get_joint_names(const std::map &whole_body)
- {
- std::vector joint_names_2d = {
- "nose",
- "eye_left",
- "eye_right",
- "ear_left",
- "ear_right",
- "shoulder_left",
- "shoulder_right",
- "elbow_left",
- "elbow_right",
- "wrist_left",
- "wrist_right",
- "hip_left",
- "hip_right",
- "knee_left",
- "knee_right",
- "ankle_left",
- "ankle_right",
- };
-
- if (whole_body.at("foots"))
- {
- joint_names_2d.insert(
- joint_names_2d.end(),
- {
- "foot_toe_big_left",
- "foot_toe_small_left",
- "foot_heel_left",
- "foot_toe_big_right",
- "foot_toe_small_right",
- "foot_heel_right",
- });
- }
- if (whole_body.at("face"))
- {
- joint_names_2d.insert(
- joint_names_2d.end(),
- {
- "face_jaw_right_1",
- "face_jaw_right_2",
- "face_jaw_right_3",
- "face_jaw_right_4",
- "face_jaw_right_5",
- "face_jaw_right_6",
- "face_jaw_right_7",
- "face_jaw_right_8",
- "face_jaw_middle",
- "face_jaw_left_1",
- "face_jaw_left_2",
- "face_jaw_left_3",
- "face_jaw_left_4",
- "face_jaw_left_5",
- "face_jaw_left_6",
- "face_jaw_left_7",
- "face_jaw_left_8",
- "face_eyebrow_right_1",
- "face_eyebrow_right_2",
- "face_eyebrow_right_3",
- "face_eyebrow_right_4",
- "face_eyebrow_right_5",
- "face_eyebrow_left_1",
- "face_eyebrow_left_2",
- "face_eyebrow_left_3",
- "face_eyebrow_left_4",
- "face_eyebrow_left_5",
- "face_nose_1",
- "face_nose_2",
- "face_nose_3",
- "face_nose_4",
- "face_nose_5",
- "face_nose_6",
- "face_nose_7",
- "face_nose_8",
- "face_nose_9",
- "face_eye_right_1",
- "face_eye_right_2",
- "face_eye_right_3",
- "face_eye_right_4",
- "face_eye_right_5",
- "face_eye_right_6",
- "face_eye_left_1",
- "face_eye_left_2",
- "face_eye_left_3",
- "face_eye_left_4",
- "face_eye_left_5",
- "face_eye_left_6",
- "face_mouth_1",
- "face_mouth_2",
- "face_mouth_3",
- "face_mouth_4",
- "face_mouth_5",
- "face_mouth_6",
- "face_mouth_7",
- "face_mouth_8",
- "face_mouth_9",
- "face_mouth_10",
- "face_mouth_11",
- "face_mouth_12",
- "face_mouth_13",
- "face_mouth_14",
- "face_mouth_15",
- "face_mouth_16",
- "face_mouth_17",
- "face_mouth_18",
- "face_mouth_19",
- "face_mouth_20",
- });
- }
- if (whole_body.at("hands"))
- {
- joint_names_2d.insert(
- joint_names_2d.end(),
- {
- "hand_wrist_left",
- "hand_finger_thumb_left_1",
- "hand_finger_thumb_left_2",
- "hand_finger_thumb_left_3",
- "hand_finger_thumb_left_4",
- "hand_finger_index_left_1",
- "hand_finger_index_left_2",
- "hand_finger_index_left_3",
- "hand_finger_index_left_4",
- "hand_finger_middle_left_1",
- "hand_finger_middle_left_2",
- "hand_finger_middle_left_3",
- "hand_finger_middle_left_4",
- "hand_finger_ring_left_1",
- "hand_finger_ring_left_2",
- "hand_finger_ring_left_3",
- "hand_finger_ring_left_4",
- "hand_finger_pinky_left_1",
- "hand_finger_pinky_left_2",
- "hand_finger_pinky_left_3",
- "hand_finger_pinky_left_4",
- "hand_wrist_right",
- "hand_finger_thumb_right_1",
- "hand_finger_thumb_right_2",
- "hand_finger_thumb_right_3",
- "hand_finger_thumb_right_4",
- "hand_finger_index_right_1",
- "hand_finger_index_right_2",
- "hand_finger_index_right_3",
- "hand_finger_index_right_4",
- "hand_finger_middle_right_1",
- "hand_finger_middle_right_2",
- "hand_finger_middle_right_3",
- "hand_finger_middle_right_4",
- "hand_finger_ring_right_1",
- "hand_finger_ring_right_2",
- "hand_finger_ring_right_3",
- "hand_finger_ring_right_4",
- "hand_finger_pinky_right_1",
- "hand_finger_pinky_right_2",
- "hand_finger_pinky_right_3",
- "hand_finger_pinky_right_4",
- });
- }
-
- joint_names_2d.insert(
- joint_names_2d.end(),
- {
- "hip_middle",
- "shoulder_middle",
- "head",
- });
-
- return joint_names_2d;
- }
-
- // =============================================================================================
-
- cv::Mat bayer2rgb(const cv::Mat &bayer)
- {
- cv::Mat rgb;
- cv::cvtColor(bayer, rgb, cv::COLOR_BayerBG2RGB);
- return rgb;
- }
-
- cv::Mat rgb2bayer(const cv::Mat &img)
- {
- CV_Assert(img.type() == CV_8UC3);
- cv::Mat bayer(img.rows, img.cols, CV_8UC1);
-
- for (int r = 0; r < img.rows; ++r)
- {
- const uchar *imgData = img.ptr(r);
- uchar *bayerRowPtr = bayer.ptr(r);
-
- for (int c = 0; c < img.cols; ++c)
- {
- int pixelIndex = 3 * c;
-
- // Use faster bit operation instead of modulo+if
- // Even row, even col => R = 0
- // Even row, odd col => G = 1
- // Odd row, even col => G = 1
- // Odd row, odd col => B = 2
- int row_mod = r & 1;
- int col_mod = c & 1;
- int component = row_mod + col_mod;
-
- bayerRowPtr[c] = imgData[pixelIndex + component];
- }
- }
-
- return bayer;
- }
-
- // =============================================================================================
-
- inline int find_index(const std::vector &vec, const std::string &key)
- {
- auto it = std::find(vec.begin(), vec.end(), key);
- if (it == vec.end())
- {
- throw std::runtime_error("Cannot find \"" + key + "\" in joint_names.");
- }
- return static_cast(std::distance(vec.begin(), it));
- }
-
- std::vector>>> update_keypoints(
- const std::vector>>> &poses_2d,
- const std::vector &joint_names,
- const std::map &whole_body)
- {
- std::vector>>> new_views;
- new_views.reserve(poses_2d.size());
-
- for (const auto &view : poses_2d)
- {
- // "view" is a list of bodies => each body is Nx3
- std::vector>> new_bodies;
- new_bodies.reserve(view.size());
-
- for (const auto &body : view)
- {
- // 1) Copy first 17 keypoints
- std::vector> new_body;
- new_body.insert(new_body.end(), body.begin(), body.begin() + 17);
-
- // 2) Optionally append extra keypoints
- if (whole_body.at("foots"))
- {
- new_body.insert(new_body.end(), body.begin() + 17, body.begin() + 23);
- }
- if (whole_body.at("face"))
- {
- new_body.insert(new_body.end(), body.begin() + 23, body.begin() + 91);
- }
- if (whole_body.at("hands"))
- {
- new_body.insert(new_body.end(), body.begin() + 91, body.end());
- }
-
- // 3) Compute mid_hip
- int hlid = find_index(joint_names, "hip_left");
- int hrid = find_index(joint_names, "hip_right");
- float mid_hip_x = 0.5 * (new_body[hlid][0] + new_body[hrid][0]);
- float mid_hip_y = 0.5 * (new_body[hlid][1] + new_body[hrid][1]);
- float mid_hip_c = std::min(new_body[hlid][2], new_body[hrid][2]);
- new_body.push_back({mid_hip_x, mid_hip_y, mid_hip_c});
-
- // 4) Compute mid_shoulder
- int slid = find_index(joint_names, "shoulder_left");
- int srid = find_index(joint_names, "shoulder_right");
- float mid_shoulder_x = 0.5 * (new_body[slid][0] + new_body[srid][0]);
- float mid_shoulder_y = 0.5 * (new_body[slid][1] + new_body[srid][1]);
- float mid_shoulder_c = std::min(new_body[slid][2], new_body[srid][2]);
- new_body.push_back({mid_shoulder_x, mid_shoulder_y, mid_shoulder_c});
-
- // 5) Compute head
- int elid = find_index(joint_names, "ear_left");
- int erid = find_index(joint_names, "ear_right");
- float head_x = 0.5 * (new_body[elid][0] + new_body[erid][0]);
- float head_y = 0.5 * (new_body[elid][1] + new_body[erid][1]);
- float head_c = std::min(new_body[elid][2], new_body[erid][2]);
- new_body.push_back({head_x, head_y, head_c});
-
- // Add this updated body into new_bodies
- new_bodies.push_back(new_body);
- }
-
- // Add all updated bodies for this view
- new_views.push_back(new_bodies);
- }
-
- return new_views;
- }
-}
diff --git a/scripts/utils_pipeline.py b/scripts/utils_pipeline.py
deleted file mode 100644
index 8e6c0cf..0000000
--- a/scripts/utils_pipeline.py
+++ /dev/null
@@ -1,189 +0,0 @@
-import json
-
-# ==================================================================================================
-
-
-def load_json(path: str):
- with open(path, "r", encoding="utf-8") as file:
- data = json.load(file)
- return data
-
-
-def save_json(data: dict, path: str):
- with open(path, "w+", encoding="utf-8") as file:
- json.dump(data, file, indent=0)
-
-
-# ==================================================================================================
-
-
-def use_whole_body(whole_body: dict) -> bool:
- return any((whole_body[k] for k in whole_body))
-
-
-# ==================================================================================================
-
-
-def get_joint_names(whole_body: dict):
-
- joint_names_2d = [
- "nose",
- "eye_left",
- "eye_right",
- "ear_left",
- "ear_right",
- "shoulder_left",
- "shoulder_right",
- "elbow_left",
- "elbow_right",
- "wrist_left",
- "wrist_right",
- "hip_left",
- "hip_right",
- "knee_left",
- "knee_right",
- "ankle_left",
- "ankle_right",
- ]
-
- if whole_body["foots"]:
- joint_names_2d.extend(
- [
- "foot_toe_big_left",
- "foot_toe_small_left",
- "foot_heel_left",
- "foot_toe_big_right",
- "foot_toe_small_right",
- "foot_heel_right",
- ]
- )
- if whole_body["face"]:
- joint_names_2d.extend(
- [
- "face_jaw_right_1",
- "face_jaw_right_2",
- "face_jaw_right_3",
- "face_jaw_right_4",
- "face_jaw_right_5",
- "face_jaw_right_6",
- "face_jaw_right_7",
- "face_jaw_right_8",
- "face_jaw_middle",
- "face_jaw_left_1",
- "face_jaw_left_2",
- "face_jaw_left_3",
- "face_jaw_left_4",
- "face_jaw_left_5",
- "face_jaw_left_6",
- "face_jaw_left_7",
- "face_jaw_left_8",
- "face_eyebrow_right_1",
- "face_eyebrow_right_2",
- "face_eyebrow_right_3",
- "face_eyebrow_right_4",
- "face_eyebrow_right_5",
- "face_eyebrow_left_1",
- "face_eyebrow_left_2",
- "face_eyebrow_left_3",
- "face_eyebrow_left_4",
- "face_eyebrow_left_5",
- "face_nose_1",
- "face_nose_2",
- "face_nose_3",
- "face_nose_4",
- "face_nose_5",
- "face_nose_6",
- "face_nose_7",
- "face_nose_8",
- "face_nose_9",
- "face_eye_right_1",
- "face_eye_right_2",
- "face_eye_right_3",
- "face_eye_right_4",
- "face_eye_right_5",
- "face_eye_right_6",
- "face_eye_left_1",
- "face_eye_left_2",
- "face_eye_left_3",
- "face_eye_left_4",
- "face_eye_left_5",
- "face_eye_left_6",
- "face_mouth_1",
- "face_mouth_2",
- "face_mouth_3",
- "face_mouth_4",
- "face_mouth_5",
- "face_mouth_6",
- "face_mouth_7",
- "face_mouth_8",
- "face_mouth_9",
- "face_mouth_10",
- "face_mouth_11",
- "face_mouth_12",
- "face_mouth_13",
- "face_mouth_14",
- "face_mouth_15",
- "face_mouth_16",
- "face_mouth_17",
- "face_mouth_18",
- "face_mouth_19",
- "face_mouth_20",
- ]
- )
- if whole_body["hands"]:
- joint_names_2d.extend(
- [
- "hand_wrist_left",
- "hand_finger_thumb_left_1",
- "hand_finger_thumb_left_2",
- "hand_finger_thumb_left_3",
- "hand_finger_thumb_left_4",
- "hand_finger_index_left_1",
- "hand_finger_index_left_2",
- "hand_finger_index_left_3",
- "hand_finger_index_left_4",
- "hand_finger_middle_left_1",
- "hand_finger_middle_left_2",
- "hand_finger_middle_left_3",
- "hand_finger_middle_left_4",
- "hand_finger_ring_left_1",
- "hand_finger_ring_left_2",
- "hand_finger_ring_left_3",
- "hand_finger_ring_left_4",
- "hand_finger_pinky_left_1",
- "hand_finger_pinky_left_2",
- "hand_finger_pinky_left_3",
- "hand_finger_pinky_left_4",
- "hand_wrist_right",
- "hand_finger_thumb_right_1",
- "hand_finger_thumb_right_2",
- "hand_finger_thumb_right_3",
- "hand_finger_thumb_right_4",
- "hand_finger_index_right_1",
- "hand_finger_index_right_2",
- "hand_finger_index_right_3",
- "hand_finger_index_right_4",
- "hand_finger_middle_right_1",
- "hand_finger_middle_right_2",
- "hand_finger_middle_right_3",
- "hand_finger_middle_right_4",
- "hand_finger_ring_right_1",
- "hand_finger_ring_right_2",
- "hand_finger_ring_right_3",
- "hand_finger_ring_right_4",
- "hand_finger_pinky_right_1",
- "hand_finger_pinky_right_2",
- "hand_finger_pinky_right_3",
- "hand_finger_pinky_right_4",
- ]
- )
-
- joint_names_2d.extend(
- [
- "hip_middle",
- "shoulder_middle",
- "head",
- ]
- )
-
- return joint_names_2d
diff --git a/skelda b/skelda
deleted file mode 160000
index d48d65b..0000000
--- a/skelda
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit d48d65b9614ddf6fb3e45d05efdbf2a90cadfc21
diff --git a/tests/README.md b/tests/README.md
index 2e092fb..e25d5c4 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -9,28 +9,3 @@ Various module tests
uv sync --group dev
uv run pytest tests/test_interface.py
```
-
-### Onnx C++ Interface
-
-```bash
-cd /RapidPoseTriangulation/tests/
-
-g++ -std=c++17 -O3 -march=native -Wall \
- $(pkg-config --cflags opencv4) \
- -I /onnxruntime/include \
- -I /onnxruntime/include/onnxruntime/core/session \
- -I /onnxruntime/include/onnxruntime/core/providers/tensorrt \
- -L /onnxruntime/build/Linux/Release \
- test_utils2d.cpp \
- -o my_app.bin \
- -Wl,--start-group \
- -lonnxruntime_providers_tensorrt \
- -lonnxruntime_providers_shared \
- -lonnxruntime_providers_cuda \
- -lonnxruntime \
- -Wl,--end-group \
- $(pkg-config --libs opencv4) \
- -Wl,-rpath,/onnxruntime/build/Linux/Release
-
-./my_app.bin
-```
diff --git a/tests/test_utils2d.cpp b/tests/test_utils2d.cpp
deleted file mode 100644
index f7d83ad..0000000
--- a/tests/test_utils2d.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-#include
-#include
-#include
-#include
-
-#include
-
-#include "/RapidPoseTriangulation/scripts/utils_2d_pose.hpp"
-
-// =================================================================================================
-// =================================================================================================
-
-int main(int argc, char **argv)
-{
- using namespace utils_2d_pose;
-
- std::string base_path = "/RapidPoseTriangulation/extras/mmdeploy/exports/";
- std::string model_path1 = base_path + "rtmdet-nano_1x320x320x3_fp16_extra-steps.onnx";
- std::string model_path2 = base_path + "rtmpose-m_1x384x288x3_fp16_extra-steps.onnx";
-
- std::vector img_paths = {
- "/RapidPoseTriangulation/data/h1/54138969-img_003201.jpg",
- "/RapidPoseTriangulation/data/h1/55011271-img_003201.jpg",
- "/RapidPoseTriangulation/data/h1/58860488-img_003201.jpg",
- "/RapidPoseTriangulation/data/h1/60457274-img_003201.jpg",
- };
-
- // {
- // std::cout << "\nTesting RTMDet and RTMPose" << std::endl;
- // RTMDet model1(model_path1, 0.3, 0.1 * 0.1, 30);
- // RTMPose model2(model_path2, 30);
- // for (size_t i = 0; i < img_paths.size(); i++)
- // {
- // cv::Mat img = cv::imread(img_paths[i]);
- // cv::cvtColor(img, img, cv::COLOR_BGR2RGB);
-
- // auto outputs1 = model1.call(img);
- // std::cout << "Model1 outputs: " << outputs1[0][0] << " " << outputs1[0][1] << " "
- // << outputs1[0][2] << " " << outputs1[0][3] << " " << outputs1[0][4] << " "
- // << std::endl;
-
- // for (size_t j = 0; j < outputs1.size(); j++)
- // {
- // std::vector