ready to merge
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
BIN
Content/Calib_ext.png
Normal file
After Width: | Height: | Size: 346 KiB |
Before Width: | Height: | Size: 600 KiB After Width: | Height: | Size: 320 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 31 KiB |
@ -545,14 +545,14 @@ def calibrate_extrinsics(calib_dir, extrinsics_config_dict, C, S, K, D):
|
|||||||
cv2.circle(img, (int(o[0]), int(o[1])), 8, (0,0,255), -1)
|
cv2.circle(img, (int(o[0]), int(o[1])), 8, (0,0,255), -1)
|
||||||
for i in imgp:
|
for i in imgp:
|
||||||
cv2.drawMarker(img, (int(i[0][0]), int(i[0][1])), (0,255,0), cv2.MARKER_CROSS, 15, 2)
|
cv2.drawMarker(img, (int(i[0][0]), int(i[0][1])), (0,255,0), cv2.MARKER_CROSS, 15, 2)
|
||||||
cv2.putText(img, 'Verify calibration results, then close window.', (20, 20), cv2.FONT_HERSHEY_SIMPLEX, .5, (255,255,255), 2, lineType = cv2.LINE_AA)
|
cv2.putText(img, 'Verify calibration results, then close window.', (20, 20), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 7, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, 'Verify calibration results, then close window.', (20, 20), cv2.FONT_HERSHEY_SIMPLEX, .5, (0,0,0), 1, lineType = cv2.LINE_AA)
|
cv2.putText(img, 'Verify calibration results, then close window.', (20, 20), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
||||||
cv2.drawMarker(img, (20,40), (0,255,0), cv2.MARKER_CROSS, 15, 2)
|
cv2.drawMarker(img, (20,40), (0,255,0), cv2.MARKER_CROSS, 15, 2)
|
||||||
cv2.putText(img, ' Clicked points', (20, 40), cv2.FONT_HERSHEY_SIMPLEX, .5, (255,255,255), 2, lineType = cv2.LINE_AA)
|
cv2.putText(img, ' Clicked points', (20, 40), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 7, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, ' Clicked points', (20, 40), cv2.FONT_HERSHEY_SIMPLEX, .5, (0,0,0), 1, lineType = cv2.LINE_AA)
|
cv2.putText(img, ' Clicked points', (20, 40), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
||||||
cv2.circle(img, (20,60), 8, (0,0,255), -1)
|
cv2.circle(img, (20,60), 8, (0,0,255), -1)
|
||||||
cv2.putText(img, ' Reprojected object points', (20, 60), cv2.FONT_HERSHEY_SIMPLEX, .5, (255,255,255), 2, lineType = cv2.LINE_AA)
|
cv2.putText(img, ' Reprojected object points', (20, 60), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 7, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, ' Reprojected object points', (20, 60), cv2.FONT_HERSHEY_SIMPLEX, .5, (0,0,0), 1, lineType = cv2.LINE_AA)
|
cv2.putText(img, ' Reprojected object points', (20, 60), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
||||||
im_pil = Image.fromarray(img)
|
im_pil = Image.fromarray(img)
|
||||||
im_pil.show(title = os.path.basename(img_vid_files[0]))
|
im_pil.show(title = os.path.basename(img_vid_files[0]))
|
||||||
|
|
||||||
@ -617,8 +617,8 @@ def findCorners(img_path, corner_nb, objp=[], show=True):
|
|||||||
# Add corner index
|
# Add corner index
|
||||||
for i, corner in enumerate(imgp):
|
for i, corner in enumerate(imgp):
|
||||||
x, y = corner.ravel()
|
x, y = corner.ravel()
|
||||||
cv2.putText(img, str(i+1), (int(x)-5, int(y)-5), cv2.FONT_HERSHEY_SIMPLEX, .5, (255, 255, 255), 2)
|
cv2.putText(img, str(i+1), (int(x)-5, int(y)-5), cv2.FONT_HERSHEY_SIMPLEX, .8, (255, 255, 255), 7)
|
||||||
cv2.putText(img, str(i+1), (int(x)-5, int(y)-5), cv2.FONT_HERSHEY_SIMPLEX, .5, (0,0,0), 1)
|
cv2.putText(img, str(i+1), (int(x)-5, int(y)-5), cv2.FONT_HERSHEY_SIMPLEX, .8, (0,0,0), 2)
|
||||||
|
|
||||||
# Visualizer and key press event handler
|
# Visualizer and key press event handler
|
||||||
for var_to_delete in ['imgp_confirmed', 'objp_confirmed']:
|
for var_to_delete in ['imgp_confirmed', 'objp_confirmed']:
|
||||||
@ -677,6 +677,7 @@ def imgp_objp_visualizer_clicker(img, imgp=[], objp=[], img_path=''):
|
|||||||
global imgp_confirmed, objp_confirmed, objp_confirmed_notok, scat, ax_3d, fig_3d, events, count
|
global imgp_confirmed, objp_confirmed, objp_confirmed_notok, scat, ax_3d, fig_3d, events, count
|
||||||
|
|
||||||
if event.key == 'y':
|
if event.key == 'y':
|
||||||
|
# TODO: DETECT WHEN WINDOW IS CLOSED
|
||||||
# If 'y', close all
|
# If 'y', close all
|
||||||
# If points have been clicked, imgp_confirmed is returned, else imgp
|
# If points have been clicked, imgp_confirmed is returned, else imgp
|
||||||
# If objp is given, objp_confirmed is returned in addition
|
# If objp is given, objp_confirmed is returned in addition
|
||||||
@ -869,19 +870,19 @@ def imgp_objp_visualizer_clicker(img, imgp=[], objp=[], img_path=''):
|
|||||||
ax.set_zlim3d([z_middle - plot_radius, z_middle + plot_radius])
|
ax.set_zlim3d([z_middle - plot_radius, z_middle + plot_radius])
|
||||||
|
|
||||||
# Write instructions
|
# Write instructions
|
||||||
cv2.putText(img, 'Type "Y" to accept point detection.', (20, 20), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 3, lineType = cv2.LINE_AA)
|
cv2.putText(img, 'Type "Y" to accept point detection.', (20, 20), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 7, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, 'Type "Y" to accept point detection.', (20, 20), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
cv2.putText(img, 'Type "Y" to accept point detection.', (20, 20), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, 'If points are wrongfully (or not) detected:', (20, 43), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 3, lineType = cv2.LINE_AA)
|
cv2.putText(img, 'If points are wrongfully (or not) detected:', (20, 43), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 7, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, 'If points are wrongfully (or not) detected:', (20, 43), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
cv2.putText(img, 'If points are wrongfully (or not) detected:', (20, 43), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, '- type "N" to dismiss this image,', (20, 66), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 3, lineType = cv2.LINE_AA)
|
cv2.putText(img, '- type "N" to dismiss this image,', (20, 66), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 7, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, '- type "N" to dismiss this image,', (20, 66), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
cv2.putText(img, '- type "N" to dismiss this image,', (20, 66), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, '- type "C" to click points by hand (beware of their order).', (20, 89), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 3, lineType = cv2.LINE_AA)
|
cv2.putText(img, '- type "C" to click points by hand (beware of their order).', (20, 89), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 7, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, '- type "C" to click points by hand (beware of their order).', (20, 89), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
cv2.putText(img, '- type "C" to click points by hand (beware of their order).', (20, 89), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, ' left click to add a point, right click to remove it, "H" to indicate it is not visible. ', (20, 112), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 3, lineType = cv2.LINE_AA)
|
cv2.putText(img, ' left click to add a point, right click to remove it, "H" to indicate it is not visible. ', (20, 112), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 7, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, ' left click to add a point, right click to remove it, "H" to indicate it is not visible. ', (20, 112), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
cv2.putText(img, ' left click to add a point, right click to remove it, "H" to indicate it is not visible. ', (20, 112), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, ' Confirm with "Y", cancel with "N".', (20, 135), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 3, lineType = cv2.LINE_AA)
|
cv2.putText(img, ' Confirm with "Y", cancel with "N".', (20, 135), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 7, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, ' Confirm with "Y", cancel with "N".', (20, 135), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
cv2.putText(img, ' Confirm with "Y", cancel with "N".', (20, 135), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, 'Use mouse wheel to zoom in and out and to pan', (20, 158), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 3, lineType = cv2.LINE_AA)
|
cv2.putText(img, 'Use mouse wheel to zoom in and out and to pan', (20, 158), cv2.FONT_HERSHEY_SIMPLEX, .7, (255,255,255), 7, lineType = cv2.LINE_AA)
|
||||||
cv2.putText(img, 'Use mouse wheel to zoom in and out and to pan', (20, 158), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
cv2.putText(img, 'Use mouse wheel to zoom in and out and to pan', (20, 158), cv2.FONT_HERSHEY_SIMPLEX, .7, (0,0,0), 2, lineType = cv2.LINE_AA)
|
||||||
|
|
||||||
# Put image in a matplotlib figure for more controls
|
# Put image in a matplotlib figure for more controls
|
||||||
|
17
README.md
@ -250,13 +250,14 @@ If you already have a calibration file, set `calibration_type` type to `convert`
|
|||||||
- **From Vicon:**
|
- **From Vicon:**
|
||||||
- Not possible yet. [Want to contribute?](#how-to-contribute)
|
- Not possible yet. [Want to contribute?](#how-to-contribute)
|
||||||
|
|
||||||
|
|
||||||
### Calculate from scratch
|
### Calculate from scratch
|
||||||
|
|
||||||
> Calculate calibration parameters with a board, or with points (such as detected on a wand or a human body).
|
> Calculate calibration parameters with a board, or with points (such as detected on a wand or a human body).
|
||||||
|
|
||||||
- **With a board:**
|
- **With a board:**
|
||||||
> *N.B.:* Try the calibration tool on the Demo by changing `calibration_type` to `calculate` instead of `convert` in `Config.toml`.\
|
> *N.B.:* Try the calibration tool on the Demo by changing `calibration_type` to `calculate` in `Config.toml`.\
|
||||||
For the sake of practicality, there are voluntarily few images for intrinsics, and few clicked points for extrinsics. *You should use more of them.* In spite of this, your reprojection error should be under 1-2 cm, which [does not hinder the quality of kinematic results in practice](https://www.mdpi.com/1424-8220/21/19/6530/htm).
|
For the sake of practicality, there are voluntarily few board images for intrinsics, and few points to click for extrinsics. *You should use more of them.* In spite of this, your reprojection error should be under 1-2 cm, which [does not hinder the quality of kinematic results in practice](https://www.mdpi.com/1424-8220/21/19/6530/htm).
|
||||||
|
|
||||||
- **Calculate intrinsic parameters:**
|
- **Calculate intrinsic parameters:**
|
||||||
|
|
||||||
@ -270,6 +271,8 @@ If you already have a calibration file, set `calibration_type` type to `convert`
|
|||||||
is filmed from different angles, covers a large part of the video frame, and is in focus.\
|
is filmed from different angles, covers a large part of the video frame, and is in focus.\
|
||||||
is flat, without reflections, surrounded by a white border, and is not rotationally invariant (Nrows ≠ Ncols, and Nrows odd if Ncols even).
|
is flat, without reflections, surrounded by a white border, and is not rotationally invariant (Nrows ≠ Ncols, and Nrows odd if Ncols even).
|
||||||
|
|
||||||
|
<img src="Content/Calib_int.png" width="600">
|
||||||
|
|
||||||
- **Calculate extrinsic parameters:**
|
- **Calculate extrinsic parameters:**
|
||||||
|
|
||||||
> *N.B.:* _Extrinsic parameters:_ camera placement in space (position and orientation), need to be calculated every time a camera is moved. Can be calculated from a board, or from points in the scene with known coordinates.
|
> *N.B.:* _Extrinsic parameters:_ camera placement in space (position and orientation), need to be calculated every time a camera is moved. Can be calculated from a board, or from points in the scene with known coordinates.
|
||||||
@ -285,6 +288,8 @@ If you already have a calibration file, set `calibration_type` type to `convert`
|
|||||||
Manually measure the 3D coordinates of 10 or more points in the scene (tiles, lines on wall, boxes, treadmill dimensions, etc). These points should be as spread out as possible.\
|
Manually measure the 3D coordinates of 10 or more points in the scene (tiles, lines on wall, boxes, treadmill dimensions, etc). These points should be as spread out as possible.\
|
||||||
Then you will click on the corresponding image points for each view.
|
Then you will click on the corresponding image points for each view.
|
||||||
|
|
||||||
|
<img src="Content/Calib_ext.png" width="920">
|
||||||
|
|
||||||
- **With points:**
|
- **With points:**
|
||||||
- Points can be detected from a wand.\
|
- Points can be detected from a wand.\
|
||||||
[Want to contribute?](#how-to-contribute)
|
[Want to contribute?](#how-to-contribute)
|
||||||
@ -302,7 +307,6 @@ Pose2Sim.calibration()
|
|||||||
|
|
||||||
Output:\
|
Output:\
|
||||||
<img src="Content/Calib2D.png" width="760">
|
<img src="Content/Calib2D.png" width="760">
|
||||||
|
|
||||||
<img src="Content/CalibFile.png" width="760">
|
<img src="Content/CalibFile.png" width="760">
|
||||||
|
|
||||||
|
|
||||||
@ -753,7 +757,12 @@ If you want to contribute to Pose2Sim, please follow [this guide](https://docs.g
|
|||||||
|
|
||||||
</br>
|
</br>
|
||||||
|
|
||||||
*Here is a to-do list, for general guidance purposes only:*
|
**Here is a to-do list, for general guidance purposes only:**\
|
||||||
|
*The main projects are (see details below):*\
|
||||||
|
*- Graphical User Interface*\
|
||||||
|
*- Multiple person triangulation*\
|
||||||
|
*- Synchronization*\
|
||||||
|
*- Self-calibration based on keypoint detection*\
|
||||||
|
|
||||||
> - [x] **Pose:** Support OpenPose [body_25b](https://github.com/CMU-Perceptual-Computing-Lab/openpose_train/tree/master/experimental_models#body_25b-model---option-2-recommended) for more accuracy, [body_135](https://github.com/CMU-Perceptual-Computing-Lab/openpose_train/tree/master/experimental_models#single-network-whole-body-pose-estimation-model) for pronation/supination.
|
> - [x] **Pose:** Support OpenPose [body_25b](https://github.com/CMU-Perceptual-Computing-Lab/openpose_train/tree/master/experimental_models#body_25b-model---option-2-recommended) for more accuracy, [body_135](https://github.com/CMU-Perceptual-Computing-Lab/openpose_train/tree/master/experimental_models#single-network-whole-body-pose-estimation-model) for pronation/supination.
|
||||||
> - [x] **Pose:** Support [BlazePose](https://developers.google.com/mediapipe/solutions/vision/pose_landmarker) for faster inference (on mobile device).
|
> - [x] **Pose:** Support [BlazePose](https://developers.google.com/mediapipe/solutions/vision/pose_landmarker) for faster inference (on mobile device).
|
||||||
|