Skip to content

Commit 7bb08ca

Browse files
committed
correct image ratio in pose detection and added sections_to_keep argument
1 parent b2195c7 commit 7bb08ca

File tree

9 files changed

+70
-4
lines changed

9 files changed

+70
-4
lines changed

Pose2Sim/Demo_Batch/Config.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ interpolation = 'linear' #linear, slinear, quadratic, cubic, or none
190190
# 'none' if you don't want to interpolate missing points
191191
interp_if_gap_smaller_than = 10 # do not interpolate bigger gaps
192192
fill_large_gaps_with = 'last_value' # 'last_value', 'nan', or 'zeros'
193+
sections_to_keep = 'all' # 'all', 'largest', 'first', 'last'
194+
# keep 'all' valid sections even when they are interspersed with untriangulated chunks, or the 'largest' valid section, or the 'first' one, or the 'last' one
193195
show_interp_indices = true # true or false (lowercase). For each keypoint, return the frames that need to be interpolated
194196
handle_LR_swap = false # Better if few cameras (eg less than 4) with risk of limb swapping (eg camera facing sagittal plane), otherwise slightly less accurate and slower
195197
undistort_points = false # Better if distorted image (parallel lines curvy on the edge or at least one param > 10^-2), but unnecessary (and slightly slower) if distortions are low

Pose2Sim/Demo_Batch/Trial_1/Config.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@
189189
# # 'none' if you don't want to interpolate missing points
190190
# interp_if_gap_smaller_than = 10 # do not interpolate bigger gaps
191191
# fill_large_gaps_with = 'last_value' # 'last_value', 'nan', or 'zeros'
192+
# sections_to_keep = 'all' # 'all', 'largest', 'first', 'last'
193+
# # keep 'all' valid sections even when they are interspersed with untriangulated chunks, or the 'largest' valid section, or the 'first' one, or the 'last' one
192194
# show_interp_indices = true # true or false (lowercase). For each keypoint, return the frames that need to be interpolated
193195
# handle_LR_swap = false # Better if few cameras (eg less than 4) with risk of limb swapping (eg camera facing sagittal plane), otherwise slightly less accurate and slower
194196
# undistort_points = false # Better if distorted image (parallel lines curvy on the edge or at least one param > 10^-2), but unnecessary (and slightly slower) if distortions are low

Pose2Sim/Demo_Batch/Trial_2/Config.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ keypoints_to_consider = ['RWrist'] # 'all' if all points should be considered, f
188188
# interpolation = 'linear' #linear, slinear, quadratic, cubic, or none
189189
# # 'none' if you don't want to interpolate missing points
190190
# interp_if_gap_smaller_than = 10 # do not interpolate bigger gaps
191+
# sections_to_keep = 'all' # 'all', 'largest', 'first', 'last'
192+
# # keep 'all' valid sections even when they are interspersed with untriangulated chunks, or the 'largest' valid section, or the 'first' one, or the 'last' one
191193
# show_interp_indices = true # true or false (lowercase). For each keypoint, return the frames that need to be interpolated
192194
# fill_large_gaps_with = 'last_value' # 'last_value', 'nan', or 'zeros'
193195
# handle_LR_swap = false # Better if few cameras (eg less than 4) with risk of limb swapping (eg camera facing sagittal plane), otherwise slightly less accurate and slower

Pose2Sim/Demo_MultiPerson/Config.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ interpolation = 'linear' #linear, slinear, quadratic, cubic, or none
189189
# 'none' if you don't want to interpolate missing points
190190
interp_if_gap_smaller_than = 10 # do not interpolate bigger gaps
191191
fill_large_gaps_with = 'last_value' # 'last_value', 'nan', or 'zeros'
192+
sections_to_keep = 'all' # 'all', 'largest', 'first', 'last'
193+
# keep 'all' valid sections even when they are interspersed with untriangulated chunks, or the 'largest' valid section, or the 'first' one, or the 'last' one
192194
show_interp_indices = true # true or false (lowercase). For each keypoint, return the frames that need to be interpolated
193195
handle_LR_swap = false # Better if few cameras (eg less than 4) with risk of limb swapping (eg camera facing sagittal plane), otherwise slightly less accurate and slower
194196
undistort_points = false # Better if distorted image (parallel lines curvy on the edge or at least one param > 10^-2), but unnecessary (and slightly slower) if distortions are low

Pose2Sim/Demo_SinglePerson/Config.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ interpolation = 'linear' #linear, slinear, quadratic, cubic, or none
190190
# 'none' if you don't want to interpolate missing points
191191
interp_if_gap_smaller_than = 10 # do not interpolate bigger gaps
192192
fill_large_gaps_with = 'last_value' # 'last_value', 'nan', or 'zeros'
193+
sections_to_keep = 'all' # 'all', 'largest', 'first', 'last'
194+
# keep 'all' valid sections even when they are interspersed with untriangulated chunks, or the 'largest' valid section, or the 'first' one, or the 'last' one
193195
show_interp_indices = true # true or false (lowercase). For each keypoint, return the frames that need to be interpolated
194196
handle_LR_swap = false # Better if few cameras (eg less than 4) with risk of limb swapping (eg camera facing sagittal plane), otherwise slightly less accurate and slower
195197
undistort_points = false # Better if distorted image (parallel lines curvy on the edge or at least one param > 10^-2), but unnecessary (and slightly slower) if distortions are low

Pose2Sim/common.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import logging
2525
from anytree import PreOrderIter
2626

27+
import tkinter as tk
2728
import matplotlib.pyplot as plt
2829
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
2930
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
@@ -1353,3 +1354,51 @@ def draw_keypts(img, X, Y, scores, cmap_str='RdYlGn'):
13531354
if not (np.isnan(x[i]) or np.isnan(y[i]))]
13541355

13551356
return img
1357+
1358+
1359+
def get_screen_size():
1360+
'''
1361+
Get the screen dimensions
1362+
1363+
INPUTS:
1364+
- None
1365+
1366+
OUTPUTS:
1367+
- tuple of int: (screen_width, screen_height)
1368+
'''
1369+
1370+
root = tk.Tk()
1371+
screen_width = root.winfo_screenwidth()
1372+
screen_height = root.winfo_screenheight()
1373+
root.destroy()
1374+
1375+
return screen_width, screen_height
1376+
1377+
1378+
def calculate_display_size(W, H, screen_width, screen_height, margin=100):
1379+
'''
1380+
Calculate the optimal display size for the image
1381+
1382+
INPUTS:
1383+
W, H: Original image dimensions
1384+
screen_width, screen_height: Screen dimensions
1385+
margin: Margin to leave around the window (pixels)
1386+
1387+
OUTPUTS:
1388+
tuple: (display_width, display_height)
1389+
'''
1390+
1391+
# If image fits within screen, use original size
1392+
if W <= screen_width - margin and H <= screen_height - margin:
1393+
return W, H
1394+
1395+
# Calculate scaling factor to fit within screen while maintaining aspect ratio
1396+
width_ratio = (screen_width - margin) / W
1397+
height_ratio = (screen_height - margin) / H
1398+
scale_factor = min(width_ratio, height_ratio)
1399+
1400+
# Calculate new dimensions
1401+
new_width = int(W * scale_factor)
1402+
new_height = int(H * scale_factor)
1403+
1404+
return new_width, new_height

Pose2Sim/poseEstimation.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
from rtmlib import PoseTracker, BodyWithFeet, Wholebody, Body, Hand, Custom, draw_skeleton
4747
from deep_sort_realtime.deepsort_tracker import DeepSort
4848
from Pose2Sim.common import natural_sort_key, sort_people_sports2d, sort_people_deepsort,\
49-
colors, thickness, draw_bounding_box, draw_keypts, draw_skel
49+
colors, thickness, draw_bounding_box, draw_keypts, draw_skel, get_screen_size, calculate_display_size
5050
from Pose2Sim.skeletons import *
5151

5252

@@ -233,7 +233,10 @@ def process_video(video_path, pose_tracker, pose_model, output_format, save_vide
233233
out = cv2.VideoWriter(output_video_path, fourcc, fps, (W, H)) # Create the output video file
234234

235235
if display_detection:
236-
cv2.namedWindow(f"Pose Estimation {os.path.basename(video_path)}", cv2.WINDOW_NORMAL + cv2.WINDOW_KEEPRATIO)
236+
screen_width, screen_height = get_screen_size()
237+
display_width, display_height = calculate_display_size(W, H, screen_width, screen_height, margin=50)
238+
cv2.namedWindow(f"Pose Estimation {os.path.basename(video_path)}", cv2.WINDOW_NORMAL)
239+
cv2.resizeWindow(f"Pose Estimation {os.path.basename(video_path)}", display_width, display_height)
237240

238241
frame_idx = 0
239242
cap = cv2.VideoCapture(video_path)
@@ -353,7 +356,10 @@ def process_images(image_folder_path, vid_img_extension, pose_tracker, pose_mode
353356
out = cv2.VideoWriter(output_video_path, fourcc, fps, (W, H)) # Create the output video file
354357

355358
if display_detection:
359+
screen_width, screen_height = get_screen_size()
360+
display_width, display_height = calculate_display_size(W, H, screen_width, screen_height, margin=50)
356361
cv2.namedWindow(f"Pose Estimation {os.path.basename(image_folder_path)}", cv2.WINDOW_NORMAL)
362+
cv2.resizeWindow(f"Pose Estimation {os.path.basename(image_folder_path)}", display_width, display_height)
357363

358364
f_range = [[0,len(image_files)] if frame_range in ('all', 'auto', []) else frame_range][0]
359365
for frame_idx, image_file in enumerate(tqdm(image_files, desc=f'\nProcessing {os.path.basename(img_output_dir)}')):

Pose2Sim/triangulation.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ def triangulate_all(config_dict):
669669
likelihood_threshold = config_dict.get('triangulation').get('likelihood_threshold_triangulation')
670670
interpolation_kind = config_dict.get('triangulation').get('interpolation')
671671
interp_gap_smaller_than = config_dict.get('triangulation').get('interp_if_gap_smaller_than')
672+
sections_to_keep = config_dict.get('triangulation').get('sections_to_keep')
672673
fill_large_gaps_with = config_dict.get('triangulation').get('fill_large_gaps_with')
673674
show_interp_indices = config_dict.get('triangulation').get('show_interp_indices')
674675
undistort_points = config_dict.get('triangulation').get('undistort_points')
@@ -878,7 +879,7 @@ def triangulate_all(config_dict):
878879
# error_tot[0].to_csv(os.path.join(session_dir, 'error_tot.csv'), index=False, sep='\t')
879880

880881
# Trim around good frames and remove persons with too few frames
881-
f_range_trimmed = [indices_of_first_last_non_nan_chunks(err['mean'], min_chunk_size=interp_gap_smaller_than, chunk_choice_method='all') for err in error_tot]
882+
f_range_trimmed = [indices_of_first_last_non_nan_chunks(err['mean'], min_chunk_size=interp_gap_smaller_than, chunk_choice_method=sections_to_keep) for err in error_tot]
882883
# f_range_trimmed = [f_range]*nb_persons_to_detect
883884
deleted_person_id = [n for n, f_range in enumerate(f_range_trimmed) if len(range(*f_range))<4]
884885
Q_tot = [Q_tot[n] for n in range(len(Q_tot)) if n not in deleted_person_id]

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ For example, try uncommenting `[project]` and set `frame_range = [10,99]`, or un
324324
Run it only when your cameras are moved or changed. If they are not, just copy a previous calibration.toml file into your new calibration folder.
325325
- `Pose2Sim.poseEstimation()`:
326326
- **Use your GPU**: This makes pose estimation significantly faster, without any impact on accuracy. See [Installation](#installation) section for more information.
327-
- Set `det_frequency = 100` in Config.toml. Run the bounding box detector and the pose estimator on the first frame; for all subsequent frames, only run pose estimation: \
327+
- Set `det_frequency = 100` in Config.toml. Run the bounding box detector and the pose estimator on the first frame; for all subsequent frames, only run pose estimation:
328328
*150 s -> 30 s on my laptop with the Demo videos*
329329
- Use `mode = 'lightweight'`: Will use a lighter version of RTMPose, which is faster but less accurate\
330330
*30 s -> 20 s*

0 commit comments

Comments
 (0)