diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b65fd5e65b0ffa7230db94c04cef860298b55a8..5a8c16936cebf4110bc42dcd3534ba1e4789ded4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ # Project setup ################################################################################ cmake_minimum_required(VERSION 3.16 FATAL_ERROR) -project(petrack LANGUAGES CXX VERSION 0.9.3) +project(petrack LANGUAGES CXX VERSION 0.9.4) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/demo/00_files/00_empty.pet b/demo/00_files/00_empty.pet index 393d5494965e6e8e131c1aaf81ca439b8ed4bbe9..41120523713d622067068bb75a816e2a89796c37 100644 --- a/demo/00_files/00_empty.pet +++ b/demo/00_files/00_empty.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="" STATUS_HEIGHT="0"/> <CONTROL TAB="0"> <CALIBRATION> @@ -57,7 +57,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="6.952642160144429e-310" AVG_PH="4.6632137672154514e-310" AVG_PX="4.9406564584124654e-324" MAX_DH="4.6632130749188108e-310" MAX_PH="4.6632130749149077e-310" MAX_PX="4.6632132612882775e-310" SD_DH="4.6632137672154514e-310" SD_PH="6.9526421601088563e-310" SD_PX="6.952642160144429e-310" USED_HEIGHT="4.6632137672154514e-310"/> + <REPROJECTION_ERROR AVG_DH="0" AVG_PH="0" AVG_PX="0" MAX_DH="0" MAX_PH="0" MAX_PX="0" SD_DH="0" SD_PH="0" SD_PX="0" USED_HEIGHT="0"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/demo/01_calibration/01_intrinsic.pet b/demo/01_calibration/01_intrinsic.pet index 9bac2f9a5917d1dfa5118393f5be1f1b60ab9a7b..8176c5d1d30c53d4530d8f22ecf5eaaa1e065e8e 100644 --- a/demo/01_calibration/01_intrinsic.pet +++ b/demo/01_calibration/01_intrinsic.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="" STATUS_HEIGHT="0"/> <CONTROL TAB="0"> <CALIBRATION> @@ -57,7 +57,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="3.5572726500569751e-322" AVG_PH="7.3338630165654629e-316" AVG_PX="2.4703282292062327e-323" MAX_DH="4.6632130749188108e-310" MAX_PH="4.6632130749149077e-310" MAX_PX="4.6632132612882775e-310" SD_DH="4.6632137672154514e-310" SD_PH="6.9526421601088563e-310" SD_PX="6.952642160144429e-310" USED_HEIGHT="4.6632137672154514e-310"/> + <REPROJECTION_ERROR AVG_DH="0" AVG_PH="0" AVG_PX="0" MAX_DH="0" MAX_PH="0" MAX_PX="0" SD_DH="0" SD_PH="0" SD_PX="0" USED_HEIGHT="0"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/demo/01_calibration/02_extrinsic.pet b/demo/01_calibration/02_extrinsic.pet index 0ed7387c160938015d1c99fc60a0699704a68d9a..c95df13b9a58151ebe497eb9c0f3a35254ede635 100644 --- a/demo/01_calibration/02_extrinsic.pet +++ b/demo/01_calibration/02_extrinsic.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="../00_files/calibration/extrinsic/00_all.jpg" STATUS_HEIGHT="0"/> <CONTROL TAB="0"> <CALIBRATION> @@ -57,7 +57,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="6.9530488178851165e-310" AVG_PH="4.6524256806213525e-310" AVG_PX="4.9406564584124654e-324" MAX_DH="1.5282007521032739" MAX_PH="1.9084653722971126" MAX_PX="2.9165169096333834" SD_DH="0.43009984448603678" SD_PH="0.47246997925264522" SD_PX="0.79801084449283222" USED_HEIGHT="180"/> + <REPROJECTION_ERROR AVG_DH="0" AVG_PH="0" AVG_PX="0" MAX_DH="1.5282007521032739" MAX_PH="1.9084653722971126" MAX_PX="2.9165169096333834" SD_DH="0.43009984448603678" SD_PH="0.47246997925264522" SD_PX="0.79801084449283222" USED_HEIGHT="180"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/demo/01_calibration/03_calibrated_with_video.pet b/demo/01_calibration/03_calibrated_with_video.pet index 51c282dde03eea90d0867d7dd8069d4a824821d5..e80e0f05bc12676d228ef23009f25bd4013e2f89 100644 --- a/demo/01_calibration/03_calibrated_with_video.pet +++ b/demo/01_calibration/03_calibrated_with_video.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="../00_files/video/video.mp4" STATUS_HEIGHT="0"/> <CONTROL TAB="0"> <CALIBRATION> @@ -57,7 +57,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="6.9531516628824416e-310" AVG_PH="4.6880404499487236e-310" AVG_PX="4.9406564584124654e-324" MAX_DH="1.5282007521032739" MAX_PH="1.9084653722971126" MAX_PX="2.9165169096333834" SD_DH="0.43009984448603678" SD_PH="0.47246997925264522" SD_PX="0.79801084449283222" USED_HEIGHT="180"/> + <REPROJECTION_ERROR AVG_DH="0" AVG_PH="0" AVG_PX="0" MAX_DH="1.5282007521032739" MAX_PH="1.9084653722971126" MAX_PX="2.9165169096333834" SD_DH="0.43009984448603678" SD_PH="0.47246997925264522" SD_PX="0.79801084449283222" USED_HEIGHT="180"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/demo/02_recognition/04_recognition.pet b/demo/02_recognition/04_recognition.pet index e31305678668dfc4b198c567528b40f8a533c93a..656593792c7351253391d90d319d4626d586aa62 100644 --- a/demo/02_recognition/04_recognition.pet +++ b/demo/02_recognition/04_recognition.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="../00_files/video/video.mp4" STATUS_HEIGHT="0"/> <CONTROL TAB="1"> <CALIBRATION> @@ -11,7 +11,7 @@ <BG_SUB DELETE="1" DELETE_NUMBER="3" ENABLED="0" FILE="" SHOW="0" UPDATE="0"/> <PATTERN BOARD_SIZE_X="6" BOARD_SIZE_Y="8" SQUARE_SIZE="4.5999999"/> <INTRINSIC_PARAMETERS CALIB_FILES="" CX="947.47000000000003" CY="698.44000000000005" ENABLED="1" EXT_MODEL_ENABLED="1" FIX_CENTER="0" FX="857.12" FY="857.50999999999999" K4="1.7398640000000001" K5="0.399007" K6="-0.013342" QUAD_ASPECT_RATIO="0" R2="1.358914" R4="0.123435" R6="-0.0091129999999999996" ReprError="0.52066329210560447" S1="0.001026" S2="-6.6000000000000005e-05" S3="-0.00019000000000000001" S4="-9.7999999999999997e-05" TANG_DIST="1" TAUX="-3.0000000000000001e-05" TAUY="-5.0000000000000002e-05" TX="0.000184" TY="-0.000388"/> - <EXTRINSIC_PARAMETERS ALTITUDE="535" COORD3D_AXIS_LEN="200" COORD3D_SWAP_X="0" COORD3D_SWAP_Y="0" COORD3D_SWAP_Z="0" COORD3D_TRANS_X="0" COORD3D_TRANS_Y="0" COORD3D_TRANS_Z="0" COORD_DIMENSION="0" EXTERNAL_CALIB_FILE="" EXTR_ROT_1="-2.1949999999999998" EXTR_ROT_2="-2.1869999999999998" EXTR_ROT_3="0.029999999999999999" EXTR_TRANS_1="-1047.981" EXTR_TRANS_2="15.172000000000001" EXTR_TRANS_3="-634.48599999999999" FIX="0" ROTATE="0" SCALE="100" SHOW="0" SHOW_CALIB_POINTS="0" TRANS_X="0" TRANS_Y="0" UNIT="100" USE_INTRINSIC_CENTER="0"/> + <EXTRINSIC_PARAMETERS ALTITUDE="535" COORD3D_AXIS_LEN="200" COORD3D_SWAP_X="0" COORD3D_SWAP_Y="0" COORD3D_SWAP_Z="0" COORD3D_TRANS_X="0" COORD3D_TRANS_Y="0" COORD3D_TRANS_Z="0" COORD_DIMENSION="0" EXTERNAL_CALIB_FILE="../01_calibration/before.3dc" EXTR_ROT_1="-2.1949999999999998" EXTR_ROT_2="-2.1869999999999998" EXTR_ROT_3="0.029999999999999999" EXTR_TRANS_1="-1047.981" EXTR_TRANS_2="15.172000000000001" EXTR_TRANS_3="-634.48599999999999" FIX="0" ROTATE="0" SCALE="100" SHOW="0" SHOW_CALIB_POINTS="0" TRANS_X="0" TRANS_Y="0" UNIT="100" USE_INTRINSIC_CENTER="0"/> <ALIGNMENT_GRID FIX="0" GRID3D_RESOLUTION="100" GRID3D_TRANS_X="0" GRID3D_TRANS_Y="0" GRID3D_TRANS_Z="0" GRID_DIMENSION="0" ROTATE="0" SCALE="100" SHOW="0" TRANS_X="0" TRANS_Y="0"/> </CALIBRATION> <RECOGNITION> @@ -61,7 +61,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="6.953007415343677e-310" AVG_PH="4.6896315456960177e-310" AVG_PX="4.9406564584124654e-324" MAX_DH="1.5282007521032739" MAX_PH="1.9084653722971126" MAX_PX="2.9165169096333834" SD_DH="0.43009984448603678" SD_PH="0.47246997925264522" SD_PX="0.79801084449283222" USED_HEIGHT="180"/> + <REPROJECTION_ERROR AVG_DH="0" AVG_PH="0" AVG_PX="0" MAX_DH="1.5282007521032739" MAX_PH="1.9084653722971126" MAX_PX="2.9165169096333834" SD_DH="0.43009984448603678" SD_PH="0.47246997925264522" SD_PX="0.79801084449283222" USED_HEIGHT="180"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/demo/03_tracking/05_tracking.pet b/demo/03_tracking/05_tracking.pet index ad4163b41d6f062710bb06ac43e1e37ff851b624..7e5e52f6f2a802e729547e6c0d86941fc1eee761 100644 --- a/demo/03_tracking/05_tracking.pet +++ b/demo/03_tracking/05_tracking.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="../00_files/video/video.mp4" STATUS_HEIGHT="0"/> <CONTROL TAB="2"> <CALIBRATION> @@ -11,7 +11,7 @@ <BG_SUB DELETE="1" DELETE_NUMBER="3" ENABLED="0" FILE="" SHOW="0" UPDATE="0"/> <PATTERN BOARD_SIZE_X="6" BOARD_SIZE_Y="8" SQUARE_SIZE="4.5999999"/> <INTRINSIC_PARAMETERS CALIB_FILES="" CX="947.47000000000003" CY="698.44000000000005" ENABLED="1" EXT_MODEL_ENABLED="1" FIX_CENTER="0" FX="857.12" FY="857.50999999999999" K4="1.7398640000000001" K5="0.399007" K6="-0.013342" QUAD_ASPECT_RATIO="0" R2="1.358914" R4="0.123435" R6="-0.0091129999999999996" ReprError="0.52066329210560447" S1="0.001026" S2="-6.6000000000000005e-05" S3="-0.00019000000000000001" S4="-9.7999999999999997e-05" TANG_DIST="1" TAUX="-3.0000000000000001e-05" TAUY="-5.0000000000000002e-05" TX="0.000184" TY="-0.000388"/> - <EXTRINSIC_PARAMETERS ALTITUDE="535" COORD3D_AXIS_LEN="200" COORD3D_SWAP_X="0" COORD3D_SWAP_Y="0" COORD3D_SWAP_Z="0" COORD3D_TRANS_X="0" COORD3D_TRANS_Y="0" COORD3D_TRANS_Z="0" COORD_DIMENSION="0" EXTERNAL_CALIB_FILE="" EXTR_ROT_1="-2.1949999999999998" EXTR_ROT_2="-2.1869999999999998" EXTR_ROT_3="0.029999999999999999" EXTR_TRANS_1="-1047.981" EXTR_TRANS_2="15.172000000000001" EXTR_TRANS_3="-634.48599999999999" FIX="0" ROTATE="0" SCALE="100" SHOW="0" SHOW_CALIB_POINTS="0" TRANS_X="0" TRANS_Y="0" UNIT="100" USE_INTRINSIC_CENTER="0"/> + <EXTRINSIC_PARAMETERS ALTITUDE="535" COORD3D_AXIS_LEN="200" COORD3D_SWAP_X="0" COORD3D_SWAP_Y="0" COORD3D_SWAP_Z="0" COORD3D_TRANS_X="0" COORD3D_TRANS_Y="0" COORD3D_TRANS_Z="0" COORD_DIMENSION="0" EXTERNAL_CALIB_FILE="../01_calibration/before.3dc" EXTR_ROT_1="-2.1949999999999998" EXTR_ROT_2="-2.1869999999999998" EXTR_ROT_3="0.029999999999999999" EXTR_TRANS_1="-1047.981" EXTR_TRANS_2="15.172000000000001" EXTR_TRANS_3="-634.48599999999999" FIX="0" ROTATE="0" SCALE="100" SHOW="0" SHOW_CALIB_POINTS="0" TRANS_X="0" TRANS_Y="0" UNIT="100" USE_INTRINSIC_CENTER="0"/> <ALIGNMENT_GRID FIX="0" GRID3D_RESOLUTION="100" GRID3D_TRANS_X="0" GRID3D_TRANS_Y="0" GRID3D_TRANS_Z="0" GRID_DIMENSION="0" ROTATE="0" SCALE="100" SHOW="0" TRANS_X="0" TRANS_Y="0"/> </CALIBRATION> <RECOGNITION> @@ -52,7 +52,7 @@ <TEST_LENGTH ENABLED="1"/> <TRACK_FILE FILENAME=""/> <SEARCH_REGION ADAPTIVE="1" LEVELS="2" MAX_ERROR="0" SCALE="14" SHOW="0"/> - <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_LINE_WIDTH="1" COLOR_MARKER_SIZE="14" CURRENT_POINT_LINE_WIDTH="1" CURRENT_POINT_SIZE="7" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="0" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" SHOW_POINTS_LINE_WIDTH="1" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> + <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_LINE_WIDTH="1" COLOR_MARKER_SIZE="14" CURRENT_POINT_LINE_WIDTH="1" CURRENT_POINT_SIZE="7" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="0" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" SHOW_POINTS_LINE_WIDTH="1" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> </TRACKING> <ANALYSIS> <SEARCH_MISSING_FRAMES ENABLED="1"/> @@ -61,7 +61,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="6.9530093310638514e-310" AVG_PH="4.6366371413902797e-310" AVG_PX="4.9406564584124654e-324" MAX_DH="1.5282007521032739" MAX_PH="1.9084653722971126" MAX_PX="2.9165169096333834" SD_DH="0.43009984448603678" SD_PH="0.47246997925264522" SD_PX="0.79801084449283222" USED_HEIGHT="180"/> + <REPROJECTION_ERROR AVG_DH="0" AVG_PH="0" AVG_PX="0" MAX_DH="1.5282007521032739" MAX_PH="1.9084653722971126" MAX_PX="2.9165169096333834" SD_DH="0.43009984448603678" SD_PH="0.47246997925264522" SD_PX="0.79801084449283222" USED_HEIGHT="180"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/demo/03_tracking/06_tracking_with_trajectories.pet b/demo/03_tracking/06_tracking_with_trajectories.pet index d6e5bbb6d10e56a49d35985406cdf84288e94c9e..3c8a16c32a6361ae66bed6a4585dfd1ad6a486ca 100644 --- a/demo/03_tracking/06_tracking_with_trajectories.pet +++ b/demo/03_tracking/06_tracking_with_trajectories.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="../00_files/video/video.mp4" STATUS_HEIGHT="0"/> <CONTROL TAB="2"> <CALIBRATION> @@ -11,7 +11,7 @@ <BG_SUB DELETE="1" DELETE_NUMBER="3" ENABLED="0" FILE="" SHOW="0" UPDATE="0"/> <PATTERN BOARD_SIZE_X="6" BOARD_SIZE_Y="8" SQUARE_SIZE="4.5999999"/> <INTRINSIC_PARAMETERS CALIB_FILES="" CX="947.47000000000003" CY="698.44000000000005" ENABLED="1" EXT_MODEL_ENABLED="1" FIX_CENTER="0" FX="857.12" FY="857.50999999999999" K4="1.7398640000000001" K5="0.399007" K6="-0.013342" QUAD_ASPECT_RATIO="0" R2="1.358914" R4="0.123435" R6="-0.0091129999999999996" ReprError="0.52066329210560447" S1="0.001026" S2="-6.6000000000000005e-05" S3="-0.00019000000000000001" S4="-9.7999999999999997e-05" TANG_DIST="1" TAUX="-3.0000000000000001e-05" TAUY="-5.0000000000000002e-05" TX="0.000184" TY="-0.000388"/> - <EXTRINSIC_PARAMETERS ALTITUDE="535" COORD3D_AXIS_LEN="200" COORD3D_SWAP_X="0" COORD3D_SWAP_Y="0" COORD3D_SWAP_Z="0" COORD3D_TRANS_X="0" COORD3D_TRANS_Y="0" COORD3D_TRANS_Z="0" COORD_DIMENSION="0" EXTERNAL_CALIB_FILE="" EXTR_ROT_1="-2.1949999999999998" EXTR_ROT_2="-2.1869999999999998" EXTR_ROT_3="0.029999999999999999" EXTR_TRANS_1="-1047.981" EXTR_TRANS_2="15.172000000000001" EXTR_TRANS_3="-634.48599999999999" FIX="0" ROTATE="0" SCALE="100" SHOW="0" SHOW_CALIB_POINTS="0" TRANS_X="0" TRANS_Y="0" UNIT="100" USE_INTRINSIC_CENTER="0"/> + <EXTRINSIC_PARAMETERS ALTITUDE="535" COORD3D_AXIS_LEN="200" COORD3D_SWAP_X="0" COORD3D_SWAP_Y="0" COORD3D_SWAP_Z="0" COORD3D_TRANS_X="0" COORD3D_TRANS_Y="0" COORD3D_TRANS_Z="0" COORD_DIMENSION="0" EXTERNAL_CALIB_FILE="../01_calibration/before.3dc" EXTR_ROT_1="-2.1949999999999998" EXTR_ROT_2="-2.1869999999999998" EXTR_ROT_3="0.029999999999999999" EXTR_TRANS_1="-1047.981" EXTR_TRANS_2="15.172000000000001" EXTR_TRANS_3="-634.48599999999999" FIX="0" ROTATE="0" SCALE="100" SHOW="0" SHOW_CALIB_POINTS="0" TRANS_X="0" TRANS_Y="0" UNIT="100" USE_INTRINSIC_CENTER="0"/> <ALIGNMENT_GRID FIX="0" GRID3D_RESOLUTION="100" GRID3D_TRANS_X="0" GRID3D_TRANS_Y="0" GRID3D_TRANS_Z="0" GRID_DIMENSION="0" ROTATE="0" SCALE="100" SHOW="0" TRANS_X="0" TRANS_Y="0"/> </CALIBRATION> <RECOGNITION> @@ -52,7 +52,7 @@ <TEST_LENGTH ENABLED="1"/> <TRACK_FILE FILENAME="06_exported_trajectories.trc"/> <SEARCH_REGION ADAPTIVE="1" LEVELS="2" MAX_ERROR="0" SCALE="14" SHOW="0"/> - <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_LINE_WIDTH="1" COLOR_MARKER_SIZE="14" CURRENT_POINT_LINE_WIDTH="1" CURRENT_POINT_SIZE="7" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="0" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" SHOW_POINTS_LINE_WIDTH="1" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> + <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_LINE_WIDTH="1" COLOR_MARKER_SIZE="14" CURRENT_POINT_LINE_WIDTH="1" CURRENT_POINT_SIZE="7" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="0" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" SHOW_POINTS_LINE_WIDTH="1" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> </TRACKING> <ANALYSIS> <SEARCH_MISSING_FRAMES ENABLED="1"/> @@ -61,7 +61,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="6.9529136044679099e-310" AVG_PH="4.6841576304786915e-310" AVG_PX="4.9406564584124654e-324" MAX_DH="1.5282007521032739" MAX_PH="1.9084653722971126" MAX_PX="2.9165169096333834" SD_DH="0.43009984448603678" SD_PH="0.47246997925264522" SD_PX="0.79801084449283222" USED_HEIGHT="180"/> + <REPROJECTION_ERROR AVG_DH="0" AVG_PH="0" AVG_PX="0" MAX_DH="1.5282007521032739" MAX_PH="1.9084653722971126" MAX_PX="2.9165169096333834" SD_DH="0.43009984448603678" SD_PH="0.47246997925264522" SD_PX="0.79801084449283222" USED_HEIGHT="180"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/demo/04_correcting/07_corrected.pet b/demo/04_correcting/07_corrected.pet index 48ec3dcd591725fd8dabc06d55d24fa3003b9280..4ca9240e6eb371cd2a5e19f6bc4e91722aa91c44 100644 --- a/demo/04_correcting/07_corrected.pet +++ b/demo/04_correcting/07_corrected.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="../00_files/video/video.mp4" STATUS_HEIGHT="0"/> <CONTROL TAB="2"> <CALIBRATION> @@ -11,7 +11,7 @@ <BG_SUB DELETE="1" DELETE_NUMBER="3" ENABLED="0" FILE="" SHOW="0" UPDATE="0"/> <PATTERN BOARD_SIZE_X="6" BOARD_SIZE_Y="8" SQUARE_SIZE="4.5999999"/> <INTRINSIC_PARAMETERS CALIB_FILES="" CX="947.47000000000003" CY="698.44000000000005" ENABLED="1" EXT_MODEL_ENABLED="1" FIX_CENTER="0" FX="857.12" FY="857.50999999999999" K4="1.7398640000000001" K5="0.399007" K6="-0.013342" QUAD_ASPECT_RATIO="0" R2="1.358914" R4="0.123435" R6="-0.0091129999999999996" ReprError="0.52066329210560447" S1="0.001026" S2="-6.6000000000000005e-05" S3="-0.00019000000000000001" S4="-9.7999999999999997e-05" TANG_DIST="1" TAUX="-3.0000000000000001e-05" TAUY="-5.0000000000000002e-05" TX="0.000184" TY="-0.000388"/> - <EXTRINSIC_PARAMETERS ALTITUDE="535" COORD3D_AXIS_LEN="200" COORD3D_SWAP_X="0" COORD3D_SWAP_Y="0" COORD3D_SWAP_Z="0" COORD3D_TRANS_X="0" COORD3D_TRANS_Y="0" COORD3D_TRANS_Z="0" COORD_DIMENSION="0" EXTERNAL_CALIB_FILE="" EXTR_ROT_1="-2.1949999999999998" EXTR_ROT_2="-2.1869999999999998" EXTR_ROT_3="0.029999999999999999" EXTR_TRANS_1="-1047.981" EXTR_TRANS_2="15.172000000000001" EXTR_TRANS_3="-634.48599999999999" FIX="0" ROTATE="0" SCALE="100" SHOW="0" SHOW_CALIB_POINTS="0" TRANS_X="0" TRANS_Y="0" UNIT="100" USE_INTRINSIC_CENTER="0"/> + <EXTRINSIC_PARAMETERS ALTITUDE="535" COORD3D_AXIS_LEN="200" COORD3D_SWAP_X="0" COORD3D_SWAP_Y="0" COORD3D_SWAP_Z="0" COORD3D_TRANS_X="0" COORD3D_TRANS_Y="0" COORD3D_TRANS_Z="0" COORD_DIMENSION="0" EXTERNAL_CALIB_FILE="../01_calibration/before.3dc" EXTR_ROT_1="-2.1949999999999998" EXTR_ROT_2="-2.1869999999999998" EXTR_ROT_3="0.029999999999999999" EXTR_TRANS_1="-1047.981" EXTR_TRANS_2="15.172000000000001" EXTR_TRANS_3="-634.48599999999999" FIX="0" ROTATE="0" SCALE="100" SHOW="0" SHOW_CALIB_POINTS="0" TRANS_X="0" TRANS_Y="0" UNIT="100" USE_INTRINSIC_CENTER="0"/> <ALIGNMENT_GRID FIX="0" GRID3D_RESOLUTION="100" GRID3D_TRANS_X="0" GRID3D_TRANS_Y="0" GRID3D_TRANS_Z="0" GRID_DIMENSION="0" ROTATE="0" SCALE="100" SHOW="0" TRANS_X="0" TRANS_Y="0"/> </CALIBRATION> <RECOGNITION> @@ -61,7 +61,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="6.9532726118450149e-310" AVG_PH="4.6888040985537879e-310" AVG_PX="4.9406564584124654e-324" MAX_DH="1.5282007521032739" MAX_PH="1.9084653722971126" MAX_PX="2.9165169096333834" SD_DH="0.43009984448603678" SD_PH="0.47246997925264522" SD_PX="0.79801084449283222" USED_HEIGHT="180"/> + <REPROJECTION_ERROR AVG_DH="0" AVG_PH="0" AVG_PX="0" MAX_DH="1.5282007521032739" MAX_PH="1.9084653722971126" MAX_PX="2.9165169096333834" SD_DH="0.43009984448603678" SD_PH="0.47246997925264522" SD_PX="0.79801084449283222" USED_HEIGHT="180"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/include/moCapEditingWidget.h b/include/moCapEditingWidget.h index 9c8721896868d01d15da5444c2c5db337744087a..59930491dc0df901e503beddbb66b833cccac33c 100644 --- a/include/moCapEditingWidget.h +++ b/include/moCapEditingWidget.h @@ -46,6 +46,8 @@ public: private slots: void onTimeOffsetChanged(double newOffset); void onVisibleChanged(int newState); + void onTranslationChanged(double); + void onRotationChanged(double newAngle); private: Ui::MoCapEditingWidget *mUi; diff --git a/include/moCapPerson.h b/include/moCapPerson.h index 00544a25e401a35282f446b258181fe199ee27ee..68a9e48fd5e19542742d929c33cd7e9b8c9ed5b7 100644 --- a/include/moCapPerson.h +++ b/include/moCapPerson.h @@ -37,13 +37,15 @@ class QDomElement; class MoCapPerson { public: - double getSampleIndex(double time) const; - inline bool hasSample(size_t index) const { return index < mSkeletons.size(); }; - inline const SkeletonTree &getSample(size_t sample) const { return mSkeletons.at(sample); } + double getSampleIndex(double time) const; + inline bool hasSample(size_t index) const { return index < mSkeletons.size(); } + SkeletonTree getSample(size_t sample) const; void setSamplerate(double samplerate); void setUserTimeOffset(double timeOffset); void setFileTimeOffset(double timeOffset); + void setTranslation(const cv::Vec3f &trans); + void setRotation(double angle); void setMetadata(const MoCapPersonMetadata &metadata); void addSkeleton(const SkeletonTree &skeleton); const SkeletonTree &getSkeleton(size_t samples) const; diff --git a/include/moCapPersonMetadata.h b/include/moCapPersonMetadata.h index afb247b71996e283fcf4375f423029f5a62f8bbf..6c01f7d0a0b314a0bb1380c383b429d0c0786c4a 100644 --- a/include/moCapPersonMetadata.h +++ b/include/moCapPersonMetadata.h @@ -58,27 +58,34 @@ public: void setSamplerate(double samplerate); void setUserTimeOffset(double offset); void setFileTimeOffset(double offset); + void setAngle(double angle); + void setTranslation(const cv::Affine3f &trans); void setMetadata( const std::string &filepath, MoCapSystem, double samplerate, double userTimeOffset, double fileTimeOffset); - MoCapSystem getSystem() const; - double getSamplerate() const; - double getOffset() const; - double getUserTimeOffset() const; - const std::string &getFilepath() const; - bool isVisible() const; - void setVisible(bool newVisible); + MoCapSystem getSystem() const; + double getSamplerate() const; + double getOffset() const; + double getUserTimeOffset() const; + const std::string &getFilepath() const; + bool isVisible() const; + void setVisible(bool newVisible); + const cv::Affine3f &getRotation() const; + const cv::Affine3f &getTranslation() const; + double getAngle() const; private: - std::string mFilepath = ""; - MoCapSystem mSystem = XSensC3D; - double mSamplerate = 60; - double mUserTimeOffset = 0; ///< user chosen time offset from MoCap to video in seconds - double mFileTimeOffset = 0; ///< time offset in seconds not from user but from MoCap-file - bool mVisible = true; ///< whether this person should be visualised + std::string mFilepath = ""; + MoCapSystem mSystem = XSensC3D; + double mSamplerate = 60; + double mUserTimeOffset = 0; ///< user chosen time offset from MoCap to video in seconds + double mFileTimeOffset = 0; ///< time offset in seconds not from user but from MoCap-file + cv::Affine3f mRotation = cv::Affine3d::Identity(); ///< user chosen rotation around root-pos for viz + cv::Affine3f mTranslation = cv::Affine3d::Identity(); ///< user chosen translation for viz; unit is cm + bool mVisible = true; ///< whether this person should be visualised }; bool readsTheSame(const MoCapPersonMetadata &lhs, const MoCapPersonMetadata &rhs); diff --git a/include/skeletonTree.h b/include/skeletonTree.h index 3b973353cefbf9c68029f03d21ea33195cc8dc82..730f557260b499c626967fe3bc13dad814a73b74 100644 --- a/include/skeletonTree.h +++ b/include/skeletonTree.h @@ -132,6 +132,8 @@ public: */ inline cv::Point3f getPos() const { return mPoint; } + inline void transform(const cv::Affine3f &transform) { mPoint = transform * mPoint; } + private: uint8_t mId; /**< An identifier for the node. */ cv::Point3f mPoint; /**< Position of the node. */ @@ -166,7 +168,11 @@ public: * @param[in] root The root node for the Skeleton. * @param[in] dir The direction the head is facing. The vector will be normalized. */ - SkeletonTree(SkeletonNode root, const Vec3F &dir) : mRoot(std::move(root)), mHeadDir(dir) { mHeadDir.normalize(); } + SkeletonTree(SkeletonNode root, const cv::Vec3f &dir, const cv::Point3f &rotationCenter) : + mRoot(std::move(root)), mHeadDir(dir), mRotationCenter(rotationCenter) + { + mHeadDir = cv::normalize(mHeadDir); + } /** * @brief Moving constructor for the Skeleton. @@ -176,7 +182,11 @@ public: * @param[in] root The root node as a r-value. * @param[in] dir The direction the head is facing in as a r-value */ - SkeletonTree(SkeletonNode &&root, Vec3F &&dir) : mRoot(root), mHeadDir(dir) { mHeadDir.normalize(); } + SkeletonTree(SkeletonNode &&root, cv::Vec3f &&dir, cv::Point3f &&rotationCenter) : + mRoot(root), mHeadDir(dir), mRotationCenter(rotationCenter) + { + mHeadDir = cv::normalize(mHeadDir); + } std::vector<SkeletonLine> getLines() const; @@ -200,11 +210,19 @@ public: * * @return The normalized direction of the head. */ - inline const Vec3F &getHeadDir() const { return mHeadDir; } + inline const cv::Vec3f &getHeadDir() const { return mHeadDir; } + + /** + * @brief Returns a copy translated by translation + * @param translation vector to add to each skeleton point + * @return translated copy of skeleton + */ + SkeletonTree transformed(cv::Affine3f rotation, cv::Affine3f translation) const; private: - SkeletonNode mRoot; /**< Root node of the skeleton. */ - Vec3F mHeadDir; /**< Direction the head is facing to. This value is normalized. */ + SkeletonNode mRoot; /**< Root node of the skeleton. */ + cv::Vec3f mHeadDir; /**< Direction the head is facing to. This value is normalized. */ + cv::Point3f mRotationCenter; /**< Center of rotation for this skeleton tree (top of head) */ }; diff --git a/include/tracker.h b/include/tracker.h index b7aeab0e286fad27642fdd29595a6b373239281c..e720363187efa97f3412edef81c090a63480694b 100644 --- a/include/tracker.h +++ b/include/tracker.h @@ -25,6 +25,7 @@ #include <QColor> #include <QList> #include <QRegularExpression> +#include <QSet> #include <QTextStream> #include <spdlog/fmt/bundled/format.h> diff --git a/include/vector.h b/include/vector.h index 6943cd6cfb9f2aec270bddaa5541c5cfb0d4a2de..c025bcbdcd933275a14cf49ec8c0df4b4d8c98cf 100644 --- a/include/vector.h +++ b/include/vector.h @@ -21,7 +21,6 @@ #include "helper.h" -#include <QMatrix4x4> #include <QVector3D> #include <opencv2/core/types_c.h> diff --git a/src/moCapController.cpp b/src/moCapController.cpp index c2bcaab6fdefecbd060045ad9263471edd3fc65e..31bb8884b4c1ce0db72e748a330c3080e2984991 100644 --- a/src/moCapController.cpp +++ b/src/moCapController.cpp @@ -112,9 +112,9 @@ void MoCapController::transformPersonSkeleton( } // Head Direction Arrow - Vec3F headDir_v = preSample.getHeadDir() * (1 - weight) + postSample.getHeadDir() * weight; - headDir_v.normalize(); - cv::Point3f headDir = cv::Point3f(headDir_v.x(), headDir_v.y(), headDir_v.z()); + cv::Vec3f headDir_v = preSample.getHeadDir() * (1 - weight) + postSample.getHeadDir() * weight; + headDir_v = cv::normalize(headDir_v); + cv::Point3f headDir = cv::Point3f(headDir_v); headDir *= neckToHead3D.length(); // Start arrow at 75% the way from C7 to top of head @@ -398,6 +398,38 @@ void MoCapController::getXml(const QDomElement &elem) throw std::invalid_argument(ss.str()); } } + if(subElem.hasAttribute("ANGLE")) + { + double angle = subElem.attribute("ANGLE").toDouble(&ok); + std::stringstream ss; + ss << "Element ANGLE of file " << path + << " does not contain a valid angle (should be between -360 and 360)!"; + if(!ok || abs(angle) > 360) + { + throw std::invalid_argument(ss.str()); + } + metadata.setAngle(angle); + } + if(subElem.hasAttribute("TRANS_X") && subElem.hasAttribute("TRANS_Y") && + subElem.hasAttribute("TRANS_Z")) + { + bool allOk = true; + double transX = subElem.attribute("TRANS_X").toDouble(&ok); + allOk &= ok; + double transY = subElem.attribute("TRANS_Y").toDouble(&ok); + allOk &= ok; + double transZ = subElem.attribute("TRANS_Z").toDouble(&ok); + allOk &= ok; + + std::stringstream ss; + ss << "Element TRANS of file " << path << " does not contain a valid translation!"; + if(!allOk) + { + throw std::invalid_argument(ss.str()); + } + metadata.setTranslation( + cv::Affine3f(cv::Mat::eye(3, 3, CV_32F), cv::Vec3f(transX, transY, transZ))); + } savedMetadata.push_back(metadata); } } diff --git a/src/moCapEditingWidget.cpp b/src/moCapEditingWidget.cpp index 911c3fe8ecb45ce8d3d2892c70951aa08cb91889..f5dbc0ce18179a07f172bd40f156a44271b82456 100644 --- a/src/moCapEditingWidget.cpp +++ b/src/moCapEditingWidget.cpp @@ -30,6 +30,11 @@ MoCapEditingWidget::MoCapEditingWidget(QWidget *parent, MoCapPerson &moCapPerson mUi->fileName->setText(QString::fromStdString(mPerson.getFilename())); mUi->timeOffset->setValue(mPerson.getMetadata().getUserTimeOffset()); mUi->showPerson->setChecked(mPerson.isVisible()); + mUi->angle->setValue(mPerson.getMetadata().getAngle()); + auto trans = mPerson.getMetadata().getTranslation().translation(); + mUi->trans_x->setValue(trans[0]); + mUi->trans_y->setValue(trans[1]); + mUi->trans_z->setValue(trans[2]); connect( mUi->timeOffset, @@ -37,6 +42,22 @@ MoCapEditingWidget::MoCapEditingWidget(QWidget *parent, MoCapPerson &moCapPerson this, &MoCapEditingWidget::onTimeOffsetChanged); connect(mUi->showPerson, &QCheckBox::stateChanged, this, &MoCapEditingWidget::onVisibleChanged); + connect(mUi->angle, qOverload<double>(&PDoubleSpinBox::valueChanged), this, &MoCapEditingWidget::onRotationChanged); + connect( + mUi->trans_x, + qOverload<double>(&PDoubleSpinBox::valueChanged), + this, + &MoCapEditingWidget::onTranslationChanged); + connect( + mUi->trans_y, + qOverload<double>(&PDoubleSpinBox::valueChanged), + this, + &MoCapEditingWidget::onTranslationChanged); + connect( + mUi->trans_z, + qOverload<double>(&PDoubleSpinBox::valueChanged), + this, + &MoCapEditingWidget::onTranslationChanged); setMinimumSize(mUi->mainLayout->minimumSize()); } @@ -67,3 +88,16 @@ void MoCapEditingWidget::onVisibleChanged(int newState) mPerson.setVisible(newState == Qt::Checked); mUpdateOverlay(); } + +void MoCapEditingWidget::onTranslationChanged(double /*newVal*/) +{ + cv::Vec3f trans(mUi->trans_x->value(), mUi->trans_y->value(), mUi->trans_z->value()); + mPerson.setTranslation(trans); + mUpdateOverlay(); +} + +void MoCapEditingWidget::onRotationChanged(double newAngle) +{ + mPerson.setRotation(newAngle); + mUpdateOverlay(); +} diff --git a/src/moCapPerson.cpp b/src/moCapPerson.cpp index 547bfafb2bd696ae6a994fb90b92934cd9ad863a..4ffb0d1f1504261aede5bc666d362fec8d30679d 100644 --- a/src/moCapPerson.cpp +++ b/src/moCapPerson.cpp @@ -34,6 +34,11 @@ double MoCapPerson::getSampleIndex(double time) const return mMetadata.getSamplerate() * (time + mMetadata.getOffset()); } +SkeletonTree MoCapPerson::getSample(size_t sample) const +{ + return mSkeletons.at(sample).transformed(mMetadata.getRotation(), mMetadata.getTranslation()); +} + void MoCapPerson::setSamplerate(double samplerate) { mMetadata.setSamplerate(samplerate); @@ -49,6 +54,17 @@ void MoCapPerson::setFileTimeOffset(double timeOffset) mMetadata.setFileTimeOffset(timeOffset); } +void MoCapPerson::setTranslation(const cv::Vec3f &trans) +{ + cv::Affine3f newTrans{cv::Mat::eye({3, 3}, CV_32F), trans}; + mMetadata.setTranslation(newTrans); +} + +void MoCapPerson::setRotation(double angle) +{ + mMetadata.setAngle(angle); +} + void MoCapPerson::addSkeleton(const SkeletonTree &skeleton) { mSkeletons.push_back(skeleton); @@ -96,6 +112,11 @@ void MoCapPerson::setXml(QDomElement &elem) const subElem.setAttribute("SAMPLE_RATE", mMetadata.getSamplerate()); subElem.setAttribute("SYSTEM", mMetadata.getSystem()); subElem.setAttribute("VISIBLE", mMetadata.isVisible()); + subElem.setAttribute("ANGLE", mMetadata.getAngle()); + auto trans = mMetadata.getTranslation().translation(); + subElem.setAttribute("TRANS_X", trans[0]); + subElem.setAttribute("TRANS_Y", trans[1]); + subElem.setAttribute("TRANS_Z", trans[2]); } void MoCapStorage::addPerson(const MoCapPerson &person) diff --git a/src/moCapPersonMetadata.cpp b/src/moCapPersonMetadata.cpp index 964aa8372a818fccc0068e4b4789cfae59c364c8..8ef696b788697ca045772a8dbeaf7ec2f54845db 100644 --- a/src/moCapPersonMetadata.cpp +++ b/src/moCapPersonMetadata.cpp @@ -90,6 +90,25 @@ void MoCapPersonMetadata::setFileTimeOffset(double offset) mFileTimeOffset = offset; } +void MoCapPersonMetadata::setAngle(double angle) +{ + // create rotation matrix rotating by angle in xy-plane + // -angle because OpenCV is made for left-handed image coords + auto rot2D = cv::getRotationMatrix2D({0, 0}, -angle, 1); + rot2D.convertTo(rot2D, CV_32F); + cv::Mat rot3D = cv::Mat::eye({3, 3}, CV_32F); + auto rot_view = rot3D.rowRange(0, 2).colRange(0, 2); + rot2D.rowRange(0, 2).colRange(0, 2).copyTo(rot_view); + + mRotation = cv::Affine3f(rot3D); +} + +void MoCapPersonMetadata::setTranslation(const cv::Affine3f &trans) +{ + mTranslation = trans; +} + + const std::string &MoCapPersonMetadata::getFilepath() const { return mFilepath; @@ -105,6 +124,34 @@ void MoCapPersonMetadata::setVisible(bool newVisible) mVisible = newVisible; } +const cv::Affine3f &MoCapPersonMetadata::getRotation() const +{ + return mRotation; +} + +const cv::Affine3f &MoCapPersonMetadata::getTranslation() const +{ + return mTranslation; +} + +/** + * @brief Returns angle with which to rotate the person + * + * The person can be rotated around its rotation point. That is + * usually the top of head. It is rotated in the xy-plane. This + * is the angle the person is rotated by. + * + * @return returns angle in degrees + */ +double MoCapPersonMetadata::getAngle() const +{ + // assume perfect rotation matrix + // [ cos a -sin a ] + // [ sin a cos a ] + const auto &rot = mRotation.rotation(); + return atan2(rot(1, 0), rot(0, 0)) * (180 / CV_PI); +} + MoCapSystem MoCapPersonMetadata::getSystem() const { return mSystem; diff --git a/src/skeletonTree.cpp b/src/skeletonTree.cpp index ed6d55f752e261ea4dace34eb823d07cd7f30f1c..6b09eb07549ddc869cdcacb29ac743350b4b7629 100644 --- a/src/skeletonTree.cpp +++ b/src/skeletonTree.cpp @@ -89,3 +89,25 @@ std::vector<SkeletonLine> SkeletonTree::getLines() const recurseSkeleton(mRoot, lines); return lines; } + +void transformTree(SkeletonNode &node, const cv::Affine3f &transform) +{ + node.transform(transform); + for(auto &child : node.getChildren()) + { + transformTree(child, transform); + } +} + +SkeletonTree SkeletonTree::transformed(cv::Affine3f rotation, cv::Affine3f translation) const +{ + SkeletonTree transformed{*this}; + auto transFrom = cv::Affine3f().translate(mRotationCenter); + auto transTo = cv::Affine3f().translate(-mRotationCenter); + auto rot_around_head = transTo.concatenate(rotation.concatenate(transFrom)); + auto transform = rot_around_head.concatenate(translation); + transformTree(transformed.mRoot, transform); + cv::Matx33f rot = transform.rotation(); + transformed.mHeadDir = rot * mHeadDir; + return transformed; +} diff --git a/src/skeletonTreeFactory.cpp b/src/skeletonTreeFactory.cpp index f9c2ba8a504f626c69ae28e3facf20931610f642..52706d262f1659198fa17c952df7476c4ecdffcb 100644 --- a/src/skeletonTreeFactory.cpp +++ b/src/skeletonTreeFactory.cpp @@ -38,8 +38,8 @@ SkeletonTree SkeletonTreeFactory::generateTree(const XSenseStruct &points) SkeletonNode &neck = root.addChild(SkeletonNode(1, points.mNeck1)); // continue with the neck - SkeletonNode &neck2 = neck.addChild(SkeletonNode(19, points.mNeck2)); - neck2.addChild(SkeletonNode(2, points.mHeadTop)); + SkeletonNode &neck2 = neck.addChild(SkeletonNode(19, points.mNeck2)); + SkeletonNode &topOfHead = neck2.addChild(SkeletonNode(2, points.mHeadTop)); // add the left arm SkeletonNode &lShoulder = neck.addChild(SkeletonNode(3, points.mShldrL)); @@ -73,7 +73,7 @@ SkeletonTree SkeletonTreeFactory::generateTree(const XSenseStruct &points) // the direction is calculated using the cross product cv::Point3f dir = headUp.cross(rightVector); - SkeletonTree skeleton(std::move(root), Vec3F(dir)); + SkeletonTree skeleton(std::move(root), dir, topOfHead.getPos()); return skeleton; } diff --git a/tests/regression_test/data/00_empty.pet b/tests/regression_test/data/00_empty.pet index ec40660a195991ecff6ae7de1015a1078df1da4a..a94248d0df1be3ff8228e8810abe22f83e807066 100644 --- a/tests/regression_test/data/00_empty.pet +++ b/tests/regression_test/data/00_empty.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="" STATUS_HEIGHT="0"/> <CONTROL TAB="0"> <CALIBRATION> @@ -57,7 +57,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="6.952642160144429e-310" AVG_PH="4.6632137672154514e-310" AVG_PX="4.9406564584124654e-324" MAX_DH="4.6632130749188108e-310" MAX_PH="4.6632130749149077e-310" MAX_PX="4.6632132612882775e-310" SD_DH="4.6632137672154514e-310" SD_PH="6.9526421601088563e-310" SD_PX="6.952642160144429e-310" USED_HEIGHT="4.6632137672154514e-310"/> + <REPROJECTION_ERROR AVG_DH="1.1400328837962875e-311" AVG_PH="3.9525251667299724e-322" AVG_PX="6.9525070095192605e-310" MAX_DH="4.6632130749188108e-310" MAX_PH="4.6632130749149077e-310" MAX_PX="4.6632132612882775e-310" SD_DH="4.6632137672154514e-310" SD_PH="6.9526421601088563e-310" SD_PX="6.952642160144429e-310" USED_HEIGHT="4.6632137672154514e-310"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/tests/regression_test/data/01_intrinsic.pet b/tests/regression_test/data/01_intrinsic.pet index 89c25ffb87f6bc1d765fe8dd2413fc3dd0c78252..0e08dffc7d543062ec2dc2964623a90b33546e5d 100644 --- a/tests/regression_test/data/01_intrinsic.pet +++ b/tests/regression_test/data/01_intrinsic.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="" STATUS_HEIGHT="0"/> <CONTROL TAB="0"> <CALIBRATION> @@ -57,7 +57,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="3.5572726500569751e-322" AVG_PH="8.7423532647800221e-318" AVG_PX="2.4703282292062327e-323" MAX_DH="4.6632130749188108e-310" MAX_PH="4.6632130749149077e-310" MAX_PX="4.6632132612882775e-310" SD_DH="4.6632137672154514e-310" SD_PH="6.9526421601088563e-310" SD_PX="6.952642160144429e-310" USED_HEIGHT="4.6632137672154514e-310"/> + <REPROJECTION_ERROR AVG_DH="1.1421466874887316e-311" AVG_PH="3.9525251667299724e-322" AVG_PX="6.9525070095192605e-310" MAX_DH="4.6632130749188108e-310" MAX_PH="4.6632130749149077e-310" MAX_PX="4.6632132612882775e-310" SD_DH="4.6632137672154514e-310" SD_PH="6.9526421601088563e-310" SD_PX="6.952642160144429e-310" USED_HEIGHT="4.6632137672154514e-310"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/tests/regression_test/data/blackdotMarker.pet b/tests/regression_test/data/blackdotMarker.pet index 750373ad0b6e7783bd96dd732a450252fb6f4eb2..5d5369b9f62bdd4a5ce53e55b0f48e8f130fc637 100755 --- a/tests/regression_test/data/blackdotMarker.pet +++ b/tests/regression_test/data/blackdotMarker.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="blackdotMarker.mp4" STATUS_HEIGHT="0"/> <CONTROL TAB="2"> <CALIBRATION> @@ -52,7 +52,7 @@ <TEST_LENGTH ENABLED="0"/> <TRACK_FILE FILENAME=""/> <SEARCH_REGION ADAPTIVE="0" LEVELS="2" MAX_ERROR="0" SCALE="12" SHOW="1"/> - <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_SIZE="14" CURRENT_POINT_SIZE="15" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="0" NUMBER_BOLD="1" NUMBER_SIZE="25" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="0" SHOW_COLOR_MARKER="0" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#0000ff"/> + <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_LINE_WIDTH="1" COLOR_MARKER_SIZE="14" CURRENT_POINT_LINE_WIDTH="1" CURRENT_POINT_SIZE="15" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="0" NUMBER_BOLD="1" NUMBER_SIZE="25" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="0" SHOW_COLOR_MARKER="0" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" SHOW_POINTS_LINE_WIDTH="1" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#0000ff"/> </TRACKING> <ANALYSIS> <SEARCH_MISSING_FRAMES ENABLED="1"/> @@ -61,7 +61,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="0" AVG_PH="4.6755133401755419e-310" AVG_PX="4.6755146667991126e-310" MAX_DH="4.646775768903306e-310" MAX_PH="4.6467757711238346e-310" MAX_PX="6.9346406892679761e-310" SD_DH="4.6467747728396915e-310" SD_PH="6.9346406888723283e-310" SD_PX="4.6467757687831492e-310" USED_HEIGHT="6.9346406107594628e-310"/> + <REPROJECTION_ERROR AVG_DH="8.3618533772265552e-312" AVG_PH="3.9525251667299724e-322" AVG_PX="6.9525070095192605e-310" MAX_DH="4.646775768903306e-310" MAX_PH="4.6467757711238346e-310" MAX_PX="6.9346406892679761e-310" SD_DH="4.6467747728396915e-310" SD_PH="6.9346406888723283e-310" SD_PX="4.6467757687831492e-310" USED_HEIGHT="6.9346406107594628e-310"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> @@ -85,7 +85,7 @@ <CODE_MARKER USE="0"/> <AUTO_CORRECT ONLY_EXPORT="0" USE="1"/> <MASK MASK="1" OPACITY="60" SHOW="1"/> - <PARAM CLOSE_RADIUS="10" CLOSE_USED="1" MAX_AREA="6518" MAX_RATIO="1.8" MIN_AREA="1955" OPEN_RADIUS="10" OPEN_USED="1" USE_HEAD_SIZE="1"/> + <PARAM CLOSE_RADIUS="10" CLOSE_USED="1" MAX_AREA="6815" MAX_RATIO="1.8" MIN_AREA="2044" OPEN_RADIUS="10" OPEN_USED="1" USE_HEAD_SIZE="1"/> </MULTI_COLOR_MARKER> <MOCAP COLOR="#ffff37" SHOW="0" SIZE="2"/> <PLAYER FPS="25" FRAME="0" PLAYER_SPEED_FIXED="0" SOURCE_FRAME_IN="0" SOURCE_FRAME_OUT="543"/> diff --git a/tests/regression_test/data/codeMarker.pet b/tests/regression_test/data/codeMarker.pet index 9718e31430afb3b2e8e096205f7da95caf6436d7..b9e59027a9c129cd5879a594288efade95f6709e 100644 --- a/tests/regression_test/data/codeMarker.pet +++ b/tests/regression_test/data/codeMarker.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="codeMarker.mp4" STATUS_HEIGHT="0"/> <CONTROL TAB="2"> <CALIBRATION> @@ -48,7 +48,7 @@ <TEST_LENGTH ENABLED="1"/> <TRACK_FILE FILENAME=""/> <SEARCH_REGION ADAPTIVE="0" LEVELS="3" MAX_ERROR="0" SCALE="16" SHOW="0"/> - <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_SIZE="14" CURRENT_POINT_SIZE="60" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="1" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> + <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_LINE_WIDTH="1" COLOR_MARKER_SIZE="14" CURRENT_POINT_LINE_WIDTH="1" CURRENT_POINT_SIZE="60" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="1" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" SHOW_POINTS_LINE_WIDTH="1" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> </TRACKING> <ANALYSIS> <SEARCH_MISSING_FRAMES ENABLED="1"/> @@ -57,7 +57,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="0" AVG_PH="4.6560217882062561e-310" AVG_PX="4.6560227635167419e-310" MAX_DH="4.6560227635167419e-310" MAX_PH="4.6560217882062561e-310" MAX_PX="6.9527326009498098e-310" SD_DH="4.6560217882058609e-310" SD_PH="6.952732600939138e-310" SD_PX="3.8829051134825777e-249" USED_HEIGHT="6.9527326009367665e-310"/> + <REPROJECTION_ERROR AVG_DH="1.2302022927518785e-311" AVG_PH="3.9525251667299724e-322" AVG_PX="1.0325971998082053e-321" MAX_DH="4.6560227635167419e-310" MAX_PH="4.6560217882062561e-310" MAX_PX="6.9527326009498098e-310" SD_DH="4.6560217882058609e-310" SD_PH="6.952732600939138e-310" SD_PX="3.8829051134825777e-249" USED_HEIGHT="6.9527326009367665e-310"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> @@ -85,7 +85,7 @@ </MULTI_COLOR_MARKER> <MOCAP COLOR="#ffff37" SHOW="0" SIZE="2"/> <PLAYER FPS="25" FRAME="0" PLAYER_SPEED_FIXED="0" SOURCE_FRAME_IN="0" SOURCE_FRAME_OUT="1073"/> - <VIEW ANTIALIAS="0" CAMERA="2" HIDE_CONTROLS="0" OPENGL="0" SAVE_TRANSFORMED="0" TRANSFORMATION="204 0 -120 -178"/> + <VIEW ANTIALIAS="0" CAMERA="2" HIDE_CONTROLS="0" OPENGL="0" SAVE_TRANSFORMED="0" TRANSFORMATION="204 0 -169 -222"/> <AUTO_TRACK BACK_TRACK="1" OPTIMZE_COLOR="0"/> <MISSING_FRAMES executed="0"/> </PETRACK> diff --git a/tests/regression_test/data/markerCasern.pet b/tests/regression_test/data/markerCasern.pet index ac2d6753605dd4cc00c61eee0824b322e82cc51f..06535af34acf0f3f330dbdf5f7d6065f4792fa2c 100644 --- a/tests/regression_test/data/markerCasern.pet +++ b/tests/regression_test/data/markerCasern.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="markerCasern.avi" STATUS_HEIGHT="180"/> <CONTROL TAB="0"> <CALIBRATION> @@ -56,7 +56,7 @@ <TEST_LENGTH ENABLED="1"/> <TRACK_FILE FILENAME=""/> <SEARCH_REGION ADAPTIVE="0" LEVELS="3" MAX_ERROR="0" SCALE="16" SHOW="0"/> - <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_SIZE="14" CURRENT_POINT_SIZE="60" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="1" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> + <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_LINE_WIDTH="1" COLOR_MARKER_SIZE="14" CURRENT_POINT_LINE_WIDTH="1" CURRENT_POINT_SIZE="60" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="1" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" SHOW_POINTS_LINE_WIDTH="1" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> </TRACKING> <ANALYSIS> <SEARCH_MISSING_FRAMES ENABLED="1"/> @@ -65,7 +65,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="0" AVG_PH="4.646262983180894e-310" AVG_PX="4.6462645603376439e-310" MAX_DH="4.6462645603376439e-310" MAX_PH="4.646262983180894e-310" MAX_PX="6.9526686235197743e-310" SD_DH="4.6462629831804987e-310" SD_PH="6.9526686235091025e-310" SD_PX="2.1013090475021298e+139" USED_HEIGHT="6.952668623506731e-310"/> + <REPROJECTION_ERROR AVG_DH="1.3264491913277669e-311" AVG_PH="3.9525251667299724e-322" AVG_PX="6.4228533959362051e-323" MAX_DH="4.6462645603376439e-310" MAX_PH="4.646262983180894e-310" MAX_PX="6.9526686235197743e-310" SD_DH="4.6462629831804987e-310" SD_PH="6.9526686235091025e-310" SD_PX="2.1013090475021298e+139" USED_HEIGHT="6.952668623506731e-310"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/tests/regression_test/data/markerJapan.pet b/tests/regression_test/data/markerJapan.pet index 78ddc28a1a8b1a3b0d76b6b602cf66f44cc36a25..3be547531f06d38833fb1dfd41b8ba0e761b808c 100644 --- a/tests/regression_test/data/markerJapan.pet +++ b/tests/regression_test/data/markerJapan.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="markerJapan/000100000.jpg" STATUS_HEIGHT="0"/> <CONTROL TAB="0"> <CALIBRATION> @@ -48,7 +48,7 @@ <TEST_LENGTH ENABLED="1"/> <TRACK_FILE FILENAME=""/> <SEARCH_REGION ADAPTIVE="0" LEVELS="1" MAX_ERROR="0" SCALE="14" SHOW="1"/> - <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_SIZE="14" CURRENT_POINT_SIZE="60" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="1" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="1" POINTS_COLORED="1" POINTS_SIZE="4" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="1" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> + <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_LINE_WIDTH="1" COLOR_MARKER_SIZE="14" CURRENT_POINT_LINE_WIDTH="1" CURRENT_POINT_SIZE="60" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="1" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="1" POINTS_COLORED="1" POINTS_SIZE="4" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="1" SHOW_POINTS_LINE_WIDTH="1" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> </TRACKING> <ANALYSIS> <SEARCH_MISSING_FRAMES ENABLED="1"/> @@ -57,7 +57,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="0" AVG_PH="4.6653566439403536e-310" AVG_PX="4.6653580084069812e-310" MAX_DH="4.6653580084069812e-310" MAX_PH="4.6653566439403536e-310" MAX_PX="6.9526629706364624e-310" SD_DH="4.6653566439399583e-310" SD_PH="6.9526629706257906e-310" SD_PX="2.033759975024312e-156" USED_HEIGHT="6.9526629706234191e-310"/> + <REPROJECTION_ERROR AVG_DH="1.0224146229884167e-311" AVG_PH="3.9525251667299724e-322" AVG_PX="6.9525070095192605e-310" MAX_DH="4.6653580084069812e-310" MAX_PH="4.6653566439403536e-310" MAX_PX="6.9526629706364624e-310" SD_DH="4.6653566439399583e-310" SD_PH="6.9526629706257906e-310" SD_PX="2.033759975024312e-156" USED_HEIGHT="6.9526629706234191e-310"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/tests/regression_test/data/multiColorMarkerWithAruco.pet b/tests/regression_test/data/multiColorMarkerWithAruco.pet index 58dea475d5eabf2c014b85055c1fc4095806407c..aea821b8f9e98b671bdb2375fef9ecf41c44b07c 100644 --- a/tests/regression_test/data/multiColorMarkerWithAruco.pet +++ b/tests/regression_test/data/multiColorMarkerWithAruco.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="multiColorMarkerWithAruco.mp4" STATUS_HEIGHT="0"/> <CONTROL TAB="1"> <CALIBRATION> @@ -48,7 +48,7 @@ <TEST_LENGTH ENABLED="1"/> <TRACK_FILE FILENAME=""/> <SEARCH_REGION ADAPTIVE="0" LEVELS="3" MAX_ERROR="0" SCALE="16" SHOW="0"/> - <PATH AFTER="1500" BEFORE="1500" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_SIZE="14" CURRENT_POINT_SIZE="60" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="1" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> + <PATH AFTER="1500" BEFORE="1500" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_LINE_WIDTH="1" COLOR_MARKER_SIZE="14" CURRENT_POINT_LINE_WIDTH="1" CURRENT_POINT_SIZE="60" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="1" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" SHOW_POINTS_LINE_WIDTH="1" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> </TRACKING> <ANALYSIS> <SEARCH_MISSING_FRAMES ENABLED="1"/> @@ -57,7 +57,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="0" AVG_PH="0" AVG_PX="0" MAX_DH="4.6482249247897014e-310" MAX_PH="4.6482248811874201e-310" MAX_PX="6.9531746720061243e-310" SD_DH="4.6482248811870248e-310" SD_PH="6.9531746719954525e-310" SD_PX="-9.9104429895508597e+290" USED_HEIGHT="6.953174671993081e-310"/> + <REPROJECTION_ERROR AVG_DH="8.0655271030870288e-312" AVG_PH="3.9525251667299724e-322" AVG_PX="6.9525070095192605e-310" MAX_DH="4.6482249247897014e-310" MAX_PH="4.6482248811874201e-310" MAX_PX="6.9531746720061243e-310" SD_DH="4.6482248811870248e-310" SD_PH="6.9531746719954525e-310" SD_PX="-9.9104429895508597e+290" USED_HEIGHT="6.953174671993081e-310"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> @@ -85,7 +85,7 @@ </MULTI_COLOR_MARKER> <MOCAP COLOR="#ffff37" SHOW="0" SIZE="2"/> <PLAYER FPS="50" FRAME="0" PLAYER_SPEED_FIXED="0" SOURCE_FRAME_IN="0" SOURCE_FRAME_OUT="33"/> - <VIEW ANTIALIAS="0" CAMERA="2" HIDE_CONTROLS="0" OPENGL="0" SAVE_TRANSFORMED="0" TRANSFORMATION="252 0 284 145"/> + <VIEW ANTIALIAS="0" CAMERA="2" HIDE_CONTROLS="0" OPENGL="0" SAVE_TRANSFORMED="0" TRANSFORMATION="252 0 284 107"/> <AUTO_TRACK BACK_TRACK="1" OPTIMZE_COLOR="0"/> <MISSING_FRAMES executed="0"/> </PETRACK> diff --git a/tests/regression_test/data/multiColorMarkerWithAruco_dictMip36h12.pet b/tests/regression_test/data/multiColorMarkerWithAruco_dictMip36h12.pet index 307555b68828c8c979368feff0a64804b0dd0bfa..256d96d997a175f5456585ba76a8cce1c984c859 100644 --- a/tests/regression_test/data/multiColorMarkerWithAruco_dictMip36h12.pet +++ b/tests/regression_test/data/multiColorMarkerWithAruco_dictMip36h12.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="multiColorMarkerWithAruco_dictMip36h12.mp4" STATUS_HEIGHT="0"/> <CONTROL TAB="1"> <CALIBRATION> @@ -48,7 +48,7 @@ <TEST_LENGTH ENABLED="1"/> <TRACK_FILE FILENAME=""/> <SEARCH_REGION ADAPTIVE="0" LEVELS="3" MAX_ERROR="0" SCALE="16" SHOW="0"/> - <PATH AFTER="1500" BEFORE="1500" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_SIZE="14" CURRENT_POINT_SIZE="60" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="1" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="5" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="0" SHOW_COLOR_MARKER="0" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="0" SHOW_PATH="1" SHOW_POINTS="0" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> + <PATH AFTER="1500" BEFORE="1500" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_LINE_WIDTH="1" COLOR_MARKER_SIZE="14" CURRENT_POINT_LINE_WIDTH="1" CURRENT_POINT_SIZE="60" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="1" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="5" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="0" SHOW_COLOR_MARKER="0" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="0" SHOW_PATH="1" SHOW_POINTS="0" SHOW_POINTS_LINE_WIDTH="1" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> </TRACKING> <ANALYSIS> <SEARCH_MISSING_FRAMES ENABLED="1"/> @@ -57,7 +57,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="0" AVG_PH="4.6363018019864395e-310" AVG_PX="4.6363028400314047e-310" MAX_DH="4.6363028400314047e-310" MAX_PH="4.6363018019864395e-310" MAX_PX="6.9531972930325466e-310" SD_DH="4.6363018019860442e-310" SD_PH="6.9531972930218748e-310" SD_PX="5.8990226972632587e-278" USED_HEIGHT="6.9531972930195033e-310"/> + <REPROJECTION_ERROR AVG_DH="8.3470056377034328e-312" AVG_PH="3.9525251667299724e-322" AVG_PX="6.9525070095192605e-310" MAX_DH="4.6363028400314047e-310" MAX_PH="4.6363018019864395e-310" MAX_PX="6.9531972930325466e-310" SD_DH="4.6363018019860442e-310" SD_PH="6.9531972930218748e-310" SD_PX="5.8990226972632587e-278" USED_HEIGHT="6.9531972930195033e-310"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> @@ -85,7 +85,7 @@ </MULTI_COLOR_MARKER> <MOCAP COLOR="#ffff37" SHOW="0" SIZE="2"/> <PLAYER FPS="25" FRAME="0" PLAYER_SPEED_FIXED="0" SOURCE_FRAME_IN="0" SOURCE_FRAME_OUT="692"/> - <VIEW ANTIALIAS="0" CAMERA="2" HIDE_CONTROLS="0" OPENGL="0" SAVE_TRANSFORMED="0" TRANSFORMATION="158 0 0 0"/> + <VIEW ANTIALIAS="0" CAMERA="2" HIDE_CONTROLS="0" OPENGL="0" SAVE_TRANSFORMED="0" TRANSFORMATION="158 0 -79 -53"/> <AUTO_TRACK BACK_TRACK="1" OPTIMZE_COLOR="0"/> <MISSING_FRAMES executed="0"/> </PETRACK> diff --git a/tests/regression_test/data/multicolor.pet b/tests/regression_test/data/multicolor.pet index cd734f56f7f28abf54b308b02ea530b1de32ae53..ee2763a0e0ded1762f7fed7cadc17eb710c5cace 100644 --- a/tests/regression_test/data/multicolor.pet +++ b/tests/regression_test/data/multicolor.pet @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE PETRACK> -<PETRACK VERSION="0.9.3"> +<PETRACK VERSION="0.9.4"> <MAIN SRC="multicolor.mp4" STATUS_HEIGHT="0"/> <CONTROL TAB="2"> <CALIBRATION> @@ -52,7 +52,7 @@ <TEST_LENGTH ENABLED="1"/> <TRACK_FILE FILENAME=""/> <SEARCH_REGION ADAPTIVE="1" LEVELS="2" MAX_ERROR="0" SCALE="14" SHOW="0"/> - <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_SIZE="14" CURRENT_POINT_SIZE="7" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="0" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> + <PATH AFTER="15" BEFORE="15" COLLECTIVE_COLOR_SIZE="11" COLOR_MARKER_LINE_WIDTH="1" COLOR_MARKER_SIZE="14" CURRENT_POINT_LINE_WIDTH="1" CURRENT_POINT_SIZE="7" FIX="0" GROUND_PATH_SIZE="1" GROUND_POSITION_SIZE="1" HEAD_SIZE="0" NUMBER_BOLD="1" NUMBER_SIZE="14" ONLY_PEOPLE="0" ONLY_PEOPLE_LIST="0" ONLY_PEOPLE_NR="1" ONLY_PEOPLE_NR_LIST="1" ONLY_VISIBLE="0" PATH_SIZE="2" POINTS_COLORED="1" POINTS_SIZE="7" SHOW="1" SHOW_COLLECTIVE_COLOR="1" SHOW_COLOR_MARKER="1" SHOW_CURRENT_POINT="1" SHOW_GROUND_PATH="0" SHOW_GROUND_POSITION="0" SHOW_NUMBER="1" SHOW_PATH="1" SHOW_POINTS="0" SHOW_POINTS_LINE_WIDTH="1" TRACK_GROUND_PATH_COLOR="#00ff00" TRACK_PATH_COLOR="#ff0000"/> </TRACKING> <ANALYSIS> <SEARCH_MISSING_FRAMES ENABLED="1"/> @@ -61,7 +61,7 @@ </ANALYSIS> </CONTROL> <EXTR_CALIBRATION> - <REPROJECTION_ERROR AVG_DH="0" AVG_PH="4.6884881402590801e-310" AVG_PX="4.6884896848343745e-310" MAX_DH="4.6884896848343745e-310" MAX_PH="4.6884881402590801e-310" MAX_PX="6.9528791764073219e-310" SD_DH="4.6884881402586848e-310" SD_PH="6.9528791763966501e-310" SD_PX="1.5962438829080507e+218" USED_HEIGHT="6.9528791763942786e-310"/> + <REPROJECTION_ERROR AVG_DH="9.4071814262911059e-312" AVG_PH="0" AVG_PX="6.9526710516562795e-310" MAX_DH="4.6884896848343745e-310" MAX_PH="4.6884881402590801e-310" MAX_PX="6.9528791764073219e-310" SD_DH="4.6884881402586848e-310" SD_PH="6.9528791763966501e-310" SD_PX="1.5962438829080507e+218" USED_HEIGHT="6.9528791763942786e-310"/> </EXTR_CALIBRATION> <STEREO> <DISPARITY ALGO="0" COLOR="0" HIDE_INVALID="1" OPACITY="100" SHOW="0"> diff --git a/tests/regression_test/tests/test_pet.py b/tests/regression_test/tests/test_pet.py index e4f9324043bf5100c2facbf09a983de62773930a..af286fbbfee30112522e291dee6149d7f62b597f 100644 --- a/tests/regression_test/tests/test_pet.py +++ b/tests/regression_test/tests/test_pet.py @@ -31,7 +31,7 @@ def compare_xml(test: ET.ElementTree, truth: ET.ElementTree): if test_attrib[0] == "SOURCE_FRAME_IN": # in 00_empty.pet = -1; but -1 gets read as 0, i.e. beginning of video # need extra comparison for this - assert int(test_attrib[1]) == 0 and int(truth_attrib[1]) == -1 + assert int(test_attrib[1]) == 0 and int(truth_attrib[1]) == -1, f"Failed comparison for SOURCE_FRAME_IN" continue try: diff --git a/tests/unit_test/tst_moCapController.cpp b/tests/unit_test/tst_moCapController.cpp index a6b6bb7ad26b759d3cfecc87856ced0785ae9795..14c1904160f67c2b2afe398dbb7652b958783e93 100644 --- a/tests/unit_test/tst_moCapController.cpp +++ b/tests/unit_test/tst_moCapController.cpp @@ -75,7 +75,7 @@ SCENARIO("I want to get the render data with one person loaded", "[ui]") GIVEN("a skeleton with a head direction") { - person.addSkeleton({rootA, Vec3F{1, 0, 0}}); + person.addSkeleton({rootA, cv::Vec3f{1, 0, 0}, {0, 0, 0}}); // TODO Person entsprechend anpassen // NOTE Also am besten Person in der arrow/narrow GIVEN aufbauen AND_GIVEN("no interpolation") @@ -106,7 +106,7 @@ SCENARIO("I want to get the render data with one person loaded", "[ui]") } AND_GIVEN("interpolation") { - person.addSkeleton({rootB, Vec3F{0, 1, 0}}); + person.addSkeleton({rootB, cv::Vec3f{0, 1, 0}, cv::Vec3f{0, 0, 0}}); storage.addPerson(person); THEN("we get the correct render data") diff --git a/ui/moCapEditingWidget.ui b/ui/moCapEditingWidget.ui index 7597cc592b3a18b9b99f5666d71078b3a9cab67c..02dbd8a7479b099794f6151eed2c0592e489ac2c 100644 --- a/ui/moCapEditingWidget.ui +++ b/ui/moCapEditingWidget.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>139</width> - <height>117</height> + <width>402</width> + <height>155</height> </rect> </property> <property name="sizePolicy"> @@ -57,10 +57,20 @@ </layout> </item> <item> - <layout class="QGridLayout" name="gridLayout" columnstretch="0,1"> + <layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,0,0,0"> <property name="sizeConstraint"> <enum>QLayout::SetMinAndMaxSize</enum> </property> + <item row="2" column="3"> + <widget class="PDoubleSpinBox" name="trans_y"> + <property name="minimum"> + <double>-99999.000000000000000</double> + </property> + <property name="maximum"> + <double>99999.000000000000000</double> + </property> + </widget> + </item> <item row="0" column="0"> <widget class="QLabel" name="label"> <property name="sizePolicy"> @@ -74,19 +84,60 @@ </property> </widget> </item> + <item row="0" column="4"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>Rotation</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>x [cm]</string> + </property> + </widget> + </item> <item row="1" column="1"> <widget class="PDoubleSpinBox" name="timeOffset"> + <property name="decimals"> + <number>3</number> + </property> <property name="minimum"> <double>-999.000000000000000</double> </property> + <property name="maximum"> + <double>999.000000000000000</double> + </property> <property name="singleStep"> - <double>0.100000000000000</double> + <double>0.010000000000000</double> </property> <property name="value"> <double>0.000000000000000</double> </property> </widget> </item> + <item row="2" column="2"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>y [cm]</string> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>z [cm]</string> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>angle [°]</string> + </property> + </widget> + </item> <item row="1" column="0"> <widget class="QLabel" name="timeOffsetLabel"> <property name="sizePolicy"> @@ -100,6 +151,43 @@ </property> </widget> </item> + <item row="1" column="3"> + <widget class="PDoubleSpinBox" name="trans_x"> + <property name="minimum"> + <double>-99999.000000000000000</double> + </property> + <property name="maximum"> + <double>99999.000000000000000</double> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Translation</string> + </property> + </widget> + </item> + <item row="3" column="3"> + <widget class="PDoubleSpinBox" name="trans_z"> + <property name="minimum"> + <double>-99999.000000000000000</double> + </property> + <property name="maximum"> + <double>99999.000000000000000</double> + </property> + </widget> + </item> + <item row="1" column="5"> + <widget class="PDoubleSpinBox" name="angle"> + <property name="minimum"> + <double>-360.000000000000000</double> + </property> + <property name="maximum"> + <double>360.000000000000000</double> + </property> + </widget> + </item> </layout> </item> </layout>