diff --git a/doc/final.jpg b/doc/final.jpg
new file mode 100644
index 0000000..5387f42
Binary files /dev/null and b/doc/final.jpg differ
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/configs/deep_sort.yaml b/src/DeepSORT/configs/deep_sort.yaml
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/configs/deep_sort.yaml
rename to src/DeepSORT/configs/deep_sort.yaml
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/README.md b/src/DeepSORT/deep_sort/README.md
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/README.md
rename to src/DeepSORT/deep_sort/README.md
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/__init__.py b/src/DeepSORT/deep_sort/__init__.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/__init__.py
rename to src/DeepSORT/deep_sort/__init__.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/__init__.py b/src/DeepSORT/deep_sort/deep/__init__.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/__init__.py
rename to src/DeepSORT/deep_sort/deep/__init__.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/checkpoint/ckpt.t7 b/src/DeepSORT/deep_sort/deep/checkpoint/ckpt.t7
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/checkpoint/ckpt.t7
rename to src/DeepSORT/deep_sort/deep/checkpoint/ckpt.t7
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/evaluate.py b/src/DeepSORT/deep_sort/deep/evaluate.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/evaluate.py
rename to src/DeepSORT/deep_sort/deep/evaluate.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/feature_extractor.py b/src/DeepSORT/deep_sort/deep/feature_extractor.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/feature_extractor.py
rename to src/DeepSORT/deep_sort/deep/feature_extractor.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/model.py b/src/DeepSORT/deep_sort/deep/model.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/model.py
rename to src/DeepSORT/deep_sort/deep/model.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/original_model.py b/src/DeepSORT/deep_sort/deep/original_model.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/original_model.py
rename to src/DeepSORT/deep_sort/deep/original_model.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/test.py b/src/DeepSORT/deep_sort/deep/test.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/test.py
rename to src/DeepSORT/deep_sort/deep/test.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/train.jpg b/src/DeepSORT/deep_sort/deep/train.jpg
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/train.jpg
rename to src/DeepSORT/deep_sort/deep/train.jpg
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/train.py b/src/DeepSORT/deep_sort/deep/train.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep/train.py
rename to src/DeepSORT/deep_sort/deep/train.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep_sort.py b/src/DeepSORT/deep_sort/deep_sort.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/deep_sort.py
rename to src/DeepSORT/deep_sort/deep_sort.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/__init__.py b/src/DeepSORT/deep_sort/sort/__init__.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/__init__.py
rename to src/DeepSORT/deep_sort/sort/__init__.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/detection.py b/src/DeepSORT/deep_sort/sort/detection.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/detection.py
rename to src/DeepSORT/deep_sort/sort/detection.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/iou_matching.py b/src/DeepSORT/deep_sort/sort/iou_matching.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/iou_matching.py
rename to src/DeepSORT/deep_sort/sort/iou_matching.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/kalman_filter.py b/src/DeepSORT/deep_sort/sort/kalman_filter.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/kalman_filter.py
rename to src/DeepSORT/deep_sort/sort/kalman_filter.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/linear_assignment.py b/src/DeepSORT/deep_sort/sort/linear_assignment.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/linear_assignment.py
rename to src/DeepSORT/deep_sort/sort/linear_assignment.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/nn_matching.py b/src/DeepSORT/deep_sort/sort/nn_matching.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/nn_matching.py
rename to src/DeepSORT/deep_sort/sort/nn_matching.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/preprocessing.py b/src/DeepSORT/deep_sort/sort/preprocessing.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/preprocessing.py
rename to src/DeepSORT/deep_sort/sort/preprocessing.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/track.py b/src/DeepSORT/deep_sort/sort/track.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/track.py
rename to src/DeepSORT/deep_sort/sort/track.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/tracker.py b/src/DeepSORT/deep_sort/sort/tracker.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/deep_sort/sort/tracker.py
rename to src/DeepSORT/deep_sort/sort/tracker.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/main.py b/src/DeepSORT/main.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/main.py
rename to src/DeepSORT/main.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/requirements.txt b/src/DeepSORT/requirements.txt
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/requirements.txt
rename to src/DeepSORT/requirements.txt
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/__init__.py b/src/DeepSORT/utils_ds/__init__.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/__init__.py
rename to src/DeepSORT/utils_ds/__init__.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/asserts.py b/src/DeepSORT/utils_ds/asserts.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/asserts.py
rename to src/DeepSORT/utils_ds/asserts.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/draw.py b/src/DeepSORT/utils_ds/draw.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/draw.py
rename to src/DeepSORT/utils_ds/draw.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/evaluation.py b/src/DeepSORT/utils_ds/evaluation.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/evaluation.py
rename to src/DeepSORT/utils_ds/evaluation.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/io.py b/src/DeepSORT/utils_ds/io.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/io.py
rename to src/DeepSORT/utils_ds/io.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/json_logger.py b/src/DeepSORT/utils_ds/json_logger.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/json_logger.py
rename to src/DeepSORT/utils_ds/json_logger.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/log.py b/src/DeepSORT/utils_ds/log.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/log.py
rename to src/DeepSORT/utils_ds/log.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/parser.py b/src/DeepSORT/utils_ds/parser.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/parser.py
rename to src/DeepSORT/utils_ds/parser.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/tools.py b/src/DeepSORT/utils_ds/tools.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/utils_ds/tools.py
rename to src/DeepSORT/utils_ds/tools.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/.github/ISSUE_TEMPLATE/--bug-report.md b/src/DeepSORT/yolov5/.github/ISSUE_TEMPLATE/--bug-report.md
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/.github/ISSUE_TEMPLATE/--bug-report.md
rename to src/DeepSORT/yolov5/.github/ISSUE_TEMPLATE/--bug-report.md
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/.github/ISSUE_TEMPLATE/--feature-request.md b/src/DeepSORT/yolov5/.github/ISSUE_TEMPLATE/--feature-request.md
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/.github/ISSUE_TEMPLATE/--feature-request.md
rename to src/DeepSORT/yolov5/.github/ISSUE_TEMPLATE/--feature-request.md
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/.github/ISSUE_TEMPLATE/-question.md b/src/DeepSORT/yolov5/.github/ISSUE_TEMPLATE/-question.md
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/.github/ISSUE_TEMPLATE/-question.md
rename to src/DeepSORT/yolov5/.github/ISSUE_TEMPLATE/-question.md
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/.github/workflows/ci-testing.yml b/src/DeepSORT/yolov5/.github/workflows/ci-testing.yml
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/.github/workflows/ci-testing.yml
rename to src/DeepSORT/yolov5/.github/workflows/ci-testing.yml
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/detect.py b/src/DeepSORT/yolov5/detect.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/detect.py
rename to src/DeepSORT/yolov5/detect.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/hubconf.py b/src/DeepSORT/yolov5/hubconf.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/hubconf.py
rename to src/DeepSORT/yolov5/hubconf.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/__init__.py b/src/DeepSORT/yolov5/models/__init__.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/__init__.py
rename to src/DeepSORT/yolov5/models/__init__.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/common.py b/src/DeepSORT/yolov5/models/common.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/common.py
rename to src/DeepSORT/yolov5/models/common.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/experimental.py b/src/DeepSORT/yolov5/models/experimental.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/experimental.py
rename to src/DeepSORT/yolov5/models/experimental.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/export.py b/src/DeepSORT/yolov5/models/export.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/export.py
rename to src/DeepSORT/yolov5/models/export.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/hub/yolov3-spp.yaml b/src/DeepSORT/yolov5/models/hub/yolov3-spp.yaml
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/hub/yolov3-spp.yaml
rename to src/DeepSORT/yolov5/models/hub/yolov3-spp.yaml
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/hub/yolov5-fpn.yaml b/src/DeepSORT/yolov5/models/hub/yolov5-fpn.yaml
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/hub/yolov5-fpn.yaml
rename to src/DeepSORT/yolov5/models/hub/yolov5-fpn.yaml
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/hub/yolov5-panet.yaml b/src/DeepSORT/yolov5/models/hub/yolov5-panet.yaml
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/hub/yolov5-panet.yaml
rename to src/DeepSORT/yolov5/models/hub/yolov5-panet.yaml
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/yolo.py b/src/DeepSORT/yolov5/models/yolo.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/yolo.py
rename to src/DeepSORT/yolov5/models/yolo.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/yolov5l.yaml b/src/DeepSORT/yolov5/models/yolov5l.yaml
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/yolov5l.yaml
rename to src/DeepSORT/yolov5/models/yolov5l.yaml
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/yolov5m.yaml b/src/DeepSORT/yolov5/models/yolov5m.yaml
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/yolov5m.yaml
rename to src/DeepSORT/yolov5/models/yolov5m.yaml
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/yolov5s.yaml b/src/DeepSORT/yolov5/models/yolov5s.yaml
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/yolov5s.yaml
rename to src/DeepSORT/yolov5/models/yolov5s.yaml
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/yolov5x.yaml b/src/DeepSORT/yolov5/models/yolov5x.yaml
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/models/yolov5x.yaml
rename to src/DeepSORT/yolov5/models/yolov5x.yaml
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/test.py b/src/DeepSORT/yolov5/test.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/test.py
rename to src/DeepSORT/yolov5/test.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/train.py b/src/DeepSORT/yolov5/train.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/train.py
rename to src/DeepSORT/yolov5/train.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/tutorial.ipynb b/src/DeepSORT/yolov5/tutorial.ipynb
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/tutorial.ipynb
rename to src/DeepSORT/yolov5/tutorial.ipynb
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/utils/__init__.py b/src/DeepSORT/yolov5/utils/__init__.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/utils/__init__.py
rename to src/DeepSORT/yolov5/utils/__init__.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/utils/activations.py b/src/DeepSORT/yolov5/utils/activations.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/utils/activations.py
rename to src/DeepSORT/yolov5/utils/activations.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/utils/datasets.py b/src/DeepSORT/yolov5/utils/datasets.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/utils/datasets.py
rename to src/DeepSORT/yolov5/utils/datasets.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/utils/general.py b/src/DeepSORT/yolov5/utils/general.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/utils/general.py
rename to src/DeepSORT/yolov5/utils/general.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/utils/google_utils.py b/src/DeepSORT/yolov5/utils/google_utils.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/utils/google_utils.py
rename to src/DeepSORT/yolov5/utils/google_utils.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/utils/torch_utils.py b/src/DeepSORT/yolov5/utils/torch_utils.py
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/utils/torch_utils.py
rename to src/DeepSORT/yolov5/utils/torch_utils.py
diff --git a/src/DeepSORT_YOLOv5_Pytorch-master/yolov5/weights/download_weights.sh b/src/DeepSORT/yolov5/weights/download_weights.sh
similarity index 100%
rename from src/DeepSORT_YOLOv5_Pytorch-master/yolov5/weights/download_weights.sh
rename to src/DeepSORT/yolov5/weights/download_weights.sh
diff --git a/src/tutorial_api_python/CMakeFiles/generate.stamp b/src/tutorial_api_python/CMakeFiles/generate.stamp
new file mode 100644
index 0000000..9b5f49f
--- /dev/null
+++ b/src/tutorial_api_python/CMakeFiles/generate.stamp
@@ -0,0 +1 @@
+# CMake generation timestamp file for this directory.
diff --git a/src/tutorial_api_python/CMakeFiles/generate.stamp.depend b/src/tutorial_api_python/CMakeFiles/generate.stamp.depend
new file mode 100644
index 0000000..3d7412e
--- /dev/null
+++ b/src/tutorial_api_python/CMakeFiles/generate.stamp.depend
@@ -0,0 +1,11 @@
+# CMake generation dependency list for this directory.
+E:/openpose/openpose_prosperity/examples/tutorial_api_python/01_body_from_image.py
+E:/openpose/openpose_prosperity/examples/tutorial_api_python/02_whole_body_from_image.py
+E:/openpose/openpose_prosperity/examples/tutorial_api_python/04_keypoints_from_images.py
+E:/openpose/openpose_prosperity/examples/tutorial_api_python/05_keypoints_from_images_multi_gpu.py
+E:/openpose/openpose_prosperity/examples/tutorial_api_python/06_face_from_image.py
+E:/openpose/openpose_prosperity/examples/tutorial_api_python/07_hand_from_image.py
+E:/openpose/openpose_prosperity/examples/tutorial_api_python/08_heatmaps_from_image.py
+E:/openpose/openpose_prosperity/examples/tutorial_api_python/09_keypoints_from_heatmaps.py
+E:/openpose/openpose_prosperity/examples/tutorial_api_python/CMakeLists.txt
+E:/openpose/openpose_prosperity/examples/tutorial_api_python/openpose_python.py
diff --git a/src/tutorial_api_python/INSTALL.vcxproj b/src/tutorial_api_python/INSTALL.vcxproj
new file mode 100644
index 0000000..80fead1
--- /dev/null
+++ b/src/tutorial_api_python/INSTALL.vcxproj
@@ -0,0 +1,122 @@
+
+
+
+ x64
+
+
+
+ Release
+ x64
+
+
+ Debug
+ x64
+
+
+
+ {6927D627-3432-3371-AC7A-318D1A465B17}
+ Win32Proj
+ 10.0.22621.0
+ x64
+ INSTALL
+ NoUpgrade
+
+
+
+ Utility
+ MultiByte
+ v143
+
+
+ Utility
+ MultiByte
+ v143
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.20506.1
+ $(Platform)\$(Configuration)\$(ProjectName)\
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+
+ Always
+
+ setlocal
+"C:\Program Files\CMake\bin\cmake.exe" -DBUILD_TYPE=$(Configuration) -P cmake_install.cmake
+if %errorlevel% neq 0 goto :cmEnd
+:cmEnd
+endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
+:cmErrorLevel
+exit /b %1
+:cmDone
+if %errorlevel% neq 0 goto :VCEnd
+
+
+
+
+ Always
+
+ setlocal
+"C:\Program Files\CMake\bin\cmake.exe" -DBUILD_TYPE=$(Configuration) -P cmake_install.cmake
+if %errorlevel% neq 0 goto :cmEnd
+:cmEnd
+endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
+:cmErrorLevel
+exit /b %1
+:cmDone
+if %errorlevel% neq 0 goto :VCEnd
+
+
+
+
+ true
+
+ setlocal
+cd .
+if %errorlevel% neq 0 goto :cmEnd
+:cmEnd
+endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
+:cmErrorLevel
+exit /b %1
+:cmDone
+if %errorlevel% neq 0 goto :VCEnd
+ %(AdditionalInputs)
+ E:\openpose\openpose_prosperity\build\examples\tutorial_api_python\CMakeFiles\INSTALL_force
+ false
+ false
+ true
+
+ setlocal
+cd .
+if %errorlevel% neq 0 goto :cmEnd
+:cmEnd
+endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
+:cmErrorLevel
+exit /b %1
+:cmDone
+if %errorlevel% neq 0 goto :VCEnd
+ %(AdditionalInputs)
+ E:\openpose\openpose_prosperity\build\examples\tutorial_api_python\CMakeFiles\INSTALL_force
+ false
+ false
+
+
+
+
+ {B248B77E-735C-311D-A166-2EFEAABC52A9}
+ ALL_BUILD
+ false
+ Never
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/tutorial_api_python/INSTALL.vcxproj.filters b/src/tutorial_api_python/INSTALL.vcxproj.filters
new file mode 100644
index 0000000..b97861d
--- /dev/null
+++ b/src/tutorial_api_python/INSTALL.vcxproj.filters
@@ -0,0 +1,13 @@
+
+
+
+
+ CMake Rules
+
+
+
+
+ {7BC68FB9-1045-3D7A-A2DB-568B5960D265}
+
+
+
diff --git a/src/tutorial_api_python/body_image.py b/src/tutorial_api_python/body_image.py
new file mode 100644
index 0000000..0010ec7
--- /dev/null
+++ b/src/tutorial_api_python/body_image.py
@@ -0,0 +1,147 @@
+# From Python
+# It requires OpenCV installed for Python
+import sys
+import cv2
+import os
+from sys import platform
+import argparse# 导入argparse模块,用于解析命令行参数
+
+try:
+ # Import Openpose (Windows/Ubuntu/OSX)
+ # 获取当前脚本文件的目录路径
+ dir_path = os.path.dirname(os.path.realpath(__file__))
+ try:
+ # 检查操作系统类型
+ # Windows Import
+ # 对于Windows系统
+ if platform == "win32":
+
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 使用 os.path.join 来避免路径分隔符的问题
+ openpose_path = os.path.join(dir_path, '../../python/openpose/Release')
+ sys.path.append(openpose_path)
+ #sys.path.append(dir_path + '/../../python/openpose/Release');
+ #os.environ['PATH'] = os.environ['PATH'] + ';' + dir_path + '/../../x64/Release;' + dir_path + '/../../bin;'
+ # 设置环境变量PATH,以便可以在命令行中调用OpenPose的可执行文件
+ # 在Python脚本中通常不需要这样做,这样可以在脚本中调用OpenPose的可执行文件
+ # 使用 os.pathsep 来确保路径分隔符的正确性
+ os.environ['PATH'] = os.environ['PATH'] + os.pathsep + os.path.join(dir_path,'../../x64/Release') \
+ + os.pathsep + os.path.join(dir_path, '../../bin')
+ # 导入OpenPose的Python接口
+ import pyopenpose as op
+ else:
+ # 对于Linux或MacOS系统
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 这里假设OpenPose的Python库位于相对于脚本的固定路径下
+ sys.path.append('../../python')
+ # If you run `make install` (default path is `/usr/local/python` for Ubuntu), you can also access the OpenPose/python module from there. This will install OpenPose and the python library at your desired installation path. Ensure that this is in your python path in order to use it.
+ # sys.path.append('/usr/local/python')
+ # 如果运行了 `make install`(对于Ubuntu,默认路径是 `/usr/local/python`),则也可以从那里访问OpenPose/python模块
+ # 注意:通常不需要这样做,除非OpenPose的Python库确实被安装到了非标准路径
+ # 并且,下面的代码行已经被注释掉了,因为它可能会覆盖掉其他重要的Python库路径
+ # sys.path.append('/usr/local/python')
+ # 从openpose模块导入pyopenpose
+ from openpose import pyopenpose as op
+ except ImportError as e:
+ # 如果在尝试导入pyopenpose时发生错误,则打印错误消息并重新抛出异常
+ print('Error: OpenPose library could not be found. Did you enable `BUILD_PYTHON` in CMake and have this Python script in the right folder?')
+
+ # 打印原始异常信息
+ print(e)
+ # 重新抛出异常,以便调用者可以处理它
+ raise e
+
+ # Flags
+ # 创建一个ArgumentParser对象,用于处理命令行参数
+ parser = argparse.ArgumentParser()
+ # 添加一个命令行参数 --image_path,它有一个默认值,用于指定要处理的图像文件路径
+ # 这个参数接受所有标准的图像格式(如jpg, png, bmp等)
+ parser.add_argument("--image_path",
+ default="../../../examples/media/COCO_val2014_000000000192.jpg",
+ help="Process an image. Read all standard formats (jpg, png, bmp, etc.).")
+ # 解析命令行参数,并获取已知的参数和未知参数(如果有的话)
+ # parse_known_args()方法返回两个值:一个是已知参数的Namespace对象,另一个是未知参数的列表
+ args = parser.parse_known_args()
+
+ # 创建一个字典params,用于存储自定义参数
+ # 这些参数通常用于配置OpenPose的行为,但不在默认的命令行参数中
+ params = dict()
+
+ # 设置一个自定义参数model_folder,指定OpenPose模型文件的存储路径
+ params["model_folder"] = "../../../models/"
+
+ # 遍历args[1](未知参数的列表),以处理可能通过命令行传递的额外自定义参数
+ # 注意:args[0]是Namespace对象,包含已知参数;args[1]是未知参数的列表
+ for i in range(0, len(args[1])):
+ curr_item = args[1][i] # 当前项
+
+ # 检查是否还有下一个项,并设置next_item的值
+ # 如果当前项是列表中的最后一个项,则假设下一个项为"1"(这里可能是一个简化的处理方式)
+ if i != len(args[1]) - 1:
+ next_item = args[1][i + 1]
+ else:
+ next_item = "1"
+
+ # 检查当前项和下一个项是否都以"--"开头,这通常意味着它们都是命令行参数(但这里逻辑可能不完全准确)
+ # 如果两个都是参数,则忽略它们,因为这里的逻辑可能不适用于处理真正的命令行参数
+ # 注意:这里的逻辑可能是一个错误或简化的处理方式,因为通常不会这样检查参数
+ if "--" in curr_item and "--" in next_item:
+ key = curr_item.replace('-', '') # 移除参数名中的'-'并作为字典的键
+ if key not in params: # 如果该键不在params字典中,则添加它,并赋值为"1"(这可能不是预期的行为)
+ params[key] = "1"
+
+ # 如果当前项以"--"开头但下一个项不是,则假设当前项是一个参数,而下一个项是该参数的值
+ elif "--" in curr_item and "--" not in next_item:
+ key = curr_item.replace('-', '') # 同样移除'-'
+ if key not in params: # 如果该键不在params字典中,则添加它,并将next_item作为值
+ params[key] = next_item
+
+ # Construct it from system arguments
+ # op.init_argv(args[1])
+ # oppython = op.OpenposePython()
+
+ # Starting OpenPose
+ # 初始化OpenPose的WrapperPython对象
+ # WrapperPython是OpenPose提供的Python接口的主要类,用于封装OpenPose的功能
+ opWrapper = op.WrapperPython()
+
+ # 使用自定义参数配置OpenPose
+ # params是一个字典,包含了OpenPose运行所需的配置参数
+ # 这些参数可以影响OpenPose的性能、输出等
+ opWrapper.configure(params)
+
+ # 启动OpenPose
+ # 在配置完成后,需要调用start方法来初始化OpenPose的内部结构
+ opWrapper.start()
+
+ # 处理图像
+ # 创建一个Datum对象,Datum是OpenPose用于存储输入和输出数据的类
+ datum = op.Datum()
+
+ # 使用OpenCV读取图像
+ #args是一个元组且args[0]是Namespace对象,则应该是args[0].image_path
+ imageToProcess = cv2.imread(args[0].image_path)
+
+ # 将读取的图像设置为Datum对象的输入数据
+ datum.cvInputData = imageToProcess
+
+ # 调用emplaceAndPop方法处理图像
+ # 这个方法将Datum对象(包含输入图像)放入OpenPose的处理队列中,并等待处理结果
+ # 处理完成后,结果会被放入Datum对象的输出字段中
+ # 注意:这里传递了一个包含datum的VectorDatum对象,因为emplaceAndPop方法期望接收一个VectorDatum作为参数
+ opWrapper.emplaceAndPop(op.VectorDatum([datum]))
+
+ # 显示处理结果
+ # 打印出图像中的人体关键点信息
+ # poseKeypoints是一个包含关键点信息的列表或数组
+ print("Body keypoints: \n" + str(datum.poseKeypoints))
+
+ # 使用OpenCV显示处理后的图像
+ # cvOutputData是Datum对象中包含的处理后图像数据
+ cv2.imshow("OpenPose 1.7.0 - Tutorial Python API", datum.cvOutputData)
+
+ # 等待用户按键后关闭窗口
+ cv2.waitKey(0)
+except Exception as e:
+ print(e)
+ sys.exit(-1)
diff --git a/src/tutorial_api_python/body_image2.py b/src/tutorial_api_python/body_image2.py
new file mode 100644
index 0000000..6c726a3
--- /dev/null
+++ b/src/tutorial_api_python/body_image2.py
@@ -0,0 +1,158 @@
+# From Python
+# It requires OpenCV installed for Python
+import sys
+import cv2
+import os
+from sys import platform
+import argparse
+
+try:
+ # Import Openpose (Windows/Ubuntu/OSX)
+ # 获取当前脚本文件的目录路径
+ dir_path = os.path.dirname(os.path.realpath(__file__))
+ try:
+ # 检查操作系统类型
+ # Windows Import
+ # 对于Windows系统
+ if platform == "win32":
+
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 使用 os.path.join 来避免路径分隔符的问题
+ openpose_path = os.path.join(dir_path, '../../python/openpose/Release')
+ sys.path.append(openpose_path)
+ #sys.path.append(dir_path + '/../../python/openpose/Release');
+ #os.environ['PATH'] = os.environ['PATH'] + ';' + dir_path + '/../../x64/Release;' + dir_path + '/../../bin;'
+ # 设置环境变量PATH,以便可以在命令行中调用OpenPose的可执行文件
+ # 在Python脚本中通常不需要这样做,这样可以在脚本中调用OpenPose的可执行文件
+ # 使用 os.pathsep 来确保路径分隔符的正确性
+ os.environ['PATH'] = os.environ['PATH'] + os.pathsep + os.path.join(dir_path,'../../x64/Release') \
+ + os.pathsep + os.path.join(dir_path, '../../bin')
+ # 导入OpenPose的Python接口
+ import pyopenpose as op
+ else:
+ # 对于Linux或MacOS系统
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 这里假设OpenPose的Python库位于相对于脚本的固定路径下
+ sys.path.append('../../python')
+ # If you run `make install` (default path is `/usr/local/python` for Ubuntu), you can also access the OpenPose/python module from there. This will install OpenPose and the python library at your desired installation path. Ensure that this is in your python path in order to use it.
+ # sys.path.append('/usr/local/python')
+ # 如果运行了 `make install`(对于Ubuntu,默认路径是 `/usr/local/python`),则也可以从那里访问OpenPose/python模块
+ # 注意:通常不需要这样做,除非OpenPose的Python库确实被安装到了非标准路径
+ # 并且,下面的代码行已经被注释掉了,因为它可能会覆盖掉其他重要的Python库路径
+ # sys.path.append('/usr/local/python')
+ # 从openpose模块导入pyopenpose
+ from openpose import pyopenpose as op
+ except ImportError as e:
+ # 如果在尝试导入pyopenpose时发生错误,则打印错误消息并重新抛出异常
+ print('Error: OpenPose library could not be found. Did you enable `BUILD_PYTHON` in CMake and have this Python script in the right folder?')
+
+ # 打印原始异常信息
+ print(e)
+ # 重新抛出异常,以便调用者可以处理它
+ raise e
+
+ # 创建一个ArgumentParser对象,用于添加和解析命令行参数
+ parser = argparse.ArgumentParser()
+
+ # 向ArgumentParser对象添加一个命令行参数 --image_path
+ # default: 设置参数的默认值,这里是一个图片的路径
+ # help: 当用户在命令行中使用 --help 时,显示的帮助信息
+ parser.add_argument("--image_path",
+ default="../../../examples/media/COCO_val2014_000000000241.jpg",
+ help="Process an image. Read all standard formats (jpg, png, bmp, etc.).")
+
+ # 解析命令行参数,parse_known_args()方法返回一个包含两个元素的元组
+ # 第一个元素是一个Namespace对象,包含了解析后的参数
+ # 第二个元素是一个列表,包含所有未识别的参数(在这个例子中,由于我们只定义了一个参数,这个列表应该是空的)
+ # 注意:通常我们会使用parse_args()而不是parse_known_args(),除非需要特别处理未识别的参数
+ args = parser.parse_known_args()
+
+ # 创建一个字典,用于存储自定义参数
+ # 这些参数可能会用于配置OpenPose或其他图像处理库
+ params = dict()
+
+ # 向params字典中添加一个键值对,指定模型文件夹的路径
+ # 这个路径应该包含OpenPose的模型文件
+ params["model_folder"] = "../../../models/"
+
+ # 向params字典中添加一个键值对,指示是否处理人脸关键点
+ # True表示启用人脸关键点检测
+ params["face"] = True
+
+ # 向params字典中添加一个键值对,指示是否处理手部关键点
+ # True表示启用手部关键点检测
+ params["hand"] = True
+
+ # 遍历args[1](未知参数的列表),以处理可能通过命令行传递的额外自定义参数
+ # 注意:args[0]是Namespace对象,包含已知参数;args[1]是未知参数的列表
+ for i in range(0, len(args[1])):
+ curr_item = args[1][i] # 当前项
+
+ # 检查是否还有下一个项,并设置next_item的值
+ # 如果当前项是列表中的最后一个项,则假设下一个项为"1"(这里可能是一个简化的处理方式)
+ if i != len(args[1]) - 1:
+ next_item = args[1][i + 1]
+ else:
+ next_item = "1"
+
+ # 检查当前项和下一个项是否都以"--"开头,这通常意味着它们都是命令行参数(但这里逻辑可能不完全准确)
+ # 如果两个都是参数,则忽略它们,因为这里的逻辑可能不适用于处理真正的命令行参数
+ # 注意:这里的逻辑可能是一个错误或简化的处理方式,因为通常不会这样检查参数
+ if "--" in curr_item and "--" in next_item:
+ key = curr_item.replace('-', '') # 移除参数名中的'-'并作为字典的键
+ if key not in params: # 如果该键不在params字典中,则添加它,并赋值为"1"(这可能不是预期的行为)
+ params[key] = "1"
+
+ # 如果当前项以"--"开头但下一个项不是,则假设当前项是一个参数,而下一个项是该参数的值
+ elif "--" in curr_item and "--" not in next_item:
+ key = curr_item.replace('-', '') # 同样移除'-'
+ if key not in params: # 如果该键不在params字典中,则添加它,并将next_item作为值
+ params[key] = next_item
+
+ # Construct it from system arguments
+ # op.init_argv(args[1])
+ # oppython = op.OpenposePython()
+
+ # 初始化OpenPose的WrapperPython对象
+ opWrapper = op.WrapperPython()
+
+ # 使用自定义参数配置OpenPose
+ # params是一个字典,包含了OpenPose运行所需的配置参数
+ # 这些参数可能包括模型路径、是否检测面部、手部等
+ opWrapper.configure(params)
+
+ # 启动OpenPose
+ # 在配置完成后,需要调用start方法来初始化OpenPose的内部结构
+ opWrapper.start()
+
+ # 处理图像
+ # 创建一个Datum对象,Datum是OpenPose用于存储输入和输出数据的类
+ datum = op.Datum()
+
+ imageToProcess = cv2.imread(args[0].image_path)
+
+ # 将读取的图像设置为Datum对象的输入数据
+ datum.cvInputData = imageToProcess
+
+ # 调用emplaceAndPop方法处理图像
+ # 这个方法将Datum对象(包含输入图像)放入OpenPose的处理队列中,并等待处理结果
+ # 处理完成后,结果会被放入Datum对象的输出字段中
+ # 注意:这里传递了一个包含datum的VectorDatum对象,因为emplaceAndPop方法期望接收一个VectorDatum作为参数
+ opWrapper.emplaceAndPop(op.VectorDatum([datum]))
+
+ # 显示处理结果
+ # 打印出图像中的人体、面部以及左右手的关键点信息
+ print("Body keypoints: \n" + str(datum.poseKeypoints))
+ print("Face keypoints: \n" + str(datum.faceKeypoints))
+ print("Left hand keypoints: \n" + str(datum.handKeypoints[0]))
+ print("Right hand keypoints: \n" + str(datum.handKeypoints[1]))
+
+ # 使用OpenCV显示处理后的图像
+ # 注意:datum.cvOutputData可能包含原始图像和处理结果的叠加,具体取决于OpenPose的配置
+ cv2.imshow("OpenPose 1.7.0 - Tutorial Python API", datum.cvOutputData)
+
+ # 等待用户按键后关闭窗口
+ cv2.waitKey(0)
+except Exception as e:
+ print(e)
+ sys.exit(-1)
diff --git a/src/tutorial_api_python/cmake_install.cmake b/src/tutorial_api_python/cmake_install.cmake
new file mode 100644
index 0000000..00d1da5
--- /dev/null
+++ b/src/tutorial_api_python/cmake_install.cmake
@@ -0,0 +1,34 @@
+# Install script for directory: E:/openpose/openpose_prosperity/examples/tutorial_api_python
+
+# Set the install prefix
+if(NOT DEFINED CMAKE_INSTALL_PREFIX)
+ set(CMAKE_INSTALL_PREFIX "C:/Program Files/OpenPose")
+endif()
+string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
+
+# Set the install configuration name.
+if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
+ if(BUILD_TYPE)
+ string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
+ CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
+ else()
+ set(CMAKE_INSTALL_CONFIG_NAME "Release")
+ endif()
+ message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
+endif()
+
+# Set the component getting installed.
+if(NOT CMAKE_INSTALL_COMPONENT)
+ if(COMPONENT)
+ message(STATUS "Install component: \"${COMPONENT}\"")
+ set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
+ else()
+ set(CMAKE_INSTALL_COMPONENT)
+ endif()
+endif()
+
+# Is this installation the result of a crosscompile?
+if(NOT DEFINED CMAKE_CROSSCOMPILING)
+ set(CMAKE_CROSSCOMPILING "FALSE")
+endif()
+
diff --git a/src/tutorial_api_python/face_image.py b/src/tutorial_api_python/face_image.py
new file mode 100644
index 0000000..6372d44
--- /dev/null
+++ b/src/tutorial_api_python/face_image.py
@@ -0,0 +1,135 @@
+# From Python
+# It requires OpenCV installed for Python
+import sys
+import cv2
+import os
+from sys import platform
+import argparse
+import time
+
+try:
+ # 获取当前脚本文件的目录路径
+ dir_path = os.path.dirname(os.path.realpath(__file__))
+ try:
+ # 检查操作系统类型
+ # Windows Import
+ # 对于Windows系统
+ if platform == "win32":
+
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 使用 os.path.join 来避免路径分隔符的问题
+ openpose_path = os.path.join(dir_path, '../../python/openpose/Release')
+ sys.path.append(openpose_path)
+ #sys.path.append(dir_path + '/../../python/openpose/Release');
+ #os.environ['PATH'] = os.environ['PATH'] + ';' + dir_path + '/../../x64/Release;' + dir_path + '/../../bin;'
+ # 设置环境变量PATH,以便可以在命令行中调用OpenPose的可执行文件
+ # 在Python脚本中通常不需要这样做,这样可以在脚本中调用OpenPose的可执行文件
+ # 使用 os.pathsep 来确保路径分隔符的正确性
+ os.environ['PATH'] = os.environ['PATH'] + os.pathsep + os.path.join(dir_path,'../../x64/Release') \
+ + os.pathsep + os.path.join(dir_path, '../../bin')
+ # 导入OpenPose的Python接口
+ import pyopenpose as op
+ else:
+ # 对于Linux或MacOS系统
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 这里假设OpenPose的Python库位于相对于脚本的固定路径下
+ sys.path.append('../../python')
+ # If you run `make install` (default path is `/usr/local/python` for Ubuntu), you can also access the OpenPose/python module from there. This will install OpenPose and the python library at your desired installation path. Ensure that this is in your python path in order to use it.
+ # sys.path.append('/usr/local/python')
+ # 如果运行了 `make install`(对于Ubuntu,默认路径是 `/usr/local/python`),则也可以从那里访问OpenPose/python模块
+ # 注意:通常不需要这样做,除非OpenPose的Python库确实被安装到了非标准路径
+ # 并且,下面的代码行已经被注释掉了,因为它可能会覆盖掉其他重要的Python库路径
+ # sys.path.append('/usr/local/python')
+ # 从openpose模块导入pyopenpose
+ from openpose import pyopenpose as op
+ except ImportError as e:
+ # 如果在尝试导入pyopenpose时发生错误,则打印错误消息并重新抛出异常
+ print('Error: OpenPose library could not be found. Did you enable `BUILD_PYTHON` in CMake and have this Python script in the right folder?')
+
+ # 打印原始异常信息
+ print(e)
+ # 重新抛出异常,以便调用者可以处理它
+ raise e
+
+
+ # Flags
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--image_path", default="../../../examples/media/COCO_val2014_000000000241.jpg", help="Process an image. Read all standard formats (jpg, png, bmp, etc.).")
+ args = parser.parse_known_args()
+
+ # 自定义参数(更多参数在 include/openpose/flags.hpp 文件)
+ params = dict()
+
+ # 设置存放 OpenPose 模型的文件夹路径
+ params["model_folder"] = "../../../models/"
+
+ # 启用面部关键点检测
+ params["face"] = True
+
+ # 选择使用的面部检测器模型(这里的数字 2 表示选择了特定的模型)
+ params["face_detector"] = 2
+
+ # 禁用身体关键点检测(0 表示不检测身体关键点)
+ params["body"] = 0
+
+ # Add others in path?
+ for i in range(0, len(args[1])):
+ curr_item = args[1][i]
+ if i != len(args[1])-1: next_item = args[1][i+1]
+ else: next_item = "1"
+ if "--" in curr_item and "--" in next_item:
+ key = curr_item.replace('-','')
+ if key not in params: params[key] = "1"
+ elif "--" in curr_item and "--" not in next_item:
+ key = curr_item.replace('-','')
+ if key not in params: params[key] = next_item
+
+ # Construct it from system arguments
+ # op.init_argv(args[1])
+ # oppython = op.OpenposePython()
+
+ # Starting OpenPose
+ # 初始化 OpenPose 的 Python 包装器
+ opWrapper = op.WrapperPython()
+
+ # 配置 OpenPose 使用的参数
+ opWrapper.configure(params)
+
+ # 启动 OpenPose
+ opWrapper.start()
+
+ # 读取要处理的图像
+ imageToProcess = cv2.imread(args[0].image_path)
+
+ # 定义面部矩形的位置信息
+ faceRectangles = [
+ op.Rectangle(330.119385, 277.532715, 48.717274, 48.717274),
+ op.Rectangle(24.036991, 267.918793, 65.175171, 65.175171),
+ op.Rectangle(151.803436, 32.477852, 108.295761, 108.295761),
+ ]
+
+ # 创建一个新的 Datum 对象,用于存储处理后的结果
+ datum = op.Datum()
+
+ # 设置输入图像数据
+ datum.cvInputData = imageToProcess
+
+ # 设置面部矩形位置信息
+ datum.faceRectangles = faceRectangles
+
+ # 处理图像并显示结果
+
+ # 将输入数据放入处理队列并从中获取处理后的数据
+ opWrapper.emplaceAndPop(op.VectorDatum([datum]))
+
+ # 输出面部关键点的信息
+ print("Face keypoints: \n" + str(datum.faceKeypoints))
+
+ # 在窗口中显示处理后的图像
+ cv2.imshow("OpenPose 1.7.0 - Tutorial Python API", datum.cvOutputData)
+
+ # 等待用户按下任意键后关闭窗口
+ cv2.waitKey(0)
+except Exception as e:
+ print(e)
+ sys.exit(-1)
diff --git a/src/tutorial_api_python/hand_image.py b/src/tutorial_api_python/hand_image.py
new file mode 100644
index 0000000..e91a6e5
--- /dev/null
+++ b/src/tutorial_api_python/hand_image.py
@@ -0,0 +1,148 @@
+# From Python
+# It requires OpenCV installed for Python
+import sys
+import cv2
+import os
+from sys import platform
+import argparse
+import time
+
+try:
+ # Import Openpose (Windows/Ubuntu/OSX)
+ # 获取当前脚本文件的目录路径
+ dir_path = os.path.dirname(os.path.realpath(__file__))
+ try:
+ # 检查操作系统类型
+ # Windows Import
+ # 对于Windows系统
+ if platform == "win32":
+
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 使用 os.path.join 来避免路径分隔符的问题
+ openpose_path = os.path.join(dir_path, '../../python/openpose/Release')
+ sys.path.append(openpose_path)
+ #sys.path.append(dir_path + '/../../python/openpose/Release');
+ #os.environ['PATH'] = os.environ['PATH'] + ';' + dir_path + '/../../x64/Release;' + dir_path + '/../../bin;'
+ # 设置环境变量PATH,以便可以在命令行中调用OpenPose的可执行文件
+ # 在Python脚本中通常不需要这样做,这样可以在脚本中调用OpenPose的可执行文件
+ # 使用 os.pathsep 来确保路径分隔符的正确性
+ os.environ['PATH'] = os.environ['PATH'] + os.pathsep + os.path.join(dir_path,'../../x64/Release') \
+ + os.pathsep + os.path.join(dir_path, '../../bin')
+ # 导入OpenPose的Python接口
+ import pyopenpose as op
+ else:
+ # 对于Linux或MacOS系统
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 这里假设OpenPose的Python库位于相对于脚本的固定路径下
+ sys.path.append('../../python')
+ # If you run `make install` (default path is `/usr/local/python` for Ubuntu), you can also access the OpenPose/python module from there. This will install OpenPose and the python library at your desired installation path. Ensure that this is in your python path in order to use it.
+ # sys.path.append('/usr/local/python')
+ # 如果运行了 `make install`(对于Ubuntu,默认路径是 `/usr/local/python`),则也可以从那里访问OpenPose/python模块
+ # 注意:通常不需要这样做,除非OpenPose的Python库确实被安装到了非标准路径
+ # 并且,下面的代码行已经被注释掉了,因为它可能会覆盖掉其他重要的Python库路径
+ # sys.path.append('/usr/local/python')
+ # 从openpose模块导入pyopenpose
+ from openpose import pyopenpose as op
+ except ImportError as e:
+ # 如果在尝试导入pyopenpose时发生错误,则打印错误消息并重新抛出异常
+ print('Error: OpenPose library could not be found. Did you enable `BUILD_PYTHON` in CMake and have this Python script in the right folder?')
+
+ # 打印原始异常信息
+ print(e)
+ # 重新抛出异常,以便调用者可以处理它
+ raise e
+
+ # Flags
+ # 创建一个ArgumentParser对象,用于处理命令行参数
+ parser = argparse.ArgumentParser()
+ # 添加一个命令行参数 --image_path,它有一个默认值,用于指定要处理的图像文件路径
+ # 这个参数接受所有标准的图像格式(如jpg, png, bmp等)
+ parser.add_argument("--image_path",
+ default="../../../examples/media/COCO_val2014_000000000192.jpg",
+ help="Process an image. Read all standard formats (jpg, png, bmp, etc.).")
+ # 解析命令行参数,并获取已知的参数和未知参数(如果有的话)
+ # parse_known_args()方法返回两个值:一个是已知参数的Namespace对象,另一个是未知参数的列表
+ args = parser.parse_known_args()
+
+ # 创建一个字典params,用于存储自定义参数
+ # 这些参数通常用于配置OpenPose的行为,但不在默认的命令行参数中
+ params = dict()
+
+ # 设置一个自定义参数model_folder,指定OpenPose模型文件的存储路径
+ params["model_folder"] = "../../../models/"
+
+ # 启用手部关键点检测
+ params["hand"] = True
+
+ # 设置手部检测器的类型为2,可能是特定于手部检测的算法或模型
+ params["hand_detector"] = 2
+
+ # 禁用身体关键点检测
+ params["body"] = 0
+
+ # Add others in path?
+ for i in range(0, len(args[1])):
+ curr_item = args[1][i]
+ if i != len(args[1])-1: next_item = args[1][i+1]
+ else: next_item = "1"
+ if "--" in curr_item and "--" in next_item:
+ key = curr_item.replace('-','')
+ if key not in params: params[key] = "1"
+ elif "--" in curr_item and "--" not in next_item:
+ key = curr_item.replace('-','')
+ if key not in params: params[key] = next_item
+
+ # Construct it from system arguments
+ # op.init_argv(args[1])
+ # oppython = op.OpenposePython()
+
+ # Starting OpenPose
+ # 创建 OpenPose 的 Python 包装器实例
+ opWrapper = op.WrapperPython()
+
+ # 配置 OpenPose 实例的参数
+ opWrapper.configure(params)
+
+ # 启动 OpenPose 实例
+ opWrapper.start()
+
+ # 读取要处理的图像和手部矩形位置
+ imageToProcess = cv2.imread(args[0].image_path)
+ handRectangles = [
+ # 第0个人的左/右手
+ [
+ op.Rectangle(320.035889, 377.675049, 69.300949, 69.300949), # 左手矩形
+ op.Rectangle(0., 0., 0., 0.), # 右手矩形(未定义,可以为空)
+ ],
+ # 第1个人的左/右手
+ [
+ op.Rectangle(80.155792, 407.673492, 80.812706, 80.812706), # 左手矩形
+ op.Rectangle(46.449715, 404.559753, 98.898178, 98.898178), # 右手矩形
+ ],
+ # 第2个人的左/右手
+ [
+ op.Rectangle(185.692673, 303.112244, 157.587555, 157.587555), # 左手矩形
+ op.Rectangle(88.984360, 268.866547, 117.818230, 117.818230), # 右手矩形
+ ]
+ ]
+
+ # 创建一个新的 datum 对象
+ datum = op.Datum()
+
+ # 设置 datum 对象的输入图像数据和手部矩形位置
+ datum.cvInputData = imageToProcess
+ datum.handRectangles = handRectangles
+
+ # 处理图像并获取结果
+ opWrapper.emplaceAndPop(op.VectorDatum([datum]))
+
+ # 打印左手和右手的关键点信息
+ print("Left hand keypoints: \n" + str(datum.handKeypoints[0]))
+ print("Right hand keypoints: \n" + str(datum.handKeypoints[1]))
+
+ # 显示处理后的图像
+ cv2.imshow("OpenPose 1.7.0 - Tutorial Python API", datum.cvOutputData)
+ cv2.waitKey(0) # 等待按键响应,然后关闭窗口
+except Exception as e:
+ print(e)
+ sys.exit(-1)
diff --git a/src/tutorial_api_python/heatmaps_image.py b/src/tutorial_api_python/heatmaps_image.py
new file mode 100644
index 0000000..0bcdc37
--- /dev/null
+++ b/src/tutorial_api_python/heatmaps_image.py
@@ -0,0 +1,123 @@
+# From Python
+# It requires OpenCV installed for Python
+import sys
+import cv2
+import os
+from sys import platform
+import argparse
+
+try:
+ # Import Openpose (Windows/Ubuntu/OSX)
+ # 获取当前脚本文件的目录路径
+ dir_path = os.path.dirname(os.path.realpath(__file__))
+ try:
+ # 检查操作系统类型
+ # Windows Import
+ # 对于Windows系统
+ if platform == "win32":
+
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 使用 os.path.join 来避免路径分隔符的问题
+ openpose_path = os.path.join(dir_path, '../../python/openpose/Release')
+ sys.path.append(openpose_path)
+ #sys.path.append(dir_path + '/../../python/openpose/Release');
+ #os.environ['PATH'] = os.environ['PATH'] + ';' + dir_path + '/../../x64/Release;' + dir_path + '/../../bin;'
+ # 设置环境变量PATH,以便可以在命令行中调用OpenPose的可执行文件
+ # 在Python脚本中通常不需要这样做,这样可以在脚本中调用OpenPose的可执行文件
+ # 使用 os.pathsep 来确保路径分隔符的正确性
+ os.environ['PATH'] = os.environ['PATH'] + os.pathsep + os.path.join(dir_path,'../../x64/Release') \
+ + os.pathsep + os.path.join(dir_path, '../../bin')
+ # 导入OpenPose的Python接口
+ import pyopenpose as op
+ else:
+ # 对于Linux或MacOS系统
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 这里假设OpenPose的Python库位于相对于脚本的固定路径下
+ sys.path.append('../../python')
+ # If you run `make install` (default path is `/usr/local/python` for Ubuntu), you can also access the OpenPose/python module from there. This will install OpenPose and the python library at your desired installation path. Ensure that this is in your python path in order to use it.
+ # sys.path.append('/usr/local/python')
+ # 如果运行了 `make install`(对于Ubuntu,默认路径是 `/usr/local/python`),则也可以从那里访问OpenPose/python模块
+ # 注意:通常不需要这样做,除非OpenPose的Python库确实被安装到了非标准路径
+ # 并且,下面的代码行已经被注释掉了,因为它可能会覆盖掉其他重要的Python库路径
+ # sys.path.append('/usr/local/python')
+ # 从openpose模块导入pyopenpose
+ from openpose import pyopenpose as op
+ except ImportError as e:
+ # 如果在尝试导入pyopenpose时发生错误,则打印错误消息并重新抛出异常
+ print('Error: OpenPose library could not be found. Did you enable `BUILD_PYTHON` in CMake and have this Python script in the right folder?')
+
+ # 打印原始异常信息
+ print(e)
+ # 重新抛出异常,以便调用者可以处理它
+ raise e
+
+
+ # Flags
+ # 创建参数解析器
+ parser = argparse.ArgumentParser()
+
+ # 添加命令行参数选项
+ parser.add_argument("--image_path",
+ default="../../../examples/media/COCO_val2014_000000000192.jpg",
+ help="处理一张图片。支持所有标准格式(jpg、png、bmp等)。")
+ args = parser.parse_known_args()
+
+ # 自定义参数设置(更多参数详见 include/openpose/flags.hpp)
+ params = dict()
+ params["model_folder"] = "../../../models/" # 模型文件夹路径
+ params["heatmaps_add_parts"] = True # 是否生成人体部位热图
+ params["heatmaps_add_bkg"] = True # 是否生成背景热图
+ params["heatmaps_add_PAFs"] = True # 是否生成关键点连接热图(PAFs)
+ params["heatmaps_scale"] = 2 # 热图的缩放比例
+
+ # Add others in path?
+ for i in range(0, len(args[1])):
+ curr_item = args[1][i]
+ if i != len(args[1])-1: next_item = args[1][i+1]
+ else: next_item = "1"
+ if "--" in curr_item and "--" in next_item:
+ key = curr_item.replace('-','')
+ if key not in params: params[key] = "1"
+ elif "--" in curr_item and "--" not in next_item:
+ key = curr_item.replace('-','')
+ if key not in params: params[key] = next_item
+
+ # Construct it from system arguments
+ # op.init_argv(args[1])
+ # oppython = op.OpenposePython()
+
+ # Starting OpenPose
+ # 创建 OpenPose 的 Python 包装器实例
+ opWrapper = op.WrapperPython()
+ opWrapper.configure(params) # 配置 OpenPose 实例的参数
+ opWrapper.start() # 启动 OpenPose 实例
+
+ # 处理图像
+ datum = op.Datum() # 创建一个 datum 对象来存储处理结果
+ imageToProcess = cv2.imread(args[0].image_path) # 读取要处理的图像
+ datum.cvInputData = imageToProcess # 设置输入图像数据
+ opWrapper.emplaceAndPop(op.VectorDatum([datum])) # 对图像进行处理并获取结果
+
+ # 处理输出
+ outputImageF = (datum.inputNetData[0].copy())[0, :, :, :] + 0.5 # 处理输出图像数据
+ outputImageF = cv2.merge([outputImageF[0, :, :], outputImageF[1, :, :], outputImageF[2, :, :]]) # 合并通道
+ outputImageF = (outputImageF * 255.).astype(dtype='uint8') # 转换为 uint8 类型
+ heatmaps = datum.poseHeatMaps.copy() # 复制姿势热图数据
+ heatmaps = (heatmaps).astype(dtype='uint8') # 转换为 uint8 类型
+
+ # 显示图像
+ counter = 0
+ while 1:
+ num_maps = heatmaps.shape[0] # 获取热图数量
+ heatmap = heatmaps[counter, :, :].copy() # 获取当前计数器对应的热图
+ heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET) # 将热图应用颜色映射
+ combined = cv2.addWeighted(outputImageF, 0.5, heatmap, 0.5, 0) # 合并原始图像和热图
+ cv2.imshow("OpenPose 1.7.0 - Tutorial Python API", combined) # 显示合成图像
+ key = cv2.waitKey(-1) # 等待按键事件
+ if key == 27: # 如果按下 ESC 键,则退出循环
+ break
+ counter += 1
+ counter = counter % num_maps # 循环更新计数器,确保在热图数量内循环显示
+except Exception as e:
+ print(e)
+ sys.exit(-1)
diff --git a/src/tutorial_api_python/keypoints_heatmaps.py b/src/tutorial_api_python/keypoints_heatmaps.py
new file mode 100644
index 0000000..a148121
--- /dev/null
+++ b/src/tutorial_api_python/keypoints_heatmaps.py
@@ -0,0 +1,118 @@
+# From Python
+# It requires OpenCV installed for Python
+import sys
+import cv2
+import os
+from sys import platform
+import argparse
+import numpy as np
+
+try:
+ # Import Openpose (Windows/Ubuntu/OSX)
+ # 获取当前脚本文件的目录路径
+ dir_path = os.path.dirname(os.path.realpath(__file__))
+ try:
+ # 检查操作系统类型
+ # Windows Import
+ # 对于Windows系统
+ if platform == "win32":
+
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 使用 os.path.join 来避免路径分隔符的问题
+ openpose_path = os.path.join(dir_path, '../../python/openpose/Release')
+ sys.path.append(openpose_path)
+ #sys.path.append(dir_path + '/../../python/openpose/Release');
+ #os.environ['PATH'] = os.environ['PATH'] + ';' + dir_path + '/../../x64/Release;' + dir_path + '/../../bin;'
+ # 设置环境变量PATH,以便可以在命令行中调用OpenPose的可执行文件
+ # 在Python脚本中通常不需要这样做,这样可以在脚本中调用OpenPose的可执行文件
+ # 使用 os.pathsep 来确保路径分隔符的正确性
+ os.environ['PATH'] = os.environ['PATH'] + os.pathsep + os.path.join(dir_path,'../../x64/Release') \
+ + os.pathsep + os.path.join(dir_path, '../../bin')
+ # 导入OpenPose的Python接口
+ import pyopenpose as op
+ else:
+ # 对于Linux或MacOS系统
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 这里假设OpenPose的Python库位于相对于脚本的固定路径下
+ sys.path.append('../../python')
+ # If you run `make install` (default path is `/usr/local/python` for Ubuntu), you can also access the OpenPose/python module from there. This will install OpenPose and the python library at your desired installation path. Ensure that this is in your python path in order to use it.
+ # sys.path.append('/usr/local/python')
+ # 如果运行了 `make install`(对于Ubuntu,默认路径是 `/usr/local/python`),则也可以从那里访问OpenPose/python模块
+ # 注意:通常不需要这样做,除非OpenPose的Python库确实被安装到了非标准路径
+ # 并且,下面的代码行已经被注释掉了,因为它可能会覆盖掉其他重要的Python库路径
+ # sys.path.append('/usr/local/python')
+ # 从openpose模块导入pyopenpose
+ from openpose import pyopenpose as op
+ except ImportError as e:
+ # 如果在尝试导入pyopenpose时发生错误,则打印错误消息并重新抛出异常
+ print('Error: OpenPose library could not be found. Did you enable `BUILD_PYTHON` in CMake and have this Python script in the right folder?')
+
+ # 打印原始异常信息
+ print(e)
+ # 重新抛出异常,以便调用者可以处理它
+ raise e
+
+
+ # Flags
+ # 创建参数解析器
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--image_path", default="../../../examples/media/COCO_val2014_000000000294.jpg",
+ help="处理一张图片,支持所有标准格式(jpg、png、bmp 等)")
+ args = parser.parse_known_args()
+
+ # 加载图片
+ imageToProcess = cv2.imread(args[0].image_path)
+
+
+ def get_sample_heatmaps():
+ # 全局设置参数,如果有新的 OpenPose 对象,需要取消在这里设置的变量。参见 *
+ params = dict()
+ params["model_folder"] = "../../../models/"
+ params["heatmaps_add_parts"] = True # 添加部位热图
+ params["heatmaps_add_bkg"] = True # 添加背景热图
+ params["heatmaps_add_PAFs"] = True # 添加关键点之间的关联热图
+ params["heatmaps_scale"] = 3 # 热图缩放因子
+ params["upsampling_ratio"] = 1 # 上采样比例
+ params["body"] = 1 # 选择身体关键点
+
+ # 启动 OpenPose
+ opWrapper = op.WrapperPython()
+ opWrapper.configure(params)
+ opWrapper.start()
+
+ # 处理图片并获取热图
+ datum = op.Datum()
+ imageToProcess = cv2.imread(args[0].image_path)
+ datum.cvInputData = imageToProcess
+ opWrapper.emplaceAndPop(op.VectorDatum([datum]))
+ poseHeatMaps = datum.poseHeatMaps.copy()
+ opWrapper.stop()
+
+ return poseHeatMaps
+
+
+ # 获取热图
+ poseHeatMaps = get_sample_heatmaps()
+
+ # 启动 OpenPose
+ params = dict()
+ params["model_folder"] = "../../../models/"
+ params["body"] = 2 # 禁用 OP Network
+ params["upsampling_ratio"] = 0 # * 取消设置此变量
+ opWrapper = op.WrapperPython()
+ opWrapper.configure(params)
+ opWrapper.start()
+
+ # 传递热图并运行 OpenPose
+ datum = op.Datum()
+ datum.cvInputData = imageToProcess
+ datum.poseNetOutput = poseHeatMaps
+ opWrapper.emplaceAndPop(op.VectorDatum([datum]))
+
+ # 显示图片
+ print("Body keypoints: \n" + str(datum.poseKeypoints))
+ cv2.imshow("OpenPose 1.7.0 - Tutorial Python API", datum.cvOutputData)
+ cv2.waitKey(0)
+except Exception as e:
+ print(e)
+ sys.exit(-1)
diff --git a/src/tutorial_api_python/keypoints_images.py b/src/tutorial_api_python/keypoints_images.py
new file mode 100644
index 0000000..f6f2b8b
--- /dev/null
+++ b/src/tutorial_api_python/keypoints_images.py
@@ -0,0 +1,109 @@
+# From Python
+# It requires OpenCV installed for Python
+import sys
+import cv2
+import os
+from sys import platform
+import argparse
+import time
+
+try:
+ # Import Openpose (Windows/Ubuntu/OSX)
+ # 获取当前脚本文件的目录路径
+ dir_path = os.path.dirname(os.path.realpath(__file__))
+ try:
+ # 检查操作系统类型
+ # Windows Import
+ # 对于Windows系统
+ if platform == "win32":
+
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 使用 os.path.join 来避免路径分隔符的问题
+ openpose_path = os.path.join(dir_path, '../../python/openpose/Release')
+ sys.path.append(openpose_path)
+ #sys.path.append(dir_path + '/../../python/openpose/Release');
+ #os.environ['PATH'] = os.environ['PATH'] + ';' + dir_path + '/../../x64/Release;' + dir_path + '/../../bin;'
+ # 设置环境变量PATH,以便可以在命令行中调用OpenPose的可执行文件
+ # 在Python脚本中通常不需要这样做,这样可以在脚本中调用OpenPose的可执行文件
+ # 使用 os.pathsep 来确保路径分隔符的正确性
+ os.environ['PATH'] = os.environ['PATH'] + os.pathsep + os.path.join(dir_path,'../../x64/Release') \
+ + os.pathsep + os.path.join(dir_path, '../../bin')
+ # 导入OpenPose的Python接口
+ import pyopenpose as op
+ else:
+ # 对于Linux或MacOS系统
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 这里假设OpenPose的Python库位于相对于脚本的固定路径下
+ sys.path.append('../../python')
+ # If you run `make install` (default path is `/usr/local/python` for Ubuntu), you can also access the OpenPose/python module from there. This will install OpenPose and the python library at your desired installation path. Ensure that this is in your python path in order to use it.
+ # sys.path.append('/usr/local/python')
+ # 如果运行了 `make install`(对于Ubuntu,默认路径是 `/usr/local/python`),则也可以从那里访问OpenPose/python模块
+ # 注意:通常不需要这样做,除非OpenPose的Python库确实被安装到了非标准路径
+ # 并且,下面的代码行已经被注释掉了,因为它可能会覆盖掉其他重要的Python库路径
+ # sys.path.append('/usr/local/python')
+ # 从openpose模块导入pyopenpose
+ from openpose import pyopenpose as op
+ except ImportError as e:
+ # 如果在尝试导入pyopenpose时发生错误,则打印错误消息并重新抛出异常
+ print('Error: OpenPose library could not be found. Did you enable `BUILD_PYTHON` in CMake and have this Python script in the right folder?')
+
+ # 打印原始异常信息
+ print(e)
+ # 重新抛出异常,以便调用者可以处理它
+ raise e
+
+
+ # Flags
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--image_dir", default="../../../examples/media/", help="Process a directory of images. Read all standard formats (jpg, png, bmp, etc.).")
+ parser.add_argument("--no_display", default=False, help="Enable to disable the visual display.")
+ args = parser.parse_known_args()
+
+ # Custom Params (refer to include/openpose/flags.hpp for more parameters)
+ params = dict()
+ params["model_folder"] = "../../../models/"
+
+ # Add others in path?
+ for i in range(0, len(args[1])):
+ curr_item = args[1][i]
+ if i != len(args[1])-1: next_item = args[1][i+1]
+ else: next_item = "1"
+ if "--" in curr_item and "--" in next_item:
+ key = curr_item.replace('-','')
+ if key not in params: params[key] = "1"
+ elif "--" in curr_item and "--" not in next_item:
+ key = curr_item.replace('-','')
+ if key not in params: params[key] = next_item
+
+ # Construct it from system arguments
+ # op.init_argv(args[1])
+ # oppython = op.OpenposePython()
+
+ # Starting OpenPose
+ opWrapper = op.WrapperPython()
+ opWrapper.configure(params)
+ opWrapper.start()
+
+ # 读取目录中的图片
+ imagePaths = op.get_images_on_directory(args[0].image_dir)
+ start = time.time()
+
+ # 处理并显示图片
+ for imagePath in imagePaths:
+ datum = op.Datum()
+ imageToProcess = cv2.imread(imagePath)
+ datum.cvInputData = imageToProcess
+ opWrapper.emplaceAndPop(op.VectorDatum([datum]))
+
+ print("Body keypoints: \n" + str(datum.poseKeypoints))
+
+ if not args[0].no_display:
+ cv2.imshow("OpenPose 1.7.0 - Tutorial Python API", datum.cvOutputData)
+ key = cv2.waitKey(15)
+ if key == 27: break
+
+ end = time.time()
+ print("OpenPose demo successfully finished. Total time: " + str(end - start) + " seconds")
+except Exception as e:
+ print(e)
+ sys.exit(-1)
diff --git a/src/tutorial_api_python/openpose_python.py b/src/tutorial_api_python/openpose_python.py
new file mode 100644
index 0000000..5e0931b
--- /dev/null
+++ b/src/tutorial_api_python/openpose_python.py
@@ -0,0 +1,107 @@
+# From Python
+# It requires OpenCV installed for Python
+import sys
+import cv2
+import os
+from sys import platform
+import argparse
+
+try:
+ # Import Openpose (Windows/Ubuntu/OSX)
+ # 获取当前脚本文件的目录路径
+ dir_path = os.path.dirname(os.path.realpath(__file__))
+ try:
+ # 检查操作系统类型
+ # Windows Import
+ # 对于Windows系统
+ if platform == "win32":
+
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 使用 os.path.join 来避免路径分隔符的问题
+ openpose_path = os.path.join(dir_path, '../../python/openpose/Release')
+ sys.path.append(openpose_path)
+ #sys.path.append(dir_path + '/../../python/openpose/Release');
+ #os.environ['PATH'] = os.environ['PATH'] + ';' + dir_path + '/../../x64/Release;' + dir_path + '/../../bin;'
+ # 设置环境变量PATH,以便可以在命令行中调用OpenPose的可执行文件
+ # 在Python脚本中通常不需要这样做,这样可以在脚本中调用OpenPose的可执行文件
+ # 使用 os.pathsep 来确保路径分隔符的正确性
+ os.environ['PATH'] = os.environ['PATH'] + os.pathsep + os.path.join(dir_path,'../../x64/Release') \
+ + os.pathsep + os.path.join(dir_path, '../../bin')
+ # 导入OpenPose的Python接口
+ import pyopenpose as op
+ else:
+ # 对于Linux或MacOS系统
+ # 修改这些变量以指向正确的文件夹(如Release/x64等)
+ # 这里假设OpenPose的Python库位于相对于脚本的固定路径下
+ sys.path.append('../../python')
+ # If you run `make install` (default path is `/usr/local/python` for Ubuntu), you can also access the OpenPose/python module from there. This will install OpenPose and the python library at your desired installation path. Ensure that this is in your python path in order to use it.
+ # sys.path.append('/usr/local/python')
+ # 如果运行了 `make install`(对于Ubuntu,默认路径是 `/usr/local/python`),则也可以从那里访问OpenPose/python模块
+ # 注意:通常不需要这样做,除非OpenPose的Python库确实被安装到了非标准路径
+ # 并且,下面的代码行已经被注释掉了,因为它可能会覆盖掉其他重要的Python库路径
+ # sys.path.append('/usr/local/python')
+ # 从openpose模块导入pyopenpose
+ from openpose import pyopenpose as op
+ except ImportError as e:
+ # 如果在尝试导入pyopenpose时发生错误,则打印错误消息并重新抛出异常
+ print('Error: OpenPose library could not be found. Did you enable `BUILD_PYTHON` in CMake and have this Python script in the right folder?')
+
+ # 打印原始异常信息
+ print(e)
+ # 重新抛出异常,以便调用者可以处理它
+ raise e
+
+
+ # Flags
+ # 创建参数解析器对象
+ parser = argparse.ArgumentParser()
+
+ # 添加命令行参数 --image_path,设置默认值为指定路径的图像文件
+ parser.add_argument("--image_path",
+ default="../../../examples/media/COCO_val2014_000000000192.jpg",
+ help="处理一张图片。支持所有标准格式(jpg、png、bmp 等)。")
+
+ # 解析命令行参数,并返回一个包含参数对象和额外参数的元组
+ args = parser.parse_known_args()
+
+ # 自定义参数(更多参数请参考 include/openpose/flags.hpp)
+ params = dict()
+
+ # 设置模型文件夹的路径
+ params["model_folder"] = "../../../models/"
+
+ # 遍历额外的命令行参数(通常是以 -- 开头的参数)
+ for i in range(0, len(args[1])):
+ curr_item = args[1][i] # 当前参数
+ if i != len(args[1]) - 1:
+ next_item = args[1][i + 1] # 下一个参数
+ else:
+ next_item = "1" # 如果没有下一个参数,默认为 "1"
+
+ # 如果当前参数和下一个参数都以 -- 开头
+ if "--" in curr_item and "--" in next_item:
+ key = curr_item.replace('-', '') # 去掉参数中的 "-" 符号,作为键名
+ if key not in params:
+ params[key] = "1" # 将参数加入到 params 字典中,值设为 "1"(默认值)
+ # 如果当前参数以 -- 开头,但下一个参数不是以 -- 开头(即下一个参数是当前参数的值)
+ elif "--" in curr_item and "--" not in next_item:
+ key = curr_item.replace('-', '') # 去掉参数中的 "-" 符号,作为键名
+ if key not in params:
+ params[key] = next_item # 将下一个参数作为当前参数的值加入到 params 字典中
+
+ # Construct it from system arguments
+ # op.init_argv(args[1])
+ # oppython = op.OpenposePython()
+
+ # Starting OpenPose
+ # 创建 OpenPose 的 Python 封装器,指定线程管理模式为同步模式
+ opWrapper = op.WrapperPython(op.ThreadManagerMode.Synchronous)
+
+ # 使用提供的参数配置 OpenPose 封装器
+ opWrapper.configure(params)
+
+ # 执行 OpenPose 运行,开始处理图像或视频
+ opWrapper.execute()
+except Exception as e:
+ print(e)
+ sys.exit(-1)
diff --git a/src/tutorial_api_python/未命名3.py b/src/tutorial_api_python/未命名3.py
new file mode 100644
index 0000000..a41958d
--- /dev/null
+++ b/src/tutorial_api_python/未命名3.py
@@ -0,0 +1,60 @@
+# From Python
+# It requires OpenCV installed for Python
+import sys
+import cv2
+import os
+from sys import platform
+import argparse
+
+try:
+ # Import Openpose (Windows/Ubuntu/OSX)
+ dir_path = os.path.dirname(os.path.realpath(__file__))
+ try:
+ # Windows Import
+ if platform == "win32":
+ # Change these variables to point to the correct folder (Release/x64 etc.)
+ sys.path.append(dir_path + '/../../build/python/openpose/Release');
+ os.environ['PATH'] = os.environ['PATH'] + ';' + dir_path + '/../../x64/Release;' + dir_path + '/../../build/bin;'
+ import pyopenpose as op
+ else:
+ # Change these variables to point to the correct folder (Release/x64 etc.)
+ sys.path.append('../../python');
+ # If you run `make install` (default path is `/usr/local/python` for Ubuntu), you can also access the OpenPose/python module from there. This will install OpenPose and the python library at your desired installation path. Ensure that this is in your python path in order to use it.
+ # sys.path.append('/usr/local/python')
+ from openpose import pyopenpose as op
+ except ImportError as e:
+ print('Error: OpenPose library could not be found. Did you enable `BUILD_PYTHON` in CMake and have this Python script in the right folder?')
+ raise e
+
+ # Flags
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--image_path", default="../../examples/media/COCO_val2014_000000000192.jpg", help="Process an image. Read all standard formats (jpg, png, bmp, etc.).")
+ args = parser.parse_known_args()
+
+ # Custom Params (refer to include/openpose/flags.hpp for more parameters)
+ params = dict()
+ params["model_folder"] = "../../models/"
+
+ # Add others in path?
+ for i in range(0, len(args[1])):
+ curr_item = args[1][i]
+ if i != len(args[1])-1: next_item = args[1][i+1]
+ else: next_item = "1"
+ if "--" in curr_item and "--" in next_item:
+ key = curr_item.replace('-','')
+ if key not in params: params[key] = "1"
+ elif "--" in curr_item and "--" not in next_item:
+ key = curr_item.replace('-','')
+ if key not in params: params[key] = next_item
+
+ # Construct it from system arguments
+ # op.init_argv(args[1])
+ # oppython = op.OpenposePython()
+
+ # Starting OpenPose
+ opWrapper = op.WrapperPython(op.ThreadManagerMode.Synchronous)
+ opWrapper.configure(params)
+ opWrapper.execute()
+except Exception as e:
+ print(e)
+ sys.exit(-1)
diff --git a/src/tutorial_api_python/未命名4.py b/src/tutorial_api_python/未命名4.py
new file mode 100644
index 0000000..e2c00ca
--- /dev/null
+++ b/src/tutorial_api_python/未命名4.py
@@ -0,0 +1,68 @@
+import cv2
+
+
+
+import pyopenpose as op
+# RTSP地址
+rtsp_url = "rtsp://192.168.1.115"
+
+# 打开RTSP流
+cap = cv2.VideoCapture(rtsp_url)
+
+# 检查摄像头是否成功打开
+if not cap.isOpened():
+ print("无法打开摄像头")
+ exit()
+
+# 创建视频写入对象,用于保存视频
+out = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*'mp4v'), 30, (640, 480))
+
+# OpenPose 参数
+params = {
+ "model_folder": "../../../models/", # 替换为您的 OpenPose 模型文件夹路径
+ "hand": False, # 是否检测手部关键点
+ "face": False, # 是否检测面部关键点
+ "display": 0, # 显示窗口的级别,0为不显示
+}
+
+# 初始化 OpenPose
+opWrapper = op.WrapperPython()
+opWrapper.configure(params)
+opWrapper.start()
+
+# 读取并显示视频流
+while True:
+ ret, frame = cap.read()
+ if not ret:
+ print("无法读取视频流")
+ break
+
+ # 执行姿态检测
+ datum = op.Datum()
+ datum.cvInputData = frame
+ opWrapper.emplaceAndPop([datum])
+
+ # 获取姿态检测结果
+ pose_keypoints = datum.poseKeypoints
+
+ # 在帧上绘制姿态关键点
+ if pose_keypoints is not None:
+ for person in pose_keypoints:
+ for point in person:
+ if point[2] > 0.1: # 确保置信度足够高
+ cv2.circle(frame, (int(point[0]), int(point[1])), 4, (0, 255, 255), thickness=-1, lineType=cv2.FILLED)
+
+ # 显示视频流
+ cv2.imshow('RTSP Stream', frame)
+
+ # 写入视频帧到输出文件
+ out.write(frame)
+
+ # 按下'q'键退出循环
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+
+# 释放资源
+cap.release()
+out.release()
+cv2.destroyAllWindows()
diff --git a/src/tutorial_api_python/未命名5.py b/src/tutorial_api_python/未命名5.py
new file mode 100644
index 0000000..d99bd29
--- /dev/null
+++ b/src/tutorial_api_python/未命名5.py
@@ -0,0 +1,41 @@
+
+
+import cv2
+
+# RTSP地址
+rtsp_url = "rtsp://192.168.1.135"
+
+# 打开RTSP流
+cap = cv2.VideoCapture(rtsp_url)
+
+# 检查摄像头是否成功打开
+if not cap.isOpened():
+ print("无法打开摄像头")
+ exit()
+
+# 创建视频写入对象,用于保存视频
+out = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*'mp4v'), 30, (640, 480))
+
+# 读取并显示视频流
+while True:
+ ret, frame = cap.read()
+ if not ret:
+ print("无法读取视频流")
+ break
+
+ # 在这里你可以对帧进行处理,例如进行对象检测、图像处理等
+
+ # 显示视频流
+ cv2.imshow('RTSP Stream', frame)
+
+ # 写入视频帧到输出文件
+ out.write(frame)
+
+ # 按下'q'键退出循环
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+
+# 释放资源
+cap.release()
+out.release()
+cv2.destroyAllWindows()
diff --git a/src/tutorial_api_python/未命名6.py b/src/tutorial_api_python/未命名6.py
new file mode 100644
index 0000000..7c29071
--- /dev/null
+++ b/src/tutorial_api_python/未命名6.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Thu May 16 22:19:59 2024
+
+@author: lenovo
+"""
+import cv2
+
+
+
+import pyopenpose as op
+# RTSP地址
+rtsp_url = "rtsp://192.168.1.135"
+
+# 打开RTSP流
+cap = cv2.VideoCapture(rtsp_url)
+
+# 检查摄像头是否成功打开
+if not cap.isOpened():
+ print("无法打开摄像头")
+ exit()
+
+# 创建视频写入对象,用于保存视频
+out = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*'mp4v'), 30, (640, 480))
+
+# OpenPose 参数
+params = {
+ "model_folder": "../../../models/", # 替换为您的 OpenPose 模型文件夹路径
+ "hand": False, # 是否检测手部关键点
+ "face": False, # 是否检测面部关键点
+ "display": 0, # 显示窗口的级别,0为不显示
+}
+
+# 初始化 OpenPose
+opWrapper = op.WrapperPython()
+opWrapper.configure(params)
+opWrapper.start()
+
+# 读取并显示视频流
+while True:
+ ret, frame = cap.read()
+ if not ret:
+ print("无法读取视频流")
+ break
+
+ # 执行姿态检测
+ datum = op.Datum()
+ datum.cvInputData = frame
+ opWrapper.emplaceAndPop([datum])
+
+ # 获取姿态检测结果
+ pose_keypoints = datum.poseKeypoints
+
+ # 在帧上绘制姿态关键点
+ if pose_keypoints is not None:
+ for person in pose_keypoints:
+ for point in person:
+ if point[2] > 0.1: # 确保置信度足够高
+ cv2.circle(frame, (int(point[0]), int(point[1])), 4, (0, 255, 255), thickness=-1, lineType=cv2.FILLED)
+
+ # 显示视频流
+ cv2.imshow('RTSP Stream', frame)
+
+ # 写入视频帧到输出文件
+ out.write(frame)
+
+ # 按下'q'键退出循环
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+
+# 释放资源
+cap.release()
+out.release()
+cv2.destroyAllWindows()
+
diff --git a/src/ui/connect.py b/src/ui/connect.py
new file mode 100644
index 0000000..6266672
--- /dev/null
+++ b/src/ui/connect.py
@@ -0,0 +1,120 @@
+import tkinter as tk
+from tkinter import ttk
+
+def save_settings():
+ # Placeholder for saving settings logic
+ print("Settings saved.")
+
+# Create main window
+root = tk.Tk()
+root.title("设备连接与配置")
+
+# Frame for serial settings
+serial_frame = ttk.LabelFrame(root, text="串口和波特率")
+serial_frame.grid(row=0, column=0, padx=10, pady=5, sticky=tk.W)
+
+serial_port_label = ttk.Label(serial_frame, text="串口:")
+serial_port_label.grid(row=0, column=0, padx=5, pady=2, sticky=tk.W)
+serial_port_combo = ttk.Combobox(serial_frame, width=8, values=["COM1", "COM2", "COM3"])
+serial_port_combo.grid(row=0, column=1, padx=5, pady=2)
+serial_port_combo.set("COM1") # Set default value
+
+baudrate_label = ttk.Label(serial_frame, text="波特率:")
+baudrate_label.grid(row=1, column=0, padx=5, pady=2, sticky=tk.W)
+baudrate_combo = ttk.Combobox(serial_frame, width=8, values=["9600", "19200", "115200"])
+baudrate_combo.grid(row=1, column=1, padx=5, pady=2)
+baudrate_combo.set("115200") # Set default value
+
+# Frame for TCP settings
+tcp_frame = ttk.LabelFrame(root, text="TCP配置")
+tcp_frame.grid(row=1, column=0, padx=10, pady=5, sticky=tk.W)
+
+tcp_ip_label = ttk.Label(tcp_frame, text="TCP 远端 IP:")
+tcp_ip_label.grid(row=0, column=0, padx=5, pady=2, sticky=tk.W)
+tcp_ip_combo = ttk.Combobox(tcp_frame, width=15, values=["192.168.1.100", "192.168.1.101", "192.168.1.102"])
+tcp_ip_combo.grid(row=0, column=1, padx=5, pady=2)
+tcp_ip_combo.set("192.168.1.100") # Set default value
+
+tcp_port_label = ttk.Label(tcp_frame, text="端口:")
+tcp_port_label.grid(row=1, column=0, padx=5, pady=2, sticky=tk.W)
+tcp_port_entry = ttk.Entry(tcp_frame, width=8)
+tcp_port_entry.grid(row=1, column=1, padx=5, pady=2)
+tcp_port_entry.insert(0, "2000")
+
+# Frame for UDP settings
+udp_frame = ttk.LabelFrame(root, text="UDP配置")
+udp_frame.grid(row=2, column=0, padx=10, pady=5, sticky=tk.W)
+
+udp_remote_ip_label = ttk.Label(udp_frame, text="UDP 远端 IP:")
+udp_remote_ip_label.grid(row=0, column=0, padx=5, pady=2, sticky=tk.W)
+udp_remote_ip_combo = ttk.Combobox(udp_frame, width=15, values=["192.168.2.100", "192.168.2.101", "192.168.2.102"])
+udp_remote_ip_combo.grid(row=0, column=1, padx=5, pady=2)
+udp_remote_ip_combo.set("192.168.2.100") # Set default value
+
+udp_remote_port_label = ttk.Label(udp_frame, text="远端端口:")
+udp_remote_port_label.grid(row=1, column=0, padx=5, pady=2, sticky=tk.W)
+udp_remote_port_entry = ttk.Entry(udp_frame, width=8)
+udp_remote_port_entry.grid(row=1, column=1, padx=5, pady=2)
+udp_remote_port_entry.insert(0, "14551")
+
+udp_local_ip_label = ttk.Label(udp_frame, text="UDP 本地 IP:")
+udp_local_ip_label.grid(row=2, column=0, padx=5, pady=2, sticky=tk.W)
+udp_local_ip_combo = ttk.Combobox(udp_frame, width=15, values=["192.168.2.101", "192.168.2.102", "192.168.2.103"])
+udp_local_ip_combo.grid(row=2, column=1, padx=5, pady=2)
+udp_local_ip_combo.set("192.168.2.101") # Set default value
+
+udp_local_port_label = ttk.Label(udp_frame, text="本地端口:")
+udp_local_port_label.grid(row=3, column=0, padx=5, pady=2, sticky=tk.W)
+udp_local_port_entry = ttk.Entry(udp_frame, width=8)
+udp_local_port_entry.grid(row=3, column=1, padx=5, pady=2)
+udp_local_port_entry.insert(0, "14550")
+
+# Frame for video settings
+video_frame = ttk.LabelFrame(root, text="视频功能")
+video_frame.grid(row=3, column=0, padx=10, pady=5, sticky=tk.W)
+
+# Network video options
+network_video_var = tk.IntVar()
+network_video_label = ttk.Label(video_frame, text="网络视频地址:")
+network_video_label.grid(row=0, column=1, padx=5, pady=2, sticky=tk.W)
+network_video_radio1 = ttk.Radiobutton(video_frame, variable=network_video_var, value=1)#text="选项1",
+network_video_radio1.grid(row=0, column=0, padx=5, pady=2, sticky=tk.W )
+
+
+network_video_entry = ttk.Entry(video_frame, width=20)
+network_video_entry.grid(row=0, column=4, padx=5, pady=2)
+
+network_video_combo = ttk.Combobox(tcp_frame, width=15, values=["192.168.1.100", "192.168.1.101", "192.168.1.102"])
+network_video_combo.grid(row=0, column=5, padx=5, pady=2)
+network_video_combo.set("192.168.2.101") # Set default value
+
+# 禁用网络视频输入框,除非选择了网络视频选项
+def update_entry_state():
+ network_video_entry.config(state='normal' if network_video_var.get() == 1 else 'disabled')
+
+
+# network_video_var.trace_add('write', update_entry_state)
+# update_entry_state() # 初始化时调用一次以设置正确的状态
+
+# USB device options
+#usb_device_var = tk.IntVar()
+usb_device_label = ttk.Label(video_frame, text="USB 设备:")
+usb_device_label.grid(row=1, column=1, padx=5, pady=2, sticky=tk.W)
+usb_device_radio1 = ttk.Radiobutton(video_frame, variable=network_video_var, value=2)#text="Camera1",
+usb_device_radio1.grid(row=1, column=0, padx=5, pady=2, sticky=tk.W)
+
+
+usb_device_entry = ttk.Entry(video_frame, width=20)
+usb_device_entry.grid(row=1, column=4, padx=5, pady=2)
+
+usb_device_combo = ttk.Combobox(tcp_frame, width=15, values=["192.168.1.100", "192.168.1.101", "192.168.1.102"])
+usb_device_combo.grid(row=1, column=5, padx=5, pady=2)
+usb_device_combo.set("192.168.2.101") # Set default value
+
+# Save settings button
+save_button = ttk.Button(root, text="保存设置", command=save_settings)
+save_button.grid(row=4, column=0, pady=10)
+save_button = ttk.Button(root, text="连接设备", command=save_settings)
+save_button.grid(row=5, column=0, pady=10)
+
+root.mainloop()
\ No newline at end of file
diff --git a/src/ui/home.py b/src/ui/home.py
new file mode 100644
index 0000000..20c2330
--- /dev/null
+++ b/src/ui/home.py
@@ -0,0 +1,96 @@
+import subprocess
+import tkinter as tk
+from tkinter import ttk
+from PIL import Image, ImageTk
+
+class MainWindow(tk.Tk):
+ def __init__(self):
+ super().__init__()
+
+ self.title("带菜单栏、按钮和自适应图片的窗口示例")
+
+ # 设置窗口初始大小
+ self.geometry("800x600") # 宽度800像素,高度600像素
+
+ # 创建菜单栏
+ self.menu_bar = tk.Menu(self)
+
+ file_menu = tk.Menu(self.menu_bar, tearoff=0)
+ file_menu.add_command(label="Command 1", command=self.menu_command_1)
+ file_menu.add_command(label="Command 2", command=self.menu_command_2)
+ file_menu.add_separator()
+ file_menu.add_command(label="Exit", command=self.quit)
+ self.menu_bar.add_cascade(label="File", menu=file_menu)
+
+ edit_menu = tk.Menu(self.menu_bar, tearoff=0)
+ edit_menu.add_command(label="Command 3", command=self.menu_command_3)
+ self.menu_bar.add_cascade(label="Edit", menu=edit_menu)
+
+ self.config(menu=self.menu_bar)
+
+ # 创建左侧帧
+ self.left_frame = tk.Frame(self, width=200, bg='light grey')
+ self.left_frame.pack(side=tk.LEFT, fill=tk.Y)
+
+ # 左侧按钮
+ self.button1 = ttk.Button(self.left_frame, text="地图定位", command=self.map_command_1)
+ self.button1.pack(pady=10)
+
+ self.button4 = ttk.Button(self.left_frame, text="连接无人机", command=self.connect_command_1)
+ self.button4.pack(pady=10)
+
+ self.button2 = ttk.Button(self.left_frame, text="路线规划", command=lambda: print("Button 2 clicked"))
+ self.button2.pack(pady=10)
+
+ self.button3 = ttk.Button(self.left_frame, text="人物识别", command=self.show_image)
+ self.button3.pack(pady=10)
+
+ self.button5 = ttk.Button(self.left_frame, text="跟踪信息", command=self.show_image)
+ self.button5.pack(pady=10)
+
+ # 创建中间区域的Frame
+ self.center_frame = tk.Frame(self, bg='white')
+ self.center_frame.pack(expand=True, fill=tk.BOTH)
+
+ # 显示图片的Label
+ self.image_label = tk.Label(self.center_frame, bg='white')
+ self.image_label.place(relx=0.5, rely=0.5, anchor=tk.CENTER) # 居中放置
+
+ # 加载并显示图片
+ self.load_and_display_image("img2.png")
+
+ # 监听窗口大小变化事件
+ self.bind("", self.on_window_resize)
+
+ def menu_command_1(self):
+ print("Menu Command 1")
+
+ def menu_command_2(self):
+ print("Menu Command 2")
+
+ def menu_command_3(self):
+ print("Menu Command 3")
+
+ def map_command_1(self):
+ subprocess.run(["python", "map.py"])
+ def connect_command_1(self):
+ subprocess.run(["python", "connect.py"])
+
+ def show_image(self):
+ self.load_and_display_image("img2.png")
+
+ def load_and_display_image(self, image_path):
+ # 加载图片并调整大小以适应窗口
+ img = Image.open(image_path)
+ width, height = self.winfo_width(), self.winfo_height() # 获取当前窗口大小
+ img = img.resize((width, height), Image.ANTIALIAS)
+ self.photo = ImageTk.PhotoImage(img)
+ self.image_label.config(image=self.photo)
+
+ def on_window_resize(self, event):
+ # 窗口大小变化时重新调整图片大小
+ self.load_and_display_image("img2.png")
+
+if __name__ == "__main__":
+ app = MainWindow()
+ app.mainloop()
\ No newline at end of file
diff --git a/src/ui/img1.png b/src/ui/img1.png
new file mode 100644
index 0000000..b0a96e5
Binary files /dev/null and b/src/ui/img1.png differ
diff --git a/src/ui/img2.png b/src/ui/img2.png
new file mode 100644
index 0000000..e01be55
Binary files /dev/null and b/src/ui/img2.png differ
diff --git a/src/ui/login.py b/src/ui/login.py
new file mode 100644
index 0000000..9f778e9
--- /dev/null
+++ b/src/ui/login.py
@@ -0,0 +1,218 @@
+import tkinter as tk # 使用Tkinter前需要先导入
+import tkinter.messagebox
+import pickle
+import subprocess
+from tkinter import font
+from PIL import Image, ImageTk
+
+
+def resize_image(event):
+ # 计算新的图片大小,保持原始比例
+ new_width = event.width
+ scale_factor = new_width / image_original.width
+ new_height = int(image_original.height * scale_factor)
+
+ # 使用 PIL 缩放图片
+ resized_image = image_original.resize((new_width, new_height), Image.ANTIALIAS)
+
+ # 创建新的 PhotoImage 对象
+ photo = ImageTk.PhotoImage(resized_image)
+
+ # 更新 Canvas 上的图片
+ canvas.itemconfig(image_id, image=photo)
+
+ # 确保图片居中
+ canvas.coords(image_id, (event.width // 2 - new_width // 2, event.height // 2 - new_height // 2))
+
+
+#实例化object,建立窗口window
+window = tk.Tk()
+
+#给窗口的可视化起名字
+window.title('Wellcome to Hongwei Website')
+
+# 设定窗口的大小(长 * 宽)
+window.geometry('500x535') # 这里的乘是小x
+
+#加载 wellcome image
+# 加载图片并获取原始尺寸
+image_original = Image.open('img1.png')
+image_width, image_height = image_original.size
+
+# 创建一个 Canvas
+canvas = tk.Canvas(window, width=500, height=335, bg='black')
+canvas.pack(fill='both', expand=True) # 让 Canvas 填充整个窗口并随窗口大小变化
+
+# 创建一个图片项目并保存其 ID
+image_id = canvas.create_image(0, 0, anchor='nw', image=None) # 初始位置设为左上角
+image_file = tk.PhotoImage(file='img1.png')
+image = canvas.create_image(250, 0, anchor='n', image=image_file)
+# canvas.pack(side='top')
+
+# 绑定窗口的 事件到 resize_image 函数
+window.bind('', resize_image)
+
+tk.Label(window, text='Wellcome', font=('Arial', 16)).pack()
+
+# 加载并显示图片(注意:这里只加载图片到变量,不直接显示在 Canvas 上)
+photo = ImageTk.PhotoImage(image_original)
+
+# 确保 Tkinter 的图片对象不会被垃圾回收
+photo_ref = [] # 创建一个列表来引用图片对象
+
+# 首次显示图片
+photo = ImageTk.PhotoImage(image_original)
+photo_ref.append(photo) # 添加到列表中防止被回收
+canvas.itemconfig(image_id, image=photo)
+canvas.coords(image_id, (canvas.winfo_width() // 2 - image_width // 2, canvas.winfo_height() // 2 - image_height // 2))
+
+# 用户信息
+# tk.Label(window, text='User name:', font=('Arial', 14)).place(x=10, y=175)
+# tk.Label(window, text='Password:', font=('Arial', 14)).place(x=10, y=215)
+# 用户信息标签
+label_usr_name = tk.Label(window, text='User name:', font=('Arial', 13))
+label_usr_name.place(x=10, y=175)
+
+label_usr_pwd = tk.Label(window, text='Password: ', font=('Arial', 13))
+label_usr_pwd.place(x=10, y=215)
+
+# 用户登录输入框entry
+# 用户名
+var_usr_name = tk.StringVar()
+var_usr_name.set('example@python.com')
+entry_usr_name = tk.Entry(window, textvariable=var_usr_name, font=('Arial', 14))
+# entry_usr_name.place(x=120, y=175)
+entry_width = 200
+entry_usr_name.place(x=label_usr_name.winfo_x() + label_usr_name.winfo_width() + 120, y=175, width=entry_width)
+
+# 用户密码
+var_usr_pwd = tk.StringVar()
+entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, font=('Arial', 14), show='*')
+# entry_usr_pwd.place(x=120, y=215)
+entry_usr_pwd.place(x=label_usr_pwd.winfo_x() + label_usr_pwd.winfo_width() + 120, y=215, width=entry_width)
+
+# 输入框在垂直方向上居中,可以调整 rowconfigure
+# 假设你的窗口只有两个行,并且你希望它们平分空间
+window.rowconfigure(0, weight=1)
+window.rowconfigure(1, weight=1)
+
+# 定义用户登录功能
+def usr_login():
+ # 这两行代码就是获取用户输入的usr_name和usr_pwd
+ usr_name = var_usr_name.get()
+ usr_pwd = var_usr_pwd.get()
+
+ # 这里设置异常捕获,当我们第一次访问用户信息文件时是不存在的,所以这里设置异常捕获。
+ # 中间的两行就是我们的匹配,即程序将输入的信息和文件中的信息匹配。
+ try:
+ with open('usrs_info.pickle', 'rb') as usr_file:
+ usrs_info = pickle.load(usr_file)
+ except FileNotFoundError:
+ # 这里就是我们在没有读取到`usr_file`的时候,程序会创建一个`usr_file`这个文件,并将管理员
+ # 的用户和密码写入,即用户名为`admin`密码为`admin`。
+ with open('usrs_info.pickle', 'wb') as usr_file:
+ usrs_info = {'admin': 'admin'}
+ pickle.dump(usrs_info, usr_file)
+ usr_file.close() # 必须先关闭,否则pickle.load()会出现EOFError: Ran out of input
+
+ # 如果用户名和密码与文件中的匹配成功,则会登录成功,并跳出弹窗how are you? 加上你的用户名。
+ if usr_name in usrs_info:
+ if usr_pwd == usrs_info[usr_name]:
+ tkinter.messagebox.showinfo(title='Welcome', message='How are you? ' + usr_name)
+ window.destroy()
+ subprocess.run(["python", "home.py"])
+ # 如果用户名匹配成功,而密码输入错误,则会弹出'Error, your password is wrong, try again.'
+ else:
+ tkinter.messagebox.showerror(message='Error, your password is wrong, try again.')
+ else: # 如果发现用户名不存在
+ is_sign_up = tkinter.messagebox.askyesno('Welcome! ', 'You have not sign up yet. Sign up now?')
+ # 提示需不需要注册新用户
+ if is_sign_up:
+ usr_sign_up()
+
+
+# 第9步,定义用户注册功能
+def usr_sign_up():
+ def sign_to_Hongwei_Website():
+ # 以下三行就是获取我们注册时所输入的信息
+ np = new_pwd.get()
+ npf = new_pwd_confirm.get()
+ nn = new_name.get()
+
+ # 这里是打开我们记录数据的文件,将注册信息读出
+ # with open('usrs_info.pickle', 'rb') as usr_file:
+ # exist_usr_info = pickle.load(usr_file)
+ # 尝试加载已存在的用户信息,如果文件不存在或为空,则使用空字典
+ try:
+ with open('usrs_info.pickle', 'rb') as usr_file:
+ exist_usr_info = pickle.load(usr_file)
+ except (FileNotFoundError, EOFError):
+ exist_usr_info = {} # 如果文件不存在或为空,则创建一个空字典
+
+ # 这里就是判断,如果两次密码输入不一致,则提示Error, Password and confirm password must be the same!
+ if np != npf:
+ tkinter.messagebox.showerror('Error', 'Password and confirm password must be the same!')
+
+ # 如果用户名已经在我们的数据文件中,则提示Error, The user has already signed up!
+ elif nn in exist_usr_info:
+ tkinter.messagebox.showerror('Error', 'The user has already signed up!')
+
+ # 最后如果输入无以上错误,则将注册输入的信息记录到文件当中,并提示注册成功Welcome!,You have successfully signed up!,然后销毁窗口。
+ else:
+ exist_usr_info[nn] = np
+ with open('usrs_info.pickle', 'wb') as usr_file:
+ pickle.dump(exist_usr_info, usr_file)
+ tkinter.messagebox.showinfo('Welcome', 'You have successfully signed up!')
+ # 然后销毁窗口。
+ window_sign_up.destroy()
+
+ # 定义长在窗口上的窗口
+ window_sign_up = tk.Toplevel(window)
+ window_sign_up.geometry('300x200')
+ window_sign_up.title('Sign up window')
+
+ new_name = tk.StringVar() # 将输入的注册名赋值给变量
+ new_name.set('example@python.com') # 将最初显示定为'example@python.com'
+ tk.Label(window_sign_up, text='User name: ').place(x=10, y=10) # 将`User name:`放置在坐标(10,10)。
+ entry_new_name = tk.Entry(window_sign_up, textvariable=new_name) # 创建一个注册名的`entry`,变量为`new_name`
+ entry_new_name.place(x=130, y=10) # `entry`放置在坐标(150,10).
+
+ new_pwd = tk.StringVar()
+ tk.Label(window_sign_up, text='Password: ').place(x=10, y=50)
+ entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show='*')
+ entry_usr_pwd.place(x=130, y=50)
+
+ new_pwd_confirm = tk.StringVar()
+ tk.Label(window_sign_up, text='Confirm password: ').place(x=10, y=90)
+ entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show='*')
+ entry_usr_pwd_confirm.place(x=130, y=90)
+
+ # 下面的 sign_to_Hongwei_Website
+ btn_comfirm_sign_up = tk.Button(window_sign_up, text='Sign up', command=sign_to_Hongwei_Website)
+ btn_comfirm_sign_up.place(x=180, y=120)
+
+
+# btn_login = tk.Button(window, text='登录', command=usr_login)
+# btn_login.place(x=120, y=340)
+# btn_sign_up = tk.Button(window, text='注册', command=usr_sign_up)
+# btn_sign_up.place(x=200, y=340)
+
+# 创建一个字体对象,用于设置按钮字体和大小
+button_font = font.Font(family='Helvetica', size=14, weight='bold')
+
+# 创建登录按钮
+btn_login = tk.Button(window, text='登录', command=usr_login, font=button_font, bg='lightblue', fg='white',
+ borderwidth=2, relief='raised')
+btn_login.place(x=140, y=340, width=80, height=30) # 这里设置了按钮的宽度和高度(以字符为单位)
+
+# 创建注册按钮
+btn_sign_up = tk.Button(window, text='注册', command=usr_sign_up, font=button_font, bg='lightgreen', fg='white',
+ borderwidth=2, relief='raised')
+btn_sign_up.place(x=250, y=340, width=80, height=30) # 同样设置了按钮的宽度和高度(以字符为单位)
+
+# ... 其他代码 ...
+
+window.mainloop()
+
+# 第10步,主窗口循环显示
+window.mainloop()
\ No newline at end of file
diff --git a/src/ui/map.py b/src/ui/map.py
new file mode 100644
index 0000000..edd8de4
--- /dev/null
+++ b/src/ui/map.py
@@ -0,0 +1,11 @@
+import webbrowser
+
+# 假设你的HTML文件位于当前工作目录的"maps"文件夹下
+file_path = 'showpoint.html' # 替换为你的HTML文件路径
+
+# 使用默认浏览器打开HTML文件
+#webbrowser.open_new_tab(file_path) # 或者使用 webbrowser.open(file_path) 来打开新窗口
+
+# 在新窗口中打开而不是新标签页,可以这样做:
+webbrowser.get('windows-default').open_new(file_path) # Windows
+# webbrowser.get('firefox').open_new(file_path) # 指定浏览器(如Firefox)
\ No newline at end of file