From f6a6bd9241520c1c94d6ddb42a7d6e909c6c4cf4 Mon Sep 17 00:00:00 2001 From: Brian McGinn Date: Tue, 7 May 2024 15:22:56 -0700 Subject: [PATCH] V3.0.0 (#563) * Release3 cleanup (#553) * fix: Reduce automated-self-checkout to only include use case files --------- Signed-off-by: Brian McGinn Co-authored-by: Jim Wang @ Intel Co-authored-by: Antonio Martinez --- .gitignore | 35 +- .gitmodules | 3 + Dockerfile.bitModel | 22 - Makefile | 226 +- README.md | 72 +- benchmark-scripts/Dockerfile.benchmark | 49 - benchmark-scripts/Dockerfile.igt | 36 - benchmark-scripts/Dockerfile.xpu | 92 - benchmark-scripts/Makefile | 20 - benchmark-scripts/benchmark.sh | 365 --- benchmark-scripts/camera-simulator.sh | 47 - benchmark-scripts/cleanup_gpu_metrics.sh | 49 - benchmark-scripts/collect_platform_metrics.sh | 146 -- .../consolidate_multiple_run_of_metrics.py | 544 ----- benchmark-scripts/copy-platform-metrics.sh | 23 - benchmark-scripts/download_sample_videos.sh | 15 - benchmark-scripts/format_avc_mp4.sh | 104 - benchmark-scripts/get-gpu-info.sh | 40 - benchmark-scripts/log_time_monitor.sh | 71 - benchmark-scripts/requirements-xpu.txt | 8 - benchmark-scripts/requirements.txt | 3 - benchmark-scripts/results_parser.py | 221 -- benchmark-scripts/smoke_test_benchmark.sh | 66 - benchmark-scripts/stop_server.sh | 10 - benchmark-scripts/stream_density.sh | 309 --- .../test_benchmark_multiple_pipelines.sh | 69 - benchmark-scripts/test_format_avc_mp4.sh | 168 -- benchmark-scripts/test_streamdensity.sh | 72 - camera-simulator/camera-simulator.sh | 117 - camera-simulator/mediamtx.yml | 275 --- configs/opencv-ovms/cmd_client/Dockerfile | 23 - .../cmd_client/Dockerfile.unit-test | 21 - configs/opencv-ovms/cmd_client/Makefile | 17 - configs/opencv-ovms/cmd_client/go.mod | 20 - configs/opencv-ovms/cmd_client/go.sum | 30 - configs/opencv-ovms/cmd_client/main.go | 716 ------ .../cmd_client/ovmsClientConf_test.go | 89 - .../opencv-ovms/cmd_client/ovmsGrpcPort.go | 83 - .../cmd_client/parser/ovmsConfigJsonParser.go | 69 - .../parser/ovmsConfigJsonParser_test.go | 56 - .../parser/test-config_template.json | 45 - .../cmd_client/parser/test-invalid.json | 1 - .../cmd_client/portfinder/findPort.go | 53 - .../cmd_client/portfinder/findPort_test.go | 48 - configs/opencv-ovms/cmd_client/readEnv.go | 86 - .../opencv-ovms/cmd_client/readEnv_test.go | 57 - .../capi_face_detection/configuration.yaml | 17 - .../res/capi_yolov5/configuration.yaml | 17 - .../capi_yolov5_ensemble/configuration.yaml | 17 - .../capi_yolov8_ensemble/configuration.yaml | 19 - .../yolov8_custom_node.json | 85 - .../res/classification/configuration.yaml | 29 - .../cmd_client/res/grpc_go/configuration.yaml | 27 - .../res/grpc_python/configuration.yaml | 29 - .../cmd_client/res/gst/configuration.yaml | 35 - .../instance_segmentation/configuration.yaml | 27 - .../res/object_detection/configuration.yaml | 29 - .../cmd_client/res/test/configuration.yaml | 28 - .../opencv-ovms/cmd_client/run_unit_test.sh | 25 - .../cmd_client/server/customNode.go | 90 - .../cmd_client/server/customNode_test.go | 67 - .../cmd_client/server/test-customnode.json | 163 -- .../cmd_client/server/test-invalid.json | 1 - .../cmd_client/server/test-update-device.json | 28 - .../server/test-yolov8_custom_node.json | 85 - .../cmd_client/server/updateDevice.go | 79 - .../cmd_client/server/updateDevice_test.go | 67 - .../opencv-ovms/cmd_client/testdata/empty.env | 0 .../opencv-ovms/cmd_client/testdata/test.env | 2 - configs/opencv-ovms/cmd_client/writeEnv.go | 138 -- .../opencv-ovms/cmd_client/writeEnv_test.go | 99 - configs/opencv-ovms/demos/Dockerfile.python | 17 - configs/opencv-ovms/demos/Makefile | 7 - .../python/classification_demo.py | 345 --- .../demos/classification/python/entrypoint.sh | 19 - .../python/labels/imagenet_2012.txt | 1000 -------- .../demos/common/python/helpers.py | 32 - .../demos/common/python/html_reader.py | 61 - .../demos/common/python/images_capture.py | 203 -- .../demos/common/python/monitors.py | 40 - .../python/monitors_extension/CMakeLists.txt | 13 - .../monitors_extension/monitors_extension.cpp | 184 -- .../demos/common/python/openvino/__init__.py | 17 - .../python/openvino/model_zoo/__init__.py | 17 - .../openvino/model_zoo/model_api/README.md | 136 -- .../openvino/model_zoo/model_api/__init__.py | 0 .../model_zoo/model_api/adapters/__init__.py | 27 - .../model_api/adapters/model_adapter.py | 159 -- .../model_api/adapters/openvino_adapter.py | 187 -- .../model_api/adapters/ovms_adapter.md | 64 - .../model_api/adapters/ovms_adapter.py | 170 -- .../model_zoo/model_api/adapters/utils.py | 78 - .../model_zoo/model_api/models/__init__.py | 79 - .../model_api/models/background_matting.py | 185 -- .../model_zoo/model_api/models/bert.py | 207 -- .../model_zoo/model_api/models/centernet.py | 188 -- .../model_api/models/classification.py | 88 - .../model_zoo/model_api/models/ctpn.py | 389 --- .../model_zoo/model_api/models/deblurring.py | 80 - .../model_api/models/detection_model.py | 127 - .../model_zoo/model_api/models/detr.py | 78 - .../model_zoo/model_api/models/faceboxes.py | 142 -- .../models/hpe_associative_embedding.py | 353 --- .../model_zoo/model_api/models/image_model.py | 163 -- .../model_api/models/instance_segmentation.py | 299 --- .../model_zoo/model_api/models/model.py | 303 --- .../model_zoo/model_api/models/monodepth.py | 39 - .../model_zoo/model_api/models/nanodet.py | 130 - .../model_zoo/model_api/models/open_pose.py | 396 --- .../model_zoo/model_api/models/retinaface.py | 432 ---- .../model_api/models/segmentation.py | 82 - .../model_zoo/model_api/models/ssd.py | 150 -- .../model_zoo/model_api/models/tokens_bert.py | 114 - .../model_zoo/model_api/models/types.py | 154 -- .../ultra_lightweight_face_detection.py | 76 - .../model_zoo/model_api/models/utils.py | 213 -- .../model_zoo/model_api/models/yolo.py | 519 ---- .../model_api/performance_metrics.py | 102 - .../model_zoo/model_api/pipelines/__init__.py | 7 - .../model_api/pipelines/async_pipeline.py | 136 -- .../demos/common/python/requirements.txt | 3 - .../demos/common/python/requirements_ovms.txt | 1 - .../opencv-ovms/demos/common/python/setup.py | 56 - .../common/python/visualizers/__init__.py | 23 - .../python/visualizers/drawing_utils.py | 61 - .../visualizers/instance_segmentation.py | 91 - .../instance_segmentation/python/Makefile | 7 - .../python/coco_80cl_bkgr.txt | 81 - .../python/entrypoint.sh | 19 - .../python/instance_segmentation_demo.py | 319 --- .../instance_segmentation_demo/__init__.py | 0 .../instance_segmentation_demo/tracker.py | 97 - .../object_detection/python/entrypoint.sh | 20 - .../python/labels/coco_91cl_bkgr.txt | 92 - .../python/object_detection_demo.py | 364 --- configs/opencv-ovms/demos/requirements.txt | 19 - .../opencv-ovms/envs/capi_face_detection.env | 12 - configs/opencv-ovms/envs/capi_yolov5.env | 12 - .../opencv-ovms/envs/capi_yolov5_ensemble.env | 13 - .../opencv-ovms/envs/capi_yolov8_ensemble.env | 15 - configs/opencv-ovms/envs/classification.env | 5 - configs/opencv-ovms/envs/grpc_python.env | 3 - configs/opencv-ovms/envs/gst.env | 5 - configs/opencv-ovms/envs/object_detection.env | 7 - configs/opencv-ovms/envs/ovms_server.env | 1 - configs/opencv-ovms/envs/yolov5-cpu.env | 16 - configs/opencv-ovms/envs/yolov5-gpu.env | 18 - configs/opencv-ovms/grpc_go/.dockerignore | 3 - configs/opencv-ovms/grpc_go/Dockerfile | 28 - configs/opencv-ovms/grpc_go/Findings.md | 26 - configs/opencv-ovms/grpc_go/Makefile | 7 - configs/opencv-ovms/grpc_go/README.md | 11 - configs/opencv-ovms/grpc_go/entrypoint.sh | 19 - configs/opencv-ovms/grpc_go/go.mod | 21 - configs/opencv-ovms/grpc_go/go.sum | 25 - configs/opencv-ovms/grpc_go/main.go | 151 -- .../grpc_go/pkg/ovms/inferRequest.go | 59 - .../grpc_go/pkg/ovms/inferResponse.go | 18 - .../grpc_go/pkg/ovms/metadataRequest.go | 32 - .../grpc_go/pkg/ovms/tensorOutput.go | 73 - .../grpc_go/pkg/ovms/tensorOutput_test.go | 75 - .../opencv-ovms/grpc_go/pkg/yolov5/consts.go | 128 - .../grpc_go/pkg/yolov5/detectedObject.go | 205 -- .../opencv-ovms/grpc_go/stream_density_run.sh | 8 - .../opencv-ovms/grpc_go/utilities/flags.go | 31 - configs/opencv-ovms/grpc_go/utilities/util.go | 42 - configs/opencv-ovms/grpc_python/Dockerfile | 24 - configs/opencv-ovms/grpc_python/Makefile | 7 - .../grpc_python/grpc_postprocess.py | 70 - .../opencv-ovms/grpc_python/grpc_python.py | 122 - .../grpc_python/grpc_python_test.py | 87 - .../grpc_python/run_grpc_python.sh | 36 - .../gst/extensions/OCR_post_processing.py | 66 - configs/opencv-ovms/gst/extensions/barcode.py | 178 -- .../gst/extensions/object_removal_by_label.py | 24 - .../gst/extensions/remote_classify.py | 211 -- .../yolov5_pipeline/yolov5s_full.sh | 31 - .../gst_capi/Dockerfile.ovms-capi-gst | 91 - .../gst_capi/Dockerfile.ovms.yolov8 | 51 - configs/opencv-ovms/gst_capi/Makefile | 46 - .../opencv-ovms/gst_capi/launch-pipeline.sh | 25 - .../gst_capi/pipelines/capi_yolov5/Makefile | 23 - .../gst_capi/pipelines/capi_yolov5/main.cpp | 1152 --------- .../pipelines/capi_yolov5_ensemble/Makefile | 28 - .../capi_yolov5_ensemble/barcode.cpp | 70 - .../capi_yolov5_ensemble/buffersqueue.cpp | 66 - .../capi_yolov5_ensemble/buffersqueue.hpp | 47 - .../custom_node_interface.h | 78 - .../custom_node_library_internal_manager.cpp | 78 - .../custom_node_library_internal_manager.hpp | 60 - .../efficientnetb0_node.cpp | 620 ----- .../pipelines/capi_yolov5_ensemble/main.cpp | 2165 ----------------- .../capi_yolov5_ensemble/opencv_utils.hpp | 162 -- .../pipelines/capi_yolov5_ensemble/queue.hpp | 136 -- .../pipelines/capi_yolov5_ensemble/utils.hpp | 145 -- .../pipelines/capi_yolov8_ensemble/Makefile | 28 - .../capi_yolov8_ensemble/buffersqueue.cpp | 66 - .../capi_yolov8_ensemble/buffersqueue.hpp | 47 - .../custom_node_interface.h | 78 - .../custom_node_library_internal_manager.cpp | 78 - .../custom_node_library_internal_manager.hpp | 60 - .../efficientnetb0_node.cpp | 630 ----- .../efficientnetb0_node_debug.cpp | 728 ------ .../pipelines/capi_yolov8_ensemble/main.cpp | 2138 ---------------- .../capi_yolov8_ensemble/opencv_utils.hpp | 163 -- .../pipelines/capi_yolov8_ensemble/queue.hpp | 139 -- .../pipelines/capi_yolov8_ensemble/utils.hpp | 145 -- .../capi_yolov8_ensemble/yolo_efficientnet.sh | 63 - .../pipelines/face_detection/Makefile | 24 - .../pipelines/face_detection/main.cpp | 1009 -------- configs/opencv-ovms/gst_capi/run_gst_capi.sh | 60 - configs/opencv-ovms/images/inputimages.txt | 1 - configs/opencv-ovms/images/readme.txt | 1 - .../models/2022/config_template.json | 247 -- .../opencv-ovms/scripts/docker-launcher.sh | 105 - .../docker_compose_generic_entrypoint.sh | 14 - .../scripts/gen_ovms_model_config_json.sh | 9 - .../scripts/get_server_grpc_port.sh | 8 - configs/opencv-ovms/scripts/image_download.sh | 7 - configs/opencv-ovms/scripts/run_test.sh | 14 - .../opencv-ovms/scripts/start_ovms_server.sh | 18 - create-symbolic-link.sh | 17 - detection.gif | Bin 1241443 -> 0 bytes docker-compose-cam.yml | 91 - docker-compose-portainer.yml | 20 - docker-compose.yml | 218 -- docs/404.html | 966 +------- docs/LICENSE.html | 1574 ------------ docs/OVMS/capiPipelineRun.html | 1669 ------------- docs/OVMS/capiYolov5EnsemblePipelineRun.html | 1498 ------------ docs/OVMS/capiYolov5PipelineRun.html | 1513 ------------ docs/OVMS/pipelineDockerCompose.html | 1525 ------------ docs/OVMS/pipelinerun.html | 1565 ------------ docs/OVMS/pipelinesetup.html | 1555 ------------ docs/OVMS/profileLauncherConfigs.html | 1504 ------------ docs/OVMS/quick_pipelinerun.html | 1697 ------------- docs/OVMS/quick_stream_density.html | 1679 ------------- ...unObjectDetectionPipelineWithNewModel.html | 1653 ------------- docs/OVMS/supportingDifferentLanguage.html | 1516 ------------ docs/OVMS/supportingDifferentModel.html | 1524 ------------ docs/faq.html | 1549 ------------ docs/hardwaresetup.html | 1548 ------------ docs/images/dashboard.png | Bin 111670 -> 0 bytes docs/images/execute_a_dev_video.png | Bin 179866 -> 0 bytes docs/images/import.png | Bin 22914 -> 0 bytes docs/images/list_dev_videos.png | Bin 40266 -> 0 bytes docs/images/logo-white-75px.png | Bin 2332 -> 0 bytes .../portainer_dashobaord_docker_compose.png | Bin 159820 -> 0 bytes docs/images/vision-data-flow.jpg | Bin 49146 -> 0 bytes docs/index.html | 985 +------- docs/platforms.html | 1410 ----------- docs/query_usb_camera.html | 1419 ----------- docs/release-notes/v1-0-1.html | 1583 ------------ docs/release-notes/v1-5-0.html | 1664 ------------- docs/releasenotes.html | 1388 ----------- docs/roadmap.html | 1522 ------------ docs/search/search_index.json | 2 +- docs/sitemap.xml | 171 +- docs/stylesheets/branding.css | 33 - docs/stylesheets/extra.css | 16 - docs/stylesheets/index.css | 43 - docs/webcam_rtsp.html | 1390 ----------- docs_src/LICENSE.md | 366 +-- docs_src/OVMS/camera_serial_number.md | 19 - docs_src/OVMS/capiPipelineRun.md | 100 - .../OVMS/capiYolov5EnsemblePipelineRun.md | 64 - docs_src/OVMS/capiYolov5PipelineRun.md | 81 - .../OVMS/capiYolov8EnsemblePipelineRun.md | 67 - docs_src/OVMS/pipelineDockerCompose.md | 36 - docs_src/OVMS/pipelinebenchmarking.md | 181 -- docs_src/OVMS/pipelinerun.md | 35 - docs_src/OVMS/pipelinesetup.md | 97 - docs_src/OVMS/profileLauncherConfigs.md | 63 - docs_src/OVMS/quick_pipelinerun.md | 136 -- docs_src/OVMS/quick_stream_density.md | 137 -- .../runObjectDetectionPipelineWithNewModel.md | 113 - docs_src/OVMS/stop_pipeline_run.md | 13 - docs_src/OVMS/supportingDifferentLanguage.md | 17 - docs_src/OVMS/supportingDifferentModel.md | 31 - docs_src/advanced.md | 97 + docs_src/dev-tools/documentation.md | 65 - docs_src/dev-tools/environment_variables.md | 67 - docs_src/dev-tools/overview.md | 3 - docs_src/dev-tools/references.md | 15 - docs_src/dev-tools/run_camera_simulator.md | 73 - docs_src/dev-tools/telemetry/setup.md | 26 - docs_src/faq.md | 32 - docs_src/getting_started.md | 94 + docs_src/hardwaresetup.md | 40 - docs_src/images/automated-checkout-1.0.jpg | Bin 61820 -> 0 bytes docs_src/images/automated-checkout-ovms.jpg | Bin 47002 -> 0 bytes docs_src/images/dashboard.png | Bin 111670 -> 0 bytes .../images/documentation-version-dropdown.png | Bin 442157 -> 0 bytes docs_src/images/import.png | Bin 22914 -> 0 bytes .../portainer_dashobaord_docker_compose.png | Bin 159820 -> 0 bytes docs_src/index.md | 11 +- docs_src/performance.md | 51 + docs_src/platforms.md | 21 - docs_src/query_usb_camera.md | 34 - docs_src/release-notes/v1-0-1.md | 29 - docs_src/release-notes/v1-5-0.md | 51 - docs_src/release-notes/v2-0-0.md | 24 - docs_src/release-notes/v2-1-0.md | 23 - docs_src/releasenotes.md | 9 - docs_src/roadmap.md | 86 - docs_src/troubleshooting.md | 24 - docs_src/webcam_rtsp.md | 12 - download_models/Dockerfile.yolov8-download | 41 - download_models/downloadModels.sh | 138 ++ download_models/downloadOVMSModels.sh | 322 --- download_models/download_mo_bit_models.sh | 30 - download_models/getModels.sh | 44 - download_models/model_build/convert-model.py | 28 - download_models/model_build/convert-model.sh | 41 - download_models/model_build/download-tools.sh | 11 - download_models/model_build/quantize-model.py | 347 --- download_models/testDownloadModels.sh | 97 + download_models/testDownloadOVMSModels.sh | 97 - get-options.sh | 116 - get-realsense-serialno.sh | 40 - mkdocs.yml | 38 +- performance-tools | 1 + run.sh | 123 - run_smoke_test.sh | 393 --- sample-media/README.md | 1 - smoke_test.sh | 100 + Dockerfile.dlstreamer => src/Dockerfile | 9 +- src/docker-compose.yml | 61 + .../scripts/run_gst.sh => src/entrypoint.sh | 43 +- .../extensions/OCR_post_processing_0012.py | 15 +- .../extensions/barcode_nv12_to_gray.py | 73 +- .../extensions/tracked_object_filter.py | 17 +- {patch => src/patch}/libusb.h | 0 .../pipelines}/yolov5s.sh | 7 +- .../pipelines}/yolov5s_effnetb0.sh | 7 +- src/pipelines/yolov5s_full.sh | 31 + requirements.txt => src/requirements.txt | 0 src/res/gst.env | 10 + src/res/yolov5-cpu.env | 4 + src/res/yolov5-gpu.env | 4 + stop_all_docker_containers.sh | 8 - test_barcode_docker_run.sh | 17 - test_default_dgpu_ocr.sh | 41 - test_device_switch.sh | 42 - test_realsense_params_docker_run.sh | 101 - 345 files changed, 1096 insertions(+), 68354 deletions(-) create mode 100644 .gitmodules delete mode 100644 Dockerfile.bitModel delete mode 100644 benchmark-scripts/Dockerfile.benchmark delete mode 100644 benchmark-scripts/Dockerfile.igt delete mode 100644 benchmark-scripts/Dockerfile.xpu delete mode 100644 benchmark-scripts/Makefile delete mode 100755 benchmark-scripts/benchmark.sh delete mode 100755 benchmark-scripts/camera-simulator.sh delete mode 100755 benchmark-scripts/cleanup_gpu_metrics.sh delete mode 100755 benchmark-scripts/collect_platform_metrics.sh delete mode 100644 benchmark-scripts/consolidate_multiple_run_of_metrics.py delete mode 100755 benchmark-scripts/copy-platform-metrics.sh delete mode 100755 benchmark-scripts/download_sample_videos.sh delete mode 100755 benchmark-scripts/format_avc_mp4.sh delete mode 100755 benchmark-scripts/get-gpu-info.sh delete mode 100755 benchmark-scripts/log_time_monitor.sh delete mode 100644 benchmark-scripts/requirements-xpu.txt delete mode 100644 benchmark-scripts/requirements.txt delete mode 100644 benchmark-scripts/results_parser.py delete mode 100755 benchmark-scripts/smoke_test_benchmark.sh delete mode 100755 benchmark-scripts/stop_server.sh delete mode 100755 benchmark-scripts/stream_density.sh delete mode 100755 benchmark-scripts/test_benchmark_multiple_pipelines.sh delete mode 100755 benchmark-scripts/test_format_avc_mp4.sh delete mode 100755 benchmark-scripts/test_streamdensity.sh delete mode 100755 camera-simulator/camera-simulator.sh delete mode 100644 camera-simulator/mediamtx.yml delete mode 100644 configs/opencv-ovms/cmd_client/Dockerfile delete mode 100644 configs/opencv-ovms/cmd_client/Dockerfile.unit-test delete mode 100644 configs/opencv-ovms/cmd_client/Makefile delete mode 100644 configs/opencv-ovms/cmd_client/go.mod delete mode 100644 configs/opencv-ovms/cmd_client/go.sum delete mode 100644 configs/opencv-ovms/cmd_client/main.go delete mode 100644 configs/opencv-ovms/cmd_client/ovmsClientConf_test.go delete mode 100644 configs/opencv-ovms/cmd_client/ovmsGrpcPort.go delete mode 100644 configs/opencv-ovms/cmd_client/parser/ovmsConfigJsonParser.go delete mode 100644 configs/opencv-ovms/cmd_client/parser/ovmsConfigJsonParser_test.go delete mode 100644 configs/opencv-ovms/cmd_client/parser/test-config_template.json delete mode 100644 configs/opencv-ovms/cmd_client/parser/test-invalid.json delete mode 100644 configs/opencv-ovms/cmd_client/portfinder/findPort.go delete mode 100644 configs/opencv-ovms/cmd_client/portfinder/findPort_test.go delete mode 100644 configs/opencv-ovms/cmd_client/readEnv.go delete mode 100644 configs/opencv-ovms/cmd_client/readEnv_test.go delete mode 100644 configs/opencv-ovms/cmd_client/res/capi_face_detection/configuration.yaml delete mode 100644 configs/opencv-ovms/cmd_client/res/capi_yolov5/configuration.yaml delete mode 100644 configs/opencv-ovms/cmd_client/res/capi_yolov5_ensemble/configuration.yaml delete mode 100644 configs/opencv-ovms/cmd_client/res/capi_yolov8_ensemble/configuration.yaml delete mode 100644 configs/opencv-ovms/cmd_client/res/capi_yolov8_ensemble/yolov8_custom_node.json delete mode 100644 configs/opencv-ovms/cmd_client/res/classification/configuration.yaml delete mode 100644 configs/opencv-ovms/cmd_client/res/grpc_go/configuration.yaml delete mode 100644 configs/opencv-ovms/cmd_client/res/grpc_python/configuration.yaml delete mode 100644 configs/opencv-ovms/cmd_client/res/gst/configuration.yaml delete mode 100644 configs/opencv-ovms/cmd_client/res/instance_segmentation/configuration.yaml delete mode 100644 configs/opencv-ovms/cmd_client/res/object_detection/configuration.yaml delete mode 100644 configs/opencv-ovms/cmd_client/res/test/configuration.yaml delete mode 100755 configs/opencv-ovms/cmd_client/run_unit_test.sh delete mode 100644 configs/opencv-ovms/cmd_client/server/customNode.go delete mode 100644 configs/opencv-ovms/cmd_client/server/customNode_test.go delete mode 100644 configs/opencv-ovms/cmd_client/server/test-customnode.json delete mode 100644 configs/opencv-ovms/cmd_client/server/test-invalid.json delete mode 100644 configs/opencv-ovms/cmd_client/server/test-update-device.json delete mode 100644 configs/opencv-ovms/cmd_client/server/test-yolov8_custom_node.json delete mode 100644 configs/opencv-ovms/cmd_client/server/updateDevice.go delete mode 100644 configs/opencv-ovms/cmd_client/server/updateDevice_test.go delete mode 100644 configs/opencv-ovms/cmd_client/testdata/empty.env delete mode 100644 configs/opencv-ovms/cmd_client/testdata/test.env delete mode 100644 configs/opencv-ovms/cmd_client/writeEnv.go delete mode 100644 configs/opencv-ovms/cmd_client/writeEnv_test.go delete mode 100644 configs/opencv-ovms/demos/Dockerfile.python delete mode 100644 configs/opencv-ovms/demos/Makefile delete mode 100755 configs/opencv-ovms/demos/classification/python/classification_demo.py delete mode 100755 configs/opencv-ovms/demos/classification/python/entrypoint.sh delete mode 100644 configs/opencv-ovms/demos/classification/python/labels/imagenet_2012.txt delete mode 100644 configs/opencv-ovms/demos/common/python/helpers.py delete mode 100644 configs/opencv-ovms/demos/common/python/html_reader.py delete mode 100644 configs/opencv-ovms/demos/common/python/images_capture.py delete mode 100644 configs/opencv-ovms/demos/common/python/monitors.py delete mode 100644 configs/opencv-ovms/demos/common/python/monitors_extension/CMakeLists.txt delete mode 100644 configs/opencv-ovms/demos/common/python/monitors_extension/monitors_extension.cpp delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/__init__.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/__init__.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/README.md delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/__init__.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/__init__.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/model_adapter.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/openvino_adapter.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/ovms_adapter.md delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/ovms_adapter.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/utils.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/__init__.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/background_matting.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/bert.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/centernet.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/classification.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/ctpn.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/deblurring.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/detection_model.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/detr.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/faceboxes.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/hpe_associative_embedding.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/image_model.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/instance_segmentation.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/model.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/monodepth.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/nanodet.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/open_pose.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/retinaface.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/segmentation.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/ssd.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/tokens_bert.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/types.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/ultra_lightweight_face_detection.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/utils.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/yolo.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/performance_metrics.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/pipelines/__init__.py delete mode 100644 configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/pipelines/async_pipeline.py delete mode 100644 configs/opencv-ovms/demos/common/python/requirements.txt delete mode 100644 configs/opencv-ovms/demos/common/python/requirements_ovms.txt delete mode 100755 configs/opencv-ovms/demos/common/python/setup.py delete mode 100644 configs/opencv-ovms/demos/common/python/visualizers/__init__.py delete mode 100644 configs/opencv-ovms/demos/common/python/visualizers/drawing_utils.py delete mode 100644 configs/opencv-ovms/demos/common/python/visualizers/instance_segmentation.py delete mode 100644 configs/opencv-ovms/demos/instance_segmentation/python/Makefile delete mode 100644 configs/opencv-ovms/demos/instance_segmentation/python/coco_80cl_bkgr.txt delete mode 100755 configs/opencv-ovms/demos/instance_segmentation/python/entrypoint.sh delete mode 100644 configs/opencv-ovms/demos/instance_segmentation/python/instance_segmentation_demo.py delete mode 100644 configs/opencv-ovms/demos/instance_segmentation/python/instance_segmentation_demo/__init__.py delete mode 100644 configs/opencv-ovms/demos/instance_segmentation/python/instance_segmentation_demo/tracker.py delete mode 100755 configs/opencv-ovms/demos/object_detection/python/entrypoint.sh delete mode 100644 configs/opencv-ovms/demos/object_detection/python/labels/coco_91cl_bkgr.txt delete mode 100755 configs/opencv-ovms/demos/object_detection/python/object_detection_demo.py delete mode 100644 configs/opencv-ovms/demos/requirements.txt delete mode 100644 configs/opencv-ovms/envs/capi_face_detection.env delete mode 100644 configs/opencv-ovms/envs/capi_yolov5.env delete mode 100644 configs/opencv-ovms/envs/capi_yolov5_ensemble.env delete mode 100644 configs/opencv-ovms/envs/capi_yolov8_ensemble.env delete mode 100644 configs/opencv-ovms/envs/classification.env delete mode 100644 configs/opencv-ovms/envs/grpc_python.env delete mode 100644 configs/opencv-ovms/envs/gst.env delete mode 100644 configs/opencv-ovms/envs/object_detection.env delete mode 100644 configs/opencv-ovms/envs/ovms_server.env delete mode 100644 configs/opencv-ovms/envs/yolov5-cpu.env delete mode 100644 configs/opencv-ovms/envs/yolov5-gpu.env delete mode 100644 configs/opencv-ovms/grpc_go/.dockerignore delete mode 100644 configs/opencv-ovms/grpc_go/Dockerfile delete mode 100644 configs/opencv-ovms/grpc_go/Findings.md delete mode 100644 configs/opencv-ovms/grpc_go/Makefile delete mode 100644 configs/opencv-ovms/grpc_go/README.md delete mode 100755 configs/opencv-ovms/grpc_go/entrypoint.sh delete mode 100644 configs/opencv-ovms/grpc_go/go.mod delete mode 100644 configs/opencv-ovms/grpc_go/go.sum delete mode 100644 configs/opencv-ovms/grpc_go/main.go delete mode 100644 configs/opencv-ovms/grpc_go/pkg/ovms/inferRequest.go delete mode 100644 configs/opencv-ovms/grpc_go/pkg/ovms/inferResponse.go delete mode 100644 configs/opencv-ovms/grpc_go/pkg/ovms/metadataRequest.go delete mode 100644 configs/opencv-ovms/grpc_go/pkg/ovms/tensorOutput.go delete mode 100644 configs/opencv-ovms/grpc_go/pkg/ovms/tensorOutput_test.go delete mode 100644 configs/opencv-ovms/grpc_go/pkg/yolov5/consts.go delete mode 100644 configs/opencv-ovms/grpc_go/pkg/yolov5/detectedObject.go delete mode 100755 configs/opencv-ovms/grpc_go/stream_density_run.sh delete mode 100644 configs/opencv-ovms/grpc_go/utilities/flags.go delete mode 100644 configs/opencv-ovms/grpc_go/utilities/util.go delete mode 100644 configs/opencv-ovms/grpc_python/Dockerfile delete mode 100644 configs/opencv-ovms/grpc_python/Makefile delete mode 100644 configs/opencv-ovms/grpc_python/grpc_postprocess.py delete mode 100644 configs/opencv-ovms/grpc_python/grpc_python.py delete mode 100644 configs/opencv-ovms/grpc_python/grpc_python_test.py delete mode 100755 configs/opencv-ovms/grpc_python/run_grpc_python.sh delete mode 100644 configs/opencv-ovms/gst/extensions/OCR_post_processing.py delete mode 100644 configs/opencv-ovms/gst/extensions/barcode.py delete mode 100644 configs/opencv-ovms/gst/extensions/object_removal_by_label.py delete mode 100644 configs/opencv-ovms/gst/extensions/remote_classify.py delete mode 100755 configs/opencv-ovms/gst/framework-pipelines/yolov5_pipeline/yolov5s_full.sh delete mode 100644 configs/opencv-ovms/gst_capi/Dockerfile.ovms-capi-gst delete mode 100644 configs/opencv-ovms/gst_capi/Dockerfile.ovms.yolov8 delete mode 100644 configs/opencv-ovms/gst_capi/Makefile delete mode 100755 configs/opencv-ovms/gst_capi/launch-pipeline.sh delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5/Makefile delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5/main.cpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/Makefile delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/barcode.cpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/buffersqueue.cpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/buffersqueue.hpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/custom_node_interface.h delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/custom_node_library_internal_manager.cpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/custom_node_library_internal_manager.hpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/efficientnetb0_node.cpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/main.cpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/opencv_utils.hpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/queue.hpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/utils.hpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/Makefile delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/buffersqueue.cpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/buffersqueue.hpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/custom_node_interface.h delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/custom_node_library_internal_manager.cpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/custom_node_library_internal_manager.hpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/efficientnetb0_node.cpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/efficientnetb0_node_debug.cpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/main.cpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/opencv_utils.hpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/queue.hpp delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/utils.hpp delete mode 100755 configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/yolo_efficientnet.sh delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/face_detection/Makefile delete mode 100644 configs/opencv-ovms/gst_capi/pipelines/face_detection/main.cpp delete mode 100755 configs/opencv-ovms/gst_capi/run_gst_capi.sh delete mode 100644 configs/opencv-ovms/images/inputimages.txt delete mode 100644 configs/opencv-ovms/images/readme.txt delete mode 100644 configs/opencv-ovms/models/2022/config_template.json delete mode 100755 configs/opencv-ovms/scripts/docker-launcher.sh delete mode 100755 configs/opencv-ovms/scripts/docker_compose_generic_entrypoint.sh delete mode 100755 configs/opencv-ovms/scripts/gen_ovms_model_config_json.sh delete mode 100755 configs/opencv-ovms/scripts/get_server_grpc_port.sh delete mode 100755 configs/opencv-ovms/scripts/image_download.sh delete mode 100755 configs/opencv-ovms/scripts/run_test.sh delete mode 100755 configs/opencv-ovms/scripts/start_ovms_server.sh delete mode 100755 create-symbolic-link.sh delete mode 100644 detection.gif delete mode 100644 docker-compose-cam.yml delete mode 100644 docker-compose-portainer.yml delete mode 100644 docker-compose.yml delete mode 100644 docs/LICENSE.html delete mode 100644 docs/OVMS/capiPipelineRun.html delete mode 100644 docs/OVMS/capiYolov5EnsemblePipelineRun.html delete mode 100644 docs/OVMS/capiYolov5PipelineRun.html delete mode 100644 docs/OVMS/pipelineDockerCompose.html delete mode 100644 docs/OVMS/pipelinerun.html delete mode 100644 docs/OVMS/pipelinesetup.html delete mode 100644 docs/OVMS/profileLauncherConfigs.html delete mode 100644 docs/OVMS/quick_pipelinerun.html delete mode 100644 docs/OVMS/quick_stream_density.html delete mode 100644 docs/OVMS/runObjectDetectionPipelineWithNewModel.html delete mode 100644 docs/OVMS/supportingDifferentLanguage.html delete mode 100644 docs/OVMS/supportingDifferentModel.html delete mode 100644 docs/faq.html delete mode 100644 docs/hardwaresetup.html delete mode 100644 docs/images/dashboard.png delete mode 100644 docs/images/execute_a_dev_video.png delete mode 100644 docs/images/import.png delete mode 100644 docs/images/list_dev_videos.png delete mode 100644 docs/images/logo-white-75px.png delete mode 100644 docs/images/portainer_dashobaord_docker_compose.png delete mode 100644 docs/images/vision-data-flow.jpg delete mode 100644 docs/platforms.html delete mode 100644 docs/query_usb_camera.html delete mode 100644 docs/release-notes/v1-0-1.html delete mode 100644 docs/release-notes/v1-5-0.html delete mode 100644 docs/releasenotes.html delete mode 100644 docs/roadmap.html delete mode 100644 docs/stylesheets/branding.css delete mode 100644 docs/stylesheets/extra.css delete mode 100644 docs/stylesheets/index.css delete mode 100644 docs/webcam_rtsp.html delete mode 100644 docs_src/OVMS/camera_serial_number.md delete mode 100644 docs_src/OVMS/capiPipelineRun.md delete mode 100644 docs_src/OVMS/capiYolov5EnsemblePipelineRun.md delete mode 100644 docs_src/OVMS/capiYolov5PipelineRun.md delete mode 100644 docs_src/OVMS/capiYolov8EnsemblePipelineRun.md delete mode 100644 docs_src/OVMS/pipelineDockerCompose.md delete mode 100644 docs_src/OVMS/pipelinebenchmarking.md delete mode 100644 docs_src/OVMS/pipelinerun.md delete mode 100644 docs_src/OVMS/pipelinesetup.md delete mode 100644 docs_src/OVMS/profileLauncherConfigs.md delete mode 100644 docs_src/OVMS/quick_pipelinerun.md delete mode 100644 docs_src/OVMS/quick_stream_density.md delete mode 100644 docs_src/OVMS/runObjectDetectionPipelineWithNewModel.md delete mode 100644 docs_src/OVMS/stop_pipeline_run.md delete mode 100644 docs_src/OVMS/supportingDifferentLanguage.md delete mode 100644 docs_src/OVMS/supportingDifferentModel.md create mode 100644 docs_src/advanced.md delete mode 100644 docs_src/dev-tools/documentation.md delete mode 100644 docs_src/dev-tools/environment_variables.md delete mode 100644 docs_src/dev-tools/overview.md delete mode 100644 docs_src/dev-tools/references.md delete mode 100644 docs_src/dev-tools/run_camera_simulator.md delete mode 100644 docs_src/dev-tools/telemetry/setup.md delete mode 100644 docs_src/faq.md create mode 100644 docs_src/getting_started.md delete mode 100644 docs_src/hardwaresetup.md delete mode 100644 docs_src/images/automated-checkout-1.0.jpg delete mode 100644 docs_src/images/automated-checkout-ovms.jpg delete mode 100644 docs_src/images/dashboard.png delete mode 100644 docs_src/images/documentation-version-dropdown.png delete mode 100644 docs_src/images/import.png delete mode 100644 docs_src/images/portainer_dashobaord_docker_compose.png create mode 100644 docs_src/performance.md delete mode 100644 docs_src/platforms.md delete mode 100644 docs_src/query_usb_camera.md delete mode 100644 docs_src/release-notes/v1-0-1.md delete mode 100644 docs_src/release-notes/v1-5-0.md delete mode 100644 docs_src/release-notes/v2-0-0.md delete mode 100644 docs_src/release-notes/v2-1-0.md delete mode 100644 docs_src/releasenotes.md delete mode 100644 docs_src/roadmap.md delete mode 100644 docs_src/troubleshooting.md delete mode 100644 docs_src/webcam_rtsp.md delete mode 100644 download_models/Dockerfile.yolov8-download create mode 100755 download_models/downloadModels.sh delete mode 100755 download_models/downloadOVMSModels.sh delete mode 100755 download_models/download_mo_bit_models.sh delete mode 100755 download_models/getModels.sh delete mode 100644 download_models/model_build/convert-model.py delete mode 100755 download_models/model_build/convert-model.sh delete mode 100755 download_models/model_build/download-tools.sh delete mode 100644 download_models/model_build/quantize-model.py create mode 100755 download_models/testDownloadModels.sh delete mode 100755 download_models/testDownloadOVMSModels.sh delete mode 100755 get-options.sh delete mode 100755 get-realsense-serialno.sh create mode 160000 performance-tools delete mode 100755 run.sh delete mode 100755 run_smoke_test.sh delete mode 100644 sample-media/README.md create mode 100755 smoke_test.sh rename Dockerfile.dlstreamer => src/Dockerfile (91%) create mode 100644 src/docker-compose.yml rename configs/opencv-ovms/scripts/run_gst.sh => src/entrypoint.sh (81%) rename {configs/opencv-ovms/gst => src}/extensions/OCR_post_processing_0012.py (84%) rename {configs/opencv-ovms/gst => src}/extensions/barcode_nv12_to_gray.py (78%) rename {configs/opencv-ovms/gst => src}/extensions/tracked_object_filter.py (75%) rename {patch => src/patch}/libusb.h (100%) rename {configs/opencv-ovms/gst/framework-pipelines/yolov5_pipeline => src/pipelines}/yolov5s.sh (74%) rename {configs/opencv-ovms/gst/framework-pipelines/yolov5_pipeline => src/pipelines}/yolov5s_effnetb0.sh (81%) create mode 100755 src/pipelines/yolov5s_full.sh rename requirements.txt => src/requirements.txt (100%) create mode 100644 src/res/gst.env create mode 100644 src/res/yolov5-cpu.env create mode 100644 src/res/yolov5-gpu.env delete mode 100755 stop_all_docker_containers.sh delete mode 100755 test_barcode_docker_run.sh delete mode 100755 test_default_dgpu_ocr.sh delete mode 100755 test_device_switch.sh delete mode 100755 test_realsense_params_docker_run.sh diff --git a/.gitignore b/.gitignore index 23cd25b2..9c62b14f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,45 +3,16 @@ .vscode results/* sample-media/*.mp4 -camera-simulator/rtsp_simple_server.log.txt docs/sitemap.xml.gz docs/* -benchmark-scripts/results/ -camera-simulator/rtsp_simple_server.log.txt -configs/opencv-ovms/images/sample-bottle.jpg -configs/opencv-ovms/models/2022/efficientnetb0/ -configs/opencv-ovms/models/2022/config.json -configs/opencv-ovms/models/2022/config_ovms-server*.json -configs/opencv-ovms/models/2022/face-detection-retail-0005/ -configs/opencv-ovms/models/2022/face-detect-retail-0005/ -configs/opencv-ovms/models/2022/face-landmarks-0002/ -configs/opencv-ovms/models/2022/face-reid-retail-0095/ -configs/opencv-ovms/models/2022/instance-segmentation-security-1040/ -configs/opencv-ovms/models/2022/instance_segmentation_omz_1040/ -configs/opencv-ovms/models/2022/BiT_M_R50x1_10C_50e_IR/ -configs/opencv-ovms/models/2022/yolov5s -configs/opencv-ovms/models/2022/ssd_mobilenet_v1_coco/ -configs/opencv-ovms/models/2022/person-detection-retail-0013/ -configs/opencv-ovms/models/2022/person_vehicle_bike_detection_2000/ -configs/opencv-ovms/models/2022/person-vehicle-bike-detection-2000/ -configs/opencv-ovms/models/2022/text-detect-0002/ -configs/opencv-ovms/models/2022/yolov8/ -configs/opencv-ovms/grpc_go/results/ -configs/opencv-ovms/cmd_client/ovms-client -configs/opencv-ovms/cmd_client/profile-launcher -!configs/opencv-ovms/scripts -!configs/opencv-ovms/envs -envs -scripts -ovms-client -profile-launcher -stream_density.sh +results/ efficientnet-b0/ -model_server/ ssd_mobilenet_v1_coco/ __pycache__ smoke_tests_output.log grpc_predict_v2.proto text-recognition-0012-mod horizontal-text-detection-0002 +models/ +src/cl-cache/* \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..3df09dd3 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "performance-tools"] + path = performance-tools + url = https://github.com/intel-retail/performance-tools diff --git a/Dockerfile.bitModel b/Dockerfile.bitModel deleted file mode 100644 index 4911b7a3..00000000 --- a/Dockerfile.bitModel +++ /dev/null @@ -1,22 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -FROM openvino/ubuntu22_dev:2023.0.0 - -USER root - -RUN apt-get update -y || true; DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - wget && \ - rm -rf /var/lib/apt/lists/* - -COPY download_models/download_mo_bit_models.sh / -RUN chmod +x /download_mo_bit_models.sh - -RUN mkdir -p /result - -WORKDIR / - -ENTRYPOINT [ "/download_mo_bit_models.sh" ] diff --git a/Makefile b/Makefile index f7875a19..183d1351 100644 --- a/Makefile +++ b/Makefile @@ -1,126 +1,87 @@ # Copyright © 2024 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -.PHONY: build-dlstreamer build-dlstreamer-realsense build-grpc-python build-grpc-go build-python-apps build-telegraf -.PHONY: build-capi_face_detection build-capi_yolov5 build-capi_yolov5_ensemble build-capi_yolov8_ensemble -.PHONY: run-camera-simulator run-telegraf run-portainer run-pipelines -.PHONY: clean-grpc-go clean-segmentation clean-ovms clean-all clean-results clean-telegraf clean-models clean-webcam -.PHONY: clean-ovms-server-configs clean-ovms-server -.PHONY: down-portainer down-pipelines -.PHONY: clean clean-simulator clean-object-detection clean-classification clean-gst clean-capi_face_detection clean-capi_yolov5 clean-capi_yolov5_ensemble clean-capi_yolov8_ensemble -.PHONY: list-profiles -.PHONY: unit-test-profile-launcher build-profile-launcher profile-launcher-status clean-profile-launcher webcam-rtsp -.PHONY: clean-test -.PHONY: hadolint -.PHONY: get-realsense-serial-num -.PHONY: run-demo run-cached-demo +.PHONY: build build-realsense run down +.PHONY: build-telegraf run-telegraf run-portainer clean-all clean-results clean-telegraf clean-models down-portainer +.PHONY: download-models clean-test run-demo stop-demo MKDOCS_IMAGE ?= asc-mkdocs -DGPU_TYPE ?= arc # arc|flex +PIPELINE_COUNT ?= 1 +TARGET_FPS ?= 14.95 +DOCKER_COMPOSE ?= docker-compose.yml -build-dlstreamer: - docker build --no-cache --build-arg HTTPS_PROXY=${HTTPS_PROXY} --build-arg HTTP_PROXY=${HTTP_PROXY} --target build-default -t dlstreamer:dev -f Dockerfile.dlstreamer . +download-models: + ./download_models/downloadModels.sh -build-dlstreamer-realsense: - docker build --no-cache --build-arg HTTPS_PROXY=${HTTPS_PROXY} --build-arg HTTP_PROXY=${HTTP_PROXY} --target build-realsense -t dlstreamer:realsense -f Dockerfile.dlstreamer . +download-sample-videos: + cd performance-tools/benchmark-scripts && ./download_sample_videos.sh -get-realsense-serial-num: - @./get-realsense-serialno.sh - -build-telegraf: - cd telegraf && $(MAKE) build - -run-camera-simulator: - ./camera-simulator/camera-simulator.sh - -run-telegraf: - cd telegraf && $(MAKE) run - -run-portainer: - docker compose -p portainer -f docker-compose-portainer.yml up -d - -run-pipelines: - @./scripts/gen_ovms_model_config_json.sh - docker compose -f docker-compose.yml up -d - -clean: - ./clean-containers.sh automated-self-checkout - -clean-simulator: - ./clean-containers.sh camera-simulator - -build-profile-launcher: - @mkdir -p ./results || true - @cd ./configs/opencv-ovms/cmd_client && $(MAKE) build - @./create-symbolic-link.sh $(PWD)/configs/opencv-ovms/cmd_client/profile-launcher profile-launcher - @./create-symbolic-link.sh $(PWD)/configs/opencv-ovms/scripts scripts - @./create-symbolic-link.sh $(PWD)/configs/opencv-ovms/envs envs - @./create-symbolic-link.sh $(PWD)/benchmark-scripts/stream_density.sh stream_density.sh - -build-ovms-server: - HTTPS_PROXY=${HTTPS_PROXY} HTTP_PROXY=${HTTP_PROXY} docker pull openvino/model_server:2023.1-gpu - -clean-profile-launcher: clean-grpc-python clean-grpc-go clean-segmentation clean-object-detection clean-classification clean-gst clean-capi_face_detection clean-test clean-capi_yolov5 clean-capi_yolov5_ensemble clean-capi_yolov8_ensemble - @echo "containers launched by profile-launcher are cleaned up." - @pkill -9 profile-launcher || true - -profile-launcher-status: - $(eval profileLauncherPid = $(shell ps -aux | grep ./profile-launcher | grep -v grep)) - $(if $(strip $(profileLauncherPid)), @echo "$@: profile-launcher running: "$(profileLauncherPid), @echo "$@: profile laucnher stopped") +clean-models: + @find ./models/ -mindepth 1 -maxdepth 1 -type d -exec sudo rm -r {} \; -clean-test: - ./clean-containers.sh test +run-smoke-tests: | download-models update-submodules download-sample-videos + @echo "Running smoke tests for OVMS profiles" + @./smoke_test.sh > smoke_tests_output.log + @echo "results of smoke tests recorded in the file smoke_tests_output.log" + @grep "Failed" ./smoke_tests_output.log || true + @grep "===" ./smoke_tests_output.log || true -clean-grpc-python: - ./clean-containers.sh grpc_python +update-submodules: + @git submodule update --init --recursive + @git submodule update --remote --merge -clean-grpc-go: - ./clean-containers.sh grpc_go +build: + docker build --build-arg HTTPS_PROXY=${HTTPS_PROXY} --build-arg HTTP_PROXY=${HTTP_PROXY} --target build-default -t dlstreamer:dev -f src/Dockerfile src/ -clean-gst: - ./clean-containers.sh gst +build-realsense: + docker build --build-arg HTTPS_PROXY=${HTTPS_PROXY} --build-arg HTTP_PROXY=${HTTP_PROXY} --target build-realsense -t dlstreamer:realsense -f src/Dockerfile src/ -clean-segmentation: - ./clean-containers.sh segmentation +run: + docker compose -f src/$(DOCKER_COMPOSE) up -d -clean-object-detection: - ./clean-containers.sh object-detection +run-render-mode: + xhost +local:docker + RENDER_MODE=1 docker compose -f src/$(DOCKER_COMPOSE) up -d -clean-classification: - ./clean-containers.sh classification +down: + docker compose -f src/$(DOCKER_COMPOSE) down -clean-ovms-server: clean-ovms-server-configs - ./clean-containers.sh ovms-server +run-demo: | download-models update-submodules download-sample-videos + @echo "Building automated self checkout app" + $(MAKE) build + @echo Running automated self checkout pipeline + $(MAKE) run-render-mode -clean-ovms: clean-profile-launcher clean-ovms-server +build-benchmark: + cd performance-tools && $(MAKE) build-benchmark-docker -clean-capi_face_detection: - ./clean-containers.sh capi_face_detection +benchmark: build-benchmark download-models + cd performance-tools/benchmark-scripts && python benchmark.py --compose_file ../../src/docker-compose.yml --pipeline $(PIPELINE_COUNT) -clean-capi_yolov5: - ./clean-containers.sh capi_yolov5 +benchmark-stream-density: build-benchmark download-models + cd performance-tools/benchmark-scripts && python benchmark.py --compose_file ../../src/docker-compose.yml --target_fps $(TARGET_FPS) -clean-capi_yolov5_ensemble: - ./clean-containers.sh capi_yolov5_ensemble +build-telegraf: + cd telegraf && $(MAKE) build -clean-capi_yolov8_ensemble: - ./clean-containers.sh capi_yolov8_ensemble +run-telegraf: + cd telegraf && $(MAKE) run clean-telegraf: ./clean-containers.sh influxdb2 ./clean-containers.sh telegraf -clean-webcam: - ./clean-containers.sh webcam +run-portainer: + docker compose -p portainer -f docker-compose-portainer.yml up -d down-portainer: docker compose -p portainer -f docker-compose-portainer.yml down -down-pipelines: - docker compose -f docker-compose.yml down - @if [ -f ./configs/opencv-ovms/models/2022/config.json ]; then rm ./configs/opencv-ovms/models/2022/config.json; fi; +clean-results: + rm -rf results/* -clean-all: clean clean-ovms clean-simulator clean-results clean-telegraf clean-webcam down-pipelines +clean-all: + docker rm -f $(docker ps -aq) docs: clean-docs mkdocs build @@ -149,86 +110,5 @@ serve-docs: docs-builder-image -w /docs \ $(MKDOCS_IMAGE) -build-grpc-python: build-profile-launcher - cd configs/opencv-ovms/grpc_python && $(MAKE) build - -build-grpc-go: build-profile-launcher - cd configs/opencv-ovms/grpc_go && $(MAKE) build - -build-python-apps: build-profile-launcher - cd configs/opencv-ovms/demos && make build - -build-capi_face_detection: build-profile-launcher - cd configs/opencv-ovms/gst_capi && DGPU_TYPE=$(DGPU_TYPE) $(MAKE) build_face_detection - -build-capi_yolov5: build-profile-launcher - cd configs/opencv-ovms/gst_capi && DGPU_TYPE=$(DGPU_TYPE) $(MAKE) build_capi_yolov5 - -build-capi_yolov5_ensemble: build-profile-launcher - cd configs/opencv-ovms/gst_capi && DGPU_TYPE=$(DGPU_TYPE) $(MAKE) build_capi_yolov5_ensemble - -build-capi_yolov8_ensemble: build-profile-launcher - cd configs/opencv-ovms/gst_capi && DGPU_TYPE=$(DGPU_TYPE) $(MAKE) build_capi_yolov8_ensemble - clean-docs: rm -rf docs/ - -clean-results: - sudo rm -rf results/* - -clean-ovms-server-configs: - @find ./configs/opencv-ovms/models/2022/ -mindepth 1 -maxdepth 1 -name 'config_ovms-server*.json' -delete - -list-profiles: - @echo "Here is the list of profile names, you may choose to use one of them for pipeline run script:" - @echo - @find ./configs/opencv-ovms/cmd_client/res/ -mindepth 1 -maxdepth 1 -type d -exec basename {} \; - @echo - @echo "Example: " - @echo "PIPELINE_PROFILE=\"grpc_python\" sudo -E ./run.sh --platform core --inputsrc rtsp://127.0.0.1:8554/camera_0" - -clean-models: - @find ./configs/opencv-ovms/models/2022/ -mindepth 1 -maxdepth 1 -type d -exec sudo rm -r {} \; - -unit-test-profile-launcher: - @cd ./configs/opencv-ovms/cmd_client && $(MAKE) unit-test - -webcam-rtsp: - docker run --rm \ - -v $(PWD)/camera-simulator/mediamtx.yml:/mediamtx.yml \ - -d \ - -p 8554:8554 \ - --device=/dev/video0 \ - --name webcam \ - bluenviron/mediamtx:latest-ffmpeg - -run-smoke-tests: - @echo "Running smoke tests for OVMS profiles" - @./run_smoke_test.sh > smoke_tests_output.log - @echo "results of smoke tests recorded in the file smoke_tests_output.log" - @grep "Failed" ./smoke_tests_output.log || true - @grep "===" ./smoke_tests_output.log || true - -hadolint: - @echo "Run hadolint..." - @docker run --rm -v `pwd`:/automated-self-checkout --entrypoint /bin/hadolint hadolint/hadolint:latest \ - --config /automated-self-checkout/.github/.hadolint.yaml \ - `sudo find * -type f -name 'Dockerfile*' | xargs -i echo '/automated-self-checkout/{}'` | grep error \ - | grep -v model_server \ - || echo "no issue found" - -run-demo: - @echo "Building python apps" - $(MAKE) build-python-apps - @echo "Downloading sample videos" - cd benchmark-scripts && ./download_sample_videos.sh - @echo "Running camera simulator" - $(MAKE) run-camera-simulator - @echo Running Object_detection gRPC pipeline - PIPELINE_PROFILE="object_detection" RENDER_MODE=1 sudo -E ./run.sh --platform core --inputsrc rtsp://127.0.0.1:8554/camera_1 - -run-cached-demo: - @echo "Running camera simulator" - $(MAKE) run-camera-simulator - @echo Running Object_detection gRPC pipeline - PIPELINE_PROFILE="object_detection" RENDER_MODE=1 sudo -E ./run.sh --platform core --inputsrc rtsp://127.0.0.1:8554/camera_1 diff --git a/README.md b/README.md index 396f87f8..e56c1c6b 100644 --- a/README.md +++ b/README.md @@ -6,22 +6,13 @@ ![DockerImageBuild](https://github.com/intel-retail/automated-self-checkout/actions/workflows/build.yaml/badge.svg?branch=main) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/intel-retail/automated-self-checkout/badge)](https://api.securityscorecards.dev/projects/github.com/intel-retail/automated-self-checkout) [![GitHub Latest Stable Tag](https://img.shields.io/github/v/tag/intel-retail/automated-self-checkout?sort=semver&label=latest-stable)](https://github.com/intel-retail/automated-self-checkout/releases) -[![Discord](https://discord.com/api/guilds/1150892043120414780/widget.png?style=shield)](https://discord.gg/ZHgtrZcu) +[![Discord](https://discord.com/api/guilds/1150892043120414780/widget.png?style=shield)](https://discord.gg/2SpNRF4SCn) > **Warning** > The **main** branch of this repository contains work-in-progress development code for the upcoming release, and is **not guaranteed to be stable or working**. > > **The source for the latest release can be found at [Releases](https://github.com/intel-retail/automated-self-checkout/releases).** -## Table of Contents - -- [Prerequisites](#prerequisites) -- [QuickStart](#quickstart) -- [Documentation](#documentation) -- [Known issues](#known-issues) -- [Disclaimer](#disclaimer) -- [Datasets & Models Disclaimer](#datasets--models-disclaimer) - ## Prerequisites - [Docker](https://docs.docker.com/engine/install/ubuntu/) @@ -31,77 +22,28 @@ ## QuickStart -0. Simply run: - (If this is the first time, it will take some time to download videos, models, docker images and build containers) ``` make run-demo ``` -More detailed instructions: - -1. Build the project - -``` -make build-python-apps -``` - -2. Download sample videos -``` -cd benchmark-scripts -./download_sample_videos.sh -``` - -3. Run camera simulator: - -(Go back to the root directory) - -``` -cd .. -make run-camera-simulator -``` - -4. Run object detection: +stop containers: -(This first command will take some time while it downloads the models for the first time) ``` -PIPELINE_PROFILE="object_detection" RENDER_MODE=1 sudo -E ./run.sh --platform core --inputsrc rtsp://127.0.0.1:8554/camera_1 +make down ``` -
- -Repeat the same command changing PIPELINE_PROFILE to "classification" or "instance_segmentation" - -You can check the pipeline's results by following this [guide](https://intel-retail.github.io/automated-self-checkout/OVMS/quick_pipelinerun.html#run-instance-segmentation) -For more advanced parameters, follow this [guide](https://intel-retail.github.io/automated-self-checkout/OVMS/pipelinerun.html#run-pipeline-with-different-input-sourceinputsrc-types) - -5. Tear everything down: - -``` -make clean-all -``` +## [Advanced Documentation](https://intel-retail.github.io/automated-self-checkout/) ## Join the community -[![Discord Banner 1](https://discordapp.com/api/guilds/1150892043120414780/widget.png?style=banner2)](https://discord.gg/ZHgtrZcu) +[![Discord Banner 1](https://discordapp.com/api/guilds/1150892043120414780/widget.png?style=banner2)](https://discord.gg/2SpNRF4SCn) -## Documentation +## References -- [Open source code for setup, install, and execution of software, with complete developer documentation](https://intel-retail.github.io/automated-self-checkout/) - [Developer focused website to enable developers to engage and build our partner community](https://www.intel.com/content/www/us/en/developer/articles/reference-implementation/automated-self-checkout.html) -- [LinkedIn blog illustrating the automated self checkout use case more in detail](https://www.linkedin.com/pulse/retail-innovation-unlocked-open-source-vision-enabled-mohideen/) - -## Smoke tests - -Smoke tests can be run from the command line: -- to run smoke tests for pipelines: `make run-smoke-tests` -- to run smoke tests for benchmark: `(cd ./benchmark-scripts || true; ./smoke_test_benchmark.sh)` (this can take long time because of stream density test) - -## Known issues - -- Once barcode is detected and decoded, barcode label text is displayed inside the object even if barcode is not visible. -- Overlapping object detection label (gvatrack adds its own labels) +- [LinkedIn blog illustrating the automated self checkout use case more in detail](https://www.linkedin.com/pulse/retail-innovation-unlocked-open-source-vision-enabled-mohideen/) ## Disclaimer diff --git a/benchmark-scripts/Dockerfile.benchmark b/benchmark-scripts/Dockerfile.benchmark deleted file mode 100644 index 54f8d289..00000000 --- a/benchmark-scripts/Dockerfile.benchmark +++ /dev/null @@ -1,49 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -FROM ubuntu:22.04 -ARG SERVER_GPU - -RUN echo $HTTP_PROXY -RUN if [ -n "$HTTP_PROXY" ] ; then echo "Acquire::http::Proxy \"$HTTP_PROXY\";" > /etc/apt/apt.conf; fi -RUN apt-get update -y || true; DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - wget \ - git \ - iotop \ - sysstat \ - jq \ - curl \ - cmake \ - python3-pip \ - build-essential \ - docker.io \ - pciutils - -COPY requirements.txt . - -RUN pip3 install -r requirements.txt - -RUN if [ -d "/opt/intel/pcm" ] ; then rm -R /opt/intel/pcm; fi - -ENV PCM_DIRECTORY=/opt/intel -RUN echo "Installing PCM" \ - [ ! -d "$PCM_DIRECTORY" ] && mkdir -p "$PCM_DIRECTORY" -RUN cd $PCM_DIRECTORY && \ - git clone --recursive https://github.com/opcm/pcm.git && \ - ls ${PCM_DIRECTORY} && \ - cd $PCM_DIRECTORY/pcm && \ - mkdir build && \ - cd build && \ - cmake .. && \ - cmake --build . - -# Cleanup -RUN mkdir -p "/opt/intel/pcm-bin/bin" && mkdir -p "/opt/intel/pcm-bin/lib" && \ - cp -r "$PCM_DIRECTORY/pcm/build/bin" "/opt/intel/pcm-bin/" && \ - cp -r "$PCM_DIRECTORY/pcm/build/lib" "/opt/intel/pcm-bin/" && \ - rm -rf "$PCM_DIRECTORY/pcm" - -COPY . . diff --git a/benchmark-scripts/Dockerfile.igt b/benchmark-scripts/Dockerfile.igt deleted file mode 100644 index 1f5ab08c..00000000 --- a/benchmark-scripts/Dockerfile.igt +++ /dev/null @@ -1,36 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - - -FROM ubuntu:20.04 -RUN if [ -n "$HTTP_PROXY" ] ; then echo "Acquire::http::Proxy \"$HTTP_PROXY\";" > /etc/apt/apt.conf; fi -RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - build-essential \ - ca-certificates \ - git \ - cmake \ - libunwind-dev \ - libgsl-dev \ - libasound2-dev \ - libxmlrpc-core-c3-dev \ - libjson-c-dev \ - libcurl4-openssl-dev \ - python-docutils \ - valgrind \ - peg \ - libdrm-intel1 \ - pkg-config libdrm-dev libkmod-dev libprocps-dev libdw-dev libpixman-1-dev libcairo-dev libudev-dev flex bison \ - meson && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* - -# Install igt -WORKDIR /igt - -# Install 1.27.1 -RUN git config --global http.proxy $HTTP_PROXY; git clone https://gitlab.freedesktop.org/drm/igt-gpu-tools.git; cd igt-gpu-tools; git checkout 2b29e8ac07fbcfadc48b9d60e4d736a6e3b289ab - -RUN cd igt-gpu-tools; meson build; ninja -C build; cd build; ninja install diff --git a/benchmark-scripts/Dockerfile.xpu b/benchmark-scripts/Dockerfile.xpu deleted file mode 100644 index ebb69350..00000000 --- a/benchmark-scripts/Dockerfile.xpu +++ /dev/null @@ -1,92 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -FROM ubuntu:22.04 as builder -ENV HOME=/home/nobody -ENV no_proxy=localhost,127.0.0.1 -ENV NO_PROXY=localhost,127.0.0.1 - -# don't ask anything -ARG DEBIAN_FRONTEND=noninteractive - -RUN apt-get update && \ -apt-get install -y --no-install-recommends \ - python3 \ - python3-pip \ - python3-venv && \ -rm -rf /var/lib/apt/lists/* - -RUN python3 -m venv /opt/venv -ENV PATH="/opt/venv/bin:$PATH" -COPY requirements-xpu.txt /requirements.txt -RUN pip install -r /requirements.txt -RUN pip install gunicorn[gthread] -WORKDIR /opt/venv -RUN find . -name "pip*" -exec rm -rf {} \; ;exit 0 -RUN find . -name "*normalizer*" -exec rm -rf {} \; ;exit 0 -RUN find . -name "activate*" -exec rm -rf {} \; ;exit 0 -RUN find . -name "Activate*" -exec rm -rf {} \; ;exit 0 -RUN find . -name "python-wheels" -exec rm -rf {} \; ;exit 0 -RUN find . -name "easy_install*" -exec rm -rf {} \; ;exit 0 -RUN find . -name "setuptools*" -exec rm -rf {} \; ;exit 0 -RUN find . -name "__pycache__" -exec rm -rf {} \; ;exit 0 - -FROM ubuntu:22.04 - -ENV HOME=/home/nobody -ENV no_proxy=localhost,127.0.0.1 -ENV NO_PROXY=localhost,127.0.0.1 - -# don't ask anything -ARG DEBIAN_FRONTEND=noninteractive - -WORKDIR /tmp/work - -RUN apt-get update && \ - apt-get install -y --no-install-recommends wget gnupg2 ca-certificates && \ - wget -qO - https://repositories.intel.com/graphics/intel-graphics.key | gpg --dearmor --output /usr/share/keyrings/intel-graphics.gpg && \ - wget https://github.com/intel/xpumanager/releases/download/V1.2.24/xpumanager_1.2.24_20231120.070911.ddc18e8a.u22.04_amd64.deb && \ - echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/graphics/ubuntu jammy flex' | \ - tee /etc/apt/sources.list.d/intel.gpu.jammy.list && \ - apt-get update && \ - apt-get install -y --no-install-recommends \ - dmidecode \ - python3 \ - libnl-genl-3-200 \ - libmfx-tools \ - intel-gsc \ - intel-level-zero-gpu \ - level-zero \ - libdrm2 && \ - apt-get remove -y wget gnupg2 ca-certificates && \ - apt-get autoremove -y && \ - rm -rf /var/lib/apt/lists/* - -COPY --from=builder /opt/venv /opt/venv - -RUN ldconfig && dpkg -i --force-all *.deb - -WORKDIR / - -ENV PATH="/opt/venv/bin:$PATH" - -# set up entry point -RUN /bin/echo -e "#!/bin/sh\n\ -export PYTHONUNBUFFERED=1\n\ -socket_folder=\${XPUM_SOCKET_FOLDER:-/tmp}\n\ -rest_host=\${XPUM_REST_HOST:-0.0.0.0}\n\ -rest_port=\${XPUM_REST_PORT:-29999}\n\ -rest_no_tls=\${XPUM_REST_NO_TLS:-0}\n\ -/usr/bin/xpumd -s \${socket_folder} &\n\ -until [ -e \${socket_folder}/xpum_p.sock ]; do sleep 0.1; done\n\ -if [ \"\${rest_no_tls}\" != \"1\" ]\n\ -then\n\ - rest_tls_param=\"--certfile conf/cert.pem --keyfile conf/key.pem\"\n\ -fi\n\ -(cd /usr/lib/xpum/rest && exec gunicorn \${rest_tls_param} --bind \${rest_host}:\${rest_port} --worker-class gthread --threads 10 --worker-connections 1000 -w 1 'xpum_rest_main:main()')\n\ -" >> /entry_point.sh && chmod +x /entry_point.sh - -ENTRYPOINT ["/entry_point.sh"] diff --git a/benchmark-scripts/Makefile b/benchmark-scripts/Makefile deleted file mode 100644 index d1e72c24..00000000 --- a/benchmark-scripts/Makefile +++ /dev/null @@ -1,20 +0,0 @@ - -build-all: build-benchmark build-xpu build-igt - -build-benchmark: - echo "Building benchmark container HTTPS_PROXY=${HTTPS_PROXY} HTTP_PROXY=${HTTP_PROXY}" - docker build --build-arg HTTPS_PROXY=${HTTPS_PROXY} --build-arg HTTP_PROXY=${HTTP_PROXY} -t benchmark:dev -f Dockerfile.benchmark . - -build-xpu: - echo "Building xpu HTTPS_PROXY=${HTTPS_PROXY} HTTP_PROXY=${HTTP_PROXY}" - docker build --build-arg HTTPS_PROXY=${HTTPS_PROXY} --build-arg HTTP_PROXY=${HTTP_PROXY} -t benchmark:xpu -f Dockerfile.xpu . - -build-igt: - echo "Building igt HTTPS_PROXY=${HTTPS_PROXY} HTTP_PROXY=${HTTP_PROXY}" - docker build --build-arg HTTPS_PROXY=${HTTPS_PROXY} --build-arg HTTP_PROXY=${HTTP_PROXY} -t benchmark:igt -f Dockerfile.igt . - -run: - docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock -v `pwd`/results:/tmp/results --net=host --privileged benchmark:dev /bin/bash - -consolidate: - docker run -itd -v `pwd`/$(ROOT_DIRECTORY):/$(ROOT_DIRECTORY) -e ROOT_DIRECTORY=$(ROOT_DIRECTORY)--net=host --privileged benchmark:dev /bin/bash -c "python3 consolidate_multiple_run_of_metrics.py --root_directory $(ROOT_DIRECTORY)/ --output $(ROOT_DIRECTORY)/summary.csv" \ No newline at end of file diff --git a/benchmark-scripts/benchmark.sh b/benchmark-scripts/benchmark.sh deleted file mode 100755 index 884e9cfb..00000000 --- a/benchmark-scripts/benchmark.sh +++ /dev/null @@ -1,365 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -error() { - printf '%s\n' "$1" >&2 - exit 1 -} - -show_help() { - echo " - usage: PIPELINE_PROFILE=\"object_detection\" (or others from make list-profiles) sudo -E ./$0 - --performance_mode the system performance setting [powersave | performance] - --pipelines NUMBER_OF_PIPELINES | --stream_density TARGET_FPS [PIPELINE_INCREMENT] - --logdir FULL_PATH_TO_DIRECTORY - --duration SECONDS (not needed when --stream_density is specified) - --init_duration SECONDS - --platform core|xeon|dgpu.x - --inputsrc RS_SERIAL_NUMBER|CAMERA_RTSP_URL|file:video.mp4|/dev/video0 - - Note: - 1. dgpu.x should be replaced with targetted GPUs such as dgpu (for all GPUs), dgpu.0, dgpu.1, etc - 2. filesrc will utilize videos stored in the sample-media folder - 3. Set environment variable STREAM_DENSITY_MODE=1 for starting single container stream density testing - 4. Set environment variable RENDER_MODE=1 for displaying pipeline and overlay CV metadata - 5. Stream density can take two parameters: first one TARGET_FPS is for target fps, a float type value, and - the second one PIPELINE_INCREMENT is increment integer of pipelines and is optional (in which case the increments will be dynamically adjusted internally) - " -} - -OPTIONS_TO_SKIP=0 -PERFORMANCE_MODE=powersave -DOCKER_RUN_ARGS="" - -get_options() { - while :; do - case $1 in - -h | -\? | --help) - show_help - exit - ;; - --performance_mode) - if [ -z "$2" ]; then - break - fi - - if [ "$2" == "powersave" ] || [ "$2" == "performance" ]; then - PERFORMANCE_MODE="$2" - fi - echo "performance_mode: $PERFORMANCE_MODE" - OPTIONS_TO_SKIP=$(( OPTIONS_TO_SKIP + 1 )) - shift - ;; - --pipelines) - if [ -z "$2" ]; then - error 'ERROR: "--pipelines" requires an integer.' - fi - - PIPELINE_COUNT=$2 - echo "pipelines: $PIPELINE_COUNT" - OPTIONS_TO_SKIP=$(( $OPTIONS_TO_SKIP + 1 )) - shift - ;; - --stream_density) - if [ -z "$2" ]; then - error 'ERROR: "--stream_density" requires an integer for target fps.' - fi - - STREAM_DENSITY_INCREMENTS="" - PIPELINE_COUNT=1 - STREAM_DENSITY_FPS=$2 - if [[ "$3" =~ ^--.* ]]; then - echo "INFO: --stream_density no increment number configured; will be dynamically adjusted internally" - else - STREAM_DENSITY_INCREMENTS=$3 - OPTIONS_TO_SKIP=$(( $OPTIONS_TO_SKIP + 1 )) - shift - fi - echo "stream_density: target fps = $STREAM_DENSITY_FPS increments = $STREAM_DENSITY_INCREMENTS" - OPTIONS_TO_SKIP=$(( $OPTIONS_TO_SKIP + 1 )) - shift - ;; - --logdir) - if [ -z "$2" ]; then - error 'ERROR: "--logdir" requires an path to a directory.' - fi - - LOG_DIRECTORY=$2 - echo "logdir: $LOG_DIRECTORY" - OPTIONS_TO_SKIP=$(( $OPTIONS_TO_SKIP + 1 )) - shift - ;; - --duration) - if [ -z "$2" ]; then - error 'ERROR: "--duration" requires an integer.' - fi - - DURATION=$2 - echo "duration: $DURATION" - OPTIONS_TO_SKIP=$(( $OPTIONS_TO_SKIP + 1 )) - shift - ;; - --init_duration) - if [ -z "$2" ]; then - error 'ERROR: "--init_duration" requires an integer.' - fi - - OPTIONS_TO_SKIP=$(( $OPTIONS_TO_SKIP + 1 )) - COMPLETE_INIT_DURATION=$2 - echo "init_duration: $COMPLETE_INIT_DURATION" - shift - ;; - --*) - DOCKER_RUN_ARGS="$DOCKER_RUN_ARGS $1" - ;; - ?*) - DOCKER_RUN_ARGS="$DOCKER_RUN_ARGS $1" - ;; - *) - break - ;; - esac - - OPTIONS_TO_SKIP=$(( $OPTIONS_TO_SKIP + 1 )) - shift - - done -} - - -# USAGE: -# 1. PLATFORM: core|xeon|dgpu.x -# 2. INPUT SOURCE: RS_SERIAL_NUMBER|CAMERA_RTSP_URL|file:video.mp4|/dev/video0 -# 3. PIPELINE_NUMBER: the number of pipelines to start or specify MAX and a stream density benchmark will be performed with a 15 fps target per pipeline -# 4. LOG_DIRECTORY: the location to store all the log files. The consolidation script will look for directories within the top level directory and process the results in each one so the user will want to keep in mind this structure when creating the log directory. For example, for multiple videos with different number of objects, a log_directory would look like: yolov5s_6330N/object1_mixed. Whatever is meaningful for the test run. -# 5. DURATION: the amount of time to run the data collection -# 6 COMPLETE_INIT_DURATION: the amount of time to allow the system to settle prior to starting the data collection. - -# load benchmark params -if [ -z $1 ] -then - show_help -fi -get_options "$@" - -# load run params -shift $OPTIONS_TO_SKIP -# the following syntax for arguments is meant to be re-splitting for correctly used on all $DOCKER_RUN_ARGS -# shellcheck disable=SC2068 -set -- $@ $DOCKER_RUN_ARGS -echo "arguments passing to get-optons.sh" "$@" -source ../get-options.sh "$@" - -# set performance mode -echo "Setting scaling_governor to perf mode" -echo "$PERFORMANCE_MODE" | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor - -# clean log directory that is being reused -if [ -d $LOG_DIRECTORY ]; then rm -Rf $LOG_DIRECTORY; fi - -if [ ! -d $LOG_DIRECTORY ]; then mkdir -p $LOG_DIRECTORY; fi - -# clean previous meta data -rm -f results/* -rm -f ../results/* - -# NOTE: pcm-memory and pcm-power only support xeon platform. Need to use pcm for core platform -# NOTE: need to separate into 2 run for xeon as pcm-power and pcm-memory cannot run in parallel -is_xeon=`lscpu | grep -i xeon | wc -l` -if [ "$is_xeon" == "1" ] -then - run_index=2 -else - run_index=1 -fi - -distributed=0 -echo "RunIndex $run_index" -for test_run in $( seq 0 $(($run_index - 1)) ) -do - echo "Entered loop" - # Start camera-simulator if rtsp is requested - if grep -q "rtsp" <<< "$INPUTSRC"; then - echo "Starting RTSP stream" - ./camera-simulator.sh - sleep 5 - fi - echo "Starting workload(s)" - - - source get-gpu-info.sh - NUM_GPU=0 - if [ "$HAS_FLEX_140" == 1 ] - then - NUM_GPU=$GPU_NUM_140 - elif [ "$HAS_FLEX_170" == 1 ] - then - NUM_GPU=$GPU_NUM_170 - fi - - # run.sh needs to run in it's directory for the file paths to work - cd ../ -# pwd - - echo "DEBUG: run.sh" "$@" - - for pipelineIdx in $( seq 0 $((PIPELINE_COUNT - 1)) ) - do - if [ -z "$STREAM_DENSITY_FPS" ]; then - isCapi=$(docker run --rm -v "${PWD}":/workdir mikefarah/yq '.OvmsSingleContainer' /workdir/configs/opencv-ovms/cmd_client/res/"$PIPELINE_PROFILE"/configuration.yaml) - if [ "$isCapi" = false ] - then - echo "multiple pipelines for non-capi case..." - while true - do - containerCnt=$(docker ps -aq -f name="_ovms_pl" | wc -w) - if [ "$containerCnt" -lt "$pipelineIdx" ] - then - echo "pipelineIdx=$pipelineIdx, containerCnt=$containerCnt" - echo "waiting for the previous pipeline container to start up..." - sleep 1 - else - break - fi - done - fi - echo "Starting pipeline$pipelineIdx" - if [ "$CPU_ONLY" != 1 ] && ([ "$HAS_FLEX_140" == 1 ] || [ "$HAS_FLEX_170" == 1 ]) - then - if [ "$NUM_GPU" != 0 ] - then - gpu_index=$(expr $pipelineIdx % $NUM_GPU) - # replacing the value of --platform with dgpu.$gpu_index for flex case - orig_args=("$@") - for ((i=0; i < $#; i++)) - do - if [ "${orig_args[i]}" == "--platform" ] - then - IFS=" " read -r -a arrgpu <<< "${orig_args[i+1]//./ }" - TARGET_GPU_NUMBER=${arrgpu[1]} - if [ -z "$TARGET_GPU_NUMBER" ] || [ "$distributed" == 1 ]; then - set -- "${@:1:i+1}" "dgpu.$gpu_index" "${@:i+3}" - distributed=1 - fi - break - fi - done - LOW_POWER=$LOW_POWER DEVICE=$DEVICE ./run.sh "$@" - else - echo "Error: NUM_GPU is 0, cannot run" - exit 1 - fi - else - CPU_ONLY=$CPU_ONLY LOW_POWER=$LOW_POWER DEVICE=$DEVICE ./run.sh "$@" - fi - sleep 1 - #popd - else - echo "Starting stream density benchmarking" - #cleanup any residual containers - mapfile -t sids < <(docker ps --filter="name=automated-self-checkout" -q -a) - if [ "${#sids[@]}" -eq 0 ] - then - echo "no dangling docker containers to clean up" - else - for sid in "${sids[@]}" - do - echo "cleaning up dangling container $sid" - docker rm $sid -f - done - fi - - DURATION=0 - #pushd .. - #echo "Cur dir: `pwd`" - # Sync sleep in stream density script and platform metrics data collection script - CPU_ONLY=$CPU_ONLY LOW_POWER=$LOW_POWER COMPLETE_INIT_DURATION=$COMPLETE_INIT_DURATION \ - STREAM_DENSITY_FPS=$STREAM_DENSITY_FPS STREAM_DENSITY_INCREMENTS=$STREAM_DENSITY_INCREMENTS \ - STREAM_DENSITY_MODE=1 DEVICE=$DEVICE ./run.sh "$@" - #popd - fi - done - cd - || { echo "ERROR: failed to change back the previous directory"; exit 1; } - - echo "Waiting for init duration to complete..." - sleep $COMPLETE_INIT_DURATION - - # launch log file monitor to detect if any pipeline stall happening - POLLING_INTERVAL=2 - ./log_time_monitor.sh ../results/ $POLLING_INTERVAL $PIPELINE_COUNT > $LOG_DIRECTORY/log_time_monitor$test_run.log & - log_time_monitor_pid=$! - - SOURCE_DIR=`pwd` - echo $SOURCE_DIR - - if [ $test_run -eq 0 ] - then - docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock -e test_run=$test_run -e LOG_DIRECTORY=$LOG_DIRECTORY -e SOURCE_DIR=$SOURCE_DIR -v $SOURCE_DIR/results:/tmp/results -v $SOURCE_DIR/$LOG_DIRECTORY:/$LOG_DIRECTORY --net=host --privileged benchmark:dev bash -c "./collect_platform_metrics.sh $DURATION $LOG_DIRECTORY $PLATFORM" - else - docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock -e test_run=$test_run -e LOG_DIRECTORY=$LOG_DIRECTORY -e SOURCE_DIR=$SOURCE_DIR -v $SOURCE_DIR/results:/tmp/results -v $SOURCE_DIR/$LOG_DIRECTORY:/$LOG_DIRECTORY --net=host --privileged benchmark:dev bash -c "./collect_platform_metrics.sh $DURATION $LOG_DIRECTORY $PLATFORM --xeon-memory-only" - fi - - if [ -z "$STREAM_DENSITY_FPS" ] - then - echo "Waiting $DURATION seconds for workload to finish" - else - echo "Waiting for workload(s) to finish..." - waitingMsg=1 - - # keep looping through until stream density script is done - while true - do - # stream density is running from profile-launcer so we check that executing process - stream_density_running=$(pgrep -fa "stream_density.sh") - if [ -z "$stream_density_running" ] - then - # when the stream-density is done, we should clean up the profile-launcer process - proifleLauncherPid=$(pgrep -f "profile-launcher") - if [ -n "$proifleLauncherPid" ] - then - pkill -P "$proifleLauncherPid" - echo "profile-launcher is done" - fi - break - else - if [ $waitingMsg -eq 1 ] - then - echo "stream density script is still running..." - waitingMsg=0 - fi - fi - # there are still some pipeline running containers, waiting for them to be finished... - sleep 1 - done - fi - - echo "workloads finished..." - if [ -e ../results/r0.jsonl ] - then - sudo ./copy-platform-metrics.sh $LOG_DIRECTORY - python3 ./results_parser.py | sudo tee -a meta_summary.txt > /dev/null - sudo mv meta_summary.txt $LOG_DIRECTORY - fi - - - sleep 2 - - # before kill the process check if it is already gone - if ps -p $log_time_monitor_pid > /dev/null - then - kill -9 $log_time_monitor_pid - while ps -p $log_time_monitor_pid > /dev/null - do - echo "$log_time_monitor_pid is still running" - sleep 1 - done - fi - - ./stop_server.sh - sleep 5 - -done # loop for test runs \ No newline at end of file diff --git a/benchmark-scripts/camera-simulator.sh b/benchmark-scripts/camera-simulator.sh deleted file mode 100755 index 9f5d0849..00000000 --- a/benchmark-scripts/camera-simulator.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash -e -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -COMMAND=$1 -SOURCE_DIR="$(dirname "$(dirname "$(readlink -f "$0")")")" -CAMERAS=$2 - -if [ -z "$COMMAND" ]; then - COMMAND="START" -fi - -if [ "${COMMAND,,}" = "start" ]; then - - cd $SOURCE_DIR/sample-media - FILES=( *.mp4 ) - - if [ -z "$CAMERAS" ]; then - CAMERAS=${#FILES[@]} - fi - - cd $SOURCE_DIR/camera-simulator - - docker run --rm -t --network=host --name camera-simulator aler9/rtsp-simple-server >rtsp_simple_server.log.txt 2>&1 & - index=0 - echo $CAMERAS - while [ $index -lt $CAMERAS ] - do - for file in "${FILES[@]}" - do - echo "Starting camera: rtsp://127.0.0.1:8554/camera_$index from $file" - docker run -t --rm --entrypoint ffmpeg --network host -v$SOURCE_DIR/sample-media:/home/pipeline-server/sample-media openvino/ubuntu20_data_runtime:2021.4.2 -nostdin -re -stream_loop -1 -i /home/pipeline-server/sample-media/$file -c copy -f rtsp -rtsp_transport tcp rtsp://localhost:8554/camera_$index >/dev/null 2>&1 & - ((index+=1)) - if [ $CAMERAS -le $index ]; then - break - fi - sleep 1 - done - done - -elif [ "${COMMAND,,}" = "stop" ]; then - docker kill camera-simulator -fi - diff --git a/benchmark-scripts/cleanup_gpu_metrics.sh b/benchmark-scripts/cleanup_gpu_metrics.sh deleted file mode 100755 index a0728581..00000000 --- a/benchmark-scripts/cleanup_gpu_metrics.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env bash -# USAGE LOG_DIRECTORY -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -fix_igt_json() { - echo "Fix IGT JSON called" - sed -i -e 's/^}$/},/' $1 - sed -i '$ s/.$//' $1 - tmp_file=/tmp/tmp.json - echo '[' > $tmp_file - cat $1 >> $tmp_file - echo ']' >> $tmp_file - mv $tmp_file $1 -} - -if [ -z "$1" ] -then - echo "Missing log_directory" - exit 1 -fi - -LOG_DIRECTORY=$1 - -echo "fixing igt and xpum for files in $LOG_DIRECTORY" -if [ -e ${LOG_DIRECTORY}/igt0.json ]; then - echo "fixing igt0.json" - fix_igt_json ${LOG_DIRECTORY}/igt0.json - #./fix_json.sh ${LOG_DIRECTORY} -fi -if [ -e ${LOG_DIRECTORY}/igt1.json ]; then - echo "fixing igt1.json" - fix_igt_json ${LOG_DIRECTORY}/igt1.json -fi - -#move the xpumanager dump files -devices=(0 1 2) -for device in "${devices[@]}"; do - xpum_file="${LOG_DIRECTORY}/device${device}*".csv - if [ -e $xpum_file ]; then - echo "==== Stopping xpumanager collection (device ${device}) ====" - cat $xpum_file | \ - python3 -c 'import csv, json, sys; print(json.dumps([dict(r) for r in csv.DictReader(sys.stdin)]))' > xpum${device}.json - mv xpum${device}.json ${LOG_DIRECTORY}/xpum${device}.json - fi -done diff --git a/benchmark-scripts/collect_platform_metrics.sh b/benchmark-scripts/collect_platform_metrics.sh deleted file mode 100755 index 2a1ae882..00000000 --- a/benchmark-scripts/collect_platform_metrics.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -BASE_XPUM_PORT=29990 -cpuOutputDir=/tmp/xpumdump/ - -show_help() { - echo " - usage: $0 DURATION LOG_DIRECTORY PLATFORM [--xeon-memory-only] - " -} - -start_xpum() { - metrics=0,5,22,24,25 - device=$1 - echo "==== Starting xpumanager capture (gpu $device) ====" - xpumPort=$(( BASE_XPUM_PORT + device )) || true - docker run -itd -v /sys/firmware/acpi/tables/MCFG:/pcm/sys/firmware/acpi/tables/MCFG:ro \ - -v /proc/bus/pci/:/pcm/proc/bus/pci/ -v /proc/sys/kernel/nmi_watchdog:/pcm/proc/sys/kernel/nmi_watchdog \ - -v "$SOURCE_DIR"/"$LOG_DIRECTORY":"$cpuOutputDir" \ - --cap-drop ALL --cap-add CAP_SYS_ADMIN --user root \ - -e XPUM_REST_NO_TLS=1 --device /dev/dri:/dev/dri --device /dev/cpu:/dev/cpu \ - --name=xpum"$device" benchmark:xpu - sleep 5 - docker exec xpum$device bash -c "xpumcli dump --rawdata --start -d $device -m $metrics -j" -} - -DURATION=$1 -LOG_DIRECTORY=$2 -PLATFORM=$3 -PCM_DIRECTORY=/opt/intel/pcm-bin/bin -source get-gpu-info.sh - -test_run=0 -if [ "$4" == "--xeon-memory-only" ] -then - test_run=1 -fi - -is_xeon=`lscpu | grep -i xeon | wc -l` - -echo "Starting platform data collection" -#if this is the first run, collect all the metrics -if [ $test_run -eq 0 ] -then - echo "Starting main data collection" - timeout "$DURATION" sar 1 >& $LOG_DIRECTORY/cpu_usage.log & - timeout "$DURATION" free -s 1 >& $LOG_DIRECTORY/memory_usage.log & - timeout "$DURATION" iotop -o -P -b >& $LOG_DIRECTORY/disk_bandwidth.log & - - if [ "$is_xeon" == "1" ] - then - echo "Starting xeon pcm-power collection" - timeout "$DURATION" $PCM_DIRECTORY/pcm-power >& $LOG_DIRECTORY/power_usage.log & - else - echo "Starting xeon pcm-power collection" - timeout "$DURATION" $PCM_DIRECTORY/pcm 1 -silent -nc -nsys -csv=$LOG_DIRECTORY/pcm.csv & - fi - - # DGPU pipeline and Flex GPU Metrics - if [ "$PLATFORM" == "dgpu" ] && [ $HAS_ARC == 0 ] - then - metrics=0,5,22,24,25 - device=0 - # Check for up to 4 GPUs e.g. 300W max - if [ -e /dev/dri/renderD128 ]; then - device=0 - echo "==== Found device $device ====" - start_xpum "$device" - fi - if [ -e /dev/dri/renderD129 ]; then - device=1 - echo "==== Found device $device ====" - start_xpum "$device" - fi - if [ -e /dev/dri/renderD130 ]; then - device=2 - echo "==== Found device $device ====" - start_xpum "$device" - fi - if [ -e /dev/dri/renderD131 ]; then - device=3 - echo "==== Found device $device ====" - start_xpum "$device" - fi - # DGPU pipeline and Arc GPU Metrics - elif [ "$PLATFORM" == "dgpu" ] && [ $HAS_ARC == 1 ] - then - echo "==== Starting igt arc ====" - # Arc is always on Core platform and although its GPU.1, the IGT device is actually 0 - # Collecting both - # Swaping igt filename to align with GPU.0 or GPU.1 - timeout "$DURATION" docker run -v "$SOURCE_DIR"/"$LOG_DIRECTORY":/"$LOG_DIRECTORY" -e LOG_DIRECTORY="$LOG_DIRECTORY" -itd --privileged benchmark:igt bash -c "/usr/local/bin/intel_gpu_top -d pci:card=0 -J > /$LOG_DIRECTORY/igt1.json" - timeout "$DURATION" docker run -v "$SOURCE_DIR"/"$LOG_DIRECTORY":/"$LOG_DIRECTORY" -e LOG_DIRECTORY="$LOG_DIRECTORY" -itd --privileged benchmark:igt bash -c "/usr/local/bin/intel_gpu_top -d pci:card=1 -J > /$LOG_DIRECTORY/igt0.json" - - # CORE pipeline and iGPU/Arc GPU Metrics - elif [ "$PLATFORM" == "core" ] - then - if [ $HAS_ARC == 1 ] - then - echo "==== Starting igt arc ====" - # Core can only have at most 2 GPUs - timeout "$DURATION" docker run -v "$SOURCE_DIR"/"$LOG_DIRECTORY":/"$LOG_DIRECTORY" -e LOG_DIRECTORY="$LOG_DIRECTORY" -itd --privileged benchmark:igt bash -c "/usr/local/bin/intel_gpu_top -d pci:card=0 -J > /$LOG_DIRECTORY/igt1.json" - timeout "$DURATION" docker run -v "$SOURCE_DIR"/"$LOG_DIRECTORY":/"$LOG_DIRECTORY" -e LOG_DIRECTORY="$LOG_DIRECTORY" -itd --privileged benchmark:igt bash -c "/usr/local/bin/intel_gpu_top -d pci:card=1 -J > /$LOG_DIRECTORY/igt0.json" - else - echo "==== Starting igt core ====" - timeout "$DURATION" docker run -v "$SOURCE_DIR"/"$LOG_DIRECTORY":/"$LOG_DIRECTORY" -e LOG_DIRECTORY="$LOG_DIRECTORY" -itd --privileged benchmark:igt bash -c "/usr/local/bin/intel_gpu_top -d pci:card=0 -J > /$LOG_DIRECTORY/igt0.json" - fi - fi -#if this is the second run, collect memory bandwidth data only -else - if [ "$is_xeon" == "1" ] - then - # this script is actually called by ./benchmark.sh shell script through the docker container benchmark:dev, so we don't need another docker run here any more - timeout "$DURATION" "$PCM_DIRECTORY"/pcm-memory 1 -silent -nc -csv="$LOG_DIRECTORY"/memory_bandwidth.csv & - fi -fi - -if [ "$DURATION" == "0" ] -then - echo "Data collection running until max stream density is reached" -else - echo "Data collection will run for $DURATION seconds" -fi -sleep $DURATION - -echo "stopping platform data collection..." -pkill -f iotop -pkill -f free -pkill -f sar -pkill -f pcm-power -pkill -f pcm -pkill -f xpumcli -pkill -f intel_gpu_top -pkill -f pcm-memory -sleep 2 - -echo "test_run is: $test_run" -if [ $test_run -eq 0 ] -then - ./cleanup_gpu_metrics.sh $LOG_DIRECTORY -fi diff --git a/benchmark-scripts/consolidate_multiple_run_of_metrics.py b/benchmark-scripts/consolidate_multiple_run_of_metrics.py deleted file mode 100644 index 232caec4..00000000 --- a/benchmark-scripts/consolidate_multiple_run_of_metrics.py +++ /dev/null @@ -1,544 +0,0 @@ -''' -* Copyright (C) 2023 Intel Corporation. -* -* SPDX-License-Identifier: Apache-2.0 -''' - -import pathlib -import datetime -import argparse -from abc import ABC, abstractmethod -from statistics import mean -import os -import re -import fnmatch -import numpy as np -import pandas as pd -from collections import defaultdict -from natsort import natsorted -from operator import add -import json - -# constants -AVG_CPU_USAGE_CONSTANT = "CPU Utilization %" -AVG_GPU_USAGE_CONSTANT = "GPU Utilization %" -AVG_GPU_MEM_USAGE_CONSTANT = "Memory Utilization %" -AVG_GPU_COMPUTE_USAGE_CONSTANT = "Compute Utilization %" -AVG_GPU_VDBOX_USAGE_CONSTANT = "Utilization %" - -AVG_DISK_READ_BANDWIDTH_CONSTANT = "Disk Read MB/s" -AVG_DISK_WRITE_BANDWIDTH_CONSTANT = "Disk Write MB/s" -AVG_MEM_USAGE_CONSTANT = "Memory Utilization %" -AVG_POWER_USAGE_CONSTANT = "Power Draw W" -AVG_MEM_BANDWIDTH_CONSTANT = "Memory Bandwidth Usage MB/s" -AVG_FPS_CONSTANT = "FPS" -LAST_MODIFIED_LOG = "Last log update" -TEXT_COUNT_CONSTANT = "Total Text count" -BARCODE_COUNT_CONSTANT = "Total Barcode count" - -class KPIExtractor(ABC): - @abstractmethod - def extract_data(self, log_file_path): - pass - - @abstractmethod - def return_blank(self): - pass - -class CPUUsageExtractor(KPIExtractor): - _SAR_CPU_USAGE_PATTERN = "(\\d\\d:\\d\\d:\\d\\d)\\s+(\\w+)\\s+(\\d+.\\d+)\\s+(\\d+.\\d+)\\s+(\\d+.\\d+)\\s+(\\d+.\\d+)\\s+(\\d+.\\d+)\\s+(\\d+.\\d+)" - _IDLE_CPU_PERCENT_GROUP = 8 - - #overriding abstract method - def extract_data(self, log_file_path): - if os.path.getsize(log_file_path) == 0: - return {AVG_CPU_USAGE_CONSTANT: "NA"} - - print("parsing CPU usages") - sar_cpu_usage_row_p = re.compile(self._SAR_CPU_USAGE_PATTERN) - cpu_usages = [] - with open(log_file_path) as f: - for line in f: - sar_cpu_usage_row_m= sar_cpu_usage_row_p.match(line) - if sar_cpu_usage_row_m: - idle_cpu_percentage = float(sar_cpu_usage_row_m.group(self._IDLE_CPU_PERCENT_GROUP)) - cpu_usages.append(float(100) - idle_cpu_percentage) - if len(cpu_usages) > 0: - return {AVG_CPU_USAGE_CONSTANT: mean(cpu_usages)} - else: - return {AVG_CPU_USAGE_CONSTANT: "NA"} - - def return_blank(self): - return {AVG_CPU_USAGE_CONSTANT: "NA"} - - -class GPUUsageExtractor(KPIExtractor): - _USAGE_PATTERN = "Render/3D/0" - #overriding abstract method - def extract_data(self, log_file_path): - print("parsing GPU usages") - #print("log file path: {}".format(log_file_path)) - device = re.findall(r'\d+', os.path.basename(log_file_path)) - # The correct field to calculate GPU utilization is [unknown]/0 on ARC - if device[0] == '0': - self._USAGE_PATTERN = "[unknown]/0" - elif device[0] == '1': - self._USAGE_PATTERN = "Render/3D/0" - #print("device number: {}".format(device)) - gpu_device_usage = {} - eu_total = 0 - device_usage_key = "GPU_{} {}".format(device[0], AVG_GPU_USAGE_CONSTANT) - device_vdbox0_usage_key = "GPU_{} VDBOX0 {}".format(device[0], AVG_GPU_VDBOX_USAGE_CONSTANT) - device_vdbox1_usage_key = "GPU_{} VDBOX1 {}".format(device[0], AVG_GPU_VDBOX_USAGE_CONSTANT) - with open(log_file_path) as f: - eu_samples = [] - vdbox0_samples = [] - vdbox1_samples = [] - data = json.load(f) - for entry in data: - #json data works for vdbox, but not for overall usage due to duplicate Render/3D/0 entries in the log file - #eu_samples.append(entry["engines"]["Render/3D/0"]["busy"]) - #print("usage: {}".format(entry["engines"]["Render/3D/0"]["busy"])) - vdbox0_samples.append(entry["engines"]["Video/0"]["busy"]) - try: - vdbox1_samples.append(entry["engines"]["Video/1"]["busy"]) - except KeyError: - pass - - if len(vdbox0_samples) > 0: - gpu_device_usage[device_vdbox0_usage_key] = mean(vdbox0_samples) - try: - gpu_device_usage[device_vdbox1_usage_key] = mean(vdbox1_samples) - except: - pass # nosec - - usage_samples = [] - with open(log_file_path) as f: - lines = f.readlines() - - for i, line in enumerate(lines): - if self._USAGE_PATTERN in line: - #print("found pattern {}".format(line)) - usage_line = lines[i+1] - #print("usage line {}".format(usage_line)) - #usage_line.strip() - #print("usage line {}".format(usage_line)) - junk, usage_percent = usage_line.split(":", 1) - usage_percent, junk = usage_percent.split(",", 1) - #print("usage percent after split {}".format(float(usage_percent))) - if float(usage_percent) > 0: - #print("usage percent {}".format(float(usage_percent))) - - usage_samples.append(float(usage_percent)) - if usage_samples: - #print("avg gpu usage: {}".format(mean(usage_samples))) - gpu_device_usage[device_usage_key] = mean(usage_samples) - else: - gpu_device_usage[device_usage_key] = 0.0 - - - if gpu_device_usage: - return gpu_device_usage - else: - return {AVG_GPU_USAGE_CONSTANT: "NA"} - - def return_blank(self): - return {AVG_GPU_USAGE_CONSTANT: "NA"} - -class XPUMUsageExtractor(KPIExtractor): - #overriding abstract method - def extract_data(self, log_file_path): - print("parsing GPU usages") - #print("log file path: {}".format(log_file_path)) - gpu_device_usage = {} - gpu_device_mem_usage = {} - gpu_device_compute_usage = {} - gpu_encode_usage = {} - gpu_decode_usage = {} - device = re.findall(r'\d+', os.path.basename(log_file_path)) - #print("Device: {}".format(device)) - device_usage_key = "GPU_{} {}".format(device[0], AVG_GPU_USAGE_CONSTANT) - device_mem_usage_key = "GPU_{} {}".format(device[0], AVG_GPU_MEM_USAGE_CONSTANT) - device_compute_usage_key = "GPU_{} {}".format(device[0], AVG_GPU_COMPUTE_USAGE_CONSTANT) - device_vdbox0_usage_key = "GPU_{} VDBOX0 {}".format(device[0], AVG_GPU_VDBOX_USAGE_CONSTANT) - device_vdbox1_usage_key = "GPU_{} VDBOX1 {}".format(device[0], AVG_GPU_VDBOX_USAGE_CONSTANT) - #print("{}".format(device_usage_key)) - with open(log_file_path) as f: - gpu_samples = [] - mem_samples = [] - compute_samples = [] - encode0_samples = [] - encode1_samples = [] - decode0_samples = [] - decode1_samples = [] - data = json.load(f) - for entry in data: - try: - gpu_samples.append(float(entry[" GPU Utilization (%)"])) - mem_samples.append(float(entry[" GPU Memory Utilization (%)"])) - compute_samples.append(float(entry[" Compute Engine 0 (%)"])) - encode0_samples.append(float(entry[" Encoder Engine 0 (%)"])) - encode1_samples.append(float(entry[" Encoder Engine 1 (%)"])) - decode0_samples.append(float(entry[" Decoder Engine 0 (%)"])) - decode1_samples.append(float(entry[" Decoder Engine 1 (%)"])) - except Exception: - # there might be some anomaly in xpu manager outputs when collecting metrics, eg. emptry strings - # here we ignore that formatting issue - pass # nosec - entries = len(gpu_samples) - #for index in range(entries): - # print("sample: {}".format(gpu_samples[index])) - - if len(gpu_samples) > 0: - gpu_device_usage[device_usage_key] = mean(gpu_samples) - gpu_device_usage[device_mem_usage_key] = mean(mem_samples) - gpu_device_usage[device_compute_usage_key] = mean(compute_samples) - gpu_device_usage[device_vdbox0_usage_key] = (mean(encode0_samples) + mean(decode0_samples)) - gpu_device_usage[device_vdbox1_usage_key] = (mean(encode1_samples) + mean(decode1_samples)) - if gpu_device_usage: - return gpu_device_usage - else: - return {AVG_GPU_USAGE_CONSTANT: "NA"} - - def return_blank(self): - return {AVG_GPU_USAGE_CONSTANT: "NA"} - - -class MetaExtractor(KPIExtractor): - _TEXT_PATTERN = "Total Text count:" - _BARCODE_PATTERN = "Total Barcode count:" - #overriding abstract method - def extract_data(self, log_file_path): - if os.path.getsize(log_file_path) == 0: - return {TEXT_COUNT_CONSTANT: "NA", BARCODE_COUNT_CONSTANT: "NA"} - - print("parsing text and barcode data") - #text_count = 0 - #barcode_count = 0 - with open(log_file_path) as f: - for line in f: - if self._TEXT_PATTERN in line: - print("got text pattern") - text_count = line.split(":", 1) - text_count = int(text_count[1]) - #print("text count: {}".format(text_count)) - elif self._BARCODE_PATTERN in line: - print("got barcode pattern") - barcode_count = line.split(":", 1) - barcode_count = int(barcode_count[1]) - #print("barcode count: {}".format(barcode_count)) - - if 'text_count' in locals() and 'barcode_count' in locals(): - return {TEXT_COUNT_CONSTANT: text_count, BARCODE_COUNT_CONSTANT: barcode_count} - else: - return {TEXT_COUNT_CONSTANT: "NA", BARCODE_COUNT_CONSTANT: "NA"} - - def return_blank(self): - return {TEXT_COUNT_CONSTANT: "NA", BARCODE_COUNT_CONSTANT: "NA"} - -class MemUsageExtractor(KPIExtractor): - _MEM_USAGE_PATTERN = "Mem:\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)" - _MEM_TOTAL_GROUP = 1 - _MEM_USED_GROUP = 2 - - #overriding abstract method - def extract_data(self, log_file_path): - if os.path.getsize(log_file_path) == 0: - return {AVG_MEM_USAGE_CONSTANT: "NA"} - - print("parsing memory usage") - mem_usages = [] - mem_usage_p = re.compile(self._MEM_USAGE_PATTERN) - with open(log_file_path) as f: - for line in f: - mem_usage_m = mem_usage_p.match(line) - if mem_usage_m: - mem_usage = float(mem_usage_m.group(self._MEM_USED_GROUP)) / float(mem_usage_m.group(self._MEM_TOTAL_GROUP)) - mem_usages.append(mem_usage) - - if len(mem_usages) > 0: - return {AVG_MEM_USAGE_CONSTANT: mean(mem_usages) * 100} - else: - return {AVG_MEM_USAGE_CONSTANT: "NA"} - - def return_blank(self): - return {AVG_MEM_USAGE_CONSTANT: "NA"} - -class PowerUsageExtractor(KPIExtractor): - #overriding abstract method - _POWER_USAGE_PATTERN = "(\\w+);.Consumed.energy.units:.(\\d+).+Joules: (\\d+.\\d+).+Watts:.(\\d+.\\d+).+TjMax:.(\\d+)" - _SOCKET_ID_GROUP = 1 - _POWER_USAGE_GROUP = 4 - def extract_data(self, log_file_path): - if os.path.getsize(log_file_path) == 0: - return {AVG_POWER_USAGE_CONSTANT: "NA"} - - power_dict = defaultdict(list) - power_usage_p = re.compile(self._POWER_USAGE_PATTERN) - print("parsing power usage") - with open(log_file_path) as f: - for line in f: - power_usage_m = power_usage_p.match(line) - if power_usage_m: - socket_id = power_usage_m.group(self._SOCKET_ID_GROUP) - power_usage = float(power_usage_m.group(self._POWER_USAGE_GROUP)) - power_dict[socket_id].append(power_usage) - - power_kpi_dict = {} - for socket_id, power_usages in power_dict.items(): - socket_key = "{} {}".format(socket_id, AVG_POWER_USAGE_CONSTANT) - power_kpi_dict[socket_key] = mean(power_usages) - - if power_kpi_dict: - return power_kpi_dict - else: - return {AVG_POWER_USAGE_CONSTANT: "NA"} - - def return_blank(self): - return {AVG_POWER_USAGE_CONSTANT: "NA"} - -class DiskBandwidthExtractor(KPIExtractor): - _DISK_BANDWIDTH_PATTERN = "Total DISK READ:.+\\s(\\d+.\\d+).(B\\/s|K\\/s).+\\s(\\d+.\\d+).(B\\/s|K\\/s)" - _READ_BYTES_PER_SECOND_GROUP = 1 - _READ_BYTES_UNITS_GROUP = 2 - _WRITE_BYTES_PER_SECOND_GROUP = 3 - _WRITE_BYTES_UNITS_GROUP = 4 - - #overriding abstract method - def extract_data(self, log_file_path): - print("parsing disk bandwidth") - disk_read_bytes_per_second = [] - disk_write_bytes_per_second = [] - disk_bandwidth_p = re.compile(self._DISK_BANDWIDTH_PATTERN) - with open(log_file_path) as f: - for line in f: - disk_bandwidth_m = disk_bandwidth_p.match(line) - if disk_bandwidth_m: - # we want the data in Bytes first before finally converting to MegaBytes - unit_multiplier = 1 if 'B' in disk_bandwidth_m.group(self._READ_BYTES_UNITS_GROUP) else 1000 - read_bytes_per_second = float(disk_bandwidth_m.group(self._READ_BYTES_PER_SECOND_GROUP)) * unit_multiplier - - unit_multiplier = 1 if 'B' in disk_bandwidth_m.group(self._WRITE_BYTES_PER_SECOND_GROUP) else 1000 - write_bytes_per_second = float(disk_bandwidth_m.group(self._WRITE_BYTES_PER_SECOND_GROUP)) * unit_multiplier - - disk_read_bytes_per_second.append(read_bytes_per_second) - disk_write_bytes_per_second.append(write_bytes_per_second) - - megabytes_to_bytes = 1000000 - if len(disk_read_bytes_per_second) > 0 and len(disk_write_bytes_per_second) > 0: - return {AVG_DISK_READ_BANDWIDTH_CONSTANT: mean(disk_read_bytes_per_second) / megabytes_to_bytes, - AVG_DISK_WRITE_BANDWIDTH_CONSTANT: mean(disk_write_bytes_per_second) / megabytes_to_bytes} - else: - {AVG_DISK_READ_BANDWIDTH_CONSTANT: "NA", AVG_DISK_WRITE_BANDWIDTH_CONSTANT: "NA"} - - def return_blank(self): - return {AVG_DISK_READ_BANDWIDTH_CONSTANT: "NA", AVG_DISK_WRITE_BANDWIDTH_CONSTANT: "NA"} - -class MemBandwidthExtractor(KPIExtractor): - #overriding abstract method - def extract_data(self, log_file_path): - if os.path.getsize(log_file_path) == 0: - return {AVG_MEM_BANDWIDTH_CONSTANT: "NA"} - - print("parsing memory bandwidth") - socket_memory_bandwidth = {} - df = pd.read_csv(log_file_path, header=1, on_bad_lines='skip') - socket_count = 0 - for column in df.columns: - if 'Memory (MB/s)' in column: - socket_key = "S{} {}".format(socket_count, AVG_MEM_BANDWIDTH_CONSTANT) - mem_bandwidth = df[column].tolist() - socket_memory_bandwidth[socket_key] = mean([ x for x in mem_bandwidth if pd.isna(x) == False ]) - socket_count = socket_count + 1 - - if socket_memory_bandwidth: - return socket_memory_bandwidth - else: - return {AVG_MEM_BANDWIDTH_CONSTANT: "NA"} - - def return_blank(self): - return {AVG_MEM_BANDWIDTH_CONSTANT: "NA"} - - -class PIPELINEFPSExtractor(KPIExtractor): - _FPS_KEYWORD = "avg_fps" - - #overriding abstract method - def extract_data(self, log_file_path): - print("parsing fps") - average_fps_list = [] - camera_fps = {} - cam = re.findall(r'\d+', os.path.basename(log_file_path)) - camera_key = "Camera_{} {}".format(cam[0], AVG_FPS_CONSTANT) - with open(log_file_path) as f: - for line in f: - average_fps_list.append(float(line)) - - if len(average_fps_list) > 0: - camera_fps[camera_key] = mean(average_fps_list) - else: - camera_fps[camera_key] = "NA" - - return camera_fps - - def return_blank(self): - return {AVG_FPS_CONSTANT: "NA"} - -class FPSExtractor(KPIExtractor): - _FPS_KEYWORD = "avg_fps" - - #overriding abstract method - def extract_data(self, log_file_path): - print("parsing fps") - average_fps_list = [] - camera_fps = {} - cam = re.findall(r'\d+', os.path.basename(log_file_path)) - camera_key = "Camera_{} {}".format(cam[0], AVG_FPS_CONSTANT) - with open(log_file_path) as f: - for line in f: - if self._FPS_KEYWORD in line: - average_fps_list.append(float((line.split(":"))[1].replace(",", ""))) - - if len(average_fps_list) > 0: - camera_fps[camera_key] = mean(average_fps_list) - - if camera_fps: - return camera_fps - else: - return {AVG_FPS_CONSTANT: "NA"} - - def return_blank(self): - return {AVG_FPS_CONSTANT: "NA"} - -class PIPELINLastModifiedExtractor(KPIExtractor): - #overriding abstract method - def extract_data(self, log_file_path): - print("parsing last modified log time") - average_fps_list = [] - last_modified = {} - cam = re.findall(r'\d+', os.path.basename(log_file_path)) - print(log_file_path) - print(cam) - camera_key = "Camera_{} {}".format(cam[0], LAST_MODIFIED_LOG) - - #get the last file modified time - print(log_file_path) - unix_date = os.path.getmtime(log_file_path) if os.path.exists(log_file_path) else None - print(unix_date) - #convert unix time to human readable date time - formatted_date = datetime.datetime.fromtimestamp(unix_date) if not (unix_date is None) else None - print(formatted_date) - #convert date format to string - last_modified[camera_key] = formatted_date.strftime('%m/%d/%Y %H:%M:%f') if not (formatted_date is None) else {LAST_MODIFIED_LOG: "NA"} - print(last_modified[camera_key]) - - return last_modified - - def return_blank(self): - return {LAST_MODIFIED_LOG: "NA"} - -class PCMExtractor(KPIExtractor): - #overriding abstract method - def extract_data(self, log_file_path): - if os.path.getsize(log_file_path) == 0: - return {AVG_POWER_USAGE_CONSTANT: "NA", AVG_MEM_BANDWIDTH_CONSTANT: "NA"} - - socket_memory_and_power = {} - print("parsing memory bandwidth") - df = pd.read_csv(log_file_path, header=1, on_bad_lines='skip') - socket_count = 0 - for column in df.columns: - if 'READ' in column: - mem_read = df[column].tolist() - elif 'WRITE' in column: - mem_write = df[column].tolist() - mem_bandwidth = list(map(add, mem_read, mem_write)) - socket_key = "S{} {}".format(socket_count, AVG_MEM_BANDWIDTH_CONSTANT) - socket_memory_and_power[socket_key] = 1000 * mean([ x for x in mem_bandwidth if pd.isna(x) == False ]) - socket_count = socket_count + 1 - - print("parsing power usage") - df = pd.read_csv(log_file_path, on_bad_lines='skip') - socket_power_usage = {} - socket_count = 0 - for column in df.columns: - if 'Proc Energy (Joules)' in column: - power_usage = df[column].tolist() - del power_usage[0] - socket_key = "S{} {}".format(socket_count, AVG_POWER_USAGE_CONSTANT) - socket_memory_and_power[socket_key] = mean([ float(x) for x in power_usage if pd.isna(x) == False ]) - socket_count = socket_count + 1 - - if socket_memory_and_power: - return socket_memory_and_power - else: - return {AVG_POWER_USAGE_CONSTANT: "NA", AVG_MEM_BANDWIDTH_CONSTANT: "NA"} - - def return_blank(self): - return {AVG_POWER_USAGE_CONSTANT: "-", AVG_MEM_BANDWIDTH_CONSTANT: "-"} - -KPIExtractor_OPTION = {"meta_summary.txt":MetaExtractor, - "camera":FPSExtractor, - "pipeline":PIPELINEFPSExtractor, - "(?:^r).*\.jsonl$":PIPELINLastModifiedExtractor, - "cpu_usage.log":CPUUsageExtractor, - "memory_usage.log":MemUsageExtractor, - "memory_bandwidth.csv":MemBandwidthExtractor, - "disk_bandwidth.log":DiskBandwidthExtractor, - "power_usage.log":PowerUsageExtractor, - "pcm.csv":PCMExtractor, - "(?:^xpum).*\.json$":XPUMUsageExtractor, - "igt":GPUUsageExtractor,} - -def add_parser(): - parser = argparse.ArgumentParser(description='Consolidate data') - parser.add_argument('--root_directory', nargs=1, help='Root directory that consists all log directory that store log file', required=True) - parser.add_argument('--output', nargs=1, help='Output file to store consolidate data', required=True) - return parser - -if __name__ == '__main__': - parser = add_parser() - args = vars(parser.parse_args()) - - root_directory = args['root_directory'][0] - output = args['output'][0] - - n = 0 - df = pd.DataFrame() - for log_directory_path in [ f.path for f in os.scandir(root_directory) if f.is_dir() ]: - folderName = os.path.basename(log_directory_path) - full_kpi_dict = {} - for kpiExtractor in KPIExtractor_OPTION: - fileFound = False - for dirpath, dirname, filename in os.walk(log_directory_path): - for file in filename: - if re.search(kpiExtractor, file): - #print("matched file: {}".format(file)) - fileFound = True - extractor = KPIExtractor_OPTION.get(kpiExtractor)() - kpi_dict = extractor.extract_data(os.path.join(log_directory_path, file)) - if kpi_dict: - full_kpi_dict.update(kpi_dict) - #if fileFound == False: - # extractor = KPIExtractor_OPTION.get(kpiExtractor)() - # kpi_dict = extractor.return_blank() - # if kpi_dict: - # full_kpi_dict.update(kpi_dict) - - list_of_metric = [] - list_of_value = [] - for kpi, value in full_kpi_dict.items(): - #print("kpi: {}, value: {}".format(kpi, value)) - #print("value list size: {}".format(len(list_of_value))) - list_of_metric.append(kpi) - if isinstance(value, str): - list_of_value.append(value) - else: - list_of_value.append(round(value, 3)) - - if n == 0: - df['Metric'] = list_of_metric - df[folderName] = list_of_value - n = -1 - - df.to_csv(output, header=True) diff --git a/benchmark-scripts/copy-platform-metrics.sh b/benchmark-scripts/copy-platform-metrics.sh deleted file mode 100755 index 4a0b400b..00000000 --- a/benchmark-scripts/copy-platform-metrics.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -LOG_DIRECTORY=$1 - -if [ -e ../results/r0.jsonl ] -then - echo "Copying data for collection scripts...`pwd`" - - # when copying results from parent directory, add -p to preserve the timestamp of original files - sudo cp -p -r ../results . - sudo cp results/stream* $LOG_DIRECTORY || true - sudo mv results/pipeline* $LOG_DIRECTORY - sudo cp results/r* $LOG_DIRECTORY - python3 ./results_parser.py | sudo tee -a meta_summary.txt > /dev/null - sudo mv meta_summary.txt $LOG_DIRECTORY -else - echo "Warning no data found for collection!" -fi diff --git a/benchmark-scripts/download_sample_videos.sh b/benchmark-scripts/download_sample_videos.sh deleted file mode 100755 index 6dbff7df..00000000 --- a/benchmark-scripts/download_sample_videos.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -# up to 3 bottles and human hand -echo "in download_sample_videos.sh...." - -./format_avc_mp4.sh coca-cola-4465029.mp4 https://www.pexels.com/video/4465029/download/ "$1" "$2" "$3" "00" -./format_avc_mp4.sh vehicle-bike.mp4 https://www.pexels.com/video/853908/download/ "$1" "$2" "$3" "01" -#./format_avc_mp4.sh grocery-items-on-the-kitchen-shelf-4983686.mp4 https://www.pexels.com/video/4983686/download/ $1 $2 $3 -./format_avc_mp4.sh video_of_people_walking_855564.mp4 https://www.pexels.com/video/855564/download/ "$1" "$2" "$3" "02" -./format_avc_mp4.sh barcode.mp4 https://github.com/antoniomtz/sample-clips/raw/main/barcode.mp4 "$1" "$2" "$3" "03" diff --git a/benchmark-scripts/format_avc_mp4.sh b/benchmark-scripts/format_avc_mp4.sh deleted file mode 100755 index 3038be0e..00000000 --- a/benchmark-scripts/format_avc_mp4.sh +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2024 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -show_help() { - echo " - usage: $0 video_name.mp4 URL_TO_MP4 [width height fps index] - - Note: - 1. This utility will convert the video_name.mp4 file to 4k@15FPS in AVC and requires Intel GPU. - 2. The video_name.mp4 file must reside in the sample-media folder. - 3. The video_name.mp4 file must already be in AVC format. - " -} - -WIDTH=1920 -HEIGHT=1080 -FPS=15 -INDEX="" - -if [ -z "$2" ] -then - show_help - exit 1 -fi - -if [ ! -z "$3" ] -then - WIDTH=$3 -fi - -if [ ! -z "$4" ] -then - HEIGHT=$4 -fi - -if [ ! -z "$5" ] -then - FPS=$5 -fi - - -if ! [[ "$WIDTH" =~ ^[0-9]+$ ]] -then - echo "ERROR: width should be integer." - exit 1 -fi - -if ! [[ "$HEIGHT" =~ ^[0-9]+$ ]] -then - echo "ERROR: height should be integer." - exit 1 -fi - -if ! [[ "$FPS" =~ ^[0-9]+(\.[0-9]+)*$ ]] -then - echo "ERROR: FPS should be number." - exit 1 -fi - -result=${1/.mp4/"-$WIDTH-$FPS-bench.mp4"} - -if [ -n "$6" ] -then - INDEX=$6 - result="$INDEX-"${1/.mp4/"-$WIDTH-$FPS-bench.mp4"} -fi - -if [ -f ../sample-media/$result ] -then - echo "Skipping...conversion was already done for ../sample-media/$result." - exit 0 -fi - -if [ ! -f ../sample-media/$1 ] && [ ! -f ../sample-media/$result ] -then - wget -O ../sample-media/$1 $2 - ls -alR ../sample-media/ -fi - -if [ ! -f ../sample-media/$1 ] -then - echo "ERROR: Can not find video file or - " - show_help - exit 1 -fi - - -echo "$WIDTH $HEIGHT $FPS" -SAMPLE_MEDIA_DIR="$PWD"/../sample-media -echo "SAMPLE_MEDIA_DIR:$SAMPLE_MEDIA_DIR" -docker run --privileged --user root -e VIDEO_FILE="$1" -e DISPLAY=:0 \ - -v /tmp/.X11-unix:/tmp/.X11-unix \ - -v "$SAMPLE_MEDIA_DIR"/:/vids \ - -w /vids -t --rm intel/dlstreamer:2023.0.0-ubuntu22-gpu682-dpcpp \ - bash -c "if [ -f /vids/$result ]; then echo 'error for '$result; exit 1; else ls -al /vids/; gst-launch-1.0 filesrc location=/vids/$1 ! qtdemux ! h264parse ! vaapih264dec ! vaapipostproc width=$WIDTH height=$HEIGHT ! videorate ! 'video/x-raw, framerate=$FPS/1' ! vaapih264enc ! h264parse ! mp4mux ! filesink location=/vids/$result; fi" - -echo "Result will be created in ../sample-media/$result" - -rm ../sample-media/"$1" diff --git a/benchmark-scripts/get-gpu-info.sh b/benchmark-scripts/get-gpu-info.sh deleted file mode 100755 index 4574775c..00000000 --- a/benchmark-scripts/get-gpu-info.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -HAS_FLEX_140=0 -HAS_FLEX_170=0 -HAS_ARC=0 -GPU_NUM_140=0 -GPU_NUM_170=0 - -has_flex_170=`lspci -d :56C0` -has_flex_140=`lspci -d :56C1` -has_arc=`lspci | grep -iE "5690|5691|5692|56A0|56A1|56A2|5693|5694|5695|5698|56A5|56A6|56B0|56B1|5696|5697|56A3|56A4|56B2|56B3"` - -if [ -z "$has_flex_170" ] && [ -z "$has_flex_140" ] && [ -z "$has_arc" ] -then - echo "No discrete Intel GPUs found" - return -fi -echo "GPU exists!" - -if [ ! -z "$has_flex_140" ] -then - HAS_FLEX_140=1 - GPU_NUM_140=`echo "$has_flex_140" | wc -l` -fi -if [ ! -z "$has_flex_170" ] -then - HAS_FLEX_170=1 - GPU_NUM_170=`echo "$has_flex_170" | wc -l` -fi -if [ ! -z "$has_arc" ] -then - HAS_ARC=1 -fi - -echo "HAS_FLEX_140=$HAS_FLEX_140, HAS_FLEX_170=$HAS_FLEX_170, HAS_ARC=$HAS_ARC, GPU_NUM_140=$GPU_NUM_140, GPU_NUM_170=$GPU_NUM_170" diff --git a/benchmark-scripts/log_time_monitor.sh b/benchmark-scripts/log_time_monitor.sh deleted file mode 100755 index f67dcc21..00000000 --- a/benchmark-scripts/log_time_monitor.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -WATCH_LOG_DIR=$1 # like ../results/ -WATCH_POLL_INTERVAL_IN_SECOND=$2 # usually per second polling -NUM_PIPELINES=$3 # number of pipelines: this determines how many pipeline log files to compare with - -if [ ! -d "$WATCH_LOG_DIR" ]; then - echo "ERROR: cannot find the log directory: $WATCH_LOG_DIR" - exit 1 -fi - -if [ $NUM_PIPELINES -lt 2 ]; then - echo "nothing to compare with, exiting" - exit 0 -fi - -PIPELINE_FILE_PREFIX=pipeline - -log_files=$(find "$WATCH_LOG_DIR" -name "$PIPELINE_FILE_PREFIX*.log" -printf '%p\n') -num_log_files=$(echo "$log_files" | wc -l) - -echo "INFO: find $num_log_files log files in $WATCH_LOG_DIR" - -if [ "$num_log_files" -lt "$NUM_PIPELINES" ]; then - echo "ERROR: expecting $NUM_PIPELINES log files but only found $num_log_files" - exit 1 -fi - -while true -do - echo "log file timestamp monitor running ..." - times=() - for log_file in $log_files - do - t=$(stat -c %Y "$log_file") - echo "timestamp for $log_file is $t" - times+=("$t") - done - - # calculate time difference and stall threshold - STALL_THRESHOLD=5 - i=0 - for log_file1 in $log_files - do - j=0 - for log_file2 in $log_files - do - # only compare to other files not itself and also compare the file later not repeat the previous already compared files - if [ "$log_file1" != "$log_file2" ] && [ "$j" -gt "$i" ]; then - t1="${times[$i]}" - t2="${times[$j]}" - time_diff=$(expr $t1 - $t2) - # removing -ve values if $t1 < $t2 - time_diff=${time_diff#-} - if [ "$time_diff" -ge "$STALL_THRESHOLD" ]; then - echo "WARNING: stalled pipelines detected, $log_file1 and $log_file2 time difference is $time_diff seconds, above stalled threshold $STALL_THRESHOLD seconds" - fi - fi - j=$((j+1)) - done - i=$((i+1)) - done - sleep $WATCH_POLL_INTERVAL_IN_SECOND -done - -echo "log_time_monitor.sh is done" diff --git a/benchmark-scripts/requirements-xpu.txt b/benchmark-scripts/requirements-xpu.txt deleted file mode 100644 index c3dff6eb..00000000 --- a/benchmark-scripts/requirements-xpu.txt +++ /dev/null @@ -1,8 +0,0 @@ -Flask==3.0.2 -Flask-HTTPAuth==4.8.0 -requests==2.31.0 -prometheus-client==0.20.0 -grpcio==1.62.1 -protobuf==5.26.0 -marshmallow==3.21.1 -gunicorn[gthread]==21.2.0 \ No newline at end of file diff --git a/benchmark-scripts/requirements.txt b/benchmark-scripts/requirements.txt deleted file mode 100644 index 8bc1f73e..00000000 --- a/benchmark-scripts/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -natsort==8.4.0 -numpy==1.26.4 -pandas==2.2.1 diff --git a/benchmark-scripts/results_parser.py b/benchmark-scripts/results_parser.py deleted file mode 100644 index bab8a785..00000000 --- a/benchmark-scripts/results_parser.py +++ /dev/null @@ -1,221 +0,0 @@ -''' -* Copyright (C) 2023 Intel Corporation. -* -* SPDX-License-Identifier: Apache-2.0 -''' - -import time -import sys -import argparse -import os -import json -from collections import Counter -from dataclasses import dataclass -import traceback - -@dataclass -class InferenceCounts: - detection: int = 0 - classification: int = 0 - text_detection: int = 0 - text_recognition: int = 0 - barcode: int = 0 - - -tracked_objects = {} -frame_count = 0 -inferenceCounts = InferenceCounts() - -def parse_args(): - parser = argparse.ArgumentParser(prog="Results Parser", - fromfile_prefix_chars='@', - formatter_class=argparse.ArgumentDefaultsHelpFormatter) - - parser.add_argument('--mode', default="file", help='Mode: file or mqtt') - parser.add_argument('--stream-index', default=0, help='Stream index') - parser.add_argument('--file', default="", help='file name') - parser.add_argument('--min-detections', default=15, help='Number of detections to define a valid object') - parser.add_argument('--reclassify-interval', default=1, help='Reclassify interval') - parser.add_argument('--broker-address', default="localhost", help='MQTT broker address') - parser.add_argument('--broker-port', default=1883, help='MQTT broker port') - return parser.parse_args() - - -def is_inside(inner, outer): - return inner["x_min"] >= outer["x_min"] and \ - inner["x_max"] <= outer["x_max"] and \ - inner["y_min"] >= outer["y_min"] and \ - inner["y_max"] <= outer["y_max"] - -def get_parent_id(detections, detection): - bbox = detection["bounding_box"] - for key in detections: - if is_inside(bbox, detections[key]["bounding_box"]): - return key - return 0 - -def print_object(obj): - print(" - Object {}: {}".format(obj["id"], obj["label"])) - print(" - Product: {}".format(obj["product"])) - print(" - Barcode: {}".format(obj.get("barcode"))) - print(" - Text: {} {}".format(len(obj["text"]),obj["text"])) - - -def process(results, reclassify_interval): - product_key = "classification_layer_name:efficientnet-b0/model/head/dense/BiasAdd/Add" - text_keys = ["inference_layer_name:logits", "inference_layer_name:shadow/LSTMLayers/transpose_time_major", - "inference_layer_name:shadow/LSTMLayers/Reshape_1"] - detections = {} - objects = {} - inferenceCounts.detection+=1 - # Needed for additional entries like non-inference results like {"resolution":{"height":2160,"width":3840},"timestamp":201018476} - if "objects" not in results: - return - for result in results["objects"]: - detection = result["detection"] - region_id = result["region_id"] - label = "EMPTY" - if "label" in detection: - label = detection["label"] - if "id" in result: - tracking_id = result["id"] - objects[region_id] = { - "id" : tracking_id, - "label" : label, - "text" : [], - "barcode": None, - "bounding_box": detection["bounding_box"] - } - detections[region_id] = detection - if product_key in result: - product = result[product_key]["label"][10:] - objects[region_id]["product"] = product - if label.startswith("barcode: "): - barcode = detection["label"][9:] - if barcode.endswith("_tracked"): - barcode = barcode[:-len("_tracked")] - else: - inferenceCounts.barcode+=1 - parent_id = get_parent_id(detections, detection) - if parent_id: - objects[parent_id]["barcode"] = barcode - for text_key in text_keys: - if text_key in result: - text = result[text_key]["label"] - inferenceCounts.text_detection+=1 - inferenceCounts.text_recognition+=1 - parent_id = get_parent_id(detections, detection) - if parent_id: - objects[parent_id]["text"].append(text) - - print("- Frame {}".format(frame_count)) - for obj in sorted(objects.values(),key=lambda obj: obj["bounding_box"]["x_min"]): - print_object(obj) - update_tracked_object(obj,tracked_objects) - - -def update_tracked_object(obj, tracked_objects): - tracked_object = tracked_objects.setdefault(obj["id"],{}) - tracked_keys = ["barcode","text","label","product"] - tracked_object["id"] = obj["id"] - for tracked_key in tracked_keys: - updates = obj[tracked_key] - if not isinstance(updates,list): - updates= [updates] - tracked_object.setdefault(tracked_key,Counter()).update( - updates) - - -def process_file(args): - if args.file: - filename=args.file - else: - filename = "results/r{}.jsonl".format(args.stream_index) - file = open(filename, "r") - line = file.readline() - global frame_count - while line: - try: - results = json.loads(line) - process(results, args.reclassify_interval) - frame_count += 1 - except Exception as e: - print("Error: {}".format(e)) - print(traceback.format_exc()) - line = file.readline() - file.close() - - -def on_connect(client, user_data, _unused_flags, return_code): - if return_code == 0: - args = user_data - print("Connected to broker at {}:{}".format(args.broker_address, args.broker_port)) - topic = "gulfstream/results_{}".format(args.stream_index) - print("Subscribing to topic {}".format(topic)) - client.subscribe(topic) - else: - print("Error {} connecting to broker".format(return_code)) - sys.exit(1) - -def on_message(_unused_client, user_data, msg): - results = json.loads(msg.payload) - process(results) - -def process_mqtt(args): - client = mqtt.Client("Gulfstream", userdata=args) - client.on_connect = on_connect - client.on_message = on_message - client.connect(args.broker_address, args.broker_port) - client.loop_forever() - - -def main(): - try: - args = parse_args() - if args.mode == "file": - process_file(args) - else: - import paho.mqtt.client as mqtt - process_mqtt(args) - text_count = 0 - barcode_count = 0 - print("-------") - print("Summary") - print("-------") - print("Frames {}".format(frame_count)) - inferenceCounts.classification = inferenceCounts.detection - print(inferenceCounts) - summary = [] - for obj in tracked_objects.values(): - summary_obj = {} - id = obj["id"] - for key in obj: - if isinstance(obj[key],Counter): - print("key is : {}".format(key)) - if key == "text": - obj[key] = {k:v for k, v in obj[key].items() if v > args.min_detections} - summary_obj[key] = list(obj[key].items()) - obj[key] = list(obj[key].items()) - if key == "barcode": - if None in obj[key][0]: - print("barcode is None, skip") - else: - print("barcode found: {}".format(obj[key][0])) - barcode_count += 1 - else: - summary_obj[key] = obj[key] - print("obj[key]: {}".format(obj[key])) - detections = obj["label"][0][1] - if detections >= args.min_detections: - print_object(obj) - text_count += len(obj["text"]) - summary.append(summary_obj) - print(json.dumps(summary)) - print("Total Objects: {} ".format(len(obj))) - print("Total Text count: {}".format(text_count)) - print("Total Barcode count: {}".format(barcode_count)) - except: - print(traceback.format_exc()) - -if __name__ == "__main__": - main() diff --git a/benchmark-scripts/smoke_test_benchmark.sh b/benchmark-scripts/smoke_test_benchmark.sh deleted file mode 100755 index fe87b472..00000000 --- a/benchmark-scripts/smoke_test_benchmark.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -# initial setup -( - cd .. - make clean-all - sleep 3 - make build-dlstreamer -) - -# build benchmark Docker images: -make - -# Download media -./download_sample_videos.sh - -PLATFORM=$1 -CPU_ONLY=$2 - -if [ -z "$PLATFORM" ] -then - PLATFORM="core" -fi - -if [ -z "$CPU_ONLY" ] -then - CPU_ONLY=0 -fi - -sudo rm -rf results || true -sudo rm -rf platform_"$PLATFORM"_cpuonly_"$CPU_ONLY"_smoke_test_camera_simulator_gst/ || true -sudo rm -rf platform_"$PLATFORM"_cpuonly_"$CPU_ONLY"_smoke_test_camera_simulator_capi_yolov5_ensemble/ || true -sudo rm -rf platform_"$PLATFORM"_cpuonly_"$CPU_ONLY"_smoke_test_camera_simulator_object_detection/ || true -sudo rm -rf platform_"$PLATFORM"_cpuonly_"$CPU_ONLY"_smoke_test_stream_density/ || true - -# Note: all of benchmarking pipelines are run with RENDER_MODE=0 for better performance without spending extra resources for rendering -# Camera simulator full pipeline -# shell check has false postive on SC2097 and SC2098 as it doesn't detect -E flag which is inhereted the envs into subprocess; hence disable here -# shellcheck disable=SC2097,SC2098 -PIPELINE_PROFILE="gst" CPU_ONLY="$CPU_ONLY" RENDER_MODE=0 sudo -E ./benchmark.sh --pipelines 1 --logdir platform_"$PLATFORM"_cpuonly_"$CPU_ONLY"_smoke_test_camera_simulator_gst/data --init_duration 30 --duration 60 --platform "$PLATFORM" --inputsrc rtsp://127.0.0.1:8554/camera_0 -# consolidate results -make consolidate ROOT_DIRECTORY=platform_"$PLATFORM"_cpuonly_"$CPU_ONLY"_smoke_te_smoke_test_camera_simulator_gst - -# Camera simulator for capi_yolov5_ensemble -# shell check has false postive on SC2097 and SC2098 as it doesn't detect -E flag which is inhereted the envs into subprocess; hence disable here -# shellcheck disable=SC2097,SC2098 -PIPELINE_PROFILE="capi_yolov5_ensemble" CPU_ONLY=$CPU_ONLY RENDER_MODE=0 sudo -E ./benchmark.sh --pipelines 1 --logdir platform_"$PLATFORM"_cpuonly_"$CPU_ONLY"_smoke_test_camera_simulator_capi_yolov5_ensemble/data --init_duration 30 --duration 60 --platform "$PLATFORM" --inputsrc rtsp://127.0.0.1:8554/camera_0 -# consolidate results -make consolidate ROOT_DIRECTORY=platform_"$PLATFORM"_cpuonly_"$CPU_ONLY"_smoke_test_camera_simulator_capi_yolov5_ensemble - -# Camera simulator yolov5 only -# shell check has false postive on SC2097 and SC2098 as it doesn't detect -E flag which is inhereted the envs into subprocess; hence disable here -# shellcheck disable=SC2097,SC2098 -PIPELINE_PROFILE="object_detection" CPU_ONLY=$CPU_ONLY RENDER_MODE=0 sudo -E ./benchmark.sh --pipelines 1 --logdir platform_"$PLATFORM"_cpuonly_"$CPU_ONLY"_smoke_test_camera_simulator_object_detection/data --init_duration 30 --duration 60 --platform "$PLATFORM" --inputsrc rtsp://127.0.0.1:8554/camera_0 -# consolidate results -make consolidate ROOT_DIRECTORY=platform_"$PLATFORM"_cpuonly_"$CPU_ONLY"_smoke_test_camera_simulator_object_detection - -# Stream density for object detection -# shell check has false postive on SC2097 and SC2098 as it doesn't detect -E flag which is inhereted the envs into subprocess; hence disable here -# shellcheck disable=SC2097,SC2098 -PIPELINE_PROFILE="object_detection" CPU_ONLY=$CPU_ONLY RENDER_MODE=0 sudo -E ./benchmark.sh --stream_density 60 --logdir platform_"$PLATFORM"_cpuonly_"$CPU_ONLY"_smoke_test_stream_density/data --init_duration 30 --duration 60 --platform "$PLATFORM" --inputsrc rtsp://127.0.0.1:8554/camera_0 diff --git a/benchmark-scripts/stop_server.sh b/benchmark-scripts/stop_server.sh deleted file mode 100755 index 4a94cec9..00000000 --- a/benchmark-scripts/stop_server.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -# the results of docker ps -aq is meant to be re-splitting in order for the docker rm to be working -# shellcheck disable=SC2046 -docker rm -f $(docker ps -aq) diff --git a/benchmark-scripts/stream_density.sh b/benchmark-scripts/stream_density.sh deleted file mode 100755 index 91c26309..00000000 --- a/benchmark-scripts/stream_density.sh +++ /dev/null @@ -1,309 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -# this function cleans up parent process and its child processes -# the first input is the parent process to be cleaned up -cleanupPipelineProcesses() -{ - pidToKill=$1 - childPids=$(pgrep -P "$pidToKill") - echo "decrementing pipelines and to kill pid $pidToKill" >> "$log" - waitForChildPidKilled=0 - if [ -z "$childPids" ] - then - echo "for parent pid $pidToKill, there is no child pids to kill" >> "$log" - else - echo "parent pid $pidToKill with childPids $childPids to be killed" >> "$log" - waitForChildPidKilled=1 - fi - - # kill the parent process with PID $pidToKill - pkill -P "$pidToKill" - - # make sure all child pids are gone before proceed - MAX_PID_WAITING_COUNT=10 - waitingCnt=0 - while [ $waitForChildPidKilled -eq 1 ] - do - numExistingChildren=0 - for childPid in $childPids - do - if ps -p "$childPid" > /dev/null - then - echo "child pid: $childPid exists" >> "$log" - numExistingChildren=$(( numExistingChildren + 1 )) - - processCmd=$(ps -p "$childPid" -o cmd=) - echo "DEBUG: pipeline process is $processCmd" >> "$log" - # for those child process is running in docker run, - # then we use docker rm to delete the process - isDockerRun=$(echo "$processCmd" | grep "docker run") - if [ -n "$isDockerRun" ] - then - containerName=$(echo "$processCmd" | awk -F "CONTAINER_NAME=" '{print $2}' | awk '{print $1}') - if [ -n "$containerName" ] - then - echo "terminating docker process with CONTAINER_NAME $containerName..." >> "$log" - docker rm "$containerName" -f - else - echo "Docker run process without CONTAINER_NAME: skip...." >> "$log" - fi - fi - # if not docker run process, use kill to terminate it when it exceeds the maiximum waitingCnt - # this also tries to kill the docker process without container name - if [ $waitingCnt -ge $MAX_PID_WAITING_COUNT ] - then - echo "exceeding the max. pid waiting count $MAX_PID_WAITING_COUNT, kill it directly..." >> "$log" - kill -9 "$childPid" - waitingCnt=0 - fi - else - echo "no child pid exists $childPid" - fi - done - - if [ $numExistingChildren -eq 0 ] - then - echo "all child processes for $pidToKill are cleaned up" - break - else - waitingCnt=$(( waitingCnt + 1 )) - fi - done - - # check the parent process is gone before proceed - while ps -p "$pidToKill" > /dev/null - do - echo "$pidToKill is still running" - sleep 1 - done - echo "done with clean up parent process $pidToKill" -} - -TARGET_FPS=15 -MEETS_FPS=true -INIT_DURATION=120 -MAX_GUESS_INCREMENTS=5 -num_pipelines=1 -increments=1 -RESULT_DIR="${RESULT_DIR:=$RUN_PATH/results}" -log="${log:=$RESULT_DIR/stream_density.log}" - -if [ -n "$STREAM_DENSITY_FPS" ] -then - if (( $(echo "$STREAM_DENSITY_FPS" | awk '{if ($1 <= 0) print 1;}') )) - then - echo "ERROR: stream density input target fps should be greater than 0" >> "$log" - exit 1 - fi - TARGET_FPS=$STREAM_DENSITY_FPS -fi - -if [ -n "$STREAM_DENSITY_INCREMENTS" ] -then - if (( $(echo "$STREAM_DENSITY_INCREMENTS" | awk '{if ($1 <= 0) print 1;}') )) - then - echo "ERROR: stream density input increments should be greater than 0" >> "$log" - exit 1 - fi -fi - -if [ -n "$COMPLETE_INIT_DURATION" ] -then - INIT_DURATION=$COMPLETE_INIT_DURATION -fi - -echo "Stream density TARGET_FPS set for $TARGET_FPS and INIT_DURATION set for $INIT_DURATION" > "$log" -echo "Starting single container stream density benchmarking" >> "$log" - -GPU_DEVICE_TOGGLE="1" - -decrementing=0 -start_cid_count=0 -declare -a pipelinePIDs - -while [ $MEETS_FPS = true ] -do - total_fps_per_stream=0.0 - total_fps=0.0 - - cid_count=$(( num_pipelines - 1 )) - - echo "Starting pipeline: $num_pipelines" >> "$log" - pipelineArgs=("${@:1}") - if [ -z "$AUTO_SCALE_FLEX_140" ] - then - echo "DEBUG: " "${pipelineArgs[@]}" >> "$log" - if [ $decrementing -eq 0 ] - then - for i in $( seq $(( start_cid_count )) $(( num_pipelines - 1 ))) - do - echo "the pipeline args is " "${pipelineArgs[@]}" - cid_count=$i - "${pipelineArgs[@]}" & - pid=$! - pipelinePIDs+=("$pid") - done - echo "pipeline pid list: " "${pipelinePIDs[@]}" - else - # kill the pipeline with index based on the current pipeline number - pidToKill="${pipelinePIDs[$num_pipelines]}" - cleanupPipelineProcesses "$pidToKill" - pgrep -fa "$1" - echo - echo "current background running pipeline PIDs: $(jobs -p)" - fi - else - echo "INFO: Auto scaling on both flex 140 gpus...targetting device $GPU_DEVICE_TOGGLE" >> "$log" - for i in $( seq $(( start_cid_count )) $(( num_pipelines - 1 ))) - do - if [ $decrementing -eq 0 ] - then - cid_count=$i - if [ "$GPU_DEVICE_TOGGLE" == "1" ] - then - GST_VAAPI_DRM_DEVICE=/dev/dri/renderD128 "${pipelineArgs[@]}" & - GPU_DEVICE_TOGGLE=2 - else - GST_VAAPI_DRM_DEVICE=/dev/dri/renderD129 "${pipelineArgs[@]}" & - GPU_DEVICE_TOGGLE=1 - fi - pid=$! - pipelinePIDs+=("$pid") - echo "pipeline pid list: " "${pipelinePIDs[@]}" - else - # kill the pipeline with index based on the current pipeline number - pidToKill="${pipelinePIDs[$num_pipelines]}" - cleanupPipelineProcesses "$pidToKill" - pgrep -fa "$1" - echo - echo "current background running pipeline PIDs: $(jobs -p)" - fi - done - fi - - echo "waiting for pipelines to settle" >> "$log" - sleep "$INIT_DURATION" - - # note: before reading the pipeline log files - # we want to give pipelines some time as the log files - # producing could be lagging behind... - max_retries=50 - retry=0 - foundAllLogs=0 - while [ $foundAllLogs -ne $num_pipelines ] - do - if [ $retry -ge $max_retries ] - then - echo "ERROR: cannot find all pipeline log files after retries, pipeline may have been failed..." >> "$log" - exit 1 - fi - - echo "checking presence of all pipeline log files..." - - foundAllLogs=0 - for i in $( seq 0 $(( cid_count ))) - do - # to make sure all non-empty pipeline log files are present before proceed - if [ -f "$RESULT_DIR/pipeline$i.log" ] && [ -s "$RESULT_DIR/pipeline$i.log" ] - then - echo "found non-empty pipeline$i.log file" >> "$log" - foundAllLogs=$(( foundAllLogs + 1 )) - else - echo "could not find non-empty pipeline$i.log file yet, will retry it again" >> "$log" - fi - done - retry=$(( retry + 1 )) - sleep 1 - done - - for i in $( seq 0 $(( cid_count ))) - do - # Last 10/20 seconds worth of currentfps - # filter out nan value just in case there is such value produced from pipeline - STREAM_FPS_LIST=$(awk '!/na/' "$RESULT_DIR"/pipeline"$i".log | tail -20) - if [ -z "$STREAM_FPS_LIST" ] - then - # we already checked non-empty log contents above, this check is here just in case everything is NaN - echo "Warning: No FPS returned from pipeline$i.log" - fi - stream_fps_sum=0 - stream_fps_count=0 - - for stream_fps in $STREAM_FPS_LIST - do - stream_fps_sum=$(echo "$stream_fps_sum" "$stream_fps" | awk '{print $1 + $2}') - stream_fps_count=$(echo "$stream_fps_count" 1 | awk '{print $1 + $2}') - done - stream_fps_avg=$(echo "$stream_fps_sum" "$stream_fps_count" | awk '{print $1 / $2}') - - - total_fps=$(echo "$total_fps" "$stream_fps_avg" | awk '{print $1 + $2}') - total_fps_per_stream=$(echo "$total_fps" "$num_pipelines" | awk '{print $1 / $2}') - echo "FPS for pipeline$i: $stream_fps_avg" >> "$log" - done - echo "Total FPS throughput: $total_fps" >> "$log" - echo "Total FPS per stream: $total_fps_per_stream" >> "$log" - - echo "decrementing: $decrementing" - echo "current total fps per stream = $total_fps_per_stream for $num_pipelines pipeline(s)" - - if [ "$decrementing" -eq 0 ] - then - if (( $(echo "$total_fps_per_stream" "$TARGET_FPS" | awk '{if ($1 >= $2) print 1;}') )) - then - # if the increments hint from $STREAM_DENSITY_INCREMENTS is not empty - # we will use it as the increments - # otherwise, we will try to adjust increments dynamically based on the rate of $total_fps_per_stream - # and $TARGET_FPS - if [ -n "$STREAM_DENSITY_INCREMENTS" ] - then - # there is increments hint from the input, so we will honor it - # after the first pipeline, the stream density increments will be appiled if we are not there yet - increments=$STREAM_DENSITY_INCREMENTS - else - # when there is no increments hint from input, the value of increments is calculated - # by the rate of $total_fps_per_stream and $TARGET_FPS per greedy policy - increments=$(echo "$total_fps_per_stream" "$TARGET_FPS" | awk '{print int($1 / $2)}') - # when calculated increments is == 1 under this case, the internal maximum increments - # will be used as there is no effective way to figure out what's the best increments in this case - if [ "$increments" -eq 1 ] - then - increments=$MAX_GUESS_INCREMENTS - fi - fi - echo "incrementing by $increments" - else - increments=-1 - decrementing=1 - echo "Below target fps $TARGET_FPS, starting to decrement pipelines by 1..." - fi - else - if (( $(echo "$total_fps_per_stream" "$TARGET_FPS" | awk '{if ($1 >= $2) print 1;}') )) - then - echo "found maximum number of pipelines to have target fps $TARGET_FPS" - MEETS_FPS=false - echo "Max stream density achieved for target FPS $TARGET_FPS is $num_pipelines" >> "$log" - echo "Finished stream density benchmarking" >> "$log" - else - if [ "$num_pipelines" -le 1 ] - then - echo "already reach num pipeline 1, and the fps per stream is $total_fps_per_stream but target FPS is $TARGET_FPS" >> "$log" - MEETS_FPS=false - break - else - echo "decrementing number of pipelines $num_pipelines by 1" - fi - fi - fi - - start_cid_count=$(( num_pipelines )) - num_pipelines=$(( num_pipelines + increments )) - -done #done while - -echo "stream_density done!" >> "$log" diff --git a/benchmark-scripts/test_benchmark_multiple_pipelines.sh b/benchmark-scripts/test_benchmark_multiple_pipelines.sh deleted file mode 100755 index 42dbd972..00000000 --- a/benchmark-scripts/test_benchmark_multiple_pipelines.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -checkNumOfPipelineLogFiles(){ - RESULT_DIR="../results" - expectedNumOfNonEmptyLogs=2 - numFoundLogs=0 - # check non-empty pipeline logs- should find 2 - for i in $( seq 0 $(( expectedNumOfNonEmptyLogs-1 ))) - do - if [ -f "$RESULT_DIR/pipeline$i.log" ] && [ -s "$RESULT_DIR/pipeline$i.log" ] - then - echo "found non-empty pipeline$i.log file" - numFoundLogs=$(( numFoundLogs + 1 )) - else - echo "could not find non-empty pipeline$i.log file" - fi - done - - if [ "$numFoundLogs" -ne "$expectedNumOfNonEmptyLogs" ] - then - echo "test for benchmarking multiple pipeline profile $PIPELINE_PROFILE FAILED: expect to have $expectedNumOfNonEmptyLogs pipelines but found $numFoundLogs" - else - echo "test for benchmarking multiple pipeline $PIPELINE_PROFILE PASSED: there are exactly $expectedNumOfNonEmptyLogs pipelines" - fi -} - -# inital setup -( - cd .. - make clean-all - sleep 3 - make build-python-apps - make build-capi_yolov5 -) - - ./download_sample_videos.sh - -# test for non-capi objec_detection -PIPELINE_PROFILE="object_detection" RENDER_MODE=0 sudo -E ./benchmark.sh --pipelines 2 --logdir test_object_detection/data --duration 30 --init_duration 10 --platform core --inputsrc rtsp://127.0.0.1:8554/camera_1 -sleep 2 -PIPELINE_PROFILE="object_detection"; checkNumOfPipelineLogFiles > testbenchmark.log - -#clean up -sudo rm -rf test_object_detection/ -( - cd .. - make clean-all -) - -# test for capi-yolov5 -PIPELINE_PROFILE="capi_yolov5" RENDER_MODE=0 sudo -E ./benchmark.sh --pipelines 2 --logdir test_capi_yolov5/data --duration 30 --init_duration 10 --platform core --inputsrc rtsp://127.0.0.1:8554/camera_1 -sleep 2 -PIPELINE_PROFILE="capi_yolov5"; checkNumOfPipelineLogFiles >> testbenchmark.log - -#clean up -sudo rm -rf test_capi_yolov5/ -( - cd .. - make clean-all -) - -# show test results: -grep --color=never "test for benchmarking multiple pipeline" testbenchmark.log -rm testbenchmark.log diff --git a/benchmark-scripts/test_format_avc_mp4.sh b/benchmark-scripts/test_format_avc_mp4.sh deleted file mode 100755 index ec7d0a02..00000000 --- a/benchmark-scripts/test_format_avc_mp4.sh +++ /dev/null @@ -1,168 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - - -# test setup: prepare test folder for download test file -testFolder=../sample-media/test -FILENAME_DOWNLOAD=test/test.mp4 -DEFAULT_FILE_PATH_NAME=../sample-media/test/test-1920-15-bench.mp4 -FILE_URL_TO_DOWNLOAD=https://storage.openvinotoolkit.org/data/test_data/videos/smartlab/v3/stream_1_left.mp4 -mkdir $testFolder - -cleanupTestFolder() { - echo - echo "remove test folder..." - rm -rf "$testFolder" - echo "done." -} - -cleanupTestFolderContent() { - echo "remove all files under test folder..." - # remove downloaded files so it's re-testable - rm -f "$testFolder/*" -} - -# test case 1: test with image, got statusCode 0 and test media file downloaded (happy path) -echo -echo "# test case 1: test with image, got statusCode 0 and test media file downloaded (happy path)" -output=$(./format_avc_mp4.sh $FILENAME_DOWNLOAD $FILE_URL_TO_DOWNLOAD) -statusCode=$? -echo "$statusCode" -if [ $statusCode == 0 ] -then - if [ -f "$DEFAULT_FILE_PATH_NAME" ] - then - echo "test PASSED: $DEFAULT_FILE_PATH_NAME has been downloaded for $FILENAME_DOWNLOAD with $FILE_URL_TO_DOWNLOAD." - else - echo "test FAILED: $DEFAULT_FILE_PATH_NAME has NOT been downloaded for $FILENAME_DOWNLOAD with $FILE_URL_TO_DOWNLOAD." - fi -else - echo "test FAILED: expecting status code 0 but found $statusCode for $FILENAME_DOWNLOAD with $FILE_URL_TO_DOWNLOAD." -fi -cleanupTestFolderContent - -# test case 2: download 2nd time, expect message "Skipping..." -SUB="Skipping..." -echo -echo "# test case 2: download 2nd time, expect message \"$SUB\"" -output=$(./format_avc_mp4.sh $FILENAME_DOWNLOAD $FILE_URL_TO_DOWNLOAD) -statusCode=$? -if [ $statusCode == 0 ] -then - if test -f "$DEFAULT_FILE_PATH_NAME"; then - #download again - output=$(./format_avc_mp4.sh $FILENAME_DOWNLOAD $FILE_URL_TO_DOWNLOAD) - statusCode=$? - if [ $statusCode == 0 ] - then - if [[ "$output" == "$SUB"* ]] - then - echo "test PASSED: Second time download was skipped!" - else - echo "test FAILED: Second time download was missing skipped message!" - fi - else - echo "test FAILED: Second time download ERROR: $output: expecting status code 0 but found $statusCode." - fi - else - echo "test FAILED: download $FILENAME_DOWNLOAD first time failed" - fi -else - echo "test FAILED: download $FILENAME_DOWNLOAD first time failed: $output: expecting status code 0 but found $statusCode." -fi -cleanupTestFolderContent - - -# test case 3: input resize, expect file name with resize in the file name (happy path) -echo -echo "# test case 3: input resize, expect file name with resize in the file name (happy path)" -WIDTH=1080 -HEIGHT=720 -FPS=10 -output=$(./format_avc_mp4.sh $FILENAME_DOWNLOAD $FILE_URL_TO_DOWNLOAD $WIDTH $HEIGHT $FPS) -statusCode=$? -FILE_PATH_NAME=../sample-media/test/test-$WIDTH-$FPS-bench.mp4 -if [ $statusCode == 0 ] -then - if test -f "$FILE_PATH_NAME"; then - echo "test PASSED: with input width $WIDTH, height $HEIGHT, FPS $FPS." - else - echo "test FAILED: with input width $WIDTH, height $HEIGHT, FPS $FPS: couldn't find downloaded file $FILE_PATH_NAME." - fi -else - echo "test FAILED: with input width $WIDTH, height $HEIGHT, FPS $FPS: expecting status code 0 but found $statusCode." -fi -cleanupTestFolderContent - -# test case 4: input Width should be integer type -echo -echo "# test case 4: input Width should be integer type" -WIDTH=8abv -HEIGHT=720 -FPS=10 -EXPECTED_MESSAGE="ERROR: width should be integer." -output=$(./format_avc_mp4.sh $FILENAME_DOWNLOAD $FILE_URL_TO_DOWNLOAD, $WIDTH $HEIGHT $FPS) -statusCode=$? -if [ $statusCode == 1 ] -then - if [[ "$output" == "$EXPECTED_MESSAGE" ]] - then - echo "test PASSED: check for invalid width input" - else - echo "test FAILED: check for invalid width input" - fi -else - echo "test FAILED: check for invalid width input, it should return status code of 1" -fi -cleanupTestFolderContent - -# test case 5: input Height should be integer type -echo -echo "# test case 5: input Height should be integer type" -WIDTH=1035 -HEIGHT=8.0fd -FPS=10 -EXPECTED_MESSAGE="ERROR: height should be integer." -output=$(./format_avc_mp4.sh $FILENAME_DOWNLOAD $FILE_URL_TO_DOWNLOAD, $WIDTH $HEIGHT $FPS) -statusCode=$? -if [ $statusCode == 1 ] -then - if [[ "$output" == "$EXPECTED_MESSAGE" ]] - then - echo "test PASSED: check for invalid height input" - else - echo "test FAILED: check for invalid height input" - fi -else - echo "test FAILED: check for invalid height input, it should return status code of 1" -fi -cleanupTestFolderContent - -# test case 6: input FPS should be float or integer type -echo -echo "# test case 6: input FPS should be float or integer type" -WIDTH=1035 -HEIGHT=335 -FPS=a.09 -EXPECTED_MESSAGE="ERROR: FPS should be number." -output=$(./format_avc_mp4.sh $FILENAME_DOWNLOAD $FILE_URL_TO_DOWNLOAD, $WIDTH $HEIGHT $FPS) -statusCode=$? -if [ $statusCode == 1 ] -then - if [[ "$output" == "$EXPECTED_MESSAGE" ]] - then - echo "test PASSED: check for invalid FPS input" - else - echo "test FAILED: check for invalid FPS input" - fi -else - echo "test FAILED: check for invalid FPS input, it should return status code of 1" -fi -cleanupTestFolderContent - -# clean up: remove the test folder -cleanupTestFolder diff --git a/benchmark-scripts/test_streamdensity.sh b/benchmark-scripts/test_streamdensity.sh deleted file mode 100755 index 394dcbb9..00000000 --- a/benchmark-scripts/test_streamdensity.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -# initial setup -( - cd .. - make clean-all - sleep 3 -) - -min_expected=2 -target_fps=14.9 -testDir=mytest1 -increment_hint=5 - -echo "testcase: minimum ${min_expected} streams expected without increments hint" -# testing for no increments hint -PIPELINE_PROFILE="gst" RENDER_MODE=0 sudo -E ./benchmark.sh --stream_density $target_fps --logdir "$testDir" --duration 120 --init_duration 60 \ - --platform core --inputsrc rtsp://127.0.0.1:8554/camera_1 - -statusCode=$? -if [ $statusCode -ne 0 ] -then - echo "test failed: expecting get status code 0 but found $statusCode" -else - # Max stream density achieved for target FPS 12 is at least 1 - res=$(grep -i -Eo "Max stream density achieved for target FPS ([0-9]+(.[0-9]+)*) is ([0-9])+" ../results/stream_density.log | awk -F ' ' '{print $10}') - - if [ -z "${res}" ]; then - echo "test failed: maximum pipeline numbers not found" - elif [ "${res}" -ge "${min_expected}" ]; then - echo "test passed: maximum pipeline number = ${res}" - else - echo "test failed: unable to reach the min. ${min_expected} streams as maximum pipeline number = ${res}" - fi -fi - -sudo rm -rf "$testDir" - -sleep 10 - -echo -echo "testcase: minimum ${min_expected} streams expected with increments hint" -#testing for core system with rtsp, you may need to edit the input source if rtsp is different for camera device -PIPELINE_PROFILE="gst" RENDER_MODE=0 sudo -E ./benchmark.sh --stream_density $target_fps $increment_hint --logdir "$testDir" --duration 120 --init_duration 60 \ - --platform core --inputsrc rtsp://127.0.0.1:8554/camera_1 - -statusCode=$? -if [ $statusCode -ne 0 ] -then - echo "test failed: expecting get status code 0 but found $statusCode" -else - # Max stream density achieved for target FPS 12 is at least 1 - res=$(grep -i -Eo "Max stream density achieved for target FPS ([0-9]+(.[0-9]+)*) is ([0-9])+" ../results/stream_density.log | awk -F ' ' '{print $10}') - - if [ -z "${res}" ]; then - echo "test failed: maximum pipeline numbers not found" - elif [ "${res}" -ge "${min_expected}" ]; then - echo "test passed: maximum pipeline number = ${res}" - else - echo "test failed: unable to reach the min. ${min_expected} streams as maximum pipeline number = ${res}" - fi -fi - -sudo rm -rf "$testDir" - -echo - diff --git a/camera-simulator/camera-simulator.sh b/camera-simulator/camera-simulator.sh deleted file mode 100755 index 0027befd..00000000 --- a/camera-simulator/camera-simulator.sh +++ /dev/null @@ -1,117 +0,0 @@ -#!/bin/bash -e -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -COMMAND="start" -SOURCE_DIR="$(dirname "$(dirname "$(readlink -f "$0")")")" -CAMERAS= -FILES= - - -get_options() { - while :; do - case $1 in - -h | -\? | --help) - show_help - exit - ;; - --command) - if [ "$2" ]; then - COMMAND=$2 - shift - else - error 'ERROR: "--command" requires an argument.' - fi - ;; - --cameras) - if [ "$2" ]; then - CAMERAS=$2 - shift - else - error 'ERROR: "--cameras" requires an argument.' - fi - ;; - --files) - if [ "$2" ]; then - FILES=$2 - if [[ ! -e $SOURCE_DIR/sample-media/$2 ]]; then - echo "File $2 does not exist" - exit 1 - fi - shift - else - error 'ERROR: "--files" requires an argument.' - fi - ;; - --) - shift - break - ;; - -?*) - error 'ERROR: Unknown option: ' $1 - ;; - ?*) - error 'ERROR: Unknown option: ' $1 - ;; - *) - break - ;; - esac - - shift - done - -} - -show_help() { - echo "usage: camera-simulator.sh" - echo " [--command start,stop]" - echo " [--cameras number of cameras]" - echo " [--files comma seperated list of files within sample-media]" - exit 0 -} - -get_options "$@" - -if [ -z "$COMMAND" ]; then - COMMAND="START" -fi - -if [ "${COMMAND,,}" = "start" ]; then - - if [ -z "$FILES" ]; then - cd $SOURCE_DIR/sample-media - FILES=( *.mp4 ) - else - IFS=','; FILES=( "${FILES[@]}" ); unset IFS; - fi - - if [ -z "$CAMERAS" ]; then - CAMERAS=${#FILES[@]} - fi - - cd $SOURCE_DIR/camera-simulator - - docker run --rm -t --network=host --name camera-simulator aler9/rtsp-simple-server >rtsp_simple_server.log.txt 2>&1 & - index=0 - while [ $index -lt $CAMERAS ] - do - for file in "${FILES[@]}" - do - echo "Starting camera: rtsp://127.0.0.1:8554/camera_$index from $file" - docker run -t --rm --name camera-simulator$index --entrypoint ffmpeg --network host -v $SOURCE_DIR/sample-media:/home/pipeline-server/sample-media openvino/ubuntu20_data_runtime:2021.4.2 -nostdin -re -stream_loop -1 -i /home/pipeline-server/sample-media/$file -c copy -f rtsp -rtsp_transport tcp rtsp://localhost:8554/camera_$index >/dev/null 2>&1 & - ((index+=1)) - if [ $CAMERAS -le $index ]; then - break - fi - sleep 1 - done - done - -elif [ "${COMMAND,,}" = "stop" ]; then - docker kill camera-simulator 2> /dev/null -fi - diff --git a/camera-simulator/mediamtx.yml b/camera-simulator/mediamtx.yml deleted file mode 100644 index cc2ec41a..00000000 --- a/camera-simulator/mediamtx.yml +++ /dev/null @@ -1,275 +0,0 @@ -############################################### -# General settings - -# Sets the verbosity of the program; available values are "error", "warn", "info", "debug". -logLevel: info -# Destinations of log messages; available values are "stdout", "file" and "syslog". -logDestinations: [stdout] -# If "file" is in logDestinations, this is the file which will receive the logs. -logFile: mediamtx.log - -# Timeout of read operations. -readTimeout: 10s -# Timeout of write operations. -writeTimeout: 10s -# Size of the queue of outgoing packets. -# A higher value allows to increase throughput, a lower value allows to save RAM. -writeQueueSize: 512 -# Maximum size of outgoing UDP packets. -# This can be decreased to avoid fragmentation on networks with a low UDP MTU. -udpMaxPayloadSize: 1472 - -# HTTP URL to perform external authentication. -# Every time a user wants to authenticate, the server calls this URL -# with the POST method and a body containing: -# { -# "ip": "ip", -# "user": "user", -# "password": "password", -# "path": "path", -# "protocol": "rtsp|rtmp|hls|webrtc", -# "id": "id", -# "action": "read|publish", -# "query": "query" -# } -# If the response code is 20x, authentication is accepted, otherwise -# it is discarded. -externalAuthenticationURL: - -# Enable the HTTP API. -api: no -# Address of the API listener. -apiAddress: 127.0.0.1:9997 - -# Enable Prometheus-compatible metrics. -metrics: no -# Address of the metrics listener. -metricsAddress: 127.0.0.1:9998 - -# Enable pprof-compatible endpoint to monitor performances. -pprof: no -# Address of the pprof listener. -pprofAddress: 127.0.0.1:9999 - -# Command to run when a client connects to the server. -# This is terminated with SIGINT when a client disconnects from the server. -# The following environment variables are available: -# * RTSP_PORT: RTSP server port -# * MTX_CONN_TYPE: connection type -# * MTX_CONN_ID: connection ID -runOnConnect: -# Restart the command if it exits. -runOnConnectRestart: no -# Command to run when a client disconnects from the server. -# Environment variables are the same of runOnConnect. -runOnDisconnect: - -############################################### -# RTSP settings - -# Allow publishing and reading streams with the RTSP protocol. -rtsp: yes -# List of enabled RTSP transport protocols. -# UDP is the most performant, but doesn't work when there's a NAT/firewall between -# server and clients, and doesn't support encryption. -# UDP-multicast allows to save bandwidth when clients are all in the same LAN. -# TCP is the most versatile, and does support encryption. -# The handshake is always performed with TCP. -protocols: [udp, multicast, tcp] -# Encrypt handshakes and TCP streams with TLS (RTSPS). -# Available values are "no", "strict", "optional". -encryption: "no" -# Address of the TCP/RTSP listener. This is needed only when encryption is "no" or "optional". -rtspAddress: :8554 -# Address of the TCP/TLS/RTSPS listener. This is needed only when encryption is "strict" or "optional". -rtspsAddress: :8322 -# Address of the UDP/RTP listener. This is needed only when "udp" is in protocols. -rtpAddress: :8000 -# Address of the UDP/RTCP listener. This is needed only when "udp" is in protocols. -rtcpAddress: :8001 -# IP range of all UDP-multicast listeners. This is needed only when "multicast" is in protocols. -multicastIPRange: 224.1.0.0/16 -# Port of all UDP-multicast/RTP listeners. This is needed only when "multicast" is in protocols. -multicastRTPPort: 8002 -# Port of all UDP-multicast/RTCP listeners. This is needed only when "multicast" is in protocols. -multicastRTCPPort: 8003 -# Path to the server key. This is needed only when encryption is "strict" or "optional". -# This can be generated with: -# openssl genrsa -out server.key 2048 -# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650 -serverKey: server.key -# Path to the server certificate. This is needed only when encryption is "strict" or "optional". -serverCert: server.crt -# Authentication methods. Available are "basic" and "digest". -# "digest" doesn't provide any additional security and is available for compatibility reasons only. -authMethods: [basic] - -############################################### -# RTMP settings - -# Allow publishing and reading streams with the RTMP protocol. -rtmp: yes -# Address of the RTMP listener. This is needed only when encryption is "no" or "optional". -rtmpAddress: :1935 -# Encrypt connections with TLS (RTMPS). -# Available values are "no", "strict", "optional". -rtmpEncryption: "no" -# Address of the RTMPS listener. This is needed only when encryption is "strict" or "optional". -rtmpsAddress: :1936 -# Path to the server key. This is needed only when encryption is "strict" or "optional". -# This can be generated with: -# openssl genrsa -out server.key 2048 -# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650 -rtmpServerKey: server.key -# Path to the server certificate. This is needed only when encryption is "strict" or "optional". -rtmpServerCert: server.crt - -############################################### -# HLS settings - -# Allow reading streams with the HLS protocol. -hls: yes -# Address of the HLS listener. -hlsAddress: :8888 -# Enable TLS/HTTPS on the HLS server. -# This is required for Low-Latency HLS. -hlsEncryption: no -# Path to the server key. This is needed only when encryption is yes. -# This can be generated with: -# openssl genrsa -out server.key 2048 -# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650 -hlsServerKey: server.key -# Path to the server certificate. -hlsServerCert: server.crt -# By default, HLS is generated only when requested by a user. -# This option allows to generate it always, avoiding the delay between request and generation. -hlsAlwaysRemux: no -# Variant of the HLS protocol to use. Available options are: -# * mpegts - uses MPEG-TS segments, for maximum compatibility. -# * fmp4 - uses fragmented MP4 segments, more efficient. -# * lowLatency - uses Low-Latency HLS. -hlsVariant: lowLatency -# Number of HLS segments to keep on the server. -# Segments allow to seek through the stream. -# Their number doesn't influence latency. -hlsSegmentCount: 7 -# Minimum duration of each segment. -# A player usually puts 3 segments in a buffer before reproducing the stream. -# The final segment duration is also influenced by the interval between IDR frames, -# since the server changes the duration in order to include at least one IDR frame -# in each segment. -hlsSegmentDuration: 1s -# Minimum duration of each part. -# A player usually puts 3 parts in a buffer before reproducing the stream. -# Parts are used in Low-Latency HLS in place of segments. -# Part duration is influenced by the distance between video/audio samples -# and is adjusted in order to produce segments with a similar duration. -hlsPartDuration: 200ms -# Maximum size of each segment. -# This prevents RAM exhaustion. -hlsSegmentMaxSize: 50M -# Value of the Access-Control-Allow-Origin header provided in every HTTP response. -# This allows to play the HLS stream from an external website. -hlsAllowOrigin: '*' -# List of IPs or CIDRs of proxies placed before the HLS server. -# If the server receives a request from one of these entries, IP in logs -# will be taken from the X-Forwarded-For header. -hlsTrustedProxies: [] -# Directory in which to save segments, instead of keeping them in the RAM. -# This decreases performance, since reading from disk is less performant than -# reading from RAM, but allows to save RAM. -hlsDirectory: '' - -############################################### -# WebRTC settings - -# Allow publishing and reading streams with the WebRTC protocol. -webrtc: yes -# Address of the WebRTC listener. -webrtcAddress: :8889 -# Enable TLS/HTTPS on the WebRTC server. -webrtcEncryption: no -# Path to the server key. -# This can be generated with: -# openssl genrsa -out server.key 2048 -# openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650 -webrtcServerKey: server.key -# Path to the server certificate. -webrtcServerCert: server.crt -# Value of the Access-Control-Allow-Origin header provided in every HTTP response. -# This allows to play the WebRTC stream from an external website. -webrtcAllowOrigin: '*' -# List of IPs or CIDRs of proxies placed before the WebRTC server. -# If the server receives a request from one of these entries, IP in logs -# will be taken from the X-Forwarded-For header. -webrtcTrustedProxies: [] -# List of ICE servers. -webrtcICEServers2: - # URL can point to a STUN, TURN or TURNS server. - # STUN servers are used to obtain the public IP of server and clients. They are - # needed when server and clients are on different LANs. - # TURN/TURNS servers are needed when a direct connection between server and - # clients is not possible. All traffic is routed through them. -- url: stun:stun.l.google.com:19302 - # if user is "AUTH_SECRET", then authentication is secret based. - # the secret must be inserted into the password field. - username: '' - password: '' -# List of public IP addresses that are to be used as a host. -# This is used typically for servers that are behind 1:1 D-NAT. -webrtcICEHostNAT1To1IPs: [] -# Address of a ICE UDP listener in format host:port. -# If filled, ICE traffic will pass through a single UDP port, -# allowing the deployment of the server inside a container or behind a NAT. -webrtcICEUDPMuxAddress: -# Address of a ICE TCP listener in format host:port. -# If filled, ICE traffic will pass through a single TCP port, -# allowing the deployment of the server inside a container or behind a NAT. -# Using this setting forces usage of the TCP protocol, which is not -# optimal for WebRTC. -webrtcICETCPMuxAddress: - -############################################### -# SRT settings - -# Allow publishing and reading streams with the SRT protocol. -srt: yes -# Address of the SRT listener. -srtAddress: :8890 - -############################################### -# Recording settings - -# Record streams to disk. -record: no -# Path of recording segments. -# Extension is added automatically. -# Available variables are %path (path name), %Y %m %d %H %M %S %f (time in strftime format) -recordPath: ./recordings/%path/%Y-%m-%d_%H-%M-%S-%f -# Format of recorded segments. -# Currently the only available format is fmp4 (fragmented MP4). -recordFormat: fmp4 -# fMP4 segments are concatenation of small MP4 files (parts), each with this duration. -# When a system failure occurs, the last part gets lost. -# Therefore, the part duration is equal to the RPO (recovery point objective). -recordPartDuration: 100ms -# Minimum duration of each segment. -recordSegmentDuration: 1h -# Delete segments after this timespan. -# Set to 0s to disable automatic deletion. -recordDeleteAfter: 24h - -############################################### -# Path settings - -# These settings are path-dependent, and the map key is the name of the path. -# It's possible to use regular expressions by using a tilde as prefix, -# for example "~^(test1|test2)$" will match both "test1" and "test2", -# for example "~^prefix" will match all paths that start with "prefix". -# Settings under the path "all" are applied to all paths that do not match -# another entry. -paths: - cam: - runOnInit: ffmpeg -f v4l2 -i /dev/video0 -pix_fmt yuv420p -preset ultrafast -b:v 600k -f rtsp rtsp://localhost:8554/cam - runOnInitRestart: yes - \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/Dockerfile b/configs/opencv-ovms/cmd_client/Dockerfile deleted file mode 100644 index bd699f62..00000000 --- a/configs/opencv-ovms/cmd_client/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -FROM golang:1.20.9-alpine3.18 AS builder -RUN apk update && \ - apk add make autoconf libtool protobuf-dev && \ - rm -rf /var/lib/apt/lists/* -WORKDIR /app -RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.31.0 -RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 -# Compile API -RUN wget https://raw.githubusercontent.com/openvinotoolkit/model_server/main/src/kfserving_api/grpc_predict_v2.proto -RUN echo 'option go_package = "./grpc-client";' >> grpc_predict_v2.proto -RUN protoc --go_out="./" --go-grpc_out="./" ./grpc_predict_v2.proto - -COPY . . -RUN go mod tidy && make build-binary - -FROM scratch as bin -COPY --from=builder /app/profile-launcher / \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/Dockerfile.unit-test b/configs/opencv-ovms/cmd_client/Dockerfile.unit-test deleted file mode 100644 index 8d58e61c..00000000 --- a/configs/opencv-ovms/cmd_client/Dockerfile.unit-test +++ /dev/null @@ -1,21 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -FROM golang:1.20.9-alpine3.18 AS builder -RUN apk update && \ - apk add make autoconf libtool protobuf-dev && \ - rm -rf /var/lib/apt/lists/* -WORKDIR /test - -# install docker, as we need docker for some unit tests -RUN apk update && apk add --update docker openrc && \ - rm -rf /var/lib/apt/lists/* - -COPY . . - -RUN chmod +x /test/run_unit_test.sh - -ENTRYPOINT ["/test/run_unit_test.sh"] diff --git a/configs/opencv-ovms/cmd_client/Makefile b/configs/opencv-ovms/cmd_client/Makefile deleted file mode 100644 index 075b90d6..00000000 --- a/configs/opencv-ovms/cmd_client/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright © 2023 Intel Corporation. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -.PHONY: build unit-test build-binary - -build: - docker build --target bin --output=. . - -unit-test: - @docker build -f Dockerfile.unit-test -t go-unit-test:dev . - @docker run --rm -v .:/test -v /var/run/docker.sock:/var/run/docker.sock go-unit-test:dev - -build-binary: - @echo "building executeable profile-launcher..." - @go build -o profile-launcher - @echo "done" - diff --git a/configs/opencv-ovms/cmd_client/go.mod b/configs/opencv-ovms/cmd_client/go.mod deleted file mode 100644 index e2165655..00000000 --- a/configs/opencv-ovms/cmd_client/go.mod +++ /dev/null @@ -1,20 +0,0 @@ -module github.com/intel-retail/automated-self-checkout/configs/opencv-ovms/cmd_client - -go 1.20 - -require ( - github.com/stretchr/testify v1.8.4 - google.golang.org/grpc v1.59.0 - google.golang.org/protobuf v1.33.0 - gopkg.in/yaml.v3 v3.0.1 -) - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect -) diff --git a/configs/opencv-ovms/cmd_client/go.sum b/configs/opencv-ovms/cmd_client/go.sum deleted file mode 100644 index 497081e0..00000000 --- a/configs/opencv-ovms/cmd_client/go.sum +++ /dev/null @@ -1,30 +0,0 @@ -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/configs/opencv-ovms/cmd_client/main.go b/configs/opencv-ovms/cmd_client/main.go deleted file mode 100644 index 08286af4..00000000 --- a/configs/opencv-ovms/cmd_client/main.go +++ /dev/null @@ -1,716 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2024 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package main - -import ( - "bufio" - "context" - "encoding/json" - "flag" - "fmt" - "io" - "log" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" - "sync" - "time" - - "github.com/intel-retail/automated-self-checkout/configs/opencv-ovms/cmd_client/parser" - "github.com/intel-retail/automated-self-checkout/configs/opencv-ovms/cmd_client/portfinder" - "github.com/intel-retail/automated-self-checkout/configs/opencv-ovms/cmd_client/server" - - grpc_client "github.com/intel-retail/automated-self-checkout/configs/opencv-ovms/cmd_client/grpc-client" - "google.golang.org/grpc" - "gopkg.in/yaml.v3" -) - -type StartPolicy int - -const ( - Ignore StartPolicy = iota - Exit - RemoveRestart -) - -func (policy StartPolicy) String() string { - return [...]string{ - "ignore", - "exit", - "remove-and-restart", - }[policy] -} - -const ( - ENV_KEY_VALUE_DELIMITER = "=" - - profileLaunchedContainerNameSuffix = "_ovms_pl" - defaultGrpcPortFrom = 9001 - defaultTargetDevice = "CPU" - - scriptDir = "./scripts" - envFileDir = "./envs" - pipelineProfileEnv = "PIPELINE_PROFILE" - resourceDir = "res" - pipelineConfigFileName = "configuration.yaml" - commandLineArgsDelimiter = " " - streamDensityScript = "/app/stream_density.sh" - streamDensityResultDir = "/tmp/results" - - ovmsConfigJsonDir = "./configs/opencv-ovms/models/2022" - ovmsTemplateConfigJson = "config_template.json" - ovmsModelReadyMaxRetries = 100 - - defaultOvmsServerStartWaitTime = time.Duration(10 * time.Second) - dockerVolumeFlag = "-v" -) - -const ( - OVMS_SERVER_DOCKER_IMG_ENV = "OVMS_SERVER_IMAGE_TAG" - OVMS_SERVER_START_UP_MSG_ENV = "SERVER_START_UP_MSG" - SERVER_CONTAINER_NAME_ENV = "SERVER_CONTAINER_NAME" - OVMS_MODEL_CONFIG_JSON_PATH_ENV = "OVMS_MODEL_CONFIG_JSON" - OVMS_INIT_WAIT_TIME_ENV = "SERVER_INIT_WAIT_TIME" - CID_COUNT_ENV = "cid_count" - RESULT_DIR_ENV = "RESULT_DIR" - DOT_ENV_FILE_ENV = "DOT_ENV_FILE" - GRPC_PORT_ENV = "GRPC_PORT" - TARGET_DEVICE_ENV = "DEVICE" -) - -type OvmsServerInfo struct { - ServerDockerScript string - ServerDockerImage string - ServerContainerName string - ServerConfig string - StartupMessage string - InitWaitTime string - EnvironmentVariableFiles []string - StartUpPolicy string -} - -const ( - // constants define the environment variable keys - DOCKER_LAUNCHER_SCRIPT_ENV = "DOCKER_LAUNCHER_SCRIPT" - DOCKER_VOLUMES_ENV = "VOLUMES" - DOCKER_IMAGE_ENV = "DOCKER_IMAGE" - DOCKER_CONTAINER_NAME_ENV = "CONTAINER_NAME" - DOCKER_CMD_ENV = "DOCKER_CMD" -) - -type DockerLauncherInfo struct { - LauncherScript string `yaml:"Script" json:"Script"` - DockerImage string `yaml:"DockerImage" json:"DockerImage"` - ContainerName string `yaml:"ContainerName" json:"ContainerName"` - DockerVolumes []string `yaml:"Volumes" json:"Volumes"` -} - -type OvmsClientInfo struct { - DockerLauncher DockerLauncherInfo - OVMSCustomNodeJson string - PipelineScript string - PipelineInputArgs string - PipelineStreamDensityRun string - EnvironmentVariableFiles []string -} - -type OvmsClientConfig struct { - OvmsSingleContainer bool - OvmsServer OvmsServerInfo - OvmsClient OvmsClientInfo -} - -type Flags struct { - FlagSet *flag.FlagSet - configDir string - oVMSModelConfigDir string -} - -func main() { - flagSet := flag.NewFlagSet("", flag.ExitOnError) - flags := &Flags{ - FlagSet: flagSet, - } - flagSet.StringVar(&flags.configDir, "configDir", filepath.Join(".", resourceDir), "") - flagSet.StringVar(&flags.configDir, "cd", filepath.Join(".", resourceDir), "") - flagSet.StringVar(&flags.oVMSModelConfigDir, "genOVMSModelConfig", "", "") - err := flags.FlagSet.Parse(os.Args[1:]) - if err != nil { - flagSet.Usage() - log.Fatalln(err) - } - - flags.genOVMSModelConfig() - - // the config yaml file is in res/ folder of the "pipeline profile" directory - contents, err := flags.readPipelineConfig() - if err != nil { - log.Fatalf("failed to read configuration yaml file: %v", err) - } - - data := make(map[string]any) - err = yaml.Unmarshal(contents, &data) - if err != nil { - log.Fatalf("failed to unmarshal configuration file configuration.yaml: %v", err) - } - - log.Println("data: ", data) - - // convert to struct - jsonBytes, err := json.Marshal(data) - if err != nil { - log.Fatalf("could not marshal map to JSON: %v", err) - } - - var ovmsClientConf *OvmsClientConfig - if err := json.Unmarshal(jsonBytes, &ovmsClientConf); err != nil { - log.Fatalf("could not unmarshal JSON data to %T: %v", *ovmsClientConf, err) - } - - log.Println("successfully converted to OvmsClientConfig struct", *ovmsClientConf) - - // set the env values for CID_COUNT_ENV and GRPC_PORT_ENV based on the number of profile Docker container instances - ovmsClientConf.setEnvContainerCountAndGrpcPort() - - // if OvmsSingleContainer mode is true, then we don't launcher another ovms server - // as the client itself has it like C-Api case - if ovmsClientConf.OvmsSingleContainer { - log.Println("running in single container mode, no distributed client-server") - ovmsClientConf.generateConfigJsonForCApi(flags.configDir) - } else { - // launcher ovms server - ovmsClientConf.startOvmsServer() - } - - // initialize the docker-launcher envs: - ovmsClientConf.initDockerLauncherEnvs() - - //launch the pipeline script from the config - if err := ovmsClientConf.launchPipelineScript(); err != nil { - log.Fatalf("found error while launching pipeline script: %v", err) - } - -} - -func (ovmsClientConf *OvmsClientConfig) setEnvContainerCountAndGrpcPort() { - // utilize docker ps to find out how many has been launched by profile-launcher and thus - // decide the cid_count value; it is equivalent to the command line: docker ps -aq -f name= | wc -w - dockerPsCmd := exec.Command("docker", []string{ - "ps", "-aq", "-f name=" + profileLaunchedContainerNameSuffix}...) - wcCmd := exec.Command("wc", "-w") - - // using pipe to connect the output from the 1st command to input of the 2nd command to figure out cid_count value - r, w := io.Pipe() - dockerPsCmd.Stdout = w - wcCmd.Stdin = r - - res, err := wcCmd.StdoutPipe() - if err != nil { - log.Fatalf("failed to get stdout pipe from wc command:%v", err) - } - if err := dockerPsCmd.Start(); err != nil { - log.Fatalf("failed to docker ps filter name `%s` command for containers launched by profile-launcher: %v", profileLaunchedContainerNameSuffix, err) - } - if err := wcCmd.Start(); err != nil { - log.Fatalf("failed to run wc command to get the docker container counts launched by profile-launcher: %v", err) - } - if err := dockerPsCmd.Wait(); err != nil { - log.Fatalf("docker ps command wait error: %v", err) - } - w.Close() - - wcReader := bufio.NewReader(res) - resBytes, _ := wcReader.ReadString('\n') - - if err := wcCmd.Wait(); err != nil { - log.Fatalf("wc command wait error: %v", err) - } - - output := strings.TrimSuffix(string(resBytes), fmt.Sprintln()) - - log.Println("output:", output) - - containerCnt := "0" - if len(output) > 0 { - containerCnt = output - // verify the output is an integer - _, err := strconv.Atoi(containerCnt) - if err != nil { - log.Println("failed to parse the output for container count: ", err) - // assuming the 0 value in this case - containerCnt = "0" - } - } else { - log.Println("output is empty, containerCnt defaults to 0") - } - - os.Setenv(CID_COUNT_ENV, containerCnt) - - portFinder := portfinder.PortFinder{ - IpAddress: "localhost", - } - - grpcPortNum := portFinder.GetFreePortNumber(defaultGrpcPortFrom) - os.Setenv(GRPC_PORT_ENV, fmt.Sprintf("%d", grpcPortNum)) - - log.Println("cid_count=", os.Getenv(CID_COUNT_ENV)) - log.Println("GRPC_PORT=", os.Getenv(GRPC_PORT_ENV)) -} - -func (ovmsClientConf *OvmsClientConfig) generateConfigJsonForCApi(configDir string) { - log.Println("generate and update config json file for C-API case...") - - customNodeJsonConfigFile := strings.TrimSpace(ovmsClientConf.OvmsClient.OVMSCustomNodeJson) - - deviceConfigJsonFileInput := ovmsTemplateConfigJson - if len(customNodeJsonConfigFile) > 0 { - log.Printf("use custom node json from %s", customNodeJsonConfigFile) - pipelineProfile := strings.TrimSpace(os.Getenv(pipelineProfileEnv)) - customNodeJsonConfigFilePath := filepath.Join(configDir, resourceDir, pipelineProfile, customNodeJsonConfigFile) - customNodeUpdater := server.NewCustomNodeUpdater(customNodeJsonConfigFilePath, ovmsConfigJsonDir, ovmsTemplateConfigJson) - newUpdateConfigJson := "config_ovms-server_" + ovmsClientConf.OvmsClient.DockerLauncher.ContainerName + os.Getenv(CID_COUNT_ENV) + ".json" - if err := customNodeUpdater.UpdateCustomNode(filepath.Join(ovmsConfigJsonDir, newUpdateConfigJson)); err != nil { - log.Printf("Error: failed to update custom node information and produce a new ovms server config json: %v", err) - os.Exit(1) - } - deviceConfigJsonFileInput = newUpdateConfigJson - } - - deviceUpdater := server.NewDeviceUpdater(ovmsConfigJsonDir, deviceConfigJsonFileInput) - targetDevice := defaultTargetDevice - if len(os.Getenv(TARGET_DEVICE_ENV)) > 0 { - // only set the value from env if env is not empty; otherwise defaults to the default value in defaultTargetDevice - // devices supported CPU, GPU, GPU.x, AUTO, MULTI:GPU,CPU - targetDevice = os.Getenv(TARGET_DEVICE_ENV) - } - - log.Println("Updating config with DEVICE environment variable:", targetDevice) - - newUpdateConfigJson := "config_ovms-server_" + ovmsClientConf.OvmsClient.DockerLauncher.ContainerName + os.Getenv(CID_COUNT_ENV) + ".json" - if err := deviceUpdater.UpdateDeviceAndCreateJson(targetDevice, filepath.Join(ovmsConfigJsonDir, newUpdateConfigJson)); err != nil { - log.Printf("Error: failed to update device and produce a new ovms server config json: %v", err) - os.Exit(1) - } - - configJsonContainer := filepath.Join("/models", newUpdateConfigJson) - log.Println("configJsonContainer:", configJsonContainer) - os.Setenv(OVMS_MODEL_CONFIG_JSON_PATH_ENV, configJsonContainer) -} - -func (ovmsClientConf *OvmsClientConfig) startOvmsServer() { - if len(ovmsClientConf.OvmsServer.ServerDockerScript) == 0 { - log.Println("Error founding any server launch script from OvmsServer.ServerDockerScript, please check configuration.yaml file") - os.Exit(1) - } - - log.Println("OVMS server config to launcher: ", ovmsClientConf.OvmsServer) - os.Setenv(OVMS_SERVER_START_UP_MSG_ENV, ovmsClientConf.OvmsServer.StartupMessage) - os.Setenv(SERVER_CONTAINER_NAME_ENV, ovmsClientConf.OvmsServer.ServerContainerName) - os.Setenv(OVMS_SERVER_DOCKER_IMG_ENV, ovmsClientConf.OvmsServer.ServerDockerImage) - - // update device in the template config json: - deviceUpdater := server.NewDeviceUpdater(ovmsConfigJsonDir, ovmsTemplateConfigJson) - configFileWithoutExtension := strings.TrimSuffix(filepath.Base(ovmsClientConf.OvmsServer.ServerConfig), ".json") - newUpdateConfigJson := configFileWithoutExtension + "_" + ovmsClientConf.OvmsServer.ServerContainerName + os.Getenv(CID_COUNT_ENV) + ".json" - targetDevice := defaultTargetDevice - if len(os.Getenv(TARGET_DEVICE_ENV)) > 0 { - // only set the value from env if env is not empty; otherwise defaults to the default value in defaultTargetDevice - // devices supported CPU, GPU, GPU.x, AUTO, MULTI:GPU,CPU - targetDevice = os.Getenv(TARGET_DEVICE_ENV) - } - - log.Println("Updating config with DEVICE environment variable:", targetDevice) - - if err := deviceUpdater.UpdateDeviceAndCreateJson(targetDevice, filepath.Join(ovmsConfigJsonDir, newUpdateConfigJson)); err != nil { - log.Printf("Error: failed to update device and produce a new ovms server config json: %v", err) - os.Exit(1) - } - - configJsonContainer := filepath.Join(filepath.Dir(ovmsClientConf.OvmsServer.ServerConfig), newUpdateConfigJson) - log.Println("configJsonContainer:", configJsonContainer) - os.Setenv(OVMS_MODEL_CONFIG_JSON_PATH_ENV, configJsonContainer) - - serverScript := filepath.Join(scriptDir, ovmsClientConf.OvmsServer.ServerDockerScript) - ovmsSrvLaunch, err := exec.LookPath(serverScript) - if err != nil { - log.Printf("Error: failed to get ovms server launch script path: %v", err) - os.Exit(1) - } - - log.Println("launch ovms server script:", ovmsSrvLaunch) - startupPolicy := Ignore.String() - if len(ovmsClientConf.OvmsServer.StartUpPolicy) > 0 { - startupPolicy = ovmsClientConf.OvmsServer.StartUpPolicy - } - switch startupPolicy { - case Ignore.String(), Exit.String(), RemoveRestart.String(): - log.Println("chose ovms server startup policy:", startupPolicy) - default: - startupPolicy = Ignore.String() - log.Println("ovms server startup policy defaults to", Ignore.String()) - } - - cmd := exec.Command(ovmsSrvLaunch) - cmd.Env = os.Environ() - origEnvs := make([]string, len(cmd.Env)) - copy(origEnvs, cmd.Env) - // apply all envs from env files if any - envList := ovmsClientConf.OvmsServer.readServerEnvs(envFileDir) - cmd.Env = append(cmd.Env, envList...) - // override envs from the origEnvs - cmd.Env = append(cmd.Env, origEnvs...) - - output, err := cmd.CombinedOutput() - if err != nil { - log.Printf("failed to run the ovms server launch : %v", err) - log.Printf("output: %v", string(output)) - // based on the startup policy when there is error on launching ovms server, - // it will deal it differently: - switch startupPolicy { - case Exit.String(): - os.Exit(1) - case RemoveRestart.String(): - rmvContainerName := ovmsClientConf.OvmsServer.ServerContainerName + os.Getenv(CID_COUNT_ENV) - rmvCmd := exec.Command("docker", []string{"rm", "-f", rmvContainerName}...) - if rmvErr := rmvCmd.Run(); rmvErr != nil { - log.Printf("failed to remove the existing container with container name %s: %v", rmvContainerName, rmvErr) - } - time.Sleep(time.Second) - ovmsClientConf.startOvmsServer() - default: - fallthrough - case Ignore.String(): - log.Println("startup error is ignored due to ignore startup policy") - // in this case, we also need to reset the env $GRPC_PORT to the ignored model server's one - // otherwise, the client will use the wrong port number - ovmsContainerName := ovmsClientConf.OvmsServer.ServerContainerName + os.Getenv(CID_COUNT_ENV) - log.Printf("ovmsContainer name: %s", ovmsContainerName) - ovmsSrvPortNum, err := getServerGrpcPort(ovmsContainerName) - if err != nil { - log.Fatalf("failed to get server gRPC port number: %v", err) - } - os.Setenv(GRPC_PORT_ENV, ovmsSrvPortNum) - } - } - - ovmsSrvWaitTime := defaultOvmsServerStartWaitTime - if len(ovmsClientConf.OvmsServer.InitWaitTime) > 0 { - ovmsSrvWaitTime, err = time.ParseDuration(ovmsClientConf.OvmsServer.InitWaitTime) - if err != nil { - log.Printf("Error parsing ovmsClientConf.OvmsServer.InitWaitTime %s, using default value %v : %s", - ovmsClientConf.OvmsServer.InitWaitTime, defaultOvmsServerStartWaitTime, err) - ovmsSrvWaitTime = defaultOvmsServerStartWaitTime - } - } - - log.Println("Let server settle a bit...") - time.Sleep(ovmsSrvWaitTime) - - // wait for the model ready state status: - // even though the ovms server is ready but the individual models may not be - // due to the model config file config.json changes on the fly - retryCnt := 0 - for { - if retryCnt >= ovmsModelReadyMaxRetries { - log.Printf("error: reaches the max retry count %d for checking model ready of ovms server; gave up", ovmsModelReadyMaxRetries) - return - } - - retryCnt++ - readyErr := ovmsClientConf.waitForOvmsModelsReady() - if readyErr == nil { - // all are error free and thus models are ready - break - } - - log.Printf("warning: ovms models from the model server not ready yet: %v", readyErr) - // sleep a bit and retry it again - time.Sleep(time.Second) - } - - log.Println("OVMS server started and ready to serve") -} - -func (ovmsClientConf *OvmsClientConfig) waitForOvmsModelsReady() error { - grpcPort := os.Getenv(GRPC_PORT_ENV) - ovmsURL := fmt.Sprintf("%s:%s", "localhost", grpcPort) - conn, err := grpc.Dial(ovmsURL, grpc.WithInsecure()) - if err != nil { - return fmt.Errorf("couldn't connect to endpoint %s: %v", ovmsURL, err) - } - defer conn.Close() - - // retrieve models: - ovmsModelParser := parser.NewConfigJsonModelParser(ovmsConfigJsonDir, ovmsTemplateConfigJson) - if err = ovmsModelParser.Parse(); err != nil { - return fmt.Errorf("couldn't parse OVMS config json: %v", err) - } - - if len(ovmsModelParser.ModelConfigList) > 0 { - // Create client from gRPC server connection - client := grpc_client.NewGRPCInferenceServiceClient(conn) - - var wg sync.WaitGroup - wg.Add(len(ovmsModelParser.ModelConfigList)) - for _, model := range ovmsModelParser.ModelConfigList { - go func(model parser.ModelConfigListInfo) { - defer wg.Done() - modelName := model.Config.ModelName - // we use /1 folder under the model so the model version is always 1 - modelVersion := "1" - modelReadyResponse, err := sendModelReadyRequest(client, modelName, modelVersion) - if err == nil && modelReadyResponse.Ready { - log.Printf("Model name %s with version %s is ready", modelName, modelVersion) - return - } - - // this model is not in ready state yet - // we will re-test this specific model for max retry - retryCnt := 0 - for { - if retryCnt >= ovmsModelReadyMaxRetries { - log.Printf("error: reaches the max retry count %d for checking model ready of ovms server; gave up", ovmsModelReadyMaxRetries) - return - } - - time.Sleep(time.Second) - retryCnt++ - // need new client every time since there is some cached issue if re-using the existing client - client := grpc_client.NewGRPCInferenceServiceClient(conn) - modelReadyResponse, err := sendModelReadyRequest(client, modelName, modelVersion) - if err == nil && modelReadyResponse.Ready { - log.Printf("Model name %s with version %s is ready", modelName, modelVersion) - break - } - } - }(model) - } - wg.Wait() - } - return nil -} - -func sendModelReadyRequest(client grpc_client.GRPCInferenceServiceClient, modelName string, modelVersion string) (*grpc_client.ModelReadyResponse, error) { - // Create context for request with 10 second timeout - // if any request takes longer than that, we consider the system is way too slow and thus unusable - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - modelReadyRequest := grpc_client.ModelReadyRequest{ - Name: modelName, - Version: modelVersion, - } - - modelReadyResponse, err := client.ModelReady(ctx, &modelReadyRequest) - if err != nil { - errMsg := fmt.Errorf("Couldn't get model name %s version %s ready state: %v", modelName, modelVersion, err) - log.Println(errMsg) - return nil, errMsg - } - - return modelReadyResponse, nil -} - -func (ovmsClientConf *OvmsClientConfig) initDockerLauncherEnvs() { - // default script for docker launcher - launcherScript := "docker-launcher.sh" - if len(ovmsClientConf.OvmsClient.DockerLauncher.LauncherScript) > 0 { - launcherScript = ovmsClientConf.OvmsClient.DockerLauncher.LauncherScript - } - - // process the volumes elements if any - volumeEnvStr := "" - if len(ovmsClientConf.OvmsClient.DockerLauncher.DockerVolumes) == 0 { - log.Println("NO Docker volumes defined") - } - - for _, volume := range ovmsClientConf.OvmsClient.DockerLauncher.DockerVolumes { - volumeEnvStr = strings.Join([]string{volumeEnvStr, dockerVolumeFlag, volume}, commandLineArgsDelimiter) - } - - pipelineRunCmd := ovmsClientConf.OvmsClient.PipelineScript - streamDensityMode := os.Getenv("STREAM_DENSITY_MODE") - if streamDensityMode == "1" { - volumeEnvStr = strings.Join([]string{ - volumeEnvStr, - dockerVolumeFlag, - strings.Join([]string{ - "\"$RUN_PATH\"/benchmark-scripts/stream_density.sh", - streamDensityScript}, ":"), - }, commandLineArgsDelimiter) - - pipelineRunCmd = strings.Join([]string{ - streamDensityScript, - ovmsClientConf.OvmsClient.PipelineScript, - }, commandLineArgsDelimiter) - os.Setenv(RESULT_DIR_ENV, streamDensityResultDir) - } - - inputArgs := strings.TrimSpace(ovmsClientConf.OvmsClient.PipelineInputArgs) - if len(inputArgs) > 0 { - pipelineRunCmd = strings.Join([]string{ - pipelineRunCmd, - inputArgs, - }, commandLineArgsDelimiter) - } - - os.Setenv(DOCKER_LAUNCHER_SCRIPT_ENV, launcherScript) - os.Setenv(DOCKER_IMAGE_ENV, ovmsClientConf.OvmsClient.DockerLauncher.DockerImage) - // append the CONTAINER_NAME env with profileLaunchedContainerNameSuffix so that it is easier to recognize those Docker containers - // launched by profile-launcher - os.Setenv(DOCKER_CONTAINER_NAME_ENV, ovmsClientConf.OvmsClient.DockerLauncher.ContainerName+profileLaunchedContainerNameSuffix) - os.Setenv(DOCKER_VOLUMES_ENV, strings.TrimSpace(volumeEnvStr)) - os.Setenv(DOCKER_CMD_ENV, pipelineRunCmd) - - log.Println(fmt.Sprintf("%s=%s", DOCKER_LAUNCHER_SCRIPT_ENV, os.Getenv(DOCKER_LAUNCHER_SCRIPT_ENV))) - log.Println(fmt.Sprintf("%s=%s", DOCKER_IMAGE_ENV, os.Getenv(DOCKER_IMAGE_ENV))) - log.Println(fmt.Sprintf("%s=%s", DOCKER_VOLUMES_ENV, os.Getenv(DOCKER_VOLUMES_ENV))) - log.Println(fmt.Sprintf("%s=%s", DOCKER_CONTAINER_NAME_ENV, os.Getenv(DOCKER_CONTAINER_NAME_ENV))) - log.Println(fmt.Sprintf("%s=%s", DOCKER_CMD_ENV, os.Getenv(DOCKER_CMD_ENV))) -} - -func (ovmsClientConf *OvmsClientConfig) launchPipelineScript() error { - launcherScript := filepath.Join(scriptDir, os.Getenv(DOCKER_LAUNCHER_SCRIPT_ENV)) - executable, err := exec.LookPath(launcherScript) - if err != nil { - return fmt.Errorf("failed to get pipeline executable path: %v", err) - } - - log.Println("running executable:", executable) - cmd := exec.Command(executable) - cmd.Env = os.Environ() - - // in order to do the environment override from the current existing cmd.Env, - // we have to save this and then apply the overrides with the existing keys - origEnvs := make([]string, len(cmd.Env)) - copy(origEnvs, cmd.Env) - // apply all envs from env files if any - envList := ovmsClientConf.OvmsClient.readClientEnvs(envFileDir) - cmd.Env = append(cmd.Env, envList...) - // override envs from the origEnvs - cmd.Env = append(cmd.Env, origEnvs...) - - // write envs to a temp file to be used in script - envWriter := NewTmpEnvFileWriter(cmd.Env) - if err := envWriter.writeEnvs(); err != nil { - return fmt.Errorf("failed to write the envs by envWriter: %v", err) - } - defer func() { - err := envWriter.cleanFile() - if err != nil { - log.Println("failed to clean tmp env file: ", envWriter.envFile.Name()) - } - }() - // make the env file name to the env so that the script can use it - cmd.Env = append(cmd.Env, strings.Join([]string{DOT_ENV_FILE_ENV, envWriter.envFile.Name()}, envDelimiter)) - - envs := cmd.Env - for _, env := range envs { - log.Println("environment variable: ", env) - } - if len(envs) == 0 { - log.Println("empty environment variable") - } - - stdout, err := cmd.StdoutPipe() - if err != nil { - return fmt.Errorf("failed to get the output from executable: %v", err) - } - stderr, err := cmd.StderrPipe() - if err != nil { - return fmt.Errorf("failed to get the error pipe from executable: %v", err) - } - if err := cmd.Start(); err != nil { - return fmt.Errorf("failed to start the pipeline executable: %v", err) - } - - stdoutBytes, _ := io.ReadAll(stdout) - log.Println("stdoutBytes: ", string(stdoutBytes)) - stdErrBytes, _ := io.ReadAll(stderr) - if err := cmd.Wait(); err != nil { - return fmt.Errorf("found error while executing pipeline scripts- stdErrMsg: %s, Err: %v", string(stdErrBytes), err) - } - - log.Println(string(stdoutBytes)) - return nil -} - -func parseInputArguments(ovmsClientConf OvmsClientConfig) []string { - inputArgs := []string{} - trimmedArgs := strings.TrimSpace(ovmsClientConf.OvmsClient.PipelineInputArgs) - if len(trimmedArgs) > 0 { - // arguments in command is space delimited - return strings.Split(trimmedArgs, commandLineArgsDelimiter) - } - return inputArgs -} - -func (flags *Flags) readPipelineConfig() ([]byte, error) { - var contents []byte - var err error - - pipelineConfig := filepath.Join(resourceDir, pipelineConfigFileName) - pipelineProfile := strings.TrimSpace(os.Getenv(pipelineProfileEnv)) - // if pipelineProfile is empty, then will default to the current folder - if len(pipelineProfile) == 0 { - log.Printf("Loading configuration yaml file from %s folder...", flags.configDir) - pipelineConfig = filepath.Join(flags.configDir, pipelineConfig) - } else { - log.Println("pipelineProfile: ", pipelineProfile) - pipelineConfig = filepath.Join(flags.configDir, resourceDir, pipelineProfile, pipelineConfigFileName) - } - - contents, err = os.ReadFile(pipelineConfig) - if err != nil { - err = fmt.Errorf("readPipelineConfig error with pipelineConfig: %v, environment variable key for pipelineProfile: %v, error: %v", - pipelineConfig, pipelineProfileEnv, err) - } - - return contents, err -} - -func (flags *Flags) genOVMSModelConfig() { - if len(flags.oVMSModelConfigDir) > 0 { - log.Println("generate config.json file for docker compose up case...") - - deviceUpdater := server.NewDeviceUpdater(flags.oVMSModelConfigDir, ovmsTemplateConfigJson) - targetDevice := defaultTargetDevice - if len(os.Getenv(TARGET_DEVICE_ENV)) > 0 { - // only set the value from env if env is not empty; otherwise defaults to the default value in defaultTargetDevice - // devices supported CPU, GPU, GPU.x, AUTO, MULTI:GPU,CPU - targetDevice = os.Getenv(TARGET_DEVICE_ENV) - } - - log.Println("Updating config with DEVICE environment variable:", targetDevice) - - newUpdateConfigJson := "config.json" - - if err := deviceUpdater.UpdateDeviceAndCreateJson(targetDevice, filepath.Join(flags.oVMSModelConfigDir, newUpdateConfigJson)); err != nil { - log.Printf("Error: failed to update device and produce a new ovms server config json: %v", err) - os.Exit(1) - } - - configJsonContainer := filepath.Join("/models", newUpdateConfigJson) - log.Println("configJsonContainer:", configJsonContainer) - os.Exit(0) - } else { - log.Println("no OVMS Model config input, skip...") - } -} diff --git a/configs/opencv-ovms/cmd_client/ovmsClientConf_test.go b/configs/opencv-ovms/cmd_client/ovmsClientConf_test.go deleted file mode 100644 index 13918161..00000000 --- a/configs/opencv-ovms/cmd_client/ovmsClientConf_test.go +++ /dev/null @@ -1,89 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2023 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package main - -import ( - "log" - "os" - "os/exec" - "strconv" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestSetEnvContainerCountAndGrpcPort(t *testing.T) { - tests := []struct { - name string - launchContainer func(t *testing.T) - cleanup func(t *testing.T) - expectedCidCnt string - }{ - {"first time run", func(t *testing.T) {}, func(t *testing.T) {}, "0"}, - {"launch one dummy container and check", launchDummyContainer, cleanupDummyContainer, "1"}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - client := &OvmsClientConfig{ - OvmsClient: OvmsClientInfo{}, - } - - origCidEnv := os.Getenv(CID_COUNT_ENV) - origGrpcPortEnv := os.Getenv(GRPC_PORT_ENV) - - tt.launchContainer(t) - - client.setEnvContainerCountAndGrpcPort() - defer func() { - tt.cleanup(t) - os.Setenv(CID_COUNT_ENV, origCidEnv) - os.Setenv(GRPC_PORT_ENV, origGrpcPortEnv) - }() - - newCidCnt := os.Getenv(CID_COUNT_ENV) - require.Equal(t, tt.expectedCidCnt, newCidCnt) - - newGrpcPort := os.Getenv(GRPC_PORT_ENV) - require.NotEmpty(t, newGrpcPort) - grpcPortNum, err := strconv.Atoi(newGrpcPort) - require.NoError(t, err) - require.True(t, grpcPortNum > defaultGrpcPortFrom) - }) - } -} - -func launchDummyContainer(t *testing.T) { - dummyContainerName := "dummy" + profileLaunchedContainerNameSuffix - dummyDockerCmd := exec.Command("docker", []string{"run", "--name", dummyContainerName, "busybox"}...) - if err := dummyDockerCmd.Run(); err != nil { - log.Printf("failed to launch dummy Docker container busybox with container name %s: %v", dummyContainerName, err) - t.Fail() - } - time.Sleep(3) -} - -func cleanupDummyContainer(t *testing.T) { - dummyContainerName := "dummy" + profileLaunchedContainerNameSuffix - dummyDockerCmd := exec.Command("docker", []string{"rm", dummyContainerName, "-f"}...) - if err := dummyDockerCmd.Run(); err != nil { - log.Printf("failed to clean up dummy Docker container busybox with container name %s: %v", dummyContainerName, err) - t.Fail() - } -} diff --git a/configs/opencv-ovms/cmd_client/ovmsGrpcPort.go b/configs/opencv-ovms/cmd_client/ovmsGrpcPort.go deleted file mode 100644 index a5983d3b..00000000 --- a/configs/opencv-ovms/cmd_client/ovmsGrpcPort.go +++ /dev/null @@ -1,83 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2023 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package main - -import ( - "bufio" - "fmt" - "io" - "log" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" -) - -const ( - SERVER_CONTAINER_INSTANCE_ENV = "SERVER_CONTAINER_INSTANCE" -) - -func getServerGrpcPort(srvContainerName string) (string, error) { - os.Setenv(SERVER_CONTAINER_INSTANCE_ENV, srvContainerName) - - grpcPortScript := filepath.Join(scriptDir, "get_server_grpc_port.sh") - script, err := exec.LookPath(grpcPortScript) - if err != nil { - return "", fmt.Errorf("failed to get server grpc port script path: %v", err) - } - - log.Println("running get server grpc port script:", script) - srvGrpcPortCmd := exec.Command(script) - stdout, err := srvGrpcPortCmd.StdoutPipe() - if err != nil { - return "", fmt.Errorf("failed to get the output from script: %v", err) - } - stderr, err := srvGrpcPortCmd.StderrPipe() - if err != nil { - return "", fmt.Errorf("failed to get the error pipe from script: %v", err) - } - if err := srvGrpcPortCmd.Start(); err != nil { - return "", fmt.Errorf("failed to start the script: %v", err) - } - - portReader := bufio.NewReader(stdout) - resBytes, _ := portReader.ReadString('\n') - - stdErrBytes, _ := io.ReadAll(stderr) - if err := srvGrpcPortCmd.Wait(); err != nil { - return "", fmt.Errorf("found error while executing get server grpc port scripts- stdErrMsg: %s, Err: %v", string(stdErrBytes), err) - } - - srvPortNum := strings.TrimSuffix(string(resBytes), fmt.Sprintln()) - - log.Printf("srvPortNum from OVMS server %s: %s", srvContainerName, srvPortNum) - - // verify it is an integer - if len(srvPortNum) > 0 { - // verify the output is an integer - _, err := strconv.Atoi(srvPortNum) - if err != nil { - return "", fmt.Errorf("failed to parse the OVMS server port number for %s: %v", srvContainerName, err) - } - } else { - return "", fmt.Errorf("srvPortNum is empty for %s, cannot continue", srvContainerName) - } - - return srvPortNum, nil -} diff --git a/configs/opencv-ovms/cmd_client/parser/ovmsConfigJsonParser.go b/configs/opencv-ovms/cmd_client/parser/ovmsConfigJsonParser.go deleted file mode 100644 index f351c54a..00000000 --- a/configs/opencv-ovms/cmd_client/parser/ovmsConfigJsonParser.go +++ /dev/null @@ -1,69 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2023 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package parser - -import ( - "encoding/json" - "fmt" - "io" - "os" - "path/filepath" -) - -type ModelConfigInfo struct { - ModelName string `json:"name"` -} - -type ModelConfigListInfo struct { - Config ModelConfigInfo `json:"config"` -} - -type ConfigJsonModelParser struct { - ModelConfigList []ModelConfigListInfo `json:"model_config_list"` - - configJsonFileName string - configJsonDir string -} - -func NewConfigJsonModelParser(configJsonDir, configJsonFileName string) *ConfigJsonModelParser { - return &ConfigJsonModelParser{ - configJsonDir: configJsonDir, - configJsonFileName: configJsonFileName, - } -} - -// Parse will parse the list of model names from the file configJsonFileName under the directory configJsonDir -func (cjmp *ConfigJsonModelParser) Parse() error { - configJsonFile := filepath.Join(cjmp.configJsonDir, cjmp.configJsonFileName) - jsonFileReader, err := os.Open(configJsonFile) - if err != nil { - return fmt.Errorf("failed to open OVMS config json file %s: %v", configJsonFile, err) - } - defer jsonFileReader.Close() - - contents, err := io.ReadAll(jsonFileReader) - if err != nil { - return fmt.Errorf("failed to read OVMS config json file %s: %v", configJsonFile, err) - } - - if err := json.Unmarshal(contents, &cjmp); err != nil { - return fmt.Errorf("failed to unmarshal OVMS config json: %v", err) - } - - return nil -} diff --git a/configs/opencv-ovms/cmd_client/parser/ovmsConfigJsonParser_test.go b/configs/opencv-ovms/cmd_client/parser/ovmsConfigJsonParser_test.go deleted file mode 100644 index 120f82f5..00000000 --- a/configs/opencv-ovms/cmd_client/parser/ovmsConfigJsonParser_test.go +++ /dev/null @@ -1,56 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2023 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package parser - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestParse(t *testing.T) { - tests := []struct { - name string - jsonFileDir string - jsonFileName string - expectError bool - }{ - {"current template json file", ".", "test-config_template.json", false}, - {"invalid json content", ".", "test-invalid.json", true}, - {"non-existing json file", ".", "non-existing.json", true}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - configParser := NewConfigJsonModelParser(tt.jsonFileDir, tt.jsonFileName) - - err := configParser.Parse() - if !tt.expectError { - require.NoError(t, err) - require.NotEmpty(t, configParser) - require.Contains(t, configParser.ModelConfigList, ModelConfigListInfo{ - Config: ModelConfigInfo{ - ModelName: "efficientnet-b0", - }, - }) - } else { - require.Error(t, err) - } - }) - } -} diff --git a/configs/opencv-ovms/cmd_client/parser/test-config_template.json b/configs/opencv-ovms/cmd_client/parser/test-config_template.json deleted file mode 100644 index 2bf48324..00000000 --- a/configs/opencv-ovms/cmd_client/parser/test-config_template.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "model_config_list": [ - { - "config": { - "name": "bit_64", - "base_path": "/models/BiT_M_R50x1_10C_50e_IR/FP16-INT8", - "nireq": 1, - "batch_size": "1", - "shape": "(1,64,64,3)", - "layout": "NHWC:NHWC", - "plugin_config": { - "PERFORMANCE_HINT": "LATENCY" - }, - "target_device": "{target_device}" - }, - "latest": { - "num_versions": 1 - } - }, - { - "config": { - "name": "yolov5s", - "base_path": "/models/yolov5s/FP16-INT8", - "layout": "NHWC:NCHW", - "shape": "(1,416,416,3)", - "nireq": 1, - "batch_size": "1", - "plugin_config": { - "PERFORMANCE_HINT": "LATENCY" - }, - "target_device": "{target_device}" - } - }, - { - "config": { - "name": "efficientnet-b0", - "base_path": "/models/efficientnet-b0/FP32", - "target_device": "{target_device}" - }, - "latest": { - "num_versions": 1 - } - } - ] -} \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/parser/test-invalid.json b/configs/opencv-ovms/cmd_client/parser/test-invalid.json deleted file mode 100644 index 8a46b88b..00000000 --- a/configs/opencv-ovms/cmd_client/parser/test-invalid.json +++ /dev/null @@ -1 +0,0 @@ -;invalid{} \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/portfinder/findPort.go b/configs/opencv-ovms/cmd_client/portfinder/findPort.go deleted file mode 100644 index 1f08a82c..00000000 --- a/configs/opencv-ovms/cmd_client/portfinder/findPort.go +++ /dev/null @@ -1,53 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2023 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package portfinder - -import ( - "fmt" - "log" - "net" -) - -const ( - defaultStartPort = 9000 -) - -type PortFinder struct { - IpAddress string -} - -func (pf *PortFinder) GetFreePortNumber(from int) int { - if from <= 0 { - return defaultStartPort - } - - if tcpAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:0", pf.IpAddress)); err == nil { - var tcpLis *net.TCPListener - if tcpLis, err = net.ListenTCP("tcp", tcpAddr); err == nil { - defer tcpLis.Close() - portNum := tcpLis.Addr().(*net.TCPAddr).Port - if portNum < from { // retry again until we find one port number is bigger - return pf.GetFreePortNumber(from) - } - return portNum - } - } else { - log.Printf("resolve error on tcpAddr: %v", tcpAddr) - } - return defaultStartPort -} diff --git a/configs/opencv-ovms/cmd_client/portfinder/findPort_test.go b/configs/opencv-ovms/cmd_client/portfinder/findPort_test.go deleted file mode 100644 index b0a0405f..00000000 --- a/configs/opencv-ovms/cmd_client/portfinder/findPort_test.go +++ /dev/null @@ -1,48 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2023 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package portfinder - -import ( - "log" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestScan(t *testing.T) { - tests := []struct { - name string - from int - }{ - {"good free port at least bigger than defaultPort", defaultStartPort}, - {"good free port at least bigger than from", 0}, - {"good free port at least bigger than from a bigger", 35000}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - portFinder := PortFinder{ - IpAddress: "localhost", - } - - result := portFinder.GetFreePortNumber(tt.from) - log.Println("result=", result) - require.True(t, result > tt.from) - }) - } -} diff --git a/configs/opencv-ovms/cmd_client/readEnv.go b/configs/opencv-ovms/cmd_client/readEnv.go deleted file mode 100644 index 1ac8a943..00000000 --- a/configs/opencv-ovms/cmd_client/readEnv.go +++ /dev/null @@ -1,86 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2023 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package main - -import ( - "bufio" - "fmt" - "log" - "os" - "path/filepath" - "strings" -) - -func (ovmsServer OvmsServerInfo) readServerEnvs(envFileDir string) (envList []string) { - return readEnvs(envFileDir, ovmsServer.EnvironmentVariableFiles) -} - -func (ovmsClient OvmsClientInfo) readClientEnvs(envFileDir string) (envList []string) { - return readEnvs(envFileDir, ovmsClient.EnvironmentVariableFiles) -} - -func readEnvs(envFileDir string, evnFileNames []string) (envList []string) { - if len(evnFileNames) > 0 { - log.Println("found env files to apply") - for _, eachEnvFile := range evnFileNames { - // load each file, parse the key value pair and append them into envs - envFilePath := filepath.Join(envFileDir, eachEnvFile) - envFileHdle, err := os.Open(envFilePath) - if err != nil { - log.Printf("Error- error found for reading env file %s: %v", envFilePath, err) - // skipping applying envs for this envFilePath - continue - } - defer envFileHdle.Close() - - reader := bufio.NewScanner(envFileHdle) - reader.Split(envSplitFunc) - - for reader.Scan() { - envKeyValue := reader.Text() - log.Println("env key-value pair:", envKeyValue) - envList = append(envList, envKeyValue) - } - - for _, envItem := range envList { - log.Println("envItem:", envItem) - } - } - return envList - } - - return -} - -func envSplitFunc(contents []byte, atEOF bool) (advance int, token []byte, err error) { - if atEOF && len(contents) == 0 { - return 0, nil, nil - } - - if atEOF { - return len(contents), contents, nil - } - - newLine := fmt.Sprintln() - if i := strings.Index(string(contents), newLine); i >= 0 { - // skip the new line delimiter - return i + len(newLine), contents[0:i], nil - } - - return -} diff --git a/configs/opencv-ovms/cmd_client/readEnv_test.go b/configs/opencv-ovms/cmd_client/readEnv_test.go deleted file mode 100644 index d4437b39..00000000 --- a/configs/opencv-ovms/cmd_client/readEnv_test.go +++ /dev/null @@ -1,57 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2023 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package main - -import ( - "log" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestReadEnvs(t *testing.T) { - tests := []struct { - name string - envFileDir string - envFilesToTest []string - expectedEnvList []string - }{ - {"valid EnvFilePath with no envfile", "./testdata", nil, nil}, - {"valid EnvFilePath with empty env", "./testdata", []string{"empty.env"}, nil}, - {"valid EnvFilePath with some envs", "./testdata", []string{"empty.env", "test.env"}, []string{"TESTKEY1=TESTVALUE1", "TESTKEY2=TESTVALUE2"}}, - {"invalid EnvFilePath", "./notfound", []string{"empty.env", "test.env"}, nil}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - log.Println(tt.envFileDir) - client := OvmsClientInfo{ - EnvironmentVariableFiles: tt.envFilesToTest, - } - - result := client.readClientEnvs(tt.envFileDir) - require.Equal(t, tt.expectedEnvList, result) - - server := OvmsServerInfo{ - EnvironmentVariableFiles: tt.envFilesToTest, - } - result = server.readServerEnvs(tt.envFileDir) - require.Equal(t, tt.expectedEnvList, result) - }) - } -} diff --git a/configs/opencv-ovms/cmd_client/res/capi_face_detection/configuration.yaml b/configs/opencv-ovms/cmd_client/res/capi_face_detection/configuration.yaml deleted file mode 100644 index 66ddfdca..00000000 --- a/configs/opencv-ovms/cmd_client/res/capi_face_detection/configuration.yaml +++ /dev/null @@ -1,17 +0,0 @@ -OvmsSingleContainer: true -OvmsClient: - DockerLauncher: - Script: docker-launcher.sh - DockerImage: openvino/model_server-capi-gst-ovms-face_detection:latest - ContainerName: capi_face_detection - Volumes: - - "$cl_cache_dir:/home/intel/gst-ovms/.cl-cache" - - /tmp/.X11-unix:/tmp/.X11-unix - - "$RUN_PATH/sample-media/:/home/intel/gst-ovms/vids" - - "$RUN_PATH/configs/opencv-ovms/gst_capi/extensions:/home/intel/gst-ovms/extensions" - - "$RUN_PATH/results:/tmp/results" - - "$RUN_PATH/configs/opencv-ovms/models/2022/:/models" - PipelineScript: ./run_gst_capi.sh - PipelineInputArgs: "" # space delimited like we run the script in command and take those input arguments - EnvironmentVariableFiles: - - capi_face_detection.env diff --git a/configs/opencv-ovms/cmd_client/res/capi_yolov5/configuration.yaml b/configs/opencv-ovms/cmd_client/res/capi_yolov5/configuration.yaml deleted file mode 100644 index 79fd997a..00000000 --- a/configs/opencv-ovms/cmd_client/res/capi_yolov5/configuration.yaml +++ /dev/null @@ -1,17 +0,0 @@ -OvmsSingleContainer: true -OvmsClient: - DockerLauncher: - Script: docker-launcher.sh - DockerImage: openvino/model_server-capi-gst-ovms-capi_yolov5:latest - ContainerName: capi_yolov5 - Volumes: - - "$cl_cache_dir:/home/intel/gst-ovms/.cl-cache" - - /tmp/.X11-unix:/tmp/.X11-unix - - "$RUN_PATH/sample-media/:/home/intel/gst-ovms/vids" - - "$RUN_PATH/configs/opencv-ovms/gst_capi/extensions:/home/intel/gst-ovms/extensions" - - "$RUN_PATH/results:/tmp/results" - - "$RUN_PATH/configs/opencv-ovms/models/2022/:/models" - PipelineScript: ./run_gst_capi.sh - PipelineInputArgs: "" # space delimited like we run the script in command and take those input arguments - EnvironmentVariableFiles: - - capi_yolov5.env diff --git a/configs/opencv-ovms/cmd_client/res/capi_yolov5_ensemble/configuration.yaml b/configs/opencv-ovms/cmd_client/res/capi_yolov5_ensemble/configuration.yaml deleted file mode 100644 index 11b149ed..00000000 --- a/configs/opencv-ovms/cmd_client/res/capi_yolov5_ensemble/configuration.yaml +++ /dev/null @@ -1,17 +0,0 @@ -OvmsSingleContainer: true -OvmsClient: - DockerLauncher: - Script: docker-launcher.sh - DockerImage: openvino/model_server-capi-gst-ovms-capi_yolov5_ensemble:latest - ContainerName: capi_yolov5_ensemble - Volumes: - - "$cl_cache_dir:/home/intel/gst-ovms/.cl-cache" - - /tmp/.X11-unix:/tmp/.X11-unix - - "$RUN_PATH/sample-media/:/home/intel/gst-ovms/vids" - - "$RUN_PATH/configs/opencv-ovms/gst_capi/extensions:/home/intel/gst-ovms/extensions" - - "$RUN_PATH/results:/tmp/results" - - "$RUN_PATH/configs/opencv-ovms/models/2022/:/models" - PipelineScript: ./run_gst_capi.sh - PipelineInputArgs: "" # space delimited like we run the script in command and take those input arguments - EnvironmentVariableFiles: - - capi_yolov5_ensemble.env diff --git a/configs/opencv-ovms/cmd_client/res/capi_yolov8_ensemble/configuration.yaml b/configs/opencv-ovms/cmd_client/res/capi_yolov8_ensemble/configuration.yaml deleted file mode 100644 index 2f00c6e7..00000000 --- a/configs/opencv-ovms/cmd_client/res/capi_yolov8_ensemble/configuration.yaml +++ /dev/null @@ -1,19 +0,0 @@ -OvmsSingleContainer: true -OvmsClient: - DockerLauncher: - Script: docker-launcher.sh - DockerImage: openvino/model_server-capi-gst-ovms-capi_yolov8_ensemble:latest - ContainerName: capi_yolov8_ensemble - Volumes: - - "$cl_cache_dir:/app/gst-ovms/.cl-cache" - - /tmp/.X11-unix:/tmp/.X11-unix - - "$RUN_PATH/sample-media/:/app/gst-ovms/vids" - - "$RUN_PATH/configs/opencv-ovms/gst_capi/extensions:/app/gst-ovms/extensions" - - "$RUN_PATH/results:/tmp/results" - - "$RUN_PATH/configs/opencv-ovms/models/2022/:/models" - # when the OVMSCustomNodeJson is not empty, then it will add or replace the existing customNode info for CAPI-OVMS server config - OVMSCustomNodeJson: yolov8_custom_node.json - PipelineScript: /app/gst-ovms/pipelines/yolov8_ensemble/yolo_efficientnet.sh - PipelineInputArgs: "" # space delimited like we run the script in command and take those input arguments - EnvironmentVariableFiles: - - capi_yolov8_ensemble.env diff --git a/configs/opencv-ovms/cmd_client/res/capi_yolov8_ensemble/yolov8_custom_node.json b/configs/opencv-ovms/cmd_client/res/capi_yolov8_ensemble/yolov8_custom_node.json deleted file mode 100644 index 905b401f..00000000 --- a/configs/opencv-ovms/cmd_client/res/capi_yolov8_ensemble/yolov8_custom_node.json +++ /dev/null @@ -1,85 +0,0 @@ -{ -"custom_node_library_config_list": [ - { - "name": "efficientnetb0_extractor", - "base_path": "/ovms/lib/libcustom_node_efficientnetb0-yolov8.so" - } -], -"pipeline_config_list": [ - { - "name": "detect_classify", - "inputs": ["images"], - "nodes": [ - { - "name": "detection_node", - "model_name": "yolov8", - "type": "DL model", - "inputs": [ - {"images": {"node_name": "request", - "data_item": "images"} - } - ], - "outputs": [ - {"data_item": "output0", - "alias": "boxes"} - ] - }, - { - "name": "extract_node", - "library_name": "efficientnetb0_extractor", - "type": "custom", - "demultiply_count": 0, - "params": { - "original_image_width": "416", - "original_image_height": "416", - "original_image_layout": "NCHW", - "target_image_width": "224", - "target_image_height": "224", - "target_image_layout": "NCHW", - "convert_to_gray_scale": "false", - "confidence_threshold": "0.5", - "max_output_batch": "100", - "debug": "false" - }, - "inputs": [ - {"images": {"node_name": "request", - "data_item": "images"}}, - {"boxes": {"node_name": "detection_node", - "data_item": "boxes"}} - ], - "outputs": [ - {"data_item": "roi_images", - "alias": "roi_images"}, - {"data_item": "roi_coordinates", - "alias": "roi_coordinates"}, - {"data_item": "confidence_levels", - "alias": "confidence_levels"} - ] - }, - { - "name": "classification_node", - "model_name": "efficientnetb0_FP32INT8", - "type": "DL model", - "inputs": [ - {"sub": {"node_name": "extract_node", - "data_item": "roi_images"}} - ], - "outputs": [ - {"data_item": "efficientnet-b0/model/head/dense/BiasAdd/Add", - "alias": "classify_output"} - ] - } - ], - "outputs": [ - {"roi_images": {"node_name": "extract_node", - "data_item": "roi_images"}}, - {"roi_coordinates": {"node_name": "extract_node", - "data_item": "roi_coordinates"}}, - {"confidence_levels": {"node_name": "extract_node", - "data_item": "confidence_levels"}}, - {"classify_output": {"node_name": "classification_node", - "data_item": "classify_output"}} - ] - } -] -} \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/res/classification/configuration.yaml b/configs/opencv-ovms/cmd_client/res/classification/configuration.yaml deleted file mode 100644 index 9f1a3447..00000000 --- a/configs/opencv-ovms/cmd_client/res/classification/configuration.yaml +++ /dev/null @@ -1,29 +0,0 @@ -OvmsSingleContainer: false -OvmsServer: - ServerDockerScript: start_ovms_server.sh - ServerDockerImage: openvino/model_server:2023.1-gpu - ServerContainerName: ovms-server - ServerConfig: "/models/config.json" - StartupMessage: Starting OVMS server - InitWaitTime: 10s - EnvironmentVariableFiles: - - ovms_server.env - # StartUpPolicy: - # when there is an error on launching ovms server startup, choose one of these values for the behavior of profile-launcher: - # remove-and-restart: it will remove the existing container with the same container name if any and then restart the container - # exit: it will exit the profile-launcher and - # ignore: it will ignore the error and continue (this is the default value if not given or none of the above) - StartUpPolicy: ignore -OvmsClient: - DockerLauncher: - Script: docker-launcher.sh - DockerImage: python-demo:dev - ContainerName: classification - Volumes: - - "$RUN_PATH/results:/tmp/results" - - ~/.Xauthority:/home/dlstreamer/.Xauthority - - /tmp/.X11-unix - PipelineScript: ./classification/python/entrypoint.sh - PipelineInputArgs: "" # space delimited like we run the script in command and take those input arguments - EnvironmentVariableFiles: - - classification.env \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/res/grpc_go/configuration.yaml b/configs/opencv-ovms/cmd_client/res/grpc_go/configuration.yaml deleted file mode 100644 index 196ed551..00000000 --- a/configs/opencv-ovms/cmd_client/res/grpc_go/configuration.yaml +++ /dev/null @@ -1,27 +0,0 @@ -OvmsSingleContainer: false -OvmsServer: - ServerDockerScript: start_ovms_server.sh - ServerDockerImage: openvino/model_server:2023.1-gpu - ServerContainerName: ovms-server - ServerConfig: "/models/config.json" - StartupMessage: Starting OVMS server - InitWaitTime: 10s - EnvironmentVariableFiles: - - ovms_server.env - # StartUpPolicy: - # when there is an error on launching ovms server startup, choose one of these values for the behavior of profile-launcher: - # remove-and-restart: it will remove the existing container with the same container name if any and then restart the container - # exit: it will exit the profile-launcher and - # ignore: it will ignore the error and continue (this is the default value if not given or none of the above) - StartUpPolicy: ignore -OvmsClient: - DockerLauncher: - Script: docker-launcher.sh - DockerImage: grpc_go:dev - ContainerName: grpc_go - Volumes: - - "$RUN_PATH/results:/tmp/results" - - ~/.Xauthority:/home/dlstreamer/.Xauthority - - /tmp/.X11-unix - PipelineScript: ./entrypoint.sh - PipelineInputArgs: "" # space delimited like we run the script in command and take those input arguments diff --git a/configs/opencv-ovms/cmd_client/res/grpc_python/configuration.yaml b/configs/opencv-ovms/cmd_client/res/grpc_python/configuration.yaml deleted file mode 100644 index 02f12e2b..00000000 --- a/configs/opencv-ovms/cmd_client/res/grpc_python/configuration.yaml +++ /dev/null @@ -1,29 +0,0 @@ -OvmsSingleContainer: false -OvmsServer: - ServerDockerScript: start_ovms_server.sh - ServerDockerImage: openvino/model_server:2023.1-gpu - ServerContainerName: ovms-server - ServerConfig: "/models/config.json" - StartupMessage: Starting OVMS server - InitWaitTime: 10s - EnvironmentVariableFiles: - - ovms_server.env - # StartUpPolicy: - # when there is an error on launching ovms server startup, choose one of these values for the behavior of profile-launcher: - # remove-and-restart: it will remove the existing container with the same container name if any and then restart the container - # exit: it will exit the profile-launcher and - # ignore: it will ignore the error and continue (this is the default value if not given or none of the above) - StartUpPolicy: ignore -OvmsClient: - DockerLauncher: - Script: docker-launcher.sh - DockerImage: grpc_python:dev - ContainerName: grpc_python - Volumes: - - "$RUN_PATH/results:/tmp/results" - PipelineScript: /app/run_grpc_python.sh - PipelineInputArgs: "--model_name instance-segmentation-security-1040" # space delimited like we run the script in command and take those input arguments - # PipelineInputArgs: "--model_name bit_64" # space delimited like we run the script in command and take those input arguments - # PipelineInputArgs: "--model_name yolov5s" # space delimited like we run the script in command and take those input arguments - EnvironmentVariableFiles: - - grpc_python.env \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/res/gst/configuration.yaml b/configs/opencv-ovms/cmd_client/res/gst/configuration.yaml deleted file mode 100644 index d48a8144..00000000 --- a/configs/opencv-ovms/cmd_client/res/gst/configuration.yaml +++ /dev/null @@ -1,35 +0,0 @@ -OvmsSingleContainer: false -OvmsServer: - ServerDockerScript: start_ovms_server.sh - ServerDockerImage: openvino/model_server:2023.1-gpu - ServerContainerName: ovms-server - ServerConfig: "/models/config.json" - StartupMessage: Starting OVMS server - InitWaitTime: 2s - EnvironmentVariableFiles: - - ovms_server.env - # StartUpPolicy: - # when there is an error on launching ovms server startup, choose one of these values for the behavior of profile-launcher: - # remove-and-restart: it will remove the existing container with the same container name if any and then restart the container - # exit: it will exit the profile-launcher and - # ignore: it will ignore the error and continue (this is the default value if not given or none of the above) - StartUpPolicy: ignore -OvmsClient: - DockerLauncher: - Script: docker-launcher.sh - DockerImage: dlstreamer:dev - ContainerName: gst - Volumes: - - "$cl_cache_dir:/home/pipeline-server/.cl-cache" - - /tmp/.X11-unix:/tmp/.X11-unix - - "$RUN_PATH/sample-media/:/home/pipeline-server/vids" - - "$RUN_PATH/configs/opencv-ovms/gst/extensions:/home/pipeline-server/extensions" - - "$RUN_PATH/configs/opencv-ovms/gst/framework-pipelines:/home/pipeline-server/framework-pipelines" - - "$RUN_PATH/configs/opencv-ovms/models/2022:/home/pipeline-server/models" - - "$RUN_PATH/results:/tmp/results" - - "$RUN_PATH/scripts:/home/pipeline-server/scripts" - - "$RUN_PATH/envs:/home/pipeline-server/envs" - PipelineScript: /home/pipeline-server/scripts/run_gst.sh - PipelineInputArgs: "--pipeline_script_choice yolov5s.sh" # space delimited like we run the script in command and take those input arguments - EnvironmentVariableFiles: - - gst.env diff --git a/configs/opencv-ovms/cmd_client/res/instance_segmentation/configuration.yaml b/configs/opencv-ovms/cmd_client/res/instance_segmentation/configuration.yaml deleted file mode 100644 index b68c763e..00000000 --- a/configs/opencv-ovms/cmd_client/res/instance_segmentation/configuration.yaml +++ /dev/null @@ -1,27 +0,0 @@ -OvmsSingleContainer: false -OvmsServer: - ServerDockerScript: start_ovms_server.sh - ServerDockerImage: openvino/model_server:2023.1-gpu - ServerContainerName: ovms-server - ServerConfig: "/models/config.json" - StartupMessage: Starting OVMS server - InitWaitTime: 10s - EnvironmentVariableFiles: - - ovms_server.env - # StartUpPolicy: - # when there is an error on launching ovms server startup, choose one of these values for the behavior of profile-launcher: - # remove-and-restart: it will remove the existing container with the same container name if any and then restart the container - # exit: it will exit the profile-launcher and - # ignore: it will ignore the error and continue (this is the default value if not given or none of the above) - StartUpPolicy: ignore -OvmsClient: - DockerLauncher: - Script: docker-launcher.sh - DockerImage: python-demo:dev - ContainerName: segmentation - Volumes: - - "$RUN_PATH/results:/tmp/results" - - ~/.Xauthority:/home/dlstreamer/.Xauthority - - /tmp/.X11-unix - PipelineScript: ./instance_segmentation/python/entrypoint.sh - PipelineInputArgs: "" # space delimited like we run the script in command and take those input arguments \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/res/object_detection/configuration.yaml b/configs/opencv-ovms/cmd_client/res/object_detection/configuration.yaml deleted file mode 100644 index da6bd8b2..00000000 --- a/configs/opencv-ovms/cmd_client/res/object_detection/configuration.yaml +++ /dev/null @@ -1,29 +0,0 @@ -OvmsSingleContainer: false -OvmsServer: - ServerDockerScript: start_ovms_server.sh - ServerDockerImage: openvino/model_server:2023.1-gpu - ServerContainerName: ovms-server - ServerConfig: "/models/config.json" - StartupMessage: Starting OVMS server - InitWaitTime: 10s - EnvironmentVariableFiles: - - ovms_server.env - # StartUpPolicy: - # when there is an error on launching ovms server startup, choose one of these values for the behavior of profile-launcher: - # remove-and-restart: it will remove the existing container with the same container name if any and then restart the container - # exit: it will exit the profile-launcher and - # ignore: it will ignore the error and continue (this is the default value if not given or none of the above) - StartUpPolicy: ignore -OvmsClient: - DockerLauncher: - Script: docker-launcher.sh - DockerImage: python-demo:dev - ContainerName: object-detection - Volumes: - - "$RUN_PATH/results:/tmp/results" - - ~/.Xauthority:/home/dlstreamer/.Xauthority - - /tmp/.X11-unix - PipelineScript: ./object_detection/python/entrypoint.sh - PipelineInputArgs: "" # space delimited like we run the script in command and take those input arguments - EnvironmentVariableFiles: - - object_detection.env diff --git a/configs/opencv-ovms/cmd_client/res/test/configuration.yaml b/configs/opencv-ovms/cmd_client/res/test/configuration.yaml deleted file mode 100644 index 91468660..00000000 --- a/configs/opencv-ovms/cmd_client/res/test/configuration.yaml +++ /dev/null @@ -1,28 +0,0 @@ -OvmsSingleContainer: false -OvmsServer: - ServerDockerScript: start_ovms_server.sh - ServerDockerImage: openvino/model_server:2023.1-gpu - ServerContainerName: ovms-server - ServerConfig: "/models/config.json" - StartupMessage: Starting OVMS server - InitWaitTime: 2s - EnvironmentVariableFiles: - - ovms_server.env - # StartUpPolicy: - # when there is an error on launching ovms server startup, choose one of these values for the behavior of profile-launcher: - # remove-and-restart: it will remove the existing container with the same container name if any and then restart the container - # exit: it will exit the profile-launcher and - # ignore: it will ignore the error and continue (this is the default value if not given or none of the above) - StartUpPolicy: ignore -OvmsClient: - DockerLauncher: - Script: docker-launcher.sh - DockerImage: ubuntu:22.04 - ContainerName: test - Volumes: - - "$RUN_PATH/results:/tmp/results" - - "$RUN_PATH/scripts:/tmp/scripts" - PipelineScript: /tmp/scripts/run_test.sh - PipelineInputArgs: "" # space delimited like we run the script in command and take those input arguments - EnvironmentVariableFiles: - - object_detection.env diff --git a/configs/opencv-ovms/cmd_client/run_unit_test.sh b/configs/opencv-ovms/cmd_client/run_unit_test.sh deleted file mode 100755 index cc43db8c..00000000 --- a/configs/opencv-ovms/cmd_client/run_unit_test.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -echo "Running go unit tests..." - -go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.31.0 -go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 - -# make sure we have fresh file every time, delete it just in case -rm grpc_predict_v2.proto || true -# Compile grpc APIs -wget https://raw.githubusercontent.com/openvinotoolkit/model_server/main/src/kfserving_api/grpc_predict_v2.proto -echo 'option go_package = "./grpc-client";' >> grpc_predict_v2.proto -protoc --go_out="./" --go-grpc_out="./" ./grpc_predict_v2.proto - -go mod tidy -go test -cover -count=1 ./... || true - -# cleanup -rm grpc_predict_v2.proto || true -rm -rf ./grpc-client/ || true diff --git a/configs/opencv-ovms/cmd_client/server/customNode.go b/configs/opencv-ovms/cmd_client/server/customNode.go deleted file mode 100644 index a9a45db0..00000000 --- a/configs/opencv-ovms/cmd_client/server/customNode.go +++ /dev/null @@ -1,90 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2024 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package server - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" -) - -type CustomNodeUpdater struct { - customNodeConfigJsonFile string - templateConfigJsonDir string - templateConfigJsonFileName string -} - -type OvmsCustomNodeConfig struct { - CustomNode []map[string]interface{} `json:"custom_node_library_config_list"` - PipelineConfig []map[string]interface{} `json:"pipeline_config_list"` -} - -func NewCustomNodeUpdater(customNodeConfigJsonFile string, templateConfigJsonDir, templateConfigJsonFileName string) *CustomNodeUpdater { - return &CustomNodeUpdater{ - customNodeConfigJsonFile: customNodeConfigJsonFile, - templateConfigJsonDir: templateConfigJsonDir, - templateConfigJsonFileName: templateConfigJsonFileName, - } -} - -// UpdateCustomNode adds (if not exists) or updates custom_node_library_config_list and related json information from customNodeConfigJsonFile into -// the template config json file and then produces a new config json file based on the input newConfigJsonFile; -// it returns error if failed to parse json or failed to produce a new config json file -func (cu *CustomNodeUpdater) UpdateCustomNode(newConfigJsonFile string) error { - templateConfigJsonFile := filepath.Join(cu.templateConfigJsonDir, cu.templateConfigJsonFileName) - contents, err := os.ReadFile(templateConfigJsonFile) - if err != nil { - return fmt.Errorf("CustomNodeUpdater failed to read OVMS template config json file %s: %v", templateConfigJsonFile, err) - } - - var ovmsConfigData OvmsConfig - err = json.Unmarshal(contents, &ovmsConfigData) - if err != nil { - return fmt.Errorf("CustomNodeUpdater parsing OVMS template config json error: %v", err) - } - - // read also the customNodeConfigJsonFile: - customNodeConfig, err := os.ReadFile(cu.customNodeConfigJsonFile) - if err != nil { - return fmt.Errorf("CustomNodeUpdater failed to read OVMS custom node json file %s: %v", cu.customNodeConfigJsonFile, err) - } - - var customNodeData OvmsCustomNodeConfig - err = json.Unmarshal(customNodeConfig, &customNodeData) - if err != nil { - return fmt.Errorf("CustomNodeUpdater parsing OVMS custom node json error: %v", err) - } - - if len(customNodeData.CustomNode) > 0 { - // replacing: - ovmsConfigData.CustomNode = customNodeData.CustomNode - ovmsConfigData.PipelineConfig = customNodeData.PipelineConfig - } - - updateConfig, err := json.MarshalIndent(ovmsConfigData, "", " ") - if err != nil { - return fmt.Errorf("CustomNodeUpdater could not marshal config to JSON: %v", err) - } - - if err := os.WriteFile(newConfigJsonFile, updateConfig, 0644); err != nil { - return fmt.Errorf("CustomNodeUpdater could not write a updated config to a new JSON: %v", err) - } - - return nil -} diff --git a/configs/opencv-ovms/cmd_client/server/customNode_test.go b/configs/opencv-ovms/cmd_client/server/customNode_test.go deleted file mode 100644 index ca3b7dd6..00000000 --- a/configs/opencv-ovms/cmd_client/server/customNode_test.go +++ /dev/null @@ -1,67 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2024 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package server - -import ( - "os" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestCustomNodes(t *testing.T) { - tests := []struct { - name string - customNodeJsonFile string - templateJsonFileDir string - templateJsonFileName string - newJsonFileName string - expectError bool - expectedCustomNodeLib string - }{ - {"add a new test custom node", "./test-yolov8_custom_node.json", ".", "test-update-device.json", "./add-test-yolov8.json", false, "/ovms/lib/libcustom_node_efficientnetb0-yolov8.so"}, - {"replacing an existing custom node", "./test-yolov8_custom_node.json", ".", "test-customnode.json", "./a-replacing-test-yolov8.json", false, "/ovms/lib/libcustom_node_efficientnetb0-yolov8.so"}, - {"non-existing custom node file", "./non-existing", ".", "test-update-device.json", "./failed-non-existing.json", true, ""}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - customNodeUpdater := NewCustomNodeUpdater(tt.customNodeJsonFile, tt.templateJsonFileDir, tt.templateJsonFileName) - - err := customNodeUpdater.UpdateCustomNode(tt.newJsonFileName) - defer func() { - _ = os.Remove(tt.newJsonFileName) - }() - - if !tt.expectError { - require.NoError(t, err) - require.NotEmpty(t, customNodeUpdater) - require.FileExists(t, tt.newJsonFileName) - newData, readErr := os.ReadFile(tt.newJsonFileName) - require.NoError(t, readErr) - require.Contains(t, string(newData), "\"base_path\": \""+tt.expectedCustomNodeLib+"\"") - if tt.templateJsonFileName == "test-customnode.json" { - require.Contains(t, string(newData), "\"custom_node_library_config_list\":") - require.Contains(t, string(newData), "\"pipeline_config_list\":") - } - } else { - require.Error(t, err) - } - }) - } -} diff --git a/configs/opencv-ovms/cmd_client/server/test-customnode.json b/configs/opencv-ovms/cmd_client/server/test-customnode.json deleted file mode 100644 index 17d00f32..00000000 --- a/configs/opencv-ovms/cmd_client/server/test-customnode.json +++ /dev/null @@ -1,163 +0,0 @@ -{ - "model_config_list": [ - { - "config": { - "name": "yolov5", - "base_path": "/models/yolov5s/FP16-INT8", - "shape": "(1,3,416,416)", - "nireq": 2, - "batch_size": "1", - "plugin_config": { - "PERFORMANCE_HINT": "LATENCY" - }, - "target_device": "{target_device}" - }, - "latest": { - "num_versions": 2 - } - }, - { - "config": { - "name": "efficientnetb0_FP32INT8", - "base_path": "/models/efficientnet-b0/FP32-INT8", - "shape": "(1,3,224,224)", - "nireq": 2, - "batch_size": "1", - "plugin_config": { - "PERFORMANCE_HINT": "LATENCY" - }, - "target_device": "{target_device}" - }, - "latest": { - "num_versions": 2 - } - } - ], - "custom_node_library_config_list": [ - { - "name": "efficientnetb0_extractor", - "base_path": "/ovms/lib/libcustom_node_efficientnetb0-yolov5.so" - } - ], - "pipeline_config_list": [ - { - "name": "detect_classify", - "inputs": [ - "images" - ], - "nodes": [ - { - "name": "detection_node", - "model_name": "yolov5", - "type": "DL model", - "inputs": [ - { - "images": { - "node_name": "request", - "data_item": "images" - } - } - ], - "outputs": [ - { - "data_item": "442", - "alias": "boxes" - } - ] - }, - { - "name": "extract_node", - "library_name": "efficientnetb0_extractor", - "type": "custom", - "demultiply_count": 0, - "params": { - "original_image_width": "416", - "original_image_height": "416", - "original_image_layout": "NCHW", - "target_image_width": "224", - "target_image_height": "224", - "target_image_layout": "NCHW", - "convert_to_gray_scale": "false", - "confidence_threshold": "0.7", - "max_output_batch": "100", - "debug": "false" - }, - "inputs": [ - { - "images": { - "node_name": "request", - "data_item": "images" - } - }, - { - "boxes": { - "node_name": "detection_node", - "data_item": "boxes" - } - } - ], - "outputs": [ - { - "data_item": "roi_images", - "alias": "roi_images" - }, - { - "data_item": "roi_coordinates", - "alias": "roi_coordinates" - }, - { - "data_item": "confidence_levels", - "alias": "confidence_levels" - } - ] - }, - { - "name": "classification_node", - "model_name": "efficientnetb0_FP32INT8", - "type": "DL model", - "inputs": [ - { - "sub": { - "node_name": "extract_node", - "data_item": "roi_images" - } - } - ], - "outputs": [ - { - "data_item": "efficientnet-b0/model/head/dense/BiasAdd/Add", - "alias": "classify_output" - } - ] - } - ], - "outputs": [ - { - "roi_images": { - "node_name": "extract_node", - "data_item": "roi_images" - } - }, - { - "roi_coordinates": { - "node_name": "extract_node", - "data_item": "roi_coordinates" - } - }, - { - "confidence_levels": { - "node_name": "extract_node", - "data_item": "confidence_levels" - } - }, - { - "classify_output": { - "node_name": "classification_node", - "data_item": "classify_output" - } - } - ] - } - - ] - } \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/server/test-invalid.json b/configs/opencv-ovms/cmd_client/server/test-invalid.json deleted file mode 100644 index 8a46b88b..00000000 --- a/configs/opencv-ovms/cmd_client/server/test-invalid.json +++ /dev/null @@ -1 +0,0 @@ -;invalid{} \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/server/test-update-device.json b/configs/opencv-ovms/cmd_client/server/test-update-device.json deleted file mode 100644 index b39bb42b..00000000 --- a/configs/opencv-ovms/cmd_client/server/test-update-device.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "model_config_list": [ - { - "config": { - "name": "yolov5s", - "base_path": "/models/yolov5s/FP16-INT8", - "layout": "NHWC:NCHW", - "shape": "(1,416,416,3)", - "nireq": 1, - "batch_size": "1", - "plugin_config": { - "PERFORMANCE_HINT": "LATENCY" - }, - "target_device": "{target_device}" - } - }, - { - "config": { - "name": "efficientnet-b0", - "base_path": "/models/efficientnet-b0/FP32", - "target_device": "{target_device}" - }, - "latest": { - "num_versions": 1 - } - } - ] -} \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/server/test-yolov8_custom_node.json b/configs/opencv-ovms/cmd_client/server/test-yolov8_custom_node.json deleted file mode 100644 index 9d24d12f..00000000 --- a/configs/opencv-ovms/cmd_client/server/test-yolov8_custom_node.json +++ /dev/null @@ -1,85 +0,0 @@ -{ -"custom_node_library_config_list": [ - { - "name": "efficientnetb0_extractor", - "base_path": "/ovms/lib/libcustom_node_efficientnetb0-yolov8.so" - } -], -"pipeline_config_list": [ - { - "name": "detect_classify", - "inputs": ["images"], - "nodes": [ - { - "name": "detection_node", - "model_name": "yolov8", - "type": "DL model", - "inputs": [ - {"images": {"node_name": "request", - "data_item": "images"} - } - ], - "outputs": [ - {"data_item": "output0", - "alias": "boxes"} - ] - }, - { - "name": "extract_node", - "library_name": "efficientnetb0_extractor", - "type": "custom", - "demultiply_count": 0, - "params": { - "original_image_width": "416", - "original_image_height": "416", - "original_image_layout": "NCHW", - "target_image_width": "224", - "target_image_height": "224", - "target_image_layout": "NCHW", - "convert_to_gray_scale": "false", - "confidence_threshold": "0.5", - "max_output_batch": "100", - "debug": "false" - }, - "inputs": [ - {"images": {"node_name": "request", - "data_item": "images"}}, - {"boxes": {"node_name": "detection_node", - "data_item": "boxes"}} - ], - "outputs": [ - {"data_item": "roi_images", - "alias": "roi_images"}, - {"data_item": "roi_coordinates", - "alias": "roi_coordinates"}, - {"data_item": "confidence_levels", - "alias": "confidence_levels"} - ] - }, - { - "name": "classification_node", - "model_name": "efficientnetb0", - "type": "DL model", - "inputs": [ - {"sub": {"node_name": "extract_node", - "data_item": "roi_images"}} - ], - "outputs": [ - {"data_item": "efficientnet-b0/model/head/dense/BiasAdd/Add", - "alias": "classify_output"} - ] - } - ], - "outputs": [ - {"roi_images": {"node_name": "extract_node", - "data_item": "roi_images"}}, - {"roi_coordinates": {"node_name": "extract_node", - "data_item": "roi_coordinates"}}, - {"confidence_levels": {"node_name": "extract_node", - "data_item": "confidence_levels"}}, - {"classify_output": {"node_name": "classification_node", - "data_item": "classify_output"}} - ] - } -] -} \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/server/updateDevice.go b/configs/opencv-ovms/cmd_client/server/updateDevice.go deleted file mode 100644 index 7f024987..00000000 --- a/configs/opencv-ovms/cmd_client/server/updateDevice.go +++ /dev/null @@ -1,79 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2023 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package server - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" -) - -type DeviceUpdater struct { - templateConfigJsonDir string - templateConfigJsonFileName string -} - -type OvmsConfig struct { - ModelList []ModelConfig `json:"model_config_list"` - CustomNode []map[string]interface{} `json:"custom_node_library_config_list"` - PipelineConfig []map[string]interface{} `json:"pipeline_config_list"` -} - -type ModelConfig struct { - Config map[string]interface{} `json:"config"` -} - -func NewDeviceUpdater(templateConfigJsonDir, templateConfigJsonFileName string) *DeviceUpdater { - return &DeviceUpdater{ - templateConfigJsonDir: templateConfigJsonDir, - templateConfigJsonFileName: templateConfigJsonFileName, - } -} - -// UpdateDeviceAndCreateJson replaces {target_device} place-holder value with the input targeDevice value in the template config json file and -// produces a new config json file based on the input newConfigJsonFile; -// it returns error if failed to parse json or failed to produce a new config json file -func (du *DeviceUpdater) UpdateDeviceAndCreateJson(targetDevice, newConfigJsonFile string) error { - templateConfigJsonFile := filepath.Join(du.templateConfigJsonDir, du.templateConfigJsonFileName) - contents, err := os.ReadFile(templateConfigJsonFile) - if err != nil { - return fmt.Errorf("DeviceUpdater failed to read OVMS template config json file %s: %v", templateConfigJsonFile, err) - } - - var data OvmsConfig - err = json.Unmarshal(contents, &data) - if err != nil { - return fmt.Errorf("DeviceUpdater parsing OVMS template config json error: %v", err) - } - - for _, modelConfig := range data.ModelList { - modelConfig.Config["target_device"] = targetDevice - } - - updateConfig, err := json.MarshalIndent(data, "", " ") - if err != nil { - return fmt.Errorf("DeviceUpdater could not marshal config to JSON: %v", err) - } - - if err := os.WriteFile(newConfigJsonFile, updateConfig, 0644); err != nil { - return fmt.Errorf("DeviceUpdater could not write a updated config to a new JSON: %v", err) - } - - return nil -} diff --git a/configs/opencv-ovms/cmd_client/server/updateDevice_test.go b/configs/opencv-ovms/cmd_client/server/updateDevice_test.go deleted file mode 100644 index 2dff6000..00000000 --- a/configs/opencv-ovms/cmd_client/server/updateDevice_test.go +++ /dev/null @@ -1,67 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2023 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package server - -import ( - "os" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestParse(t *testing.T) { - tests := []struct { - name string - jsonFileDir string - jsonFileName string - targetDevice string - newJsonFileName string - expectError bool - }{ - {"update test template json file", ".", "test-update-device.json", "GPU.0", "./a-new-test-update-device.json", false}, - {"invalid json content", ".", "test-invalid.json", "GPU", "", true}, - {"non-existing json file", ".", "non-existing.json", "GPU", "", true}, - {"custom node template json file", ".", "test-customnode.json", "CPU", "./custom-node-test.json", false}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - deviceUpdater := NewDeviceUpdater(tt.jsonFileDir, tt.jsonFileName) - - err := deviceUpdater.UpdateDeviceAndCreateJson(tt.targetDevice, tt.newJsonFileName) - defer func() { - _ = os.Remove(tt.newJsonFileName) - }() - - if !tt.expectError { - require.NoError(t, err) - require.NotEmpty(t, deviceUpdater) - require.FileExists(t, tt.newJsonFileName) - newData, readErr := os.ReadFile(tt.newJsonFileName) - require.NoError(t, readErr) - require.Contains(t, string(newData), "\"target_device\": \""+tt.targetDevice+"\"") - if tt.jsonFileName == "test-customnode.json" { - require.Contains(t, string(newData), "\"custom_node_library_config_list\":") - require.Contains(t, string(newData), "\"pipeline_config_list\":") - } - } else { - require.Error(t, err) - } - }) - } -} diff --git a/configs/opencv-ovms/cmd_client/testdata/empty.env b/configs/opencv-ovms/cmd_client/testdata/empty.env deleted file mode 100644 index e69de29b..00000000 diff --git a/configs/opencv-ovms/cmd_client/testdata/test.env b/configs/opencv-ovms/cmd_client/testdata/test.env deleted file mode 100644 index e6c395fa..00000000 --- a/configs/opencv-ovms/cmd_client/testdata/test.env +++ /dev/null @@ -1,2 +0,0 @@ -TESTKEY1=TESTVALUE1 -TESTKEY2=TESTVALUE2 \ No newline at end of file diff --git a/configs/opencv-ovms/cmd_client/writeEnv.go b/configs/opencv-ovms/cmd_client/writeEnv.go deleted file mode 100644 index c04c6f10..00000000 --- a/configs/opencv-ovms/cmd_client/writeEnv.go +++ /dev/null @@ -1,138 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2023 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package main - -import ( - "fmt" - "log" - "os" - "strings" -) - -const ( - DOT_ENV_DIR = "/tmp" - DOT_ENV_FILE_NAME_PATTERN = ".env_*" - - ignored = "" - envDelimiter = "=" -) - -type TmpEnvFileWriter struct { - envList []string - envFile *os.File -} - -func NewTmpEnvFileWriter(envList []string) *TmpEnvFileWriter { - return &TmpEnvFileWriter{ - envList: envList, - } -} - -func (f *TmpEnvFileWriter) writeEnvs() error { - if len(f.envList) == 0 { - log.Println("No envs to write") - return nil - } - - //f.envList = testMultiLinesEnv(f.envList) - - // Create a temporary .env file - envFile, err := os.CreateTemp(DOT_ENV_DIR, DOT_ENV_FILE_NAME_PATTERN) - if err != nil { - return fmt.Errorf("could not create temp %s file: %v", DOT_ENV_FILE_NAME_PATTERN, err) - } - - log.Println("start writing envs into tmp env file:", envFile.Name()) - for _, envStr := range f.envList { - log.Println("envStr:", envStr) - // scrutinizing the env list for those values having multiple lines to replace \\n with \n - envStr = convertMultiNewLines(envStr) - if len(envStr) == 0 { - continue - } - - _, err = envFile.WriteString(fmt.Sprintln(envStr)) - if err != nil { - return fmt.Errorf("failed to write temp %s file: %v", DOT_ENV_FILE_NAME_PATTERN, err) - } - } - - defer func() error { - err = envFile.Close() - if err != nil { - return fmt.Errorf("failed to close temp %s file: %v", DOT_ENV_FILE_NAME_PATTERN, err) - } - return nil - }() - - log.Printf("The temp %s file is created", envFile.Name()) - f.envFile = envFile - - return err -} - -func convertMultiNewLines(envStr string) string { - newEnvStr := envStr - keyValue := strings.SplitN(envStr, envDelimiter, 2) - if len(keyValue) != 2 { - log.Printf("Corrupted key-value pair %s from environment variable, ignored", keyValue) - return ignored - } - - excludeEnvKeys := map[string]bool{ - "BASH_FUNC_which%%": true, - "PATH": true, - "HOME": true, - "PWD": true, - "USER": true, - } - - key := keyValue[0] - value := keyValue[1] - - if _, exists := excludeEnvKeys[key]; exists { - log.Printf("env key %s is in exclude list, ignored", key) - return ignored - } - - newLine := fmt.Sprintln() - if strings.Contains(value, newLine) { - log.Printf("found new line for env %s, converting to \n literal", key) - newVal := strings.ReplaceAll(value, newLine, "\\n") - newEnvStr = strings.Join([]string{key, newVal}, envDelimiter) - } - return newEnvStr -} - -func (f *TmpEnvFileWriter) cleanFile() error { - return os.Remove(f.envFile.Name()) -} - -func testMultiLinesEnv(envList []string) []string { - testEnv := `MULTI_LINE_ENV%%=() { ( alias; - eval ${which_declare} ) | /usr/bin/which - - }` - - if err := os.Setenv("MULTI_LINE_ENV%%", testEnv); err != nil { - log.Println("DEBUG: failed to set multiple line env") - } - - envList = append(envList, testEnv) - return envList -} diff --git a/configs/opencv-ovms/cmd_client/writeEnv_test.go b/configs/opencv-ovms/cmd_client/writeEnv_test.go deleted file mode 100644 index e1875a37..00000000 --- a/configs/opencv-ovms/cmd_client/writeEnv_test.go +++ /dev/null @@ -1,99 +0,0 @@ -// ---------------------------------------------------------------------------------- -// Copyright 2023 Intel Corp. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ---------------------------------------------------------------------------------- - -package main - -import ( - "fmt" - "log" - "os" - "path/filepath" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestWriteEnvs(t *testing.T) { - readEnvFileDir := "./testdata" - - tests := []struct { - name string - readEnvFileToTest []string - }{ - {"valid write temp env file from test.env file", []string{"empty.env", "test.env"}}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - log.Println(readEnvFileDir) - client := OvmsClientInfo{ - EnvironmentVariableFiles: tt.readEnvFileToTest, - } - envList := client.readClientEnvs(readEnvFileDir) - - if len(envList) == 0 { - log.Println("empty env list") - } else { - for _, env := range envList { - log.Println("env: ", env) - keyValue := strings.SplitN(env, envDelimiter, 2) - require.Equal(t, 2, len(keyValue)) - require.NoError(t, os.Setenv(keyValue[0], keyValue[1])) - } - } - - tmpEnv := NewTmpEnvFileWriter(envList) - err := tmpEnv.writeEnvs() - require.NoError(t, err) - defer func() { - err = tmpEnv.cleanFile() - require.NoError(t, err) - }() - - require.FileExists(t, tmpEnv.envFile.Name(), fmt.Sprintf("temp env file %s does not exist", tmpEnv.envFile.Name())) - - data, err := os.ReadFile(tmpEnv.envFile.Name()) - require.NoError(t, err) - require.NotEmpty(t, data) - - log.Println("data:", string(data)) - - // for those envs in envList we write out to .env file and we should expect to see - // those envs are also in the .env files - envs := string(data) - for _, env := range envList { - keyValue := strings.SplitN(env, envDelimiter, 2) - require.Contains(t, envs, keyValue[0]) - require.Contains(t, envs, keyValue[1]) - } - - // verify that envs from the written file can be set into os envs: - tempEnvClient := OvmsClientInfo{ - EnvironmentVariableFiles: []string{filepath.Base(tmpEnv.envFile.Name())}, - } - tmpEnvList := tempEnvClient.readClientEnvs(DOT_ENV_DIR) - require.NotEmpty(t, tmpEnvList) - for _, env := range tmpEnvList { - log.Println("env: ", env) - keyValue := strings.SplitN(env, envDelimiter, 2) - require.Equal(t, 2, len(keyValue)) - require.NoError(t, os.Setenv(keyValue[0], keyValue[1])) - } - }) - } -} diff --git a/configs/opencv-ovms/demos/Dockerfile.python b/configs/opencv-ovms/demos/Dockerfile.python deleted file mode 100644 index 21bbe58a..00000000 --- a/configs/opencv-ovms/demos/Dockerfile.python +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -FROM python:3.10-bullseye -RUN apt-get update && apt-get install ffmpeg libsm6 libxext6 -y && \ - rm -rf /var/lib/apt/lists/* -WORKDIR /app -COPY . . -RUN pip install --upgrade pip && pip3 install openvino && \ - pip3 install -r requirements.txt -ENV QT_DEBUG_PLUGINS=1 -ENV DISPLAY=0 - - diff --git a/configs/opencv-ovms/demos/Makefile b/configs/opencv-ovms/demos/Makefile deleted file mode 100644 index 1f283af8..00000000 --- a/configs/opencv-ovms/demos/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright © 2023 Intel Corporation. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -.PHONY: build - -build: - docker build --tag python-demo:dev -f Dockerfile.python . \ No newline at end of file diff --git a/configs/opencv-ovms/demos/classification/python/classification_demo.py b/configs/opencv-ovms/demos/classification/python/classification_demo.py deleted file mode 100755 index d433d920..00000000 --- a/configs/opencv-ovms/demos/classification/python/classification_demo.py +++ /dev/null @@ -1,345 +0,0 @@ -#!/usr/bin/env python3 -""" - Copyright (C) 2018-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import logging as log -import sys -from argparse import ArgumentParser, SUPPRESS -from pathlib import Path -from time import perf_counter - -import os -import paho.mqtt.client as mqtt -import json -import time - -import cv2 - -sys.path.append(str(Path(__file__).resolve().parents[2] / 'common/python')) -sys.path.append(str(Path(__file__).resolve().parents[2] / 'common/python/openvino/model_zoo')) - -from model_api.models import Classification, OutputTransform -from model_api.performance_metrics import put_highlighted_text, PerformanceMetrics -from model_api.pipelines import get_user_config, AsyncPipeline -from model_api.adapters import create_core, OpenvinoAdapter, OVMSAdapter - -import monitors -from images_capture import open_images_capture -from helpers import resolution, log_latency_per_stage - -log.basicConfig(format='[ %(levelname)s ] %(message)s', level=log.DEBUG, stream=sys.stdout) - - -def build_argparser(): - parser = ArgumentParser(add_help=False) - args = parser.add_argument_group('Options') - args.add_argument('-h', '--help', action='help', default=SUPPRESS, help='Show this help message and exit.') - args.add_argument('-mqtt', '--mqtt', - help='Optional. Set mqtt broker host to publish results. Example: 127.0.0.1:1883',type=str) - args.add_argument('-m', '--model', required=True, - help='Required. Path to an .xml file with a trained model ' - 'or address of model inference service if using OVMS adapter.') - args.add_argument('--adapter', help='Optional. Specify the model adapter. Default is openvino.', - default='openvino', type=str, choices=('openvino', 'ovms')) - args.add_argument('-i', '--input', required=True, - help='Required. An input to process. The input must be a single image, ' - 'a folder of images, video file or camera id.') - args.add_argument('-d', '--device', default='CPU', type=str, - help="Optional. Specify a device to infer on (the list of available devices is shown below). Use " - "'-d HETERO:' format to specify HETERO plugin. Use " - "'-d MULTI:' format to specify MULTI plugin. Default is CPU") - - common_model_args = parser.add_argument_group('Common model options') - common_model_args.add_argument('--labels', help='Optional. Labels mapping file.', default=None, type=str) - common_model_args.add_argument('-topk', help='Optional. Number of top results. Default value is 5. Must be from 1 to 10.', default=5, - type=int, choices=range(1, 11)) - common_model_args.add_argument('--layout', type=str, default=None, - help='Optional. Model inputs layouts. ' - 'Ex. NCHW or input0:NCHW,input1:NC in case of more than one input.') - - infer_args = parser.add_argument_group('Inference options') - infer_args.add_argument('-nireq', '--num_infer_requests', help='Optional. Number of infer requests', - default=0, type=int) - infer_args.add_argument('-nstreams', '--num_streams', - help='Optional. Number of streams to use for inference on the CPU or/and GPU in throughput ' - 'mode (for HETERO and MULTI device cases use format ' - ':,: or just ).', - default='', type=str) - infer_args.add_argument('-nthreads', '--num_threads', default=None, type=int, - help='Optional. Number of threads to use for inference on CPU (including HETERO cases).') - - io_args = parser.add_argument_group('Input/output options') - io_args.add_argument('--loop', default=False, action='store_true', - help='Optional. Enable reading the input in a loop.') - io_args.add_argument('-o', '--output', required=False, - help='Optional. Name of the output file(s) to save.') - io_args.add_argument('-limit', '--output_limit', required=False, default=1000, type=int, - help='Optional. Number of frames to store in output. ' - 'If 0 is set, all frames are stored.') - io_args.add_argument('--no_show', help="Optional. Don't show output.", action='store_true') - io_args.add_argument('--output_resolution', default=None, type=resolution, - help='Optional. Specify the maximum output window resolution ' - 'in (width x height) format. Example: 1280x720. ' - 'Input frame size used by default.') - io_args.add_argument('-u', '--utilization_monitors', default='', type=str, - help='Optional. List of monitors to show initially.') - - input_transform_args = parser.add_argument_group('Input transform options') - input_transform_args.add_argument('--reverse_input_channels', default=False, action='store_true', - help='Optional. Switch the input channels order from ' - 'BGR to RGB.') - input_transform_args.add_argument('--mean_values', default=None, type=float, nargs=3, - help='Optional. Normalize input by subtracting the mean ' - 'values per channel. Example: 255.0 255.0 255.0') - input_transform_args.add_argument('--scale_values', default=None, type=float, nargs=3, - help='Optional. Divide input by scale values per channel. ' - 'Division is applied after mean values subtraction. ' - 'Example: 255.0 255.0 255.0') - - debug_args = parser.add_argument_group('Debug options') - debug_args.add_argument('-r', '--raw_output_message', help='Optional. Output inference results raw values showing.', - default=False, action='store_true') - return parser - - -def draw_labels(frame, classifications, output_transform): - frame = output_transform.resize(frame) - class_label = "" - if classifications: - class_label = classifications[0][1] - font_scale = 0.7 - label_height = cv2.getTextSize(class_label, cv2.FONT_HERSHEY_COMPLEX, font_scale, 2)[0][1] - initial_labels_pos = frame.shape[0] - label_height * (int(1.5 * len(classifications)) + 1) - - if (initial_labels_pos < 0): - initial_labels_pos = label_height - log.warning('Too much labels to display on this frame, some will be omitted') - offset_y = initial_labels_pos - - header = "Label: Score:" - label_width = cv2.getTextSize(header, cv2.FONT_HERSHEY_COMPLEX, font_scale, 2)[0][0] - put_highlighted_text(frame, header, (frame.shape[1] - label_width, offset_y), - cv2.FONT_HERSHEY_COMPLEX, font_scale, (255, 0, 0), 2) - - for idx, class_label, score in classifications: - label = '{}. {} {:.2f}'.format(idx, class_label, score) - label_width = cv2.getTextSize(label, cv2.FONT_HERSHEY_COMPLEX, font_scale, 2)[0][0] - offset_y += int(label_height * 1.5) - put_highlighted_text(frame, label, (frame.shape[1] - label_width, offset_y), - cv2.FONT_HERSHEY_COMPLEX, font_scale, (255, 0, 0), 2) - return frame - - -def print_raw_results(classifications, frame_id): - data = [] - for class_id, class_label, score in classifications: - json_object = { - "label": class_label, - "score": float(score) - } - data.append(json_object) - json_array = json.dumps(data) - return json_array - - -def main(): - args = build_argparser().parse_args() - - cap = open_images_capture(args.input, args.loop) - delay = int(cap.get_type() in {'VIDEO', 'CAMERA'}) - - # Overwritting --no_show - render = os.environ.get("RENDER_MODE", "0") - if render == "1": - args.no_show = False - elif render == "0": - args.no_show = True - - # Connect to MQTT - containerName = os.environ.get("CONTAINER_NAME", "classification") - client = None - if args.mqtt: - try: - mqttInfo = args.mqtt.split(':',1) - client = mqtt.Client(containerName) - if len(mqttInfo) == 2: - client.connect(mqttInfo[0],int(mqttInfo[1]),60) - client.loop_start() - print(f"connected to mqtt: {args.mqtt}") - except Exception as e: - print("Connection failed to mqtt: {}".format(e)) - - - if args.adapter == 'openvino': - plugin_config = get_user_config(args.device, args.num_streams, args.num_threads) - model_adapter = OpenvinoAdapter(create_core(), args.model, device=args.device, plugin_config=plugin_config, - max_num_requests=args.num_infer_requests, model_parameters = {'input_layouts': args.layout}) - elif args.adapter == 'ovms': - model_adapter = OVMSAdapter(args.model) - - config = { - 'mean_values': args.mean_values, - 'scale_values': args.scale_values, - 'reverse_input_channels': args.reverse_input_channels, - 'topk': args.topk, - 'path_to_labels': args.labels - } - model = Classification(model_adapter, config) - model.log_layers_info() - - async_pipeline = AsyncPipeline(model) - - next_frame_id = 0 - next_frame_id_to_show = 0 - - metrics = PerformanceMetrics() - render_metrics = PerformanceMetrics() - presenter = None - output_transform = None - video_writer = cv2.VideoWriter() - ESC_KEY = 27 - key = -1 - while True: - if async_pipeline.callback_exceptions: - raise async_pipeline.callback_exceptions[0] - # Process all completed requests - results = async_pipeline.get_result(next_frame_id_to_show) - if results: - classifications, frame_meta = results - frame = frame_meta['frame'] - start_time = frame_meta['start_time'] - if args.raw_output_message: - print_raw_results(classifications, next_frame_id_to_show) - - presenter.drawGraphs(frame) - rendering_start_time = perf_counter() - frame = draw_labels(frame, classifications, output_transform) - if delay or args.no_show: - render_metrics.update(rendering_start_time) - metrics.update(start_time, frame) - - if video_writer.isOpened() and (args.output_limit <= 0 or next_frame_id_to_show <= args.output_limit-1): - video_writer.write(frame) - next_frame_id_to_show += 1 - - # Print stats - total_latency, total_fps = metrics.get_total() - print("Processing time: {:.2f} ms; fps: {:.2f}".format(total_latency * 1e3,total_fps)) - - # Publish results to mqtt - if args.mqtt: - json_objects = print_raw_results(classifications, next_frame_id_to_show) - client.publish(containerName,json_objects) - - if not args.no_show: - cv2.imshow('Classification Results', frame) - key = cv2.waitKey(delay) - # Quit. - if key in {ord('q'), ord('Q'), ESC_KEY}: - break - presenter.handleKey(key) - continue - - if async_pipeline.is_ready(): - # Get new image/frame - start_time = perf_counter() - status,frame = cap.read() - # If errors during decoding, then retry grab new image/frame - if not(status): - st = time.time() - for retry in range(3): - try: - cap = open_images_capture(args.input, args.loop) - print("time lost due to reinitialization: ", time.time() - st) - break # If successful, exit the loop - except Exception as e: - print(f"Error on attempt reinitialization {retry + 1}: {e}") - if retry < 2: - print("Retrying...") - time.sleep(1) - else: - print("Max retries reached. Exiting.") - raise RuntimeError("Can't reinitialize image capture") - continue - if frame is None: - if next_frame_id == 0: - raise ValueError("Can't read an image from the input") - break - if next_frame_id == 0: - output_transform = OutputTransform(frame.shape[:2], args.output_resolution) - if args.output_resolution: - output_resolution = output_transform.new_resolution - else: - output_resolution = (frame.shape[1], frame.shape[0]) - presenter = monitors.Presenter(args.utilization_monitors, 55, - (round(output_resolution[0] / 4), round(output_resolution[1] / 8))) - if args.output and not video_writer.open(args.output, cv2.VideoWriter_fourcc(*'MJPG'), - cap.fps(), output_resolution): - raise RuntimeError("Can't open video writer") - # Submit for inference - async_pipeline.submit_data(frame, next_frame_id, {'frame': frame, 'start_time': start_time}) - next_frame_id += 1 - - else: - # Wait for empty request - async_pipeline.await_any() - - async_pipeline.await_all() - if async_pipeline.callback_exceptions: - raise async_pipeline.callback_exceptions[0] - if key not in {ord('q'), ord('Q'), ESC_KEY}: - # Process completed requests - for next_frame_id_to_show in range(next_frame_id_to_show, next_frame_id): - results = async_pipeline.get_result(next_frame_id_to_show) - classifications, frame_meta = results - frame = frame_meta['frame'] - start_time = frame_meta['start_time'] - - if args.raw_output_message: - print_raw_results(classifications, next_frame_id_to_show) - - presenter.drawGraphs(frame) - rendering_start_time = perf_counter() - frame = draw_labels(frame, classifications, output_transform) - if delay or args.no_show: - render_metrics.update(rendering_start_time) - metrics.update(start_time, frame) - - if video_writer.isOpened() and (args.output_limit <= 0 or next_frame_id_to_show <= args.output_limit-1): - video_writer.write(frame) - - if not args.no_show: - cv2.imshow('Classification Results', frame) - key = cv2.waitKey(delay) - - # Quit. - if key in {ord('q'), ord('Q'), ESC_KEY}: - break - presenter.handleKey(key) - - if delay or args.no_show: - metrics.log_total() - log_latency_per_stage(cap.reader_metrics.get_latency(), - async_pipeline.preprocess_metrics.get_latency(), - async_pipeline.inference_metrics.get_latency(), - async_pipeline.postprocess_metrics.get_latency(), - render_metrics.get_latency()) - for rep in presenter.reportMeans(): - log.info(rep) - - -if __name__ == '__main__': - sys.exit(main() or 0) diff --git a/configs/opencv-ovms/demos/classification/python/entrypoint.sh b/configs/opencv-ovms/demos/classification/python/entrypoint.sh deleted file mode 100755 index 2c67c95c..00000000 --- a/configs/opencv-ovms/demos/classification/python/entrypoint.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -MQTT="${MQTT:=}" - -if [ "$MQTT" != "" ] -then - mqttArgs="--mqtt ${MQTT}" -fi - -echo "Note: Pipeline log and results are available at location - ./results" - -python3 classification/python/classification_demo.py -m localhost:"$GRPC_PORT"/models/"$CLASSIFICATION_MODEL_NAME" \ - --label classification/python/labels/"$CLASSIFICATION_LABEL_FILE" -i $INPUTSRC \ - --adapter ovms --output_resolution "$CLASSIFICATION_OUTPUT_RESOLUTION" $mqttArgs 2>&1 | tee >/tmp/results/r$cid_count.jsonl >(stdbuf -oL sed -n -e 's/^.*fps: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid_count.log) \ No newline at end of file diff --git a/configs/opencv-ovms/demos/classification/python/labels/imagenet_2012.txt b/configs/opencv-ovms/demos/classification/python/labels/imagenet_2012.txt deleted file mode 100644 index a9e8c7f5..00000000 --- a/configs/opencv-ovms/demos/classification/python/labels/imagenet_2012.txt +++ /dev/null @@ -1,1000 +0,0 @@ -n01440764 tench, Tinca tinca -n01443537 goldfish, Carassius auratus -n01484850 great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias -n01491361 tiger shark, Galeocerdo cuvieri -n01494475 hammerhead, hammerhead shark -n01496331 electric ray, crampfish, numbfish, torpedo -n01498041 stingray -n01514668 cock -n01514859 hen -n01518878 ostrich, Struthio camelus -n01530575 brambling, Fringilla montifringilla -n01531178 goldfinch, Carduelis carduelis -n01532829 house finch, linnet, Carpodacus mexicanus -n01534433 junco, snowbird -n01537544 indigo bunting, indigo finch, indigo bird, Passerina cyanea -n01558993 robin, American robin, Turdus migratorius -n01560419 bulbul -n01580077 jay -n01582220 magpie -n01592084 chickadee -n01601694 water ouzel, dipper -n01608432 kite -n01614925 bald eagle, American eagle, Haliaeetus leucocephalus -n01616318 vulture -n01622779 great grey owl, great gray owl, Strix nebulosa -n01629819 European fire salamander, Salamandra salamandra -n01630670 common newt, Triturus vulgaris -n01631663 eft -n01632458 spotted salamander, Ambystoma maculatum -n01632777 axolotl, mud puppy, Ambystoma mexicanum -n01641577 bullfrog, Rana catesbeiana -n01644373 tree frog, tree-frog -n01644900 tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui -n01664065 loggerhead, loggerhead turtle, Caretta caretta -n01665541 leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea -n01667114 mud turtle -n01667778 terrapin -n01669191 box turtle, box tortoise -n01675722 banded gecko -n01677366 common iguana, iguana, Iguana iguana -n01682714 American chameleon, anole, Anolis carolinensis -n01685808 whiptail, whiptail lizard -n01687978 agama -n01688243 frilled lizard, Chlamydosaurus kingi -n01689811 alligator lizard -n01692333 Gila monster, Heloderma suspectum -n01693334 green lizard, Lacerta viridis -n01694178 African chameleon, Chamaeleo chamaeleon -n01695060 Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis -n01697457 African crocodile, Nile crocodile, Crocodylus niloticus -n01698640 American alligator, Alligator mississipiensis -n01704323 triceratops -n01728572 thunder snake, worm snake, Carphophis amoenus -n01728920 ringneck snake, ring-necked snake, ring snake -n01729322 hognose snake, puff adder, sand viper -n01729977 green snake, grass snake -n01734418 king snake, kingsnake -n01735189 garter snake, grass snake -n01737021 water snake -n01739381 vine snake -n01740131 night snake, Hypsiglena torquata -n01742172 boa constrictor, Constrictor constrictor -n01744401 rock python, rock snake, Python sebae -n01748264 Indian cobra, Naja naja -n01749939 green mamba -n01751748 sea snake -n01753488 horned viper, cerastes, sand viper, horned asp, Cerastes cornutus -n01755581 diamondback, diamondback rattlesnake, Crotalus adamanteus -n01756291 sidewinder, horned rattlesnake, Crotalus cerastes -n01768244 trilobite -n01770081 harvestman, daddy longlegs, Phalangium opilio -n01770393 scorpion -n01773157 black and gold garden spider, Argiope aurantia -n01773549 barn spider, Araneus cavaticus -n01773797 garden spider, Aranea diademata -n01774384 black widow, Latrodectus mactans -n01774750 tarantula -n01775062 wolf spider, hunting spider -n01776313 tick -n01784675 centipede -n01795545 black grouse -n01796340 ptarmigan -n01797886 ruffed grouse, partridge, Bonasa umbellus -n01798484 prairie chicken, prairie grouse, prairie fowl -n01806143 peacock -n01806567 quail -n01807496 partridge -n01817953 African grey, African gray, Psittacus erithacus -n01818515 macaw -n01819313 sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita -n01820546 lorikeet -n01824575 coucal -n01828970 bee eater -n01829413 hornbill -n01833805 hummingbird -n01843065 jacamar -n01843383 toucan -n01847000 drake -n01855032 red-breasted merganser, Mergus serrator -n01855672 goose -n01860187 black swan, Cygnus atratus -n01871265 tusker -n01872401 echidna, spiny anteater, anteater -n01873310 platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus -n01877812 wallaby, brush kangaroo -n01882714 koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus -n01883070 wombat -n01910747 jellyfish -n01914609 sea anemone, anemone -n01917289 brain coral -n01924916 flatworm, platyhelminth -n01930112 nematode, nematode worm, roundworm -n01943899 conch -n01944390 snail -n01945685 slug -n01950731 sea slug, nudibranch -n01955084 chiton, coat-of-mail shell, sea cradle, polyplacophore -n01968897 chambered nautilus, pearly nautilus, nautilus -n01978287 Dungeness crab, Cancer magister -n01978455 rock crab, Cancer irroratus -n01980166 fiddler crab -n01981276 king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica -n01983481 American lobster, Northern lobster, Maine lobster, Homarus americanus -n01984695 spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish -n01985128 crayfish, crawfish, crawdad, crawdaddy -n01986214 hermit crab -n01990800 isopod -n02002556 white stork, Ciconia ciconia -n02002724 black stork, Ciconia nigra -n02006656 spoonbill -n02007558 flamingo -n02009229 little blue heron, Egretta caerulea -n02009912 American egret, great white heron, Egretta albus -n02011460 bittern -n02012849 crane -n02013706 limpkin, Aramus pictus -n02017213 European gallinule, Porphyrio porphyrio -n02018207 American coot, marsh hen, mud hen, water hen, Fulica americana -n02018795 bustard -n02025239 ruddy turnstone, Arenaria interpres -n02027492 red-backed sandpiper, dunlin, Erolia alpina -n02028035 redshank, Tringa totanus -n02033041 dowitcher -n02037110 oystercatcher, oyster catcher -n02051845 pelican -n02056570 king penguin, Aptenodytes patagonica -n02058221 albatross, mollymawk -n02066245 grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus -n02071294 killer whale, killer, orca, grampus, sea wolf, Orcinus orca -n02074367 dugong, Dugong dugon -n02077923 sea lion -n02085620 Chihuahua -n02085782 Japanese spaniel -n02085936 Maltese dog, Maltese terrier, Maltese -n02086079 Pekinese, Pekingese, Peke -n02086240 Shih-Tzu -n02086646 Blenheim spaniel -n02086910 papillon -n02087046 toy terrier -n02087394 Rhodesian ridgeback -n02088094 Afghan hound, Afghan -n02088238 basset, basset hound -n02088364 beagle -n02088466 bloodhound, sleuthhound -n02088632 bluetick -n02089078 black-and-tan coonhound -n02089867 Walker hound, Walker foxhound -n02089973 English foxhound -n02090379 redbone -n02090622 borzoi, Russian wolfhound -n02090721 Irish wolfhound -n02091032 Italian greyhound -n02091134 whippet -n02091244 Ibizan hound, Ibizan Podenco -n02091467 Norwegian elkhound, elkhound -n02091635 otterhound, otter hound -n02091831 Saluki, gazelle hound -n02092002 Scottish deerhound, deerhound -n02092339 Weimaraner -n02093256 Staffordshire bullterrier, Staffordshire bull terrier -n02093428 American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier -n02093647 Bedlington terrier -n02093754 Border terrier -n02093859 Kerry blue terrier -n02093991 Irish terrier -n02094114 Norfolk terrier -n02094258 Norwich terrier -n02094433 Yorkshire terrier -n02095314 wire-haired fox terrier -n02095570 Lakeland terrier -n02095889 Sealyham terrier, Sealyham -n02096051 Airedale, Airedale terrier -n02096177 cairn, cairn terrier -n02096294 Australian terrier -n02096437 Dandie Dinmont, Dandie Dinmont terrier -n02096585 Boston bull, Boston terrier -n02097047 miniature schnauzer -n02097130 giant schnauzer -n02097209 standard schnauzer -n02097298 Scotch terrier, Scottish terrier, Scottie -n02097474 Tibetan terrier, chrysanthemum dog -n02097658 silky terrier, Sydney silky -n02098105 soft-coated wheaten terrier -n02098286 West Highland white terrier -n02098413 Lhasa, Lhasa apso -n02099267 flat-coated retriever -n02099429 curly-coated retriever -n02099601 golden retriever -n02099712 Labrador retriever -n02099849 Chesapeake Bay retriever -n02100236 German short-haired pointer -n02100583 vizsla, Hungarian pointer -n02100735 English setter -n02100877 Irish setter, red setter -n02101006 Gordon setter -n02101388 Brittany spaniel -n02101556 clumber, clumber spaniel -n02102040 English springer, English springer spaniel -n02102177 Welsh springer spaniel -n02102318 cocker spaniel, English cocker spaniel, cocker -n02102480 Sussex spaniel -n02102973 Irish water spaniel -n02104029 kuvasz -n02104365 schipperke -n02105056 groenendael -n02105162 malinois -n02105251 briard -n02105412 kelpie -n02105505 komondor -n02105641 Old English sheepdog, bobtail -n02105855 Shetland sheepdog, Shetland sheep dog, Shetland -n02106030 collie -n02106166 Border collie -n02106382 Bouvier des Flandres, Bouviers des Flandres -n02106550 Rottweiler -n02106662 German shepherd, German shepherd dog, German police dog, alsatian -n02107142 Doberman, Doberman pinscher -n02107312 miniature pinscher -n02107574 Greater Swiss Mountain dog -n02107683 Bernese mountain dog -n02107908 Appenzeller -n02108000 EntleBucher -n02108089 boxer -n02108422 bull mastiff -n02108551 Tibetan mastiff -n02108915 French bulldog -n02109047 Great Dane -n02109525 Saint Bernard, St Bernard -n02109961 Eskimo dog, husky -n02110063 malamute, malemute, Alaskan malamute -n02110185 Siberian husky -n02110341 dalmatian, coach dog, carriage dog -n02110627 affenpinscher, monkey pinscher, monkey dog -n02110806 basenji -n02110958 pug, pug-dog -n02111129 Leonberg -n02111277 Newfoundland, Newfoundland dog -n02111500 Great Pyrenees -n02111889 Samoyed, Samoyede -n02112018 Pomeranian -n02112137 chow, chow chow -n02112350 keeshond -n02112706 Brabancon griffon -n02113023 Pembroke, Pembroke Welsh corgi -n02113186 Cardigan, Cardigan Welsh corgi -n02113624 toy poodle -n02113712 miniature poodle -n02113799 standard poodle -n02113978 Mexican hairless -n02114367 timber wolf, grey wolf, gray wolf, Canis lupus -n02114548 white wolf, Arctic wolf, Canis lupus tundrarum -n02114712 red wolf, maned wolf, Canis rufus, Canis niger -n02114855 coyote, prairie wolf, brush wolf, Canis latrans -n02115641 dingo, warrigal, warragal, Canis dingo -n02115913 dhole, Cuon alpinus -n02116738 African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus -n02117135 hyena, hyaena -n02119022 red fox, Vulpes vulpes -n02119789 kit fox, Vulpes macrotis -n02120079 Arctic fox, white fox, Alopex lagopus -n02120505 grey fox, gray fox, Urocyon cinereoargenteus -n02123045 tabby, tabby cat -n02123159 tiger cat -n02123394 Persian cat -n02123597 Siamese cat, Siamese -n02124075 Egyptian cat -n02125311 cougar, puma, catamount, mountain lion, painter, panther, Felis concolor -n02127052 lynx, catamount -n02128385 leopard, Panthera pardus -n02128757 snow leopard, ounce, Panthera uncia -n02128925 jaguar, panther, Panthera onca, Felis onca -n02129165 lion, king of beasts, Panthera leo -n02129604 tiger, Panthera tigris -n02130308 cheetah, chetah, Acinonyx jubatus -n02132136 brown bear, bruin, Ursus arctos -n02133161 American black bear, black bear, Ursus americanus, Euarctos americanus -n02134084 ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus -n02134418 sloth bear, Melursus ursinus, Ursus ursinus -n02137549 mongoose -n02138441 meerkat, mierkat -n02165105 tiger beetle -n02165456 ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle -n02167151 ground beetle, carabid beetle -n02168699 long-horned beetle, longicorn, longicorn beetle -n02169497 leaf beetle, chrysomelid -n02172182 dung beetle -n02174001 rhinoceros beetle -n02177972 weevil -n02190166 fly -n02206856 bee -n02219486 ant, emmet, pismire -n02226429 grasshopper, hopper -n02229544 cricket -n02231487 walking stick, walkingstick, stick insect -n02233338 cockroach, roach -n02236044 mantis, mantid -n02256656 cicada, cicala -n02259212 leafhopper -n02264363 lacewing, lacewing fly -n02268443 dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk -n02268853 damselfly -n02276258 admiral -n02277742 ringlet, ringlet butterfly -n02279972 monarch, monarch butterfly, milkweed butterfly, Danaus plexippus -n02280649 cabbage butterfly -n02281406 sulphur butterfly, sulfur butterfly -n02281787 lycaenid, lycaenid butterfly -n02317335 starfish, sea star -n02319095 sea urchin -n02321529 sea cucumber, holothurian -n02325366 wood rabbit, cottontail, cottontail rabbit -n02326432 hare -n02328150 Angora, Angora rabbit -n02342885 hamster -n02346627 porcupine, hedgehog -n02356798 fox squirrel, eastern fox squirrel, Sciurus niger -n02361337 marmot -n02363005 beaver -n02364673 guinea pig, Cavia cobaya -n02389026 sorrel -n02391049 zebra -n02395406 hog, pig, grunter, squealer, Sus scrofa -n02396427 wild boar, boar, Sus scrofa -n02397096 warthog -n02398521 hippopotamus, hippo, river horse, Hippopotamus amphibius -n02403003 ox -n02408429 water buffalo, water ox, Asiatic buffalo, Bubalus bubalis -n02410509 bison -n02412080 ram, tup -n02415577 bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis -n02417914 ibex, Capra ibex -n02422106 hartebeest -n02422699 impala, Aepyceros melampus -n02423022 gazelle -n02437312 Arabian camel, dromedary, Camelus dromedarius -n02437616 llama -n02441942 weasel -n02442845 mink -n02443114 polecat, fitch, foulmart, foumart, Mustela putorius -n02443484 black-footed ferret, ferret, Mustela nigripes -n02444819 otter -n02445715 skunk, polecat, wood pussy -n02447366 badger -n02454379 armadillo -n02457408 three-toed sloth, ai, Bradypus tridactylus -n02480495 orangutan, orang, orangutang, Pongo pygmaeus -n02480855 gorilla, Gorilla gorilla -n02481823 chimpanzee, chimp, Pan troglodytes -n02483362 gibbon, Hylobates lar -n02483708 siamang, Hylobates syndactylus, Symphalangus syndactylus -n02484975 guenon, guenon monkey -n02486261 patas, hussar monkey, Erythrocebus patas -n02486410 baboon -n02487347 macaque -n02488291 langur -n02488702 colobus, colobus monkey -n02489166 proboscis monkey, Nasalis larvatus -n02490219 marmoset -n02492035 capuchin, ringtail, Cebus capucinus -n02492660 howler monkey, howler -n02493509 titi, titi monkey -n02493793 spider monkey, Ateles geoffroyi -n02494079 squirrel monkey, Saimiri sciureus -n02497673 Madagascar cat, ring-tailed lemur, Lemur catta -n02500267 indri, indris, Indri indri, Indri brevicaudatus -n02504013 Indian elephant, Elephas maximus -n02504458 African elephant, Loxodonta africana -n02509815 lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens -n02510455 giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca -n02514041 barracouta, snoek -n02526121 eel -n02536864 coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch -n02606052 rock beauty, Holocanthus tricolor -n02607072 anemone fish -n02640242 sturgeon -n02641379 gar, garfish, garpike, billfish, Lepisosteus osseus -n02643566 lionfish -n02655020 puffer, pufferfish, blowfish, globefish -n02666196 abacus -n02667093 abaya -n02669723 academic gown, academic robe, judge's robe -n02672831 accordion, piano accordion, squeeze box -n02676566 acoustic guitar -n02687172 aircraft carrier, carrier, flattop, attack aircraft carrier -n02690373 airliner -n02692877 airship, dirigible -n02699494 altar -n02701002 ambulance -n02704792 amphibian, amphibious vehicle -n02708093 analog clock -n02727426 apiary, bee house -n02730930 apron -n02747177 ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin -n02749479 assault rifle, assault gun -n02769748 backpack, back pack, knapsack, packsack, rucksack, haversack -n02776631 bakery, bakeshop, bakehouse -n02777292 balance beam, beam -n02782093 balloon -n02783161 ballpoint, ballpoint pen, ballpen, Biro -n02786058 Band Aid -n02787622 banjo -n02788148 bannister, banister, balustrade, balusters, handrail -n02790996 barbell -n02791124 barber chair -n02791270 barbershop -n02793495 barn -n02794156 barometer -n02795169 barrel, cask -n02797295 barrow, garden cart, lawn cart, wheelbarrow -n02799071 baseball -n02802426 basketball -n02804414 bassinet -n02804610 bassoon -n02807133 bathing cap, swimming cap -n02808304 bath towel -n02808440 bathtub, bathing tub, bath, tub -n02814533 beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon -n02814860 beacon, lighthouse, beacon light, pharos -n02815834 beaker -n02817516 bearskin, busby, shako -n02823428 beer bottle -n02823750 beer glass -n02825657 bell cote, bell cot -n02834397 bib -n02835271 bicycle-built-for-two, tandem bicycle, tandem -n02837789 bikini, two-piece -n02840245 binder, ring-binder -n02841315 binoculars, field glasses, opera glasses -n02843684 birdhouse -n02859443 boathouse -n02860847 bobsled, bobsleigh, bob -n02865351 bolo tie, bolo, bola tie, bola -n02869837 bonnet, poke bonnet -n02870880 bookcase -n02871525 bookshop, bookstore, bookstall -n02877765 bottlecap -n02879718 bow -n02883205 bow tie, bow-tie, bowtie -n02892201 brass, memorial tablet, plaque -n02892767 brassiere, bra, bandeau -n02894605 breakwater, groin, groyne, mole, bulwark, seawall, jetty -n02895154 breastplate, aegis, egis -n02906734 broom -n02909870 bucket, pail -n02910353 buckle -n02916936 bulletproof vest -n02917067 bullet train, bullet -n02927161 butcher shop, meat market -n02930766 cab, hack, taxi, taxicab -n02939185 caldron, cauldron -n02948072 candle, taper, wax light -n02950826 cannon -n02951358 canoe -n02951585 can opener, tin opener -n02963159 cardigan -n02965783 car mirror -n02966193 carousel, carrousel, merry-go-round, roundabout, whirligig -n02966687 carpenter's kit, tool kit -n02971356 carton -n02974003 car wheel -n02977058 cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM -n02978881 cassette -n02979186 cassette player -n02980441 castle -n02981792 catamaran -n02988304 CD player -n02992211 cello, violoncello -n02992529 cellular telephone, cellular phone, cellphone, cell, mobile phone -n02999410 chain -n03000134 chainlink fence -n03000247 chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour -n03000684 chain saw, chainsaw -n03014705 chest -n03016953 chiffonier, commode -n03017168 chime, bell, gong -n03018349 china cabinet, china closet -n03026506 Christmas stocking -n03028079 church, church building -n03032252 cinema, movie theater, movie theatre, movie house, picture palace -n03041632 cleaver, meat cleaver, chopper -n03042490 cliff dwelling -n03045698 cloak -n03047690 clog, geta, patten, sabot -n03062245 cocktail shaker -n03063599 coffee mug -n03063689 coffeepot -n03065424 coil, spiral, volute, whorl, helix -n03075370 combination lock -n03085013 computer keyboard, keypad -n03089624 confectionery, confectionary, candy store -n03095699 container ship, containership, container vessel -n03100240 convertible -n03109150 corkscrew, bottle screw -n03110669 cornet, horn, trumpet, trump -n03124043 cowboy boot -n03124170 cowboy hat, ten-gallon hat -n03125729 cradle -n03126707 crane -n03127747 crash helmet -n03127925 crate -n03131574 crib, cot -n03133878 Crock Pot -n03134739 croquet ball -n03141823 crutch -n03146219 cuirass -n03160309 dam, dike, dyke -n03179701 desk -n03180011 desktop computer -n03187595 dial telephone, dial phone -n03188531 diaper, nappy, napkin -n03196217 digital clock -n03197337 digital watch -n03201208 dining table, board -n03207743 dishrag, dishcloth -n03207941 dishwasher, dish washer, dishwashing machine -n03208938 disk brake, disc brake -n03216828 dock, dockage, docking facility -n03218198 dogsled, dog sled, dog sleigh -n03220513 dome -n03223299 doormat, welcome mat -n03240683 drilling platform, offshore rig -n03249569 drum, membranophone, tympan -n03250847 drumstick -n03255030 dumbbell -n03259280 Dutch oven -n03271574 electric fan, blower -n03272010 electric guitar -n03272562 electric locomotive -n03290653 entertainment center -n03291819 envelope -n03297495 espresso maker -n03314780 face powder -n03325584 feather boa, boa -n03337140 file, file cabinet, filing cabinet -n03344393 fireboat -n03345487 fire engine, fire truck -n03347037 fire screen, fireguard -n03355925 flagpole, flagstaff -n03372029 flute, transverse flute -n03376595 folding chair -n03379051 football helmet -n03384352 forklift -n03388043 fountain -n03388183 fountain pen -n03388549 four-poster -n03393912 freight car -n03394916 French horn, horn -n03400231 frying pan, frypan, skillet -n03404251 fur coat -n03417042 garbage truck, dustcart -n03424325 gasmask, respirator, gas helmet -n03425413 gas pump, gasoline pump, petrol pump, island dispenser -n03443371 goblet -n03444034 go-kart -n03445777 golf ball -n03445924 golfcart, golf cart -n03447447 gondola -n03447721 gong, tam-tam -n03450230 gown -n03452741 grand piano, grand -n03457902 greenhouse, nursery, glasshouse -n03459775 grille, radiator grille -n03461385 grocery store, grocery, food market, market -n03467068 guillotine -n03476684 hair slide -n03476991 hair spray -n03478589 half track -n03481172 hammer -n03482405 hamper -n03483316 hand blower, blow dryer, blow drier, hair dryer, hair drier -n03485407 hand-held computer, hand-held microcomputer -n03485794 handkerchief, hankie, hanky, hankey -n03492542 hard disc, hard disk, fixed disk -n03494278 harmonica, mouth organ, harp, mouth harp -n03495258 harp -n03496892 harvester, reaper -n03498962 hatchet -n03527444 holster -n03529860 home theater, home theatre -n03530642 honeycomb -n03532672 hook, claw -n03534580 hoopskirt, crinoline -n03535780 horizontal bar, high bar -n03538406 horse cart, horse-cart -n03544143 hourglass -n03584254 iPod -n03584829 iron, smoothing iron -n03590841 jack-o'-lantern -n03594734 jean, blue jean, denim -n03594945 jeep, landrover -n03595614 jersey, T-shirt, tee shirt -n03598930 jigsaw puzzle -n03599486 jinrikisha, ricksha, rickshaw -n03602883 joystick -n03617480 kimono -n03623198 knee pad -n03627232 knot -n03630383 lab coat, laboratory coat -n03633091 ladle -n03637318 lampshade, lamp shade -n03642806 laptop, laptop computer -n03649909 lawn mower, mower -n03657121 lens cap, lens cover -n03658185 letter opener, paper knife, paperknife -n03661043 library -n03662601 lifeboat -n03666591 lighter, light, igniter, ignitor -n03670208 limousine, limo -n03673027 liner, ocean liner -n03676483 lipstick, lip rouge -n03680355 Loafer -n03690938 lotion -n03691459 loudspeaker, speaker, speaker unit, loudspeaker system, speaker system -n03692522 loupe, jeweler's loupe -n03697007 lumbermill, sawmill -n03706229 magnetic compass -n03709823 mailbag, postbag -n03710193 mailbox, letter box -n03710637 maillot -n03710721 maillot, tank suit -n03717622 manhole cover -n03720891 maraca -n03721384 marimba, xylophone -n03724870 mask -n03729826 matchstick -n03733131 maypole -n03733281 maze, labyrinth -n03733805 measuring cup -n03742115 medicine chest, medicine cabinet -n03743016 megalith, megalithic structure -n03759954 microphone, mike -n03761084 microwave, microwave oven -n03763968 military uniform -n03764736 milk can -n03769881 minibus -n03770439 miniskirt, mini -n03770679 minivan -n03773504 missile -n03775071 mitten -n03775546 mixing bowl -n03776460 mobile home, manufactured home -n03777568 Model T -n03777754 modem -n03781244 monastery -n03782006 monitor -n03785016 moped -n03786901 mortar -n03787032 mortarboard -n03788195 mosque -n03788365 mosquito net -n03791053 motor scooter, scooter -n03792782 mountain bike, all-terrain bike, off-roader -n03792972 mountain tent -n03793489 mouse, computer mouse -n03794056 mousetrap -n03796401 moving van -n03803284 muzzle -n03804744 nail -n03814639 neck brace -n03814906 necklace -n03825788 nipple -n03832673 notebook, notebook computer -n03837869 obelisk -n03838899 oboe, hautboy, hautbois -n03840681 ocarina, sweet potato -n03841143 odometer, hodometer, mileometer, milometer -n03843555 oil filter -n03854065 organ, pipe organ -n03857828 oscilloscope, scope, cathode-ray oscilloscope, CRO -n03866082 overskirt -n03868242 oxcart -n03868863 oxygen mask -n03871628 packet -n03873416 paddle, boat paddle -n03874293 paddlewheel, paddle wheel -n03874599 padlock -n03876231 paintbrush -n03877472 pajama, pyjama, pj's, jammies -n03877845 palace -n03884397 panpipe, pandean pipe, syrinx -n03887697 paper towel -n03888257 parachute, chute -n03888605 parallel bars, bars -n03891251 park bench -n03891332 parking meter -n03895866 passenger car, coach, carriage -n03899768 patio, terrace -n03902125 pay-phone, pay-station -n03903868 pedestal, plinth, footstall -n03908618 pencil box, pencil case -n03908714 pencil sharpener -n03916031 perfume, essence -n03920288 Petri dish -n03924679 photocopier -n03929660 pick, plectrum, plectron -n03929855 pickelhaube -n03930313 picket fence, paling -n03930630 pickup, pickup truck -n03933933 pier -n03935335 piggy bank, penny bank -n03937543 pill bottle -n03938244 pillow -n03942813 ping-pong ball -n03944341 pinwheel -n03947888 pirate, pirate ship -n03950228 pitcher, ewer -n03954731 plane, carpenter's plane, woodworking plane -n03956157 planetarium -n03958227 plastic bag -n03961711 plate rack -n03967562 plow, plough -n03970156 plunger, plumber's helper -n03976467 Polaroid camera, Polaroid Land camera -n03976657 pole -n03977966 police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria -n03980874 poncho -n03982430 pool table, billiard table, snooker table -n03983396 pop bottle, soda bottle -n03991062 pot, flowerpot -n03992509 potter's wheel -n03995372 power drill -n03998194 prayer rug, prayer mat -n04004767 printer -n04005630 prison, prison house -n04008634 projectile, missile -n04009552 projector -n04019541 puck, hockey puck -n04023962 punching bag, punch bag, punching ball, punchball -n04026417 purse -n04033901 quill, quill pen -n04033995 quilt, comforter, comfort, puff -n04037443 racer, race car, racing car -n04039381 racket, racquet -n04040759 radiator -n04041544 radio, wireless -n04044716 radio telescope, radio reflector -n04049303 rain barrel -n04065272 recreational vehicle, RV, R.V. -n04067472 reel -n04069434 reflex camera -n04070727 refrigerator, icebox -n04074963 remote control, remote -n04081281 restaurant, eating house, eating place, eatery -n04086273 revolver, six-gun, six-shooter -n04090263 rifle -n04099969 rocking chair, rocker -n04111531 rotisserie -n04116512 rubber eraser, rubber, pencil eraser -n04118538 rugby ball -n04118776 rule, ruler -n04120489 running shoe -n04125021 safe -n04127249 safety pin -n04131690 saltshaker, salt shaker -n04133789 sandal -n04136333 sarong -n04141076 sax, saxophone -n04141327 scabbard -n04141975 scale, weighing machine -n04146614 school bus -n04147183 schooner -n04149813 scoreboard -n04152593 screen, CRT screen -n04153751 screw -n04154565 screwdriver -n04162706 seat belt, seatbelt -n04179913 sewing machine -n04192698 shield, buckler -n04200800 shoe shop, shoe-shop, shoe store -n04201297 shoji -n04204238 shopping basket -n04204347 shopping cart -n04208210 shovel -n04209133 shower cap -n04209239 shower curtain -n04228054 ski -n04229816 ski mask -n04235860 sleeping bag -n04238763 slide rule, slipstick -n04239074 sliding door -n04243546 slot, one-armed bandit -n04251144 snorkel -n04252077 snowmobile -n04252225 snowplow, snowplough -n04254120 soap dispenser -n04254680 soccer ball -n04254777 sock -n04258138 solar dish, solar collector, solar furnace -n04259630 sombrero -n04263257 soup bowl -n04264628 space bar -n04265275 space heater -n04266014 space shuttle -n04270147 spatula -n04273569 speedboat -n04275548 spider web, spider's web -n04277352 spindle -n04285008 sports car, sport car -n04286575 spotlight, spot -n04296562 stage -n04310018 steam locomotive -n04311004 steel arch bridge -n04311174 steel drum -n04317175 stethoscope -n04325704 stole -n04326547 stone wall -n04328186 stopwatch, stop watch -n04330267 stove -n04332243 strainer -n04335435 streetcar, tram, tramcar, trolley, trolley car -n04336792 stretcher -n04344873 studio couch, day bed -n04346328 stupa, tope -n04347754 submarine, pigboat, sub, U-boat -n04350905 suit, suit of clothes -n04355338 sundial -n04355933 sunglass -n04356056 sunglasses, dark glasses, shades -n04357314 sunscreen, sunblock, sun blocker -n04366367 suspension bridge -n04367480 swab, swob, mop -n04370456 sweatshirt -n04371430 swimming trunks, bathing trunks -n04371774 swing -n04372370 switch, electric switch, electrical switch -n04376876 syringe -n04380533 table lamp -n04389033 tank, army tank, armored combat vehicle, armoured combat vehicle -n04392985 tape player -n04398044 teapot -n04399382 teddy, teddy bear -n04404412 television, television system -n04409515 tennis ball -n04417672 thatch, thatched roof -n04418357 theater curtain, theatre curtain -n04423845 thimble -n04428191 thresher, thrasher, threshing machine -n04429376 throne -n04435653 tile roof -n04442312 toaster -n04443257 tobacco shop, tobacconist shop, tobacconist -n04447861 toilet seat -n04456115 torch -n04458633 totem pole -n04461696 tow truck, tow car, wrecker -n04462240 toyshop -n04465501 tractor -n04467665 trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi -n04476259 tray -n04479046 trench coat -n04482393 tricycle, trike, velocipede -n04483307 trimaran -n04485082 tripod -n04486054 triumphal arch -n04487081 trolleybus, trolley coach, trackless trolley -n04487394 trombone -n04493381 tub, vat -n04501370 turnstile -n04505470 typewriter keyboard -n04507155 umbrella -n04509417 unicycle, monocycle -n04515003 upright, upright piano -n04517823 vacuum, vacuum cleaner -n04522168 vase -n04523525 vault -n04525038 velvet -n04525305 vending machine -n04532106 vestment -n04532670 viaduct -n04536866 violin, fiddle -n04540053 volleyball -n04542943 waffle iron -n04548280 wall clock -n04548362 wallet, billfold, notecase, pocketbook -n04550184 wardrobe, closet, press -n04552348 warplane, military plane -n04553703 washbasin, handbasin, washbowl, lavabo, wash-hand basin -n04554684 washer, automatic washer, washing machine -n04557648 water bottle -n04560804 water jug -n04562935 water tower -n04579145 whiskey jug -n04579432 whistle -n04584207 wig -n04589890 window screen -n04590129 window shade -n04591157 Windsor tie -n04591713 wine bottle -n04592741 wing -n04596742 wok -n04597913 wooden spoon -n04599235 wool, woolen, woollen -n04604644 worm fence, snake fence, snake-rail fence, Virginia fence -n04606251 wreck -n04612504 yawl -n04613696 yurt -n06359193 web site, website, internet site, site -n06596364 comic book -n06785654 crossword puzzle, crossword -n06794110 street sign -n06874185 traffic light, traffic signal, stoplight -n07248320 book jacket, dust cover, dust jacket, dust wrapper -n07565083 menu -n07579787 plate -n07583066 guacamole -n07584110 consomme -n07590611 hot pot, hotpot -n07613480 trifle -n07614500 ice cream, icecream -n07615774 ice lolly, lolly, lollipop, popsicle -n07684084 French loaf -n07693725 bagel, beigel -n07695742 pretzel -n07697313 cheeseburger -n07697537 hotdog, hot dog, red hot -n07711569 mashed potato -n07714571 head cabbage -n07714990 broccoli -n07715103 cauliflower -n07716358 zucchini, courgette -n07716906 spaghetti squash -n07717410 acorn squash -n07717556 butternut squash -n07718472 cucumber, cuke -n07718747 artichoke, globe artichoke -n07720875 bell pepper -n07730033 cardoon -n07734744 mushroom -n07742313 Granny Smith -n07745940 strawberry -n07747607 orange -n07749582 lemon -n07753113 fig -n07753275 pineapple, ananas -n07753592 banana -n07754684 jackfruit, jak, jack -n07760859 custard apple -n07768694 pomegranate -n07802026 hay -n07831146 carbonara -n07836838 chocolate sauce, chocolate syrup -n07860988 dough -n07871810 meat loaf, meatloaf -n07873807 pizza, pizza pie -n07875152 potpie -n07880968 burrito -n07892512 red wine -n07920052 espresso -n07930864 cup -n07932039 eggnog -n09193705 alp -n09229709 bubble -n09246464 cliff, drop, drop-off -n09256479 coral reef -n09288635 geyser -n09332890 lakeside, lakeshore -n09399592 promontory, headland, head, foreland -n09421951 sandbar, sand bar -n09428293 seashore, coast, seacoast, sea-coast -n09468604 valley, vale -n09472597 volcano -n09835506 ballplayer, baseball player -n10148035 groom, bridegroom -n10565667 scuba diver -n11879895 rapeseed -n11939491 daisy -n12057211 yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum -n12144580 corn -n12267677 acorn -n12620546 hip, rose hip, rosehip -n12768682 buckeye, horse chestnut, conker -n12985857 coral fungus -n12998815 agaric -n13037406 gyromitra -n13040303 stinkhorn, carrion fungus -n13044778 earthstar -n13052670 hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa -n13054560 bolete -n13133613 ear, spike, capitulum -n15075141 toilet tissue, toilet paper, bathroom tissue diff --git a/configs/opencv-ovms/demos/common/python/helpers.py b/configs/opencv-ovms/demos/common/python/helpers.py deleted file mode 100644 index 8bf332cb..00000000 --- a/configs/opencv-ovms/demos/common/python/helpers.py +++ /dev/null @@ -1,32 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import logging as log - - -def resolution(value): - try: - result = [int(v) for v in value.split('x')] - if len(result) != 2: - raise RuntimeError('Correct format of --output_resolution parameter is "width"x"height".') - except ValueError: - raise RuntimeError('Correct format of --output_resolution parameter is "width"x"height".') - return result - -def log_latency_per_stage(*pipeline_metrics): - stages = ('Decoding', 'Preprocessing', 'Inference', 'Postprocessing', 'Rendering') - for stage, latency in zip(stages, pipeline_metrics): - log.info('\t{}:\t{:.1f} ms'.format(stage, latency)) diff --git a/configs/opencv-ovms/demos/common/python/html_reader.py b/configs/opencv-ovms/demos/common/python/html_reader.py deleted file mode 100644 index cc676b76..00000000 --- a/configs/opencv-ovms/demos/common/python/html_reader.py +++ /dev/null @@ -1,61 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import urllib.request -import re -from html.parser import HTMLParser -import logging as log - -class HTMLDataExtractor(HTMLParser): - def __init__(self, tags): - super(HTMLDataExtractor, self).__init__() - self.started_tags = {k: [] for k in tags} - self.ended_tags = {k: [] for k in tags} - - def handle_starttag(self, tag, attrs): - if tag in self.started_tags: - self.started_tags[tag].append([]) - - def handle_endtag(self, tag): - if tag in self.ended_tags: - txt = ''.join(self.started_tags[tag].pop()) - self.ended_tags[tag].append(txt) - - def handle_data(self, data): - for tag, l in self.started_tags.items(): - for d in l: - d.append(data) - -# read html urls and list of all paragraphs data -def get_paragraphs(url_list): - paragraphs_all = [] - for url in url_list: - log.debug("Get paragraphs from {}".format(url)) - with urllib.request.urlopen(url) as response: # nosec - disable B310:urllib-urlopen check - parser = HTMLDataExtractor(['title', 'p']) - charset='utf-8' - if 'Content-type' in response.headers: - m = re.match(r'.*charset=(\S+).*', response.headers['Content-type']) - if m: - charset = m.group(1) - data = response.read() - parser.feed(data.decode(charset)) - title = ' '.join(parser.ended_tags['title']) - paragraphs = parser.ended_tags['p'] - log.debug("Page '{}' has {} chars in {} paragraphs".format(title, sum(len(p) for p in paragraphs), len(paragraphs))) - paragraphs_all.extend(paragraphs) - - return paragraphs_all diff --git a/configs/opencv-ovms/demos/common/python/images_capture.py b/configs/opencv-ovms/demos/common/python/images_capture.py deleted file mode 100644 index 2b168545..00000000 --- a/configs/opencv-ovms/demos/common/python/images_capture.py +++ /dev/null @@ -1,203 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import os -import sys -from pathlib import Path -import copy -from time import perf_counter - -import cv2 - -sys.path.append(str(Path(__file__).resolve().parents[2] / 'common/python/openvino/model_zoo')) - -from model_api.performance_metrics import PerformanceMetrics - - -class InvalidInput(Exception): - - def __init__(self, message): - self.message = message - - -class OpenError(Exception): - - def __init__(self, message): - self.message = message - - -class ImagesCapture: - - def read(): - raise NotImplementedError - - def fps(): - raise NotImplementedError - - def get_type(): - raise NotImplementedError - - -class ImreadWrapper(ImagesCapture): - - def __init__(self, input, loop): - self.loop = loop - self.reader_metrics = PerformanceMetrics() - start_time = perf_counter() - if not os.path.isfile(input): - raise InvalidInput("Can't find the image by {}".format(input)) - self.image = cv2.imread(input, cv2.IMREAD_COLOR) - if self.image is None: - raise OpenError("Can't open the image from {}".format(input)) - self.reader_metrics.update(start_time) - self.can_read = True - - def read(self): - if self.loop: - return copy.deepcopy(self.image) - if self.can_read: - self.can_read = False - return copy.deepcopy(self.image) - return None - - def fps(self): - return 1.0 - - def get_type(self): - return 'IMAGE' - - -class DirReader(ImagesCapture): - - def __init__(self, input, loop): - self.loop = loop - self.reader_metrics = PerformanceMetrics() - self.dir = input - if not os.path.isdir(self.dir): - raise InvalidInput("Can't find the dir by {}".format(input)) - self.names = sorted(os.listdir(self.dir)) - if not self.names: - raise OpenError("The dir {} is empty".format(input)) - self.file_id = 0 - for name in self.names: - filename = os.path.join(self.dir, name) - image = cv2.imread(filename, cv2.IMREAD_COLOR) - if image is not None: - return - raise OpenError("Can't read the first image from {}".format(input)) - - def read(self): - start_time = perf_counter() - while self.file_id < len(self.names): - filename = os.path.join(self.dir, self.names[self.file_id]) - image = cv2.imread(filename, cv2.IMREAD_COLOR) - self.file_id += 1 - if image is not None: - self.reader_metrics.update(start_time) - return image - if self.loop: - self.file_id = 0 - while self.file_id < len(self.names): - filename = os.path.join(self.dir, self.names[self.file_id]) - image = cv2.imread(filename, cv2.IMREAD_COLOR) - self.file_id += 1 - if image is not None: - self.reader_metrics.update(start_time) - return image - return None - - def fps(self): - return 1.0 - - def get_type(self): - return 'DIR' - - -class VideoCapWrapper(ImagesCapture): - - def __init__(self, input, loop): - self.loop = loop - self.reader_metrics = PerformanceMetrics() - self.cap = cv2.VideoCapture() - status = self.cap.open(input) - if not status: - raise InvalidInput("Can't open the video from {}".format(input)) - - def read(self): - start_time = perf_counter() - status, image = self.cap.read() - if not status: - self.cap.set(cv2.CAP_PROP_POS_FRAMES, 0) - status, image = self.cap.read() - self.reader_metrics.update(start_time) - return status,image - - def fps(self): - return self.cap.get(cv2.CAP_PROP_FPS) - - def get_type(self): - return 'VIDEO' - - -class CameraCapWrapper(ImagesCapture): - - def __init__(self, input, camera_resolution): - self.reader_metrics = PerformanceMetrics() - self.cap = cv2.VideoCapture() - try: - status = self.cap.open(int(input)) - self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) - self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, camera_resolution[0]) - self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, camera_resolution[1]) - self.cap.set(cv2.CAP_PROP_FPS, 30) - self.cap.set(cv2.CAP_PROP_AUTOFOCUS, 1) - self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG')) - if not status: - raise OpenError("Can't open the camera from {}".format(input)) - except ValueError: - raise InvalidInput("Can't find the camera {}".format(input)) - - def read(self): - start_time = perf_counter() - status, image = self.cap.read() - if not status: - return None - self.reader_metrics.update(start_time) - return image - - def fps(self): - return self.cap.get(cv2.CAP_PROP_FPS) - - def get_type(self): - return 'CAMERA' - - -def open_images_capture(input, loop, camera_resolution=(1280, 720)): - errors = {InvalidInput: [], OpenError: []} - for reader in (ImreadWrapper, DirReader, VideoCapWrapper): - try: - return reader(input, loop) - except (InvalidInput, OpenError) as e: - errors[type(e)].append(e.message) - try: - return CameraCapWrapper(input, camera_resolution) - except (InvalidInput, OpenError) as e: - errors[type(e)].append(e.message) - if not errors[OpenError]: - print(*errors[InvalidInput], file=sys.stderr, sep='\n') - else: - print(*errors[OpenError], file=sys.stderr, sep='\n') - sys.exit(1) diff --git a/configs/opencv-ovms/demos/common/python/monitors.py b/configs/opencv-ovms/demos/common/python/monitors.py deleted file mode 100644 index 5c567c47..00000000 --- a/configs/opencv-ovms/demos/common/python/monitors.py +++ /dev/null @@ -1,40 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import os -if hasattr(os, "add_dll_directory"): - for path in os.environ.get("PATH", "").split(";"): - if os.path.isdir(path): - os.add_dll_directory(path) -try: - from monitors_extension import Presenter -except ImportError: - import logging as log - - - class Presenter: - def __init__(self, keys, yPos=20, graphSize=(150, 60), historySize=20): - self.yPos = yPos - self.graphSize = graphSize - self.graphPadding = 0 - if keys: - log.warning("monitors_extension wasn't found") - - def handleKey(self, key): pass - - def drawGraphs(self, frame): pass - - def reportMeans(self): return '' diff --git a/configs/opencv-ovms/demos/common/python/monitors_extension/CMakeLists.txt b/configs/opencv-ovms/demos/common/python/monitors_extension/CMakeLists.txt deleted file mode 100644 index 24562fef..00000000 --- a/configs/opencv-ovms/demos/common/python/monitors_extension/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (C) 2018-2023 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 -# - -find_package(OpenCV 4 REQUIRED COMPONENTS core) - -add_library(monitors_extension MODULE monitors_extension.cpp) -target_include_directories(monitors_extension PRIVATE ${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIR}) -target_link_libraries(monitors_extension PRIVATE ${PYTHON_LIBRARIES} opencv_core monitors utils) -set_target_properties(monitors_extension PROPERTIES PREFIX "") -if(WIN32) - set_target_properties(monitors_extension PROPERTIES SUFFIX ".pyd") -endif() diff --git a/configs/opencv-ovms/demos/common/python/monitors_extension/monitors_extension.cpp b/configs/opencv-ovms/demos/common/python/monitors_extension/monitors_extension.cpp deleted file mode 100644 index 6d5bd5d4..00000000 --- a/configs/opencv-ovms/demos/common/python/monitors_extension/monitors_extension.cpp +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright (C) 2018-2023 Intel Corporation -// SPDX-License-Identifier: Apache-2.0 -// - -#define PY_SSIZE_T_CLEAN -#include - -#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION -#include "numpy/arrayobject.h" - -#include -#include - -struct PresenterObject { - PyObject_HEAD - Presenter *_presenter; -}; - -namespace { -void presenter_dealloc(PresenterObject *self) { - delete self->_presenter; - PyTypeObject *tp = Py_TYPE(self); - tp->tp_free(self); - Py_DECREF(tp); -} - -char yPosName[] = "yPos", graphSizeName[] = "graphSize"; - -int presenter_init(PresenterObject *self, PyObject *args, PyObject *kwds) { - static char keysName[] = "keys", historySizeName[] = "graphSize"; - static char *kwlist[] = {keysName, yPosName, graphSizeName, historySizeName, nullptr}; - const char *keys; - int yPos = 20, graphSizeWidth = 150, graphSizeHeight = 60; - unsigned long long historySize = 20; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i(ii)K", kwlist, &keys, &yPos, &graphSizeWidth, &graphSizeHeight, - &historySize)) return -1; - try { - self->_presenter = new Presenter(keys, yPos, {graphSizeWidth, graphSizeHeight}, historySize); - return 0; - } catch (std::exception &exception) { - PyErr_SetString(PyExc_RuntimeError, exception.what()); - return -1; - } -} - -PyObject *presenter_handleKey(PresenterObject *self, PyObject *args, PyObject *kwds) { - if (!self->_presenter) { - PyErr_SetString(PyExc_AssertionError, "Underlying C++ presenter is nullptr"); - return nullptr; - } - static char keyName[] = "key"; - static char *kwlist[] = {keyName, nullptr}; - int key; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &key)) return nullptr; - try { - self->_presenter->handleKey(key); - Py_RETURN_NONE; - } catch (std::exception &exception) { - PyErr_SetString(PyExc_RuntimeError, exception.what()); - return nullptr; - } -} - -PyObject *presenter_drawGraphs(PresenterObject *self, PyObject *args, PyObject *kwds) { - if (!self->_presenter) { - PyErr_SetString(PyExc_AssertionError, "Underlying C++ presenter is nullptr"); - return nullptr; - } - static char frameName[] = "frame"; - static char *kwlist[] = {frameName, nullptr}; - PyArrayObject *npFrame; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &npFrame)) return nullptr; - if (PyArray_Check(npFrame) - && PyArray_TYPE(npFrame) != NPY_UINT8 - && PyArray_NDIM(npFrame) != 3 - && PyArray_SHAPE(npFrame)[2] != 3) { - PyErr_SetString(PyExc_TypeError, "frame must be an array of type uint8 with 3 dimensions with 3 elements in the" - " last dimension"); - return nullptr; - } - int height = static_cast(PyArray_SHAPE(npFrame)[0]); - int width = static_cast(PyArray_SHAPE(npFrame)[1]); - try { - cv::Mat frame(height, width, CV_8UC3, PyArray_DATA(npFrame), PyArray_STRIDE(npFrame, 0)); - self->_presenter->drawGraphs(frame); - Py_RETURN_NONE; - } catch (std::exception &exception) { - PyErr_SetString(PyExc_RuntimeError, exception.what()); - return nullptr; - } -} - -PyObject *presenter_reportMeans(PresenterObject *self, PyObject *Py_UNUSED(ignored)) { - if (!self->_presenter) { - PyErr_SetString(PyExc_AssertionError, "Underlying C++ presenter is nullptr"); - return nullptr; - } - try { - PyObject *PList = PyList_New(0); - auto report = self->_presenter->reportMeans(); - for(const auto& s : report){ - PyList_Append(PList, Py_BuildValue("s", s.c_str())); - } - return PList; - } catch (std::exception &exception) { - PyErr_SetString(PyExc_RuntimeError, exception.what()); - return nullptr; - } -} - -PyMethodDef presenter_methods[] = { - {"handleKey", reinterpret_cast(presenter_handleKey), METH_VARARGS | METH_KEYWORDS}, - {"drawGraphs", reinterpret_cast(presenter_drawGraphs), METH_VARARGS | METH_KEYWORDS}, - {"reportMeans", reinterpret_cast(presenter_reportMeans), METH_NOARGS}, - {}}; // Sentinel - -PyObject *presenter_getYPos(PresenterObject *self, void *closure) { - if (!self->_presenter) { - PyErr_SetString(PyExc_AssertionError, "Underlying C++ presenter is nullptr"); - return nullptr; - } - return PyLong_FromLong(self->_presenter->yPos); -} - -PyObject *presenter_getGraphSize(PresenterObject *self, void *closure) { - if (!self->_presenter) { - PyErr_SetString(PyExc_AssertionError , "Underlying C++ presenter is nullptr"); - return nullptr; - } - return Py_BuildValue("ii", self->_presenter->graphSize.width, self->_presenter->graphSize.height); -} - -PyObject *presenter_getGraphPadding(PresenterObject *self, void *closure) { - if (!self->_presenter) { - PyErr_SetString(PyExc_AssertionError, "Underlying C++ presenter is nullptr"); - return nullptr; - } - return PyLong_FromLong(self->_presenter->graphPadding); -} - -char graphPaddingName[] = "graphPadding"; -PyGetSetDef presenter_getsetters[] = { - {yPosName, reinterpret_cast(presenter_getYPos)}, - {graphSizeName, reinterpret_cast(presenter_getGraphSize)}, - {graphPaddingName, reinterpret_cast(presenter_getGraphPadding)}, - {}}; // Sentinel - -char monitors_extension_doc[] = "The module is a wrapper over C++ monitors. It guarantees that C++ and Python " - "monitors are consistent."; - -PyType_Slot presenterSlots[] = { - {Py_tp_dealloc, reinterpret_cast(presenter_dealloc)}, - {Py_tp_doc, monitors_extension_doc}, - {Py_tp_methods, presenter_methods}, - {Py_tp_getset, presenter_getsetters}, - {Py_tp_init, reinterpret_cast(presenter_init)}, - {Py_tp_new, reinterpret_cast(PyType_GenericNew)}, - {}}; // Sentinel - -PyType_Spec presenterSpec{"monitors_extension.Presenter", sizeof(PresenterObject), 0, 0, presenterSlots}; - -PyModuleDef monitors_extension{PyModuleDef_HEAD_INIT, "monitors_extension", monitors_extension_doc, 0}; -} - -PyMODINIT_FUNC PyInit_monitors_extension() { - import_array(); - if (PyErr_Occurred()) return nullptr; - - PyObject *presenterType = PyType_FromSpec(&presenterSpec); - if (!presenterType) return nullptr; - - PyObject *m = PyModule_Create(&monitors_extension); - if (m == nullptr) { - Py_DECREF(presenterType); - return nullptr; - } - - if (PyModule_AddObject(m, "Presenter", presenterType) < 0) { - Py_DECREF(presenterType); - Py_DECREF(m); - return nullptr; - } - return m; -} diff --git a/configs/opencv-ovms/demos/common/python/openvino/__init__.py b/configs/opencv-ovms/demos/common/python/openvino/__init__.py deleted file mode 100644 index 86ed7b8e..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -""" - Copyright (C) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -__path__ = __import__('pkgutil').extend_path(__path__, __name__) diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/__init__.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/__init__.py deleted file mode 100644 index 86ed7b8e..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -""" - Copyright (C) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -__path__ = __import__('pkgutil').extend_path(__path__, __name__) diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/README.md b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/README.md deleted file mode 100644 index 9057e7bd..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/README.md +++ /dev/null @@ -1,136 +0,0 @@ -# Python* Model API package - -Model API package is a set of wrapper classes for particular tasks and model architectures, simplifying data preprocess and postprocess as well as routine procedures (model loading, asynchronous execution, etc...) -An application feeds model class with input data, then the model returns postprocessed output data in user-friendly format. - -## Package structure - -The Model API consists of 3 libraries: -* _adapters_ implements a common interface to allow Model API wrappers usage with different executors. See [Model API adapters](#model-api-adapters) section -* _models_ implements wrappers for Open Model Zoo models. See [Model API Wrappers](#model-api-wrappers) section -* _pipelines_ implements pipelines for model inference and manage the synchronous/asynchronous execution. See [Model API Pipelines](#model-api-pipelines) section - -### Prerequisites - -The package requires -- one of OpenVINO supported Python version (see OpenVINO documentation for the details) -- OpenVINO™ toolkit - -If you build Model API package from source, you should install the OpenVINO™ toolkit. See the options: - -Use installation package for [Intel® Distribution of OpenVINO™ toolkit](https://www.intel.com/content/www/us/en/developer/tools/openvino-toolkit-download.html) or build the open-source version available in the [OpenVINO GitHub repository](https://github.com/openvinotoolkit/openvino) using the [build instructions](https://github.com/openvinotoolkit/openvino/wiki/BuildingCode). - -Also, you can install the OpenVINO Python\* package via the command: - ```sh -pip install openvino - ``` - -## Installing Python* Model API package - -Use the following command to install Model API from source: -```sh -pip install /demos/common/python -``` - -Alternatively, you can generate the package using a wheel. Follow the steps below: -1. Build the wheel. - -```sh -python /demos/common/python/setup.py bdist_wheel -``` -The wheel should appear in the dist folder. -Name example: `openmodelzoo_modelapi-0.0.0-py3-none-any.whl` - -2. Install the package in the clean environment with `--force-reinstall` key. -```sh -pip install openmodelzoo_modelapi-0.0.0-py3-none-any.whl --force-reinstall -``` - -To verify the package is installed, you might use the following command: -```sh -python -c "from openvino.model_zoo import model_api" -``` - -## Model API Wrappers - -The Model API package provides model wrappers, which implement standardized preprocessing/postprocessing functions per "task type" and incapsulate model-specific logic for usage of different models in a unified manner inside the application. - -The following tasks can be solved with wrappers usage: - -| Task type | Model API wrappers | -|----------------------------|--------------------| -| Background Matting |
  • `VideoBackgroundMatting`
  • `ImageMattingWithBackground`
  • `PortraitBackgroundMatting`
| -| Classification |
  • `Classification`
| -| Deblurring |
  • `Deblurring`
| -| Human Pose Estimation |
  • `HpeAssociativeEmbedding`
  • `OpenPose`
| -| Instance Segmentation |
  • `MaskRCNNModel`
  • `YolactModel`
| -| Monocular Depth Estimation |
  • `MonoDepthModel`
| -| Named Entity Recognition |
  • `BertNamedEntityRecognition`
| -| Object Detection |
  • `CenterNet`
  • `DETR`
  • `CTPN`
  • `FaceBoxes`
  • `NanoDet`
  • `NanoDetPlus`
  • `RetinaFace`
  • `RetinaFacePyTorch`
  • `SSD`
  • `UltraLightweightFaceDetection`
  • `YOLO`
  • `YoloV3ONNX`
  • `YoloV4`
  • `YOLOF`
  • `YOLOX`
| -| Question Answering |
  • `BertQuestionAnswering`
| -| Salient Object Detection |
  • `SalientObjectDetectionModel`
| -| Semantic Segmentation |
  • `SegmentationModel`
| - -## Model API Adapters - -Model API wrappers are executor-agnostic, meaning it does not implement the specific model inference or model loading, instead it can be used with different executors having the implementation of common interface methods in adapter class respectively. - -Currently, `OpenvinoAdapter` and `OVMSAdapter` are supported. - -#### OpenVINO Adapter - -`OpenvinoAdapter` hides the OpenVINO™ toolkit API, which allows Model API wrappers launching with models represented in Intermediate Representation (IR) format. -It accepts a path to either `xml` model file or `onnx` model file. - -#### OpenVINO Model Server Adapter - -`OVMSAdapter` hides the OpenVINO Model Server python client API, which allows Model API wrappers launching with models served by OVMS. - -Refer to __[`OVMSAdapter`](adapters/ovms_adapter.md)__ to learn about running demos with OVMS. - -For using OpenVINO Model Server Adapter you need to install the package with extra module: -```sh -pip install /demos/common/python[ovms] -``` - -## Model API Pipelines - -Model API Pipelines represent the high-level wrappers upon the input data and accessing model results management. -They perform the data submission for model inference, verification of inference status, whether the result is ready or not, and results accessing. - -The `AsyncPipeline` is available, which handles the asynchronous execution of a single model. - -## Ready-to-use Model API solutions - -To apply Model API wrappers in custom applications, learn the provided example of common scenario of how to use Model API. - - In the example, the SSD architecture is used to predict bounding boxes on input image `"sample.png"`. The model execution is produced by `OpenvinoAdapter`, therefore we submit the path to the model's `xml` file. - -Once the SSD model wrapper instance is created, we get the predictions by the model in one line: `ssd_model(input_data)` - the wrapper performs the preprocess method, synchronous inference on OpenVINO™ toolkit side and postprocess method. - -```python -import cv2 -# import model wrapper class -from openvino.model_zoo.model_api.models import SSD -# import inference adapter and helper for runtime setup -from openvino.model_zoo.model_api.adapters import OpenvinoAdapter, create_core - - -# read input image using opencv -input_data = cv2.imread("sample.png") - -# define the path to mobilenet-ssd model in IR format -model_path = "public/mobilenet-ssd/FP32/mobilenet-ssd.xml" - -# create adapter for OpenVINO™ runtime, pass the model path -model_adapter = OpenvinoAdapter(create_core(), model_path, device="CPU") - -# create model API wrapper for SSD architecture -# preload=True loads the model on CPU inside the adapter -ssd_model = SSD(model_adapter, preload=True) - -# apply input preprocessing, sync inference, model output postprocessing -results = ssd_model(input_data) -``` - -To study the complex scenarios, refer to Open Model Zoo Python* demos, where the asynchronous inference is applied. diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/__init__.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/__init__.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/__init__.py deleted file mode 100644 index be139d88..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -""" - Copyright (C) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - - -from .openvino_adapter import create_core, OpenvinoAdapter -from .ovms_adapter import OVMSAdapter -from .utils import Layout - -__all__ = [ - 'create_core', - 'Layout', - 'OpenvinoAdapter', - 'OVMSAdapter', -] diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/model_adapter.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/model_adapter.py deleted file mode 100644 index ceca4c36..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/model_adapter.py +++ /dev/null @@ -1,159 +0,0 @@ -""" - Copyright (c) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import abc -from dataclasses import dataclass, field -from typing import Dict, List, Set - - -@dataclass -class Metadata: - names: Set[str] = field(default_factory=set) - shape: List[int] = field(default_factory=list) - layout: str = '' - precision: str = '' - type: str = '' - meta: Dict = field(default_factory=dict) - - -class ModelAdapter(metaclass=abc.ABCMeta): - ''' - An abstract Model Adapter with the following interface: - - - Reading the model from disk or other place - - Loading the model to the device - - Accessing the information about inputs/outputs - - The model reshaping - - Synchronous model inference - - Asynchronous model inference - ''' - precisions = ('FP32', 'I32', 'FP16', 'I16', 'I8', 'U8') - - @abc.abstractmethod - def __init__(self): - ''' - An abstract Model Adapter constructor. - Reads the model from disk or other place. - ''' - - @abc.abstractmethod - def load_model(self): - ''' - Loads the model on the device. - ''' - - @abc.abstractmethod - def get_input_layers(self): - ''' - Gets the names of model inputs and for each one creates the Metadata structure, - which contains the information about the input shape, layout, precision - in OpenVINO format, meta (optional) - - Returns: - - the dict containing Metadata for all inputs - ''' - - @abc.abstractmethod - def get_output_layers(self): - ''' - Gets the names of model outputs and for each one creates the Metadata structure, - which contains the information about the output shape, layout, precision - in OpenVINO format, meta (optional) - - Returns: - - the dict containing Metadata for all outputs - ''' - - @abc.abstractmethod - def reshape_model(self, new_shape): - ''' - Reshapes the model inputs to fit the new input shape. - - Args: - - new_shape (dict): the dictionary with inputs names as keys and - list of new shape as values in the following format: - { - 'input_layer_name_1': [1, 128, 128, 3], - 'input_layer_name_2': [1, 128, 128, 3], - ... - } - ''' - - @abc.abstractmethod - def infer_sync(self, dict_data): - ''' - Performs the synchronous model inference. The infer is a blocking method. - - Args: - - dict_data: it's submitted to the model for inference and has the following format: - { - 'input_layer_name_1': data_1, - 'input_layer_name_2': data_2, - ... - } - - Returns: - - raw result (dict) - model raw output in the following format: - { - 'output_layer_name_1': raw_result_1, - 'output_layer_name_2': raw_result_2, - ... - } - ''' - - @abc.abstractmethod - def infer_async(self, dict_data, callback_fn, callback_data): - ''' - Performs the asynchronous model inference and sets - the callback for inference completion. Also, it should - define get_raw_result() function, which handles the result - of inference from the model. - - Args: - - dict_data: it's submitted to the model for inference and has the following format: - { - 'input_layer_name_1': data_1, - 'input_layer_name_2': data_2, - ... - } - - callback_fn: the callback function, which is defined outside the adapter - - callback_data: the data for callback, that will be taken after the model inference is ended - ''' - - @abc.abstractmethod - def is_ready(self): - ''' - In case of asynchronous execution checks if one can submit input data - to the model for inference, or all infer requests are busy. - - Returns: - - the boolean flag whether the input data can be - submitted to the model for inference or not - ''' - - @abc.abstractmethod - def await_all(self): - ''' - In case of asynchronous execution waits the completion of all - busy infer requests. - ''' - - @abc.abstractmethod - def await_any(self): - ''' - In case of asynchronous execution waits the completion of any - busy infer request until it becomes available for the data submission. - ''' diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/openvino_adapter.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/openvino_adapter.py deleted file mode 100644 index 30a3f442..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/openvino_adapter.py +++ /dev/null @@ -1,187 +0,0 @@ -""" - Copyright (c) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import logging as log -from pathlib import Path - -try: - from openvino.runtime import AsyncInferQueue, Core, PartialShape, layout_helpers, get_version, Dimension - openvino_absent = False -except ImportError: - openvino_absent = True - -from .model_adapter import ModelAdapter, Metadata -from .utils import Layout -from ..pipelines import parse_devices - - -def create_core(): - if openvino_absent: - raise ImportError('The OpenVINO package is not installed') - - log.info('OpenVINO Runtime') - log.info('\tbuild: {}'.format(get_version())) - return Core() - - -class OpenvinoAdapter(ModelAdapter): - ''' - Works with OpenVINO model - ''' - - def __init__(self, core, model_path, weights_path=None, model_parameters = {}, device='CPU', plugin_config=None, max_num_requests=0): - self.core = core - self.model_path = model_path - self.device = device - self.plugin_config = plugin_config - self.max_num_requests = max_num_requests - self.model_parameters = model_parameters - self.model_parameters['input_layouts'] = Layout.parse_layouts(self.model_parameters.get('input_layouts', None)) - - if isinstance(model_path, (str, Path)): - if Path(model_path).suffix == ".onnx" and weights_path: - log.warning('For model in ONNX format should set only "model_path" parameter.' - 'The "weights_path" will be omitted') - - self.model_from_buffer = isinstance(model_path, bytes) and isinstance(weights_path, bytes) - log.info('Reading model {}'.format('from buffer' if self.model_from_buffer else model_path)) - weights = weights_path if self.model_from_buffer else '' - self.model = core.read_model(model_path, weights) - - def load_model(self): - self.compiled_model = self.core.compile_model(self.model, self.device, self.plugin_config) - self.async_queue = AsyncInferQueue(self.compiled_model, self.max_num_requests) - if self.max_num_requests == 0: - # +1 to use it as a buffer of the pipeline - self.async_queue = AsyncInferQueue(self.compiled_model, len(self.async_queue) + 1) - - log.info('The model {} is loaded to {}'.format("from buffer" if self.model_from_buffer else self.model_path, self.device)) - self.log_runtime_settings() - - def log_runtime_settings(self): - devices = set(parse_devices(self.device)) - if 'AUTO' not in devices: - for device in devices: - try: - nstreams = self.compiled_model.get_property(device + '_THROUGHPUT_STREAMS') - log.info('\tDevice: {}'.format(device)) - log.info('\t\tNumber of streams: {}'.format(nstreams)) - if device == 'CPU': - nthreads = self.compiled_model.get_property('CPU_THREADS_NUM') - log.info('\t\tNumber of threads: {}'.format(nthreads if int(nthreads) else 'AUTO')) - except RuntimeError: - pass - log.info('\tNumber of model infer requests: {}'.format(len(self.async_queue))) - - def get_input_layers(self): - inputs = {} - for input in self.model.inputs: - input_shape = get_input_shape(input) - input_layout = self.get_layout_for_input(input, input_shape) - inputs[input.get_any_name()] = Metadata(input.get_names(), input_shape, input_layout, input.get_element_type().get_type_name()) - inputs = self._get_meta_from_ngraph(inputs) - return inputs - - def get_layout_for_input(self, input, shape=None) -> str: - input_layout = '' - if self.model_parameters['input_layouts']: - input_layout = Layout.from_user_layouts(input.get_names(), self.model_parameters['input_layouts']) - if not input_layout: - if not layout_helpers.get_layout(input).empty: - input_layout = Layout.from_openvino(input) - else: - input_layout = Layout.from_shape(shape if shape is not None else input.shape) - return input_layout - - def get_output_layers(self): - outputs = {} - for output in self.model.outputs: - output_shape = output.partial_shape.get_min_shape() if self.model.is_dynamic() else output.shape - outputs[output.get_any_name()] = Metadata(output.get_names(), list(output_shape), precision=output.get_element_type().get_type_name()) - outputs = self._get_meta_from_ngraph(outputs) - return outputs - - def reshape_model(self, new_shape): - new_shape = {name: PartialShape( - [Dimension(dim) if not isinstance(dim, tuple) else Dimension(dim[0], dim[1]) - for dim in shape]) for name, shape in new_shape.items()} - self.model.reshape(new_shape) - - def get_raw_result(self, request): - return {key: request.get_tensor(key).data for key in self.get_output_layers()} - - def copy_raw_result(self, request): - return {key: request.get_tensor(key).data.copy() for key in self.get_output_layers()} - - def infer_sync(self, dict_data): - self.infer_request = self.async_queue[self.async_queue.get_idle_request_id()] - self.infer_request.infer(dict_data) - return self.get_raw_result(self.infer_request) - - def infer_async(self, dict_data, callback_data) -> None: - self.async_queue.start_async(dict_data, (self.copy_raw_result, callback_data)) - - def set_callback(self, callback_fn): - self.async_queue.set_callback(callback_fn) - - def is_ready(self) -> bool: - return self.async_queue.is_ready() - - def await_all(self) -> None: - self.async_queue.wait_all() - - def await_any(self) -> None: - self.async_queue.get_idle_request_id() - - def _get_meta_from_ngraph(self, layers_info): - for node in self.model.get_ordered_ops(): - layer_name = node.get_friendly_name() - if layer_name not in layers_info.keys(): - continue - layers_info[layer_name].meta = node.get_attributes() - layers_info[layer_name].type = node.get_type_name() - return layers_info - - def operations_by_type(self, operation_type): - layers_info = {} - for node in self.model.get_ordered_ops(): - if node.get_type_name() == operation_type: - layer_name = node.get_friendly_name() - layers_info[layer_name] = Metadata(type=node.get_type_name(), meta=node.get_attributes()) - return layers_info - - -def get_input_shape(input_tensor): - def string_to_tuple(string, casting_type=int): - processed = string.replace(' ', '').replace('(', '').replace(')', '').split(',') - processed = filter(lambda x: x, processed) - return tuple(map(casting_type, processed)) if casting_type else tuple(processed) - if not input_tensor.partial_shape.is_dynamic: - return list(input_tensor.shape) - ps = str(input_tensor.partial_shape) - if ps[0] == '[' and ps[-1] == ']': - ps = ps[1:-1] - preprocessed = ps.replace('{', '(').replace('}', ')').replace('?', '-1') - preprocessed = preprocessed.replace('(', '').replace(')', '') - if '..' in preprocessed: - shape_list = [] - for dim in preprocessed.split(','): - if '..' in dim: - shape_list.append(string_to_tuple(dim.replace('..', ','))) - else: - shape_list.append(int(dim)) - return shape_list - return string_to_tuple(preprocessed) diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/ovms_adapter.md b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/ovms_adapter.md deleted file mode 100644 index 6d72ac6b..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/ovms_adapter.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenVINO Model Server Adapter - -The `OVMSAdapter` implements `ModelAdapter` interface. The `OVMSAdapter` makes it possible to use Model API with models hosted in OpenVINO Model Server. - -## Prerequisites - -`OVMSAdapter` enables inference via gRPC calls to OpenVINO Model Server, so in order to use it you need two things: -- OpenVINO Model Server that serves your model -- [`ovmsclient`](https://pypi.org/project/ovmsclient/) package installed to enable communication with the model server - -### Deploy OpenVINO Model Server - -Model Server is distributed as a docker image and it's available in DockerHub, so you can use it with `docker run` command. See [model server documentation](https://github.com/openvinotoolkit/model_server/blob/main/docs/docker_container.md) to learn how to deploy OpenVINO optimized models with OpenVINO Model Server. - -### Install ovmsclient - -`ovmsclient` package is distributed on PyPi, so the easiest way to install it is via: - -``` -pip3 install ovmsclient -``` - -## Model configuration - -When using OpenVINO Model Server model cannot be directly accessed from the client application (like OMZ demos). Therefore any configuration must be done on model server side. - -### Input reshaping - -For some use cases you may want your model to reshape to match input of certain size. In that case, you should provide `--shape auto` parameter to model server startup command. With that option, model server will reshape model input on demand to match the input data. - -### Inference options - -It's possible to configure inference related options for the model in OpenVINO Model Server with options: -- `--target_device` - name of the device to load the model to -- `--nireq` - number of InferRequests -- `--plugin_config` - configuration of the device plugin - -See [model server configuration parameters](https://github.com/openvinotoolkit/model_server/blob/main/docs/docker_container.md#configuration-parameters) for more details. - -### Example OVMS startup command -``` -docker run -d --rm -v /home/user/models:/models -p 9000:9000 openvino/model_server:latest --model_path /models/model1 --model_name model1 --port 9000 --shape auto --nireq 32 --target_device CPU --plugin_config "{\"CPU_THROUGHPUT_STREAMS\": \"CPU_THROUGHPUT_AUTO\"}" -``` - -> **Note**: In demos, while using `--adapter ovms`, inference options like: `-nireq`, `-nstreams` `-nthreads` as well as device specification with `-d` will be ignored. - -## Running demos with OVMSAdapter - -To run the demo with model served in OpenVINO Model Server, you would have to provide `--adapter ovms` option and modify `-m` parameter to indicate model inference service instead of the model files. Model parameter for `OVMSAdapter` follows this schema: - -```/models/[:]``` - -- `` - OVMS gRPC service address in form `
:` -- `` - name of the target model (the one specified by `model_name` parameter in the model server startup command) -- `` *(optional)* - version of the target model (default: latest) - - Assuming that model server runs on the same machine as the demo, exposes gRPC service on port 9000 and serves model called `model1`, the value of `-m` parameter would be: - -- `localhost:9000/models/model1` - requesting latest model version -- `localhost:9000/models/model1:2` - requesting model version number 2 - -## See Also - -* [OpenVINO Model Server](https://github.com/openvinotoolkit/model_server) diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/ovms_adapter.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/ovms_adapter.py deleted file mode 100644 index 1cb9b218..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/ovms_adapter.py +++ /dev/null @@ -1,170 +0,0 @@ -""" - Copyright (c) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -try: - import ovmsclient - ovmsclient_absent = False -except ImportError: - ovmsclient_absent = True - -import re -import numpy as np -import logging as log -from .model_adapter import ModelAdapter, Metadata -from .utils import Layout - - -class OVMSAdapter(ModelAdapter): - ''' - Class that allows working with models served by the OpenVINO Model Server - ''' - - tf2ov_precision = { - "DT_INT64": "I64", - "DT_UINT64": "U64", - "DT_FLOAT": "FP32", - "DT_UINT32": "U32", - "DT_INT32": "I32", - "DT_HALF" : "FP16", - "DT_INT16": "I16", - "DT_INT8" : "I8", - "DT_UINT8": "U8", - } - - tf2np_precision = { - "DT_INT64": np.int64, - "DT_UINT64": np.uint64, - "DT_FLOAT": np.float32, - "DT_UINT32": np.uint32, - "DT_INT32": np.int32, - "DT_HALF" : np.float16, - "DT_INT16": np.int16, - "DT_INT8" : np.int8, - "DT_UINT8": np.uint8, - } - - @classmethod - def parse_model_arg(cls, target_model): - if not isinstance(target_model, str): - raise TypeError("--model option should be str") - # Expecting format:
:/models/[:] - pattern = re.compile(r"(\w+\.*\-*)*\w+:\d+\/models\/(\w+\.*\-*)+(\:\d+)*") - if not pattern.fullmatch(target_model): - raise ValueError("invalid --model option format") - service_url, _, model = target_model.split("/") - model_spec = model.split(":") - if len(model_spec) == 1: - # model version not specified - use latest - return service_url, model_spec[0], 0 - elif len(model_spec) == 2: - return service_url, model_spec[0], int(model_spec[1]) - else: - raise ValueError("invalid --model option format") - - - def _is_model_available(self): - try: - model_status = self.client.get_model_status(self.model_name, self.model_version) - except ovmsclient.ModelNotFoundError: - return False - target_version = max(model_status.keys()) - version_status = model_status[target_version] - if version_status["state"] == "AVAILABLE" and version_status["error_code"] == 0: - return True - return False - - def _prepare_inputs(self, dict_data): - inputs = {} - for input_name, input_data in dict_data.items(): - if input_name not in self.metadata["inputs"].keys(): - raise ValueError("Input data does not match model inputs") - input_info = self.metadata["inputs"][input_name] - model_precision = self.tf2np_precision[input_info["dtype"]] - if isinstance(input_data, np.ndarray) and input_data.dtype != model_precision: - input_data = input_data.astype(model_precision) - elif isinstance(input_data, list): - input_data = np.array(input_data, dtype=model_precision) - inputs[input_name] = input_data - return inputs - - def __init__(self, target_model): - if ovmsclient_absent: - raise ImportError("The ovmsclient package is not installed") - - log.info('Connecting to remote model: {}'.format(target_model)) - service_url, model_name, model_version = OVMSAdapter.parse_model_arg(target_model) - self.model_name = model_name - self.model_version = model_version - self.client = ovmsclient.make_grpc_client(url=service_url) - # Ensure the model is available - if not self._is_model_available(): - model_version_str = "latest" if self.model_version == 0 else str(self.model_version) - raise RuntimeError("Requested model: {}, version: {}, has not been found or is not " - "in available state".format(self.model_name, model_version_str)) - - self.metadata = self.client.get_model_metadata(model_name=self.model_name, - model_version=self.model_version) - - def load_model(self): - pass - - def get_input_layers(self): - inputs = {} - for name, meta in self.metadata["inputs"].items(): - input_layout = Layout.from_shape(meta["shape"]) - inputs[name] = Metadata(set(name), meta["shape"], input_layout, self.tf2ov_precision.get(meta["dtype"], meta["dtype"])) - return inputs - - def get_output_layers(self): - outputs = {} - for name, meta in self.metadata["outputs"].items(): - outputs[name] = Metadata(names=set(name), shape=meta["shape"], precision=self.tf2ov_precision.get(meta["dtype"], meta["dtype"])) - return outputs - - def reshape_model(self, new_shape): - pass - - def infer_sync(self, dict_data): - inputs = self._prepare_inputs(dict_data) - raw_result = self.client.predict(inputs, model_name=self.model_name, model_version=self.model_version) - # For models with single output ovmsclient returns ndarray with results, - # so the dict must be created to correctly implement interface. - if isinstance(raw_result, np.ndarray): - output_name = list(self.metadata["outputs"].keys())[0] - return {output_name: raw_result} - return raw_result - - def infer_async(self, dict_data, callback_data): - inputs = self._prepare_inputs(dict_data) - raw_result = self.client.predict(inputs, model_name=self.model_name, model_version=self.model_version) - # For models with single output ovmsclient returns ndarray with results, - # so the dict must be created to correctly implement interface. - if isinstance(raw_result, np.ndarray): - output_name = list(self.metadata["outputs"].keys())[0] - raw_result = {output_name: raw_result} - self.callback_fn(raw_result, (lambda x: x, callback_data)) - - def set_callback(self, callback_fn): - self.callback_fn = callback_fn - - def is_ready(self): - return True - - def await_all(self): - pass - - def await_any(self): - pass diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/utils.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/utils.py deleted file mode 100644 index 84ddd0ab..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/adapters/utils.py +++ /dev/null @@ -1,78 +0,0 @@ -""" - Copyright (C) 2022-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from typing import Optional -from openvino.runtime import layout_helpers - - -class Layout: - def __init__(self, layout = '') -> None: - self.layout = layout - - @staticmethod - def from_shape(shape): - ''' - Create Layout from given shape - ''' - if len(shape) == 2: - return 'NC' - if len(shape) == 3: - return 'CHW' if shape[0] in range(1, 5) else 'HWC' - if len(shape) == 4: - return 'NCHW' if shape[1] in range(1, 5) else 'NHWC' - - raise RuntimeError("Get layout from shape method doesn't support {}D shape".format(len(shape))) - - @staticmethod - def from_openvino(input): - ''' - Create Layout from openvino input - ''' - return layout_helpers.get_layout(input).to_string().strip('[]').replace(',', '') - - @staticmethod - def from_user_layouts(input_names: set, user_layouts: dict): - ''' - Create Layout for input based on user info - ''' - for input_name in input_names: - if input_name in user_layouts: - return user_layouts[input_name] - return user_layouts.get('', '') - - @staticmethod - def parse_layouts(layout_string: str) -> Optional[dict]: - ''' - Parse layout parameter in format "input0:NCHW,input1:NC" or "NCHW" (applied to all inputs) - ''' - if not layout_string: - return None - search_string = layout_string if layout_string.rfind(':') != -1 else ":" + layout_string - colon_pos = search_string.rfind(':') - user_layouts = {} - while (colon_pos != -1): - start_pos = search_string.rfind(',') - input_name = search_string[start_pos + 1:colon_pos] - input_layout = search_string[colon_pos + 1:] - user_layouts[input_name] = input_layout - search_string = search_string[:start_pos + 1] - if search_string == "" or search_string[-1] != ',': - break - search_string = search_string[:-1] - colon_pos = search_string.rfind(':') - if search_string != "": - raise ValueError("Can't parse input layout string: " + layout_string) - return user_layouts diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/__init__.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/__init__.py deleted file mode 100644 index 81fccc71..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/__init__.py +++ /dev/null @@ -1,79 +0,0 @@ -""" - Copyright (C) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - - -from .bert import BertEmbedding, BertNamedEntityRecognition, BertQuestionAnswering -from .background_matting import ImageMattingWithBackground, VideoBackgroundMatting, PortraitBackgroundMatting -from .centernet import CenterNet -from .classification import Classification -from .deblurring import Deblurring -from .detection_model import DetectionModel -from .detr import DETR -from .ctpn import CTPN -from .faceboxes import FaceBoxes -from .hpe_associative_embedding import HpeAssociativeEmbedding -from .image_model import ImageModel -from .instance_segmentation import MaskRCNNModel, YolactModel -from .model import Model -from .monodepth import MonoDepthModel -from .nanodet import NanoDet, NanoDetPlus -from .open_pose import OpenPose -from .retinaface import RetinaFace, RetinaFacePyTorch -from .segmentation import SegmentationModel, SalientObjectDetectionModel -from .ssd import SSD -from .ultra_lightweight_face_detection import UltraLightweightFaceDetection -from .utils import DetectionWithLandmarks, InputTransform, OutputTransform, RESIZE_TYPES -from .yolo import YOLO, YoloV3ONNX, YoloV4, YOLOF, YOLOX - -__all__ = [ - 'BertEmbedding', - 'BertNamedEntityRecognition', - 'BertQuestionAnswering', - 'CenterNet', - 'Classification', - 'CTPN', - 'Deblurring', - 'DetectionModel', - 'DetectionWithLandmarks', - 'DETR', - 'FaceBoxes', - 'HpeAssociativeEmbedding', - 'ImageMattingWithBackground', - 'ImageModel', - 'InputTransform', - 'MaskRCNNModel', - 'Model', - 'MonoDepthModel', - 'NanoDet', - 'NanoDetPlus', - 'OpenPose', - 'OutputTransform', - 'PortraitBackgroundMatting', - 'RESIZE_TYPES', - 'RetinaFace', - 'RetinaFacePyTorch', - 'SalientObjectDetectionModel', - 'SegmentationModel', - 'SSD', - 'UltraLightweightFaceDetection', - 'VideoBackgroundMatting', - 'YolactModel', - 'YOLO', - 'YoloV3ONNX', - 'YoloV4', - 'YOLOF', - 'YOLOX', -] diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/background_matting.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/background_matting.py deleted file mode 100644 index 78b73a3b..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/background_matting.py +++ /dev/null @@ -1,185 +0,0 @@ -""" - Copyright (c) 2022-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import cv2 -import numpy as np - -from .image_model import ImageModel - - -class VideoBackgroundMatting(ImageModel): - __model__ = 'Robust-video-matting' - - def __init__(self, model_adapter, configuration, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number((5, ), (6, )) - self.output_blob_name = self._get_outputs() - self.rec_map = self.get_inputs_map() - self.rec = self.initialize_rec() - - @classmethod - def parameters(cls): - return super().parameters() - - def _get_inputs(self): - image_blob_names, image_info_blob_names = [], [] - for name, metadata in self.inputs.items(): - if len(metadata.shape) == 4 and metadata.shape[1] == 3: - image_blob_names.append(name) - if not image_blob_names: - self.raise_error('Compatible inputs are not found') - return image_blob_names, image_info_blob_names - - def _get_outputs(self): - image_blob_names = {} - for name, metadata in self.outputs.items(): - if len(metadata.shape) == 4 and metadata.shape[1] == 3: - image_blob_names['fgr'] = name - elif len(metadata.shape) == 4 and metadata.shape[1] == 1: - image_blob_names['pha'] = name - if len(image_blob_names) != 2: - self.raise_error('Compatible outputs are not found') - return image_blob_names - - def get_inputs_map(self): - rec_map = {} - for in_name, in_meta in self.inputs.items(): - if in_meta.shape[1] not in [1, 3]: - for out_name, out_meta in self.outputs.items(): - if in_meta.shape == out_meta.shape: - rec_map[in_name] = out_name - break - return rec_map - - def preprocess(self, inputs): - dict_inputs, meta = super().preprocess(inputs) - dict_inputs.update(self.rec) - return dict_inputs, meta - - def postprocess(self, outputs, meta): - fgr = outputs[self.output_blob_name['fgr']] - pha = outputs[self.output_blob_name['pha']] - self.rec = {in_name: outputs[out_name] for in_name, out_name in self.rec_map.items()} - fgr = fgr[0].transpose(1, 2, 0) - pha = pha[0].transpose(1, 2, 0) - h, w = meta['original_shape'][:2] - fgr = cv2.cvtColor(cv2.resize(fgr, (w, h)), cv2.COLOR_RGB2BGR) - pha = np.expand_dims(cv2.resize(pha, (w, h)), axis=-1) - return fgr, pha - - def initialize_rec(self): - rec = {} - for name, metadata in self.inputs.items(): - if name in self.rec_map.keys(): - rec[name] = np.zeros(metadata.shape, dtype=np.float32) - return rec - - -class ImageMattingWithBackground(ImageModel): - __model__ = 'Background-matting' - - def __init__(self, model_adapter, configuration, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number((2, ), (2, 3)) - self.output_blob_name = self._get_outputs() - self.n, self.c, self.h, self.w = self.set_input_shape() - - @classmethod - def parameters(cls): - return super().parameters() - - def _get_inputs(self): - image_blob_names, image_info_blob_names = [], [] - for name, metadata in self.inputs.items(): - if len(metadata.shape) == 4 and metadata.shape[1] == 3: - image_blob_names.append(name) - if len(image_blob_names) != 2: - self.raise_error('Compatible inputs are not found') - return image_blob_names, image_info_blob_names - - def set_input_shape(self): - shapes = [tuple(self.inputs[name].shape) for name in self.image_blob_names] - if len(set(shapes)) != 1: - self.raise_error('Image inputs have incompatible shapes: {}'.format(shapes)) - return shapes[0] - - def _get_outputs(self): - image_blob_names = {} - for name, metadata in self.outputs.items(): - if len(metadata.shape) == 4 and metadata.shape[1] == 3: - image_blob_names['fgr'] = name - elif len(metadata.shape) == 4 and metadata.shape[1] == 1: - image_blob_names['pha'] = name - if len(image_blob_names) != 2: - self.raise_error('Compatible outputs are not found') - return image_blob_names - - def preprocess(self, inputs): - dict_inputs = {} - target_shape = None - for name, image in inputs.items(): - self.image_blob_name = name - dict_input, meta = super().preprocess(image) - dict_inputs.update(dict_input) - if target_shape is None: - target_shape = meta['original_shape'] - elif meta['original_shape'] != target_shape: - self.raise_error('Image inputs must have equal shapes but got: {} vs {}'.format( - target_shape, meta['original_shape'])) - return dict_inputs, meta - - def postprocess(self, outputs, meta): - fgr = outputs[self.output_blob_name['fgr']] - pha = outputs[self.output_blob_name['pha']] - fgr = fgr[0].transpose(1, 2, 0) - pha = pha[0].transpose(1, 2, 0) - h, w = meta['original_shape'][:2] - fgr = cv2.cvtColor(cv2.resize(fgr, (w, h)), cv2.COLOR_RGB2BGR) - pha = np.expand_dims(cv2.resize(pha, (w, h)), axis=-1) - return fgr, pha - - -class PortraitBackgroundMatting(ImageModel): - __model__ = 'Portrait-matting' - - def __init__(self, model_adapter, configuration, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number(1, 1) - self.output_blob_name = self._get_outputs() - - @classmethod - def parameters(cls): - return super().parameters() - - def _get_outputs(self): - output_blob_name = next(iter(self.outputs)) - output_size = self.outputs[output_blob_name].shape - if len(output_size) != 4: - self.raise_error("Unexpected output blob shape {}. Only 4D output blob is supported".format(output_size)) - - return output_blob_name - - def preprocess(self, inputs): - dict_inputs, meta = super().preprocess(inputs) - meta.update({"original_image": inputs}) - return dict_inputs, meta - - def postprocess(self, outputs, meta): - output = outputs[self.output_blob_name][0].transpose(1, 2, 0) - original_frame = meta['original_image'] / 255.0 - h, w = meta['original_shape'][:2] - res_output = np.expand_dims(cv2.resize(output, (w, h)), -1) - return original_frame, res_output diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/bert.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/bert.py deleted file mode 100644 index a3c46e27..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/bert.py +++ /dev/null @@ -1,207 +0,0 @@ -""" - Copyright (c) 2021-2023 Intel Corporation - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import numpy as np - -from .model import Model -from .types import DictValue, NumericalValue, StringValue, BooleanValue - - -class Bert(Model): - __model__ = 'bert' - - def __init__(self, model_adapter, configuration, preload=False): - super().__init__(model_adapter, configuration, preload) - self.token_cls = [self.vocab['[CLS]']] - self.token_sep = [self.vocab['[SEP]']] - self.token_pad = [self.vocab['[PAD]']] - self.input_names = [i.strip() for i in self.input_names.split(',')] - if self.inputs.keys() != set(self.input_names): - self.raise_error('The Wrapper expects input names: {}, actual network input names: {}'.format( - self.input_names, list(self.inputs.keys()))) - self.max_length = self.inputs[self.input_names[0]].shape[1] - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'vocab': DictValue(), - 'input_names': StringValue(description='Comma-separated names of input layers'), - 'enable_padding': BooleanValue( - description='Should be input sequence padded to max sequence len or not', default_value=True - ) - }) - return parameters - - def preprocess(self, inputs): - input_ids, attention_mask, token_type_ids = self.form_request(inputs) - pad_len = self.pad_input(input_ids, attention_mask, token_type_ids) if self.enable_padding else 0 - meta = {'pad_len': pad_len, 'inputs': inputs} - - return self.create_input_dict(input_ids, attention_mask, token_type_ids), meta - - def form_request(self, inputs): - raise NotImplementedError - - def pad_input(self, input_ids, attention_mask, token_type_ids): - pad_len = self.max_length - len(input_ids) - if pad_len < 0: - self.raise_error("The input request is longer than max number of tokens ({})" - " processed by model".format(self.max_length)) - input_ids += self.token_pad * pad_len - token_type_ids += [0] * pad_len - attention_mask += [0] * pad_len - return pad_len - - def create_input_dict(self, input_ids, attention_mask, token_type_ids): - inputs = { - self.input_names[0]: np.array([input_ids], dtype=np.int32), - self.input_names[1]: np.array([attention_mask], dtype=np.int32), - self.input_names[2]: np.array([token_type_ids], dtype=np.int32), - } - if len(self.input_names) > 3: - inputs[self.input_names[3]] = np.arange(len(input_ids), dtype=np.int32)[None, :] - - return inputs - - def reshape(self, new_length): - new_shapes = {} - for input_name, input_info in self.inputs.items(): - new_shapes[input_name] = [1, new_length] - default_input_shape = input_info.shape - super().reshape(new_shapes) - self.logger.debug("\tReshape model from {} to {}".format(default_input_shape, new_shapes[input_name])) - self.max_length = new_length if not isinstance(new_length, tuple) else new_length[1] - - -class BertNamedEntityRecognition(Bert): - __model__ = 'bert-named-entity-recognition' - - def __init__(self, model_adapter, configuration, preload=False): - super().__init__(model_adapter, configuration, preload) - - self.output_names = list(self.outputs) - self._check_io_number(-1, 1) - - def form_request(self, inputs): - c_tokens_id = inputs - input_ids = self.token_cls + c_tokens_id + self.token_sep - attention_mask = [1] * len(input_ids) - token_type_ids = [0] * len(input_ids) - return input_ids, attention_mask, token_type_ids - - def postprocess(self, outputs, meta): - output = outputs[self.output_names[0]] - output = np.exp(output[0]) - score = output / output.sum(axis=-1, keepdims=True) - labels_id = score.argmax(-1) - - filtered_labels_id = [ - (i, label_i) for i, label_i in enumerate(labels_id) - if label_i != 0 and 0 < i < self.max_length - meta['pad_len'] - 1 - ] - return score, filtered_labels_id - - -class BertEmbedding(Bert): - __model__ = 'bert-embedding' - - def __init__(self, model_adapter, configuration, preload=False): - super().__init__(model_adapter, configuration, preload) - - self.output_names = list(self.outputs) - self._check_io_number(-1, 1) - - def form_request(self, inputs): - tokens_id, self.max_length = inputs - input_ids = self.token_cls + tokens_id + self.token_sep - attention_mask = [1] * len(input_ids) - token_type_ids = [0] * len(input_ids) - return input_ids, attention_mask, token_type_ids - - def postprocess(self, outputs, meta): - output = outputs[self.output_names[0]] - return output.squeeze(0) - - -class BertQuestionAnswering(Bert): - __model__ = 'bert-question-answering' - - def __init__(self, model_adapter, configuration, preload=False): - super().__init__(model_adapter, configuration, preload) - - self.output_names = [o.strip() for o in self.output_names.split(',')] - if self.outputs.keys() != set(self.output_names): - self.raise_error('The Wrapper expects output names: {}, actual network output names: {}'.format( - self.output_names, list(self.outputs.keys()))) - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'output_names': StringValue(description='Comma-separated names of output layers'), - 'max_answer_token_num': NumericalValue(value_type=int), - 'squad_ver': StringValue(), - }) - return parameters - - def form_request(self, inputs): - c_data, q_tokens_id = inputs - input_ids = self.token_cls + q_tokens_id + self.token_sep + c_data.c_tokens_id + self.token_sep - attention_mask = [1] * len(input_ids) - token_type_ids = [0] * (len(q_tokens_id) + 2) + [1] * (len(c_data.c_tokens_id) + 1) - return input_ids, attention_mask, token_type_ids - - def postprocess(self, outputs, meta): - - def get_score(blob_name): - out = np.exp(outputs[blob_name].reshape((self.max_length,))) - return out / out.sum(axis=-1) - - pad_len, (c_data, q_tokens_id) = meta['pad_len'], meta['inputs'] - # get start-end scores for context - score_s = get_score(self.output_names[0]) - score_e = get_score(self.output_names[1]) - - # index of first context token in tensor - c_s_idx = len(q_tokens_id) + 2 - # index of last+1 context token in tensor - c_e_idx = self.max_length - (pad_len + 1) - - # find product of all start-end combinations to find the best one - max_score, max_s, max_e = self.find_best_answer_window(score_s, score_e, c_s_idx, c_e_idx) - - # convert to context text start-end index - max_s = c_data.c_tokens_se[max_s][0] - max_e = c_data.c_tokens_se[max_e][1] - - return max_score, max_s, max_e - - def find_best_answer_window(self, start_score, end_score, context_start_idx, context_end_idx): - # get 'no-answer' score (not valid if model has been fine-tuned on squad1.x) - score_na = 0 if '1.' in self.squad_ver else start_score[0] * end_score[0] - - context_len = context_end_idx - context_start_idx - score_mat = np.matmul( - start_score[context_start_idx:context_end_idx].reshape((context_len, 1)), - end_score[context_start_idx:context_end_idx].reshape((1, context_len)), - ) - # reset candidates with end before start - score_mat = np.triu(score_mat) - # reset long candidates (>max_answer_token_num) - score_mat = np.tril(score_mat, self.max_answer_token_num - 1) - # find the best start-end pair - max_s, max_e = divmod(score_mat.flatten().argmax(), score_mat.shape[1]) - max_score = score_mat[max_s, max_e] * (1 - score_na) - - return max_score, max_s, max_e diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/centernet.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/centernet.py deleted file mode 100644 index e89254f3..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/centernet.py +++ /dev/null @@ -1,188 +0,0 @@ -""" - Copyright (c) 2019-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import cv2 -import numpy as np -from numpy.lib.stride_tricks import as_strided - -from .detection_model import DetectionModel -from .utils import Detection, clip_detections - - -class CenterNet(DetectionModel): - __model__ = 'centernet' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number(1, 3) - self._output_layer_names = sorted(self.outputs) - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters['resize_type'].update_default_value('standard') - return parameters - - def postprocess(self, outputs, meta): - heat = outputs[self._output_layer_names[0]][0] - reg = outputs[self._output_layer_names[1]][0] - wh = outputs[self._output_layer_names[2]][0] - heat = np.exp(heat)/(1 + np.exp(heat)) - height, width = heat.shape[1:3] - num_predictions = 100 - - heat = self._nms(heat) - scores, inds, clses, ys, xs = self._topk(heat, K=num_predictions) - reg = self._tranpose_and_gather_feat(reg, inds) - - reg = reg.reshape((num_predictions, 2)) - xs = xs.reshape((num_predictions, 1)) + reg[:, 0:1] - ys = ys.reshape((num_predictions, 1)) + reg[:, 1:2] - - wh = self._tranpose_and_gather_feat(wh, inds) - wh = wh.reshape((num_predictions, 2)) - clses = clses.reshape((num_predictions, 1)) - scores = scores.reshape((num_predictions, 1)) - bboxes = np.concatenate((xs - wh[..., 0:1] / 2, - ys - wh[..., 1:2] / 2, - xs + wh[..., 0:1] / 2, - ys + wh[..., 1:2] / 2), axis=1) - detections = np.concatenate((bboxes, scores, clses), axis=1) - mask = detections[..., 4] >= self.confidence_threshold - filtered_detections = detections[mask] - scale = max(meta['original_shape']) - center = np.array(meta['original_shape'][:2])/2.0 - dets = self._transform(filtered_detections, np.flip(center, 0), scale, height, width) - dets = [Detection(x[0], x[1], x[2], x[3], score=x[4], id=x[5]) for x in dets] - return clip_detections(dets, meta['original_shape']) - - @staticmethod - def get_affine_transform(center, scale, rot, output_size, inv=False): - - def get_dir(src_point, rot_rad): - sn, cs = np.sin(rot_rad), np.cos(rot_rad) - src_result = [0, 0] - src_result[0] = src_point[0] * cs - src_point[1] * sn - src_result[1] = src_point[0] * sn + src_point[1] * cs - return src_result - - def get_3rd_point(a, b): - direct = a - b - return b + np.array([-direct[1], direct[0]], dtype=np.float32) - - if not isinstance(scale, np.ndarray) and not isinstance(scale, list): - scale = np.array([scale, scale], dtype=np.float32) - - scale_tmp = scale - src_w = scale_tmp[0] - dst_w, dst_h = output_size - - rot_rad = np.pi * rot / 180 - src_dir = get_dir([0, src_w * -0.5], rot_rad) - dst_dir = np.array([0, dst_w * -0.5], dtype=np.float32) - - dst = np.zeros((3, 2), dtype=np.float32) - src = np.zeros((3, 2), dtype=np.float32) - src[0, :], src[1, :] = center, center + src_dir - dst[0, :] = [dst_w * 0.5, dst_h * 0.5] - dst[1, :] = np.array([dst_w * 0.5, dst_h * 0.5], np.float32) + dst_dir - src[2:, :] = get_3rd_point(src[0, :], src[1, :]) - dst[2:, :] = get_3rd_point(dst[0, :], dst[1, :]) - - if inv: - trans = cv2.getAffineTransform(np.float32(dst), np.float32(src)) - else: - trans = cv2.getAffineTransform(np.float32(src), np.float32(dst)) - - return trans - - @staticmethod - def _gather_feat(feat, ind): - dim = feat.shape[1] - ind = np.expand_dims(ind, axis=1) - ind = np.repeat(ind, dim, axis=1) - feat = feat[ind, np.arange(feat.shape[1])] - return feat - - @staticmethod - def _tranpose_and_gather_feat(feat, ind): - feat = np.transpose(feat, (1, 2, 0)) - feat = feat.reshape((-1, feat.shape[2])) - feat = CenterNet._gather_feat(feat, ind) - return feat - - @staticmethod - def _topk(scores, K=40): - cat, _, width = scores.shape - - scores = scores.reshape((cat, -1)) - topk_inds = np.argpartition(scores, -K, axis=1)[:, -K:] - topk_scores = scores[np.arange(scores.shape[0])[:, None], topk_inds] - - topk_ys = (topk_inds / width).astype(np.int32).astype(float) - topk_xs = (topk_inds % width).astype(np.int32).astype(float) - - topk_scores = topk_scores.reshape((-1)) - topk_ind = np.argpartition(topk_scores, -K)[-K:] - topk_score = topk_scores[topk_ind] - topk_clses = topk_ind / K - topk_inds = CenterNet._gather_feat( - topk_inds.reshape((-1, 1)), topk_ind).reshape((K)) - topk_ys = CenterNet._gather_feat(topk_ys.reshape((-1, 1)), topk_ind).reshape((K)) - topk_xs = CenterNet._gather_feat(topk_xs.reshape((-1, 1)), topk_ind).reshape((K)) - - return topk_score, topk_inds, topk_clses, topk_ys, topk_xs - - @staticmethod - def _nms(heat, kernel=3): - def max_pool2d(A, kernel_size, padding=1, stride=1): - A = np.pad(A, padding, mode='constant') - output_shape = ((A.shape[0] - kernel_size)//stride + 1, - (A.shape[1] - kernel_size)//stride + 1) - kernel_size = (kernel_size, kernel_size) - A_w = as_strided(A, shape=output_shape + kernel_size, - strides=(stride*A.strides[0], - stride*A.strides[1]) + A.strides) - A_w = A_w.reshape(-1, *kernel_size) - - return A_w.max(axis=(1, 2)).reshape(output_shape) - - pad = (kernel - 1) // 2 - - hmax = np.array([max_pool2d(channel, kernel, pad) for channel in heat]) - keep = (hmax == heat) - return heat * keep - - @staticmethod - def _transform_preds(coords, center, scale, output_size): - def affine_transform(pt, t): - new_pt = np.array([pt[0], pt[1], 1.], dtype=np.float32).T - new_pt = np.dot(t, new_pt) - return new_pt[:2] - - target_coords = np.zeros(coords.shape) - trans = CenterNet.get_affine_transform(center, scale, 0, output_size, inv=True) - for p in range(coords.shape[0]): - target_coords[p, 0:2] = affine_transform(coords[p, 0:2], trans) - return target_coords - - @staticmethod - def _transform(dets, center, scale, height, width): - dets[:, :2] = CenterNet._transform_preds( - dets[:, 0:2], center, scale, (width, height)) - dets[:, 2:4] = CenterNet._transform_preds( - dets[:, 2:4], center, scale, (width, height)) - return dets diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/classification.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/classification.py deleted file mode 100644 index 2776cb4d..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/classification.py +++ /dev/null @@ -1,88 +0,0 @@ -""" - Copyright (c) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import numpy as np - -from .types import NumericalValue, ListValue, StringValue -from .utils import softmax - -from .image_model import ImageModel - - -class Classification(ImageModel): - __model__ = 'Classification' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number(1, 1) - if self.path_to_labels: - self.labels = self._load_labels(self.path_to_labels) - self.out_layer_name = self._get_outputs() - - def _load_labels(self, labels_file): - with open(labels_file, 'r') as f: - labels = [] - for s in f: - begin_idx = s.find(' ') - if (begin_idx == -1): - self.raise_error('The labels file has incorrect format.') - end_idx = s.find(',') - labels.append(s[(begin_idx + 1):end_idx]) - return labels - - def _get_outputs(self): - layer_name = next(iter(self.outputs)) - layer_shape = self.outputs[layer_name].shape - - if len(layer_shape) != 2 and len(layer_shape) != 4: - self.raise_error('The Classification model wrapper supports topologies only with 2D or 4D output') - if len(layer_shape) == 4 and (layer_shape[2] != 1 or layer_shape[3] != 1): - self.raise_error('The Classification model wrapper supports topologies only with 4D ' - 'output which has last two dimensions of size 1') - if self.labels: - if (layer_shape[1] == len(self.labels) + 1): - self.labels.insert(0, 'other') - self.logger.warning("\tInserted 'other' label as first.") - if layer_shape[1] != len(self.labels): - self.raise_error("Model's number of classes and parsed " - 'labels must match ({} != {})'.format(layer_shape[1], len(self.labels))) - return layer_name - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters['resize_type'].update_default_value('crop') - parameters.update({ - 'topk': NumericalValue(value_type=int, default_value=1, min=1), - 'labels': ListValue(description="List of class labels"), - 'path_to_labels': StringValue( - description="Path to file with labels. Overrides the labels, if they sets via 'labels' parameter" - ), - }) - return parameters - - def postprocess(self, outputs, meta): - outputs = outputs[self.out_layer_name].squeeze() - indices = np.argpartition(outputs, -self.topk)[-self.topk:] - scores = outputs[indices] - - desc_order = scores.argsort()[::-1] - scores = scores[desc_order] - indices = indices[desc_order] - if not np.isclose(np.sum(outputs), 1.0, atol=0.01): - scores = softmax(scores) - labels = [self.labels[i] if self.labels else "" for i in indices] - return list(zip(indices, labels, scores)) diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/ctpn.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/ctpn.py deleted file mode 100644 index fefa4005..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/ctpn.py +++ /dev/null @@ -1,389 +0,0 @@ -""" - Copyright (c) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import cv2 -import numpy as np - -from .detection_model import DetectionModel -from .types import ListValue, NumericalValue -from .utils import Detection, nms, clip_detections - - -class CTPN(DetectionModel): - __model__ = 'CTPN' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, False) - self._check_io_number(1, 2) - self.bboxes_blob_name, self.scores_blob_name = self._get_outputs() - - self.min_size = 8 - self.min_ratio = 0.5 - self.min_width = 32 - self.pre_nms_top_n = 1000 - self.post_nms_top_n = 500 - self.text_proposal_connector = TextProposalConnector() - - self.anchors = np.array([ - [0, 2, 15, 13], - [0, 0, 15, 15], - [0, -4, 15, 19], - [0, -9, 15, 24], - [0, -16, 15, 31], - [0, -26, 15, 41], - [0, -41, 15, 56], - [0, -62, 15, 77], - [0, -91, 15, 106], - [0, -134, 15, 149] - ]) - - self.h1, self.w1 = self.ctpn_keep_aspect_ratio(1200, 600, self.input_size[1], self.input_size[0]) - self.h2, self.w2 = self.ctpn_keep_aspect_ratio(600, 600, self.w1, self.h1) - default_input_shape = self.inputs[self.image_blob_name].shape - new_shape = [self.n, self.c, self.h2, self.w2] if self.nchw_layout else [self.n, self.h2, self.w2, self.c] - input_shape = {self.image_blob_name: (new_shape)} - self.logger.debug('\tReshape model from {} to {}'.format(default_input_shape, input_shape[self.image_blob_name])) - self.reshape(input_shape) - if preload: - self.load() - - def _get_outputs(self): - (boxes_name, boxes_data_repr), (scores_name, scores_data_repr) = self.outputs.items() - - if len(boxes_data_repr.shape) != 4 or len(scores_data_repr.shape) != 4: - self.raise_error("Unexpected output blob shape. Only 4D output blobs are supported") - - if self.nchw_layout: - scores_channels = scores_data_repr.shape[1] - boxes_channels = boxes_data_repr.shape[1] - else: - scores_channels = scores_data_repr.shape[3] - boxes_channels = boxes_data_repr.shape[3] - - if scores_channels == boxes_channels * 2: - return scores_name, boxes_name - if boxes_channels == scores_channels * 2: - return boxes_name, scores_name - self.raise_error("One of outputs must be two times larger than another") - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'iou_threshold': NumericalValue(default_value=0.5, description="Threshold for NMS filtering"), - 'input_size': ListValue() - }) - parameters['confidence_threshold'].update_default_value(0.9) - parameters['labels'].update_default_value(['Text']) - return parameters - - def preprocess(self, inputs): - meta = {'original_shape': inputs.shape} - scales = (self.w1 / inputs.shape[1], self.h1 / inputs.shape[0]) - - if scales[0] < 1 and scales[1] < 1: - meta['scales'] = [scales] - inputs = cv2.resize(inputs, (self.w1, self.h1)) - if (self.h2 == 600 and self.w2 == 600 or - (self.h1 != self.h2 or self.w1 != self.w2)): - meta.setdefault('scales', []).append((self.w2 / inputs.shape[1], - self.h2 / inputs.shape[0])) - inputs = cv2.resize(inputs, (self.w2, self.h2)) - - inputs = self._change_layout(inputs) - dict_inputs = {self.image_blob_name: inputs} - return dict_inputs, meta - - def postprocess(self, outputs, meta): - first_scales = meta['scales'].pop() - boxes = outputs[self.bboxes_blob_name][0].transpose((1, 2, 0)) \ - if self.nchw_layout else outputs[self.bboxes_blob_name][0] - scores = outputs[self.scores_blob_name][0].transpose((1, 2, 0)) \ - if self.nchw_layout else outputs[self.scores_blob_name][0] - - textsegs, scores = self.get_proposals(scores, boxes, meta['original_shape']) - textsegs[:, 0::2] /= first_scales[0] - textsegs[:, 1::2] /= first_scales[1] - boxes = self.get_detections(textsegs, scores[:, np.newaxis], meta['original_shape']) - if meta['scales']: - second_scales = meta['scales'].pop() - boxes[:, 0:8:2] /= second_scales[0] - boxes[:, 1:8:2] /= second_scales[1] - detections = [Detection(box[0], box[1], box[2], box[5], box[8], 0) for box in boxes] - return clip_detections(detections, meta['original_shape']) - - @staticmethod - def ctpn_keep_aspect_ratio(dst_width, dst_height, image_width, image_height): - scale = min(dst_height, dst_width) - max_scale = max(dst_height, dst_width) - im_min_size = min(image_width, image_height) - im_max_size = max(image_width, image_height) - im_scale = float(scale) / float(im_min_size) - if np.round(im_scale * im_max_size) > max_scale: - im_scale = float(max_scale) / float(im_max_size) - new_h = np.round(image_height * im_scale) - new_w = np.round(image_width * im_scale) - - return int(new_h), int(new_w) - - def get_proposals(self, rpn_cls_prob_reshape, bbox_deltas, image_size, _feat_stride=16): - """ - Parameters - rpn_cls_prob_reshape: (H , W , Ax2), probabilities for predicted regions - bbox_deltas: (H , W , Ax4), predicted regions - image_size: a list of [image_height, image_width] - _feat_stride: the downsampling ratio of feature map to the original input image - Algorithm: - for each (H, W) location i - generate A anchor boxes centered on location i - apply predicted bbox deltas at location i to each of the A anchors - clip predicted boxes to image - remove predicted boxes with either height or width < threshold - sort all (proposal, score) pairs by score from highest to lowest - take top pre_nms_topN proposals before NMS - apply NMS with threshold to remaining proposals - take after_nms_top_n proposals after NMS - return the top proposals (-> RoIs top, scores top) - """ - - _anchors = self.anchors.copy() - _num_anchors = _anchors.shape[0] - height, width = rpn_cls_prob_reshape.shape[:2] - scores = np.reshape( - np.reshape(rpn_cls_prob_reshape, [height, width, _num_anchors, 2])[:, :, :, 1], - [height, width, _num_anchors] - ) - shift_x = np.arange(0, width) * _feat_stride - shift_y = np.arange(0, height) * _feat_stride - shift_x, shift_y = np.meshgrid(shift_x, shift_y) - shifts = np.vstack((shift_x.ravel(), shift_y.ravel(), shift_x.ravel(), shift_y.ravel())).transpose() - _num_shifts = shifts.shape[0] - anchors = _anchors.reshape((1, _num_anchors, 4)) + shifts.reshape((1, _num_shifts, 4)).transpose((1, 0, 2)) - anchors = anchors.reshape((_num_shifts * _num_anchors, 4)) - # Transpose and reshape predicted bbox transformations to get them - # into the same order as the anchors: - # bbox deltas will be (4 * A, H, W) format - # transpose to (H, W, 4 * A) - # reshape to (H * W * A, 4) where rows are ordered by (h, w, a) - # in slowest to fastest order - bbox_deltas = bbox_deltas.reshape((-1, 4)) # (HxWxA, 4) - - # Same story for the scores: - scores = scores.reshape((-1, 1)) - - # Convert anchors into proposals via bbox transformations - proposals = self.bbox_transform_inv(anchors, bbox_deltas) - - # clip predicted boxes to image - proposals[:, :4].clip(min=0, max=(image_size[1] - 1, image_size[0] - 1, image_size[1] - 1, image_size[0] - 1), - out=proposals[:, :4]) - # sort all (proposal, score) pairs by score from highest to lowest - order = scores.ravel().argsort()[::-1] - if self.pre_nms_top_n > 0: - order = order[:self.pre_nms_top_n] - proposals, scores = proposals[order, :], scores[order] - - # apply nms - keep = nms(proposals[:, 0], proposals[:, 1], proposals[:, 2], proposals[:, 3], scores.reshape(-1), - self.iou_threshold, include_boundaries=True) - if self.post_nms_top_n > 0: - keep = keep[:self.post_nms_top_n] - proposals, scores = proposals[keep, :], scores[keep] - return proposals, scores - - def get_detections(self, text_proposals, scores, size): - keep_inds = np.where(scores > 0.7)[0] - text_proposals, scores = text_proposals[keep_inds], scores[keep_inds] - - sorted_indices = np.argsort(scores.ravel())[::-1] - text_proposals, scores = text_proposals[sorted_indices], scores[sorted_indices] - - text_recs = self.text_proposal_connector.get_text_lines(text_proposals, scores, size) - - heights = (abs(text_recs[:, 5] - text_recs[:, 1]) + abs(text_recs[:, 7] - text_recs[:, 3])) / 2.0 + 1 - widths = (abs(text_recs[:, 2] - text_recs[:, 0]) + abs(text_recs[:, 6] - text_recs[:, 4])) / 2.0 + 1 - scores = text_recs[:, 8] - keep_inds = np.where((widths / heights > self.min_ratio) & (scores > self.confidence_threshold) & - (widths > self.min_width))[0] - - return text_recs[keep_inds] - - @staticmethod - def bbox_transform_inv(boxes, deltas): - - boxes = boxes.astype(deltas.dtype, copy=False) - - widths = boxes[:, 2] - boxes[:, 0] + 1.0 - heights = boxes[:, 3] - boxes[:, 1] + 1.0 - ctr_x = boxes[:, 0] + 0.5 * widths - ctr_y = boxes[:, 1] + 0.5 * heights - - dy = deltas[:, 1::4] - dh = deltas[:, 3::4] - - pred_ctr_x = ctr_x[:, np.newaxis] - pred_ctr_y = dy * heights[:, np.newaxis] + ctr_y[:, np.newaxis] - pred_w = widths[:, np.newaxis] - pred_h = np.exp(dh) * heights[:, np.newaxis] - - pred_boxes = np.zeros(deltas.shape, dtype=deltas.dtype) - pred_boxes[:, 0::4] = pred_ctr_x - 0.5 * pred_w - pred_boxes[:, 1::4] = pred_ctr_y - 0.5 * pred_h - pred_boxes[:, 2::4] = pred_ctr_x + 0.5 * pred_w - pred_boxes[:, 3::4] = pred_ctr_y + 0.5 * pred_h - - return pred_boxes - - -class Graph: - def __init__(self, graph): - self.graph = graph - - def sub_graphs_connected(self): - sub_graphs = [] - for index in range(self.graph.shape[0]): - if not self.graph[:, index].any() and self.graph[index, :].any(): - v = index - sub_graphs.append([v]) - while self.graph[v, :].any(): - v = np.where(self.graph[v, :])[0][0] - sub_graphs[-1].append(v) - - return sub_graphs - - -class TextProposalGraphBuilder: - """ - Build Text proposals into a graph. - """ - def get_successions(self, index): - box = self.text_proposals[index] - results = [] - for left in range(int(box[0]) + 1, min(int(box[0]) + 50 + 1, self.im_size[1])): - adj_box_indices = self.boxes_table[left] - for adj_box_index in adj_box_indices: - if self.meet_v_iou(adj_box_index, index): - results.append(adj_box_index) - if results: - return results - return results - - def get_precursors(self, index): - box = self.text_proposals[index] - results = [] - for left in range(int(box[0]) - 1, max(int(box[0] - 50), 0) - 1, -1): - adj_box_indices = self.boxes_table[left] - for adj_box_index in adj_box_indices: - if self.meet_v_iou(adj_box_index, index): - results.append(adj_box_index) - if results: - return results - return results - - def is_succession_node(self, index, succession_index): - precursors = self.get_precursors(succession_index) - return self.scores[index] >= np.max(self.scores[precursors]) - - def meet_v_iou(self, index1, index2): - def overlaps_v(h1, h2, text_proposal1, text_proposal2): - y0 = max(text_proposal2[1], text_proposal1[1]) - y1 = min(text_proposal2[3], text_proposal1[3]) - return max(0, y1 - y0 + 1) / min(h1, h2) - - def size_similarity(h1, h2): - return min(h1, h2) / max(h1, h2) - - height_1 = self.heights[index1] - height_2 = self.heights[index2] - proposal_1 = self.text_proposals[index1] - proposal_2 = self.text_proposals[index2] - size_similarity_estimation = size_similarity(height_1, height_2) - vertical_overlap = overlaps_v(height_1, height_2, proposal_1, proposal_2) - - return vertical_overlap >= 0.7 and size_similarity_estimation >= 0.7 - - def build_graph(self, text_proposals, scores, im_size): - self.text_proposals = text_proposals - self.scores = scores - self.im_size = im_size - self.heights = text_proposals[:, 3] - text_proposals[:, 1] + 1 - - boxes_table = [[] for _ in range(self.im_size[1])] - for index, box in enumerate(text_proposals): - boxes_table[int(box[0])].append(index) - self.boxes_table = boxes_table - - graph = np.zeros((text_proposals.shape[0], text_proposals.shape[0]), bool) - - for index, box in enumerate(text_proposals): - successions = self.get_successions(index) - if not successions: - continue - succession_index = successions[np.argmax(scores[successions])] - if self.is_succession_node(index, succession_index): - graph[index, succession_index] = True - - return Graph(graph) - - -class TextProposalConnector: - def __init__(self): - self.graph_builder = TextProposalGraphBuilder() - - def group_text_proposals(self, text_proposals, scores, image_size): - graph = self.graph_builder.build_graph(text_proposals, scores, image_size) - return graph.sub_graphs_connected() - - def get_text_lines(self, text_proposals, scores, image_size): - def fit_y(x, y, x1, x2): - if np.sum(x == x[0]) == np.size(x): - return y[0], y[0] - p = np.poly1d(np.polyfit(x, y, 1)) - return p(x1), p(x2) - - tp_groups = self.group_text_proposals(text_proposals, scores, image_size) - - text_lines = np.zeros((len(tp_groups), 5), np.float32) - - for index, tp_indices in enumerate(tp_groups): - text_line_boxes = text_proposals[list(tp_indices)] - - x0 = np.min(text_line_boxes[:, 0]) - x1 = np.max(text_line_boxes[:, 2]) - - offset = (text_line_boxes[0, 2] - text_line_boxes[0, 0]) * 0.5 - - lt_y, rt_y = fit_y(text_line_boxes[:, 0], text_line_boxes[:, 1], x0 + offset, x1 - offset) - lb_y, rb_y = fit_y(text_line_boxes[:, 0], text_line_boxes[:, 3], x0 + offset, x1 - offset) - score = scores[list(tp_indices)].sum() / float(len(tp_indices)) - - text_lines[index, 0] = x0 - text_lines[index, 1] = min(lt_y, rt_y) - text_lines[index, 2] = x1 - text_lines[index, 3] = max(lb_y, rb_y) - text_lines[index, 4] = score - - text_lines[:, :4].clip(min=0, max=(image_size[1] - 1, image_size[0] - 1, image_size[1] - 1, image_size[0] - 1), - out=text_lines[:, :4]) - - text_recs = np.zeros((len(text_lines), 9), float) - for index, line in enumerate(text_lines): - xmin, ymin, xmax, ymax = line[0], line[1], line[2], line[3] - text_recs[index, 0], text_recs[index, 1], text_recs[index, 2], text_recs[index, 3] = xmin, ymin, xmax, ymin - text_recs[index, 4], text_recs[index, 5], text_recs[index, 6], text_recs[index, 7] = xmax, ymax, xmin, ymax - text_recs[index, 8] = line[4] - - return text_recs diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/deblurring.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/deblurring.py deleted file mode 100644 index 76f208a3..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/deblurring.py +++ /dev/null @@ -1,80 +0,0 @@ -""" - Copyright (c) 2021-2023 Intel Corporation - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import cv2 -import math -import numpy as np - -from .image_model import ImageModel - - -class Deblurring(ImageModel): - __model__ = 'Deblurring' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number(1, 1) - self.block_size = 32 - self.output_blob_name = self._get_outputs() - - @classmethod - def parameters(cls): - parameters = super().parameters() - return parameters - - def reshape(self, base_shape): - h, w, _ = base_shape - new_height = math.ceil(h / self.block_size) * self.block_size - new_width = math.ceil(w / self.block_size) * self.block_size - self.h, self.w = new_height, new_width - self.logger.debug("\tReshape model from {} to {}".format( - [self.n, self.c, h, w], [self.n, self.c, self.h, self.w])) - super().reshape({self.image_blob_name: [self.n, self.c, self.h, self.w]}) - - def _get_outputs(self): - output_blob_name = next(iter(self.outputs)) - output_size = self.outputs[output_blob_name].shape - if len(output_size) != 4: - self.raise_error("Unexpected output blob shape {}. Only 4D output blob is supported".format(output_size)) - - return output_blob_name - - def preprocess(self, inputs): - image = inputs - - if self.h - self.block_size < image.shape[0] <= self.h and self.w - self.block_size < image.shape[1] <= self.w: - pad_params = {'mode': 'constant', - 'constant_values': 0, - 'pad_width': ((0, self.h - image.shape[0]), (0, self.w - image.shape[1]), (0, 0)) - } - resized_image = np.pad(image, **pad_params) - else: - self.logger.warning("\tChosen model size doesn't match image size. The image is resized") - resized_image = cv2.resize(image, (self.w, self.h)) - - resized_image = resized_image.transpose((2, 0, 1)) - resized_image = np.expand_dims(resized_image, 0) - dict_inputs = {self.image_blob_name: resized_image} - meta = {'original_shape': image.shape[1::-1]} - return dict_inputs, meta - - def postprocess(self, outputs, meta): - dsize = meta['original_shape'] - prediction = outputs[self.output_blob_name].squeeze() - prediction = prediction.transpose((1, 2, 0)) - if self.h - self.block_size < dsize[1] <= self.h and self.w - self.block_size < dsize[0] <= self.w: - prediction = prediction[:dsize[1], :dsize[0], :] - else: - prediction = cv2.resize(prediction, dsize) - prediction *= 255 - return prediction.astype(np.uint8) diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/detection_model.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/detection_model.py deleted file mode 100644 index 48574703..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/detection_model.py +++ /dev/null @@ -1,127 +0,0 @@ -""" - Copyright (c) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" -from .types import ListValue, NumericalValue, StringValue -from .image_model import ImageModel -from .utils import load_labels, clip_detections - - -class DetectionModel(ImageModel): - '''An abstract wrapper for object detection model - - The DetectionModel must have a single image input. - It inherits `preprocess` from `ImageModel` wrapper. Also, it defines `_resize_detections` method, - which should be used in `postprocess`, to clip bounding boxes and resize ones to original image shape. - - The `postprocess` method must be implemented in a specific inherited wrapper. - ''' - - def __init__(self, model_adapter, configuration=None, preload=False): - '''Detection Model constructor - - It extends the `ImageModel` construtor. - - Args: - model_adapter (ModelAdapter): allows working with the specified executor - configuration (dict, optional): it contains values for parameters accepted by specific - wrapper (`confidence_threshold`, `labels` etc.) which are set as data attributes - preload (bool, optional): a flag whether the model is loaded to device while - initialization. If `preload=False`, the model must be loaded via `load` method before inference - - Raises: - WrapperError: if the model has more than 1 image inputs - ''' - - super().__init__(model_adapter, configuration, preload) - - if not self.image_blob_name: - self.raise_error("The Wrapper supports only one image input, but {} found".format( - len(self.image_blob_names))) - - if self.path_to_labels: - self.labels = load_labels(self.path_to_labels) - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'confidence_threshold': NumericalValue(default_value=0.5, description="Threshold value for detection box confidence"), - 'labels': ListValue(description="List of class labels"), - 'path_to_labels': StringValue( - description="Path to file with labels. Overrides the labels, if they sets via 'labels' parameter" - ) - }) - - return parameters - - def _resize_detections(self, detections, meta): - '''Resizes detection bounding boxes according to initial image shape. - - It implements image resizing depending on the set `resize_type`(see `ImageModel` for details). - Next, it applies bounding boxes clipping. - - Args: - detections (List[Detection]): list of detections with coordinates in normalized form - meta (dict): the input metadata obtained from `preprocess` method - - Returns: - - list of detections with resized and clipped coordinates fit to initial image - - Raises: - WrapperError: If the model uses custom resize or `resize_type` is not set - ''' - resized_shape = meta['resized_shape'] - original_shape = meta['original_shape'] - - if self.resize_type == 'fit_to_window_letterbox': - detections = resize_detections_letterbox(detections, original_shape[1::-1], resized_shape[1::-1]) - elif self.resize_type == 'fit_to_window': - detections = resize_detections_with_aspect_ratio(detections, original_shape[1::-1], resized_shape[1::-1], (self.w, self.h)) - elif self.resize_type == 'standard': - detections = resize_detections(detections, original_shape[1::-1]) - else: - self.raise_error('Unknown resize type {}'.format(self.resize_type)) - return clip_detections(detections, original_shape) - - -def resize_detections(detections, original_image_size): - for detection in detections: - detection.xmin *= original_image_size[0] - detection.xmax *= original_image_size[0] - detection.ymin *= original_image_size[1] - detection.ymax *= original_image_size[1] - return detections - -def resize_detections_with_aspect_ratio(detections, original_image_size, resized_image_size, model_input_size): - scale_x = model_input_size[0] / resized_image_size[0] * original_image_size[0] - scale_y = model_input_size[1] / resized_image_size[1] * original_image_size[1] - for detection in detections: - detection.xmin *= scale_x - detection.xmax *= scale_x - detection.ymin *= scale_y - detection.ymax *= scale_y - return detections - -def resize_detections_letterbox(detections, original_image_size, resized_image_size): - scales = [x / y for x, y in zip(resized_image_size, original_image_size)] - scale = min(scales) - scales = (scale / scales[0], scale / scales[1]) - offset = [0.5 * (1 - x) for x in scales] - for detection in detections: - detection.xmin = ((detection.xmin - offset[0]) / scales[0]) * original_image_size[0] - detection.xmax = ((detection.xmax - offset[0]) / scales[0]) * original_image_size[0] - detection.ymin = ((detection.ymin - offset[1]) / scales[1]) * original_image_size[1] - detection.ymax = ((detection.ymax - offset[1]) / scales[1]) * original_image_size[1] - return detections diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/detr.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/detr.py deleted file mode 100644 index 7105c1f7..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/detr.py +++ /dev/null @@ -1,78 +0,0 @@ -""" - Copyright (c) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" -import numpy as np - -from .detection_model import DetectionModel -from .utils import Detection, softmax - - -class DETR(DetectionModel): - __model__ = 'DETR' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number(1, 2) - self.bboxes_blob_name, self.scores_blob_name = self._get_outputs() - - def _get_outputs(self): - (bboxes_blob_name, bboxes_layer), (scores_blob_name, scores_layer) = self.outputs.items() - - if bboxes_layer.shape[1] != scores_layer.shape[1]: - self.raise_error("Expected the same second dimension for boxes and scores, but got {} and {}".format( - bboxes_layer.shape, scores_layer.shape)) - - if bboxes_layer.shape[2] == 4: - return bboxes_blob_name, scores_blob_name - elif scores_layer.shape[2] == 4: - return scores_blob_name, bboxes_blob_name - else: - self.raise_error("Expected shape [:,:,4] for bboxes output, but got {} and {}".format( - bboxes_layer.shape, scores_layer.shape)) - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters['resize_type'].update_default_value('standard') - parameters['confidence_threshold'].update_default_value(0.5) - return parameters - - def postprocess(self, outputs, meta): - detections = self._parse_outputs(outputs) - detections = self._resize_detections(detections, meta) - return detections - - def _parse_outputs(self, outputs): - boxes = outputs[self.bboxes_blob_name][0] - scores = outputs[self.scores_blob_name][0] - - x_mins, y_mins, x_maxs, y_maxs = self.box_cxcywh_to_xyxy(boxes) - - scores = np.array([softmax(logit) for logit in scores]) - labels = np.argmax(scores[:, :-1], axis=-1) - det_scores = np.max(scores[:, :-1], axis=-1) - - keep = det_scores > self.confidence_threshold - - detections = [Detection(*det) for det in zip(x_mins[keep], y_mins[keep], x_maxs[keep], y_maxs[keep], - det_scores[keep], labels[keep])] - return detections - - @staticmethod - def box_cxcywh_to_xyxy(box): - x_c, y_c, w, h = box.T - b = [(x_c - 0.5 * w), (y_c - 0.5 * h), - (x_c + 0.5 * w), (y_c + 0.5 * h)] - return b diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/faceboxes.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/faceboxes.py deleted file mode 100644 index 80d0750c..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/faceboxes.py +++ /dev/null @@ -1,142 +0,0 @@ -""" - Copyright (c) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" -import itertools -import math -import numpy as np - -from .types import NumericalValue -from .detection_model import DetectionModel -from .utils import Detection, nms - - -class FaceBoxes(DetectionModel): - __model__ = 'FaceBoxes' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self.bboxes_blob_name, self.scores_blob_name = self._get_outputs() - self.min_sizes = [[32, 64, 128], [256], [512]] - self.steps = [32, 64, 128] - self.variance = [0.1, 0.2] - self.keep_top_k = 750 - - def _get_outputs(self): - (bboxes_blob_name, bboxes_layer), (scores_blob_name, scores_layer) = self.outputs.items() - - if bboxes_layer.shape[1] != scores_layer.shape[1]: - self.raise_error("Expected the same second dimension for boxes and scores, but got {} and {}".format( - bboxes_layer.shape, scores_layer.shape)) - - if bboxes_layer.shape[2] == 4: - return bboxes_blob_name, scores_blob_name - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'iou_threshold': NumericalValue(default_value=0.3, description="Threshold for NMS filtering") - }) - parameters['labels'].update_default_value(['Face']) - return parameters - - def postprocess(self, outputs, meta): - detections = self._parse_outputs(outputs, meta) - detections = self._resize_detections(detections, meta) - return detections - - def _parse_outputs(self, outputs, meta): - boxes = outputs[self.bboxes_blob_name][0] - scores = outputs[self.scores_blob_name][0] - - detections = [] - - feature_maps = [[math.ceil(self.h / step), math.ceil(self.w / step)] for step in - self.steps] - prior_data = self.prior_boxes(feature_maps, [self.h, self.w]) - - boxes[:, :2] = self.variance[0] * boxes[:, :2] - boxes[:, 2:] = self.variance[1] * boxes[:, 2:] - boxes[:, :2] = boxes[:, :2] * prior_data[:, 2:] + prior_data[:, :2] - boxes[:, 2:] = np.exp(boxes[:, 2:]) * prior_data[:, 2:] - - score = np.transpose(scores)[1] - - mask = score > self.confidence_threshold - filtered_boxes, filtered_score = boxes[mask, :], score[mask] - if filtered_score.size != 0: - x_mins = (filtered_boxes[:, 0] - 0.5 * filtered_boxes[:, 2]) - y_mins = (filtered_boxes[:, 1] - 0.5 * filtered_boxes[:, 3]) - x_maxs = (filtered_boxes[:, 0] + 0.5 * filtered_boxes[:, 2]) - y_maxs = (filtered_boxes[:, 1] + 0.5 * filtered_boxes[:, 3]) - - keep = nms(x_mins, y_mins, x_maxs, y_maxs, filtered_score, self.iou_threshold, - keep_top_k=self.keep_top_k) - - filtered_score = filtered_score[keep] - x_mins = x_mins[keep] - y_mins = y_mins[keep] - x_maxs = x_maxs[keep] - y_maxs = y_maxs[keep] - - if filtered_score.size > self.keep_top_k: - filtered_score = filtered_score[:self.keep_top_k] - x_mins = x_mins[:self.keep_top_k] - y_mins = y_mins[:self.keep_top_k] - x_maxs = x_maxs[:self.keep_top_k] - y_maxs = y_maxs[:self.keep_top_k] - - detections = [Detection(*det, 0) for det in zip(x_mins, y_mins, x_maxs, y_maxs, filtered_score)] - return detections - - @staticmethod - def calculate_anchors(list_x, list_y, min_size, image_size, step): - anchors = [] - s_kx = min_size / image_size[1] - s_ky = min_size / image_size[0] - dense_cx = [x * step / image_size[1] for x in list_x] - dense_cy = [y * step / image_size[0] for y in list_y] - for cy, cx in itertools.product(dense_cy, dense_cx): - anchors.append([cx, cy, s_kx, s_ky]) - return anchors - - def calculate_anchors_zero_level(self, f_x, f_y, min_sizes, image_size, step): - anchors = [] - for min_size in min_sizes: - if min_size == 32: - list_x = [f_x + 0, f_x + 0.25, f_x + 0.5, f_x + 0.75] - list_y = [f_y + 0, f_y + 0.25, f_y + 0.5, f_y + 0.75] - elif min_size == 64: - list_x = [f_x + 0, f_x + 0.5] - list_y = [f_y + 0, f_y + 0.5] - else: - list_x = [f_x + 0.5] - list_y = [f_y + 0.5] - anchors.extend(self.calculate_anchors(list_x, list_y, min_size, image_size, step)) - return anchors - - def prior_boxes(self, feature_maps, image_size): - anchors = [] - for k, f in enumerate(feature_maps): - for i, j in itertools.product(range(f[0]), range(f[1])): - if k == 0: - anchors.extend(self.calculate_anchors_zero_level(j, i, self.min_sizes[k], - image_size, self.steps[k])) - else: - anchors.extend(self.calculate_anchors([j + 0.5], [i + 0.5], self.min_sizes[k][0], - image_size, self.steps[k])) - anchors = np.clip(anchors, 0, 1) - - return anchors diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/hpe_associative_embedding.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/hpe_associative_embedding.py deleted file mode 100644 index 0615ce31..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/hpe_associative_embedding.py +++ /dev/null @@ -1,353 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import numpy as np -from scipy.optimize import linear_sum_assignment - - - -from .image_model import ImageModel -from .types import NumericalValue, StringValue -from .utils import resize_image - - -class HpeAssociativeEmbedding(ImageModel): - __model__ = 'HPE-assosiative-embedding' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload=False) - self.heatmaps_blob_name = find_layer_by_name('heatmaps', self.outputs) - try: - self.nms_heatmaps_blob_name = find_layer_by_name('nms_heatmaps', self.outputs) - except ValueError: - self.nms_heatmaps_blob_name = self.heatmaps_blob_name - self.embeddings_blob_name = find_layer_by_name('embeddings', self.outputs) - self.output_scale = self.w / self.outputs[self.heatmaps_blob_name].shape[-1] - - if self.target_size is None: - self.target_size = min(self.h, self.w) - self.index_of_max_dimension = 0 - if self.aspect_ratio >= 1.0: # img width >= height - input_height, input_width = self.target_size, round(self.target_size * self.aspect_ratio) - self.index_of_max_dimension = 1 - else: - input_height, input_width = round(self.target_size / self.aspect_ratio), self.target_size - self.h = (input_height + self.size_divisor - 1) // self.size_divisor * self.size_divisor - self.w = (input_width + self.size_divisor - 1) // self.size_divisor * self.size_divisor - default_input_shape = self.inputs[self.image_blob_name].shape - input_shape = {self.image_blob_name: [self.n, self.c, self.h, self.w]} - self.logger.debug('\tReshape model from {} to {}'.format(default_input_shape, input_shape[self.image_blob_name])) - super().reshape(input_shape) - - if preload: - self.load() - - self.decoder = AssociativeEmbeddingDecoder( - num_joints=self.outputs[self.heatmaps_blob_name].shape[1], - adjust=True, - refine=True, - delta=self.delta, - max_num_people=30, - detection_threshold=0.1, - tag_threshold=1, - pose_threshold=self.confidence_threshold, - use_detection_val=True, - ignore_too_much=False, - dist_reweight=True) - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'target_size': NumericalValue(value_type=int, min=1), - 'aspect_ratio': NumericalValue(), - 'confidence_threshold': NumericalValue(), - 'delta': NumericalValue(default_value=0.0), - 'size_divisor': NumericalValue(default_value=32, value_type=int), - 'padding_mode': StringValue(default_value='right_bottom', choices=('center', 'right_bottom')), - }) - return parameters - - def preprocess(self, inputs): - img = resize_image(inputs, (self.w, self.h), keep_aspect_ratio=True) - h, w = img.shape[:2] - if not (self.h - self.size_divisor < h <= self.h and self.w - self.size_divisor < w <= self.w): - self.logger.warning("\tChosen model aspect ratio doesn't match image aspect ratio") - resize_img_scale = np.array((inputs.shape[1] / w, inputs.shape[0] / h), np.float32) - - if self.padding_mode == 'center': - pad = ((self.h - h + 1) // 2, (self.h - h) // 2, (self.w - w + 1) // 2, (self.w - w) // 2) - else: - pad = (0, self.h - h, 0, self.w - w) - img = np.pad(img, (pad[:2], pad[2:], (0, 0)), mode='constant', constant_values=0) - img = img.transpose((2, 0, 1)) # Change data layout from HWC to CHW - img = img[None] - meta = { - 'original_size': inputs.shape[:2], - 'resize_img_scale': resize_img_scale - } - return {self.image_blob_name: img}, meta - - def postprocess(self, outputs, meta): - heatmaps = outputs[self.heatmaps_blob_name] - nms_heatmaps = outputs[self.nms_heatmaps_blob_name] - aembds = outputs[self.embeddings_blob_name] - poses, scores = self.decoder(heatmaps, aembds, nms_heatmaps=nms_heatmaps) - # Rescale poses to the original image. - if self.padding_mode == 'center': - scale = meta['resize_img_scale'][self.index_of_max_dimension] - poses[:, :, :2] *= scale * self.output_scale - shift = (meta['original_size'][self.index_of_max_dimension] - max(self.h, self.w) * scale) / 2 - poses[:, :, 1 - self.index_of_max_dimension] += shift - else: - poses[:, :, :2] *= meta['resize_img_scale'] * self.output_scale - return poses, scores - - -def find_layer_by_name(name, layers): - suitable_layers = [] - for layer, metadata in layers.items(): - count_names = len([layer_name for layer_name in metadata.names if layer_name.startswith(name)]) - if count_names > 0: - suitable_layers.append(layer) - if not suitable_layers: - raise ValueError('Suitable layer for "{}" output is not found'.format(name)) - - if len(suitable_layers) > 1: - raise ValueError('More than 1 layer matched to "{}" output'.format(name)) - - return suitable_layers[0] - - -class Pose: - def __init__(self, num_joints, tag_size=1): - self.num_joints = num_joints - self.tag_size = tag_size - # 2 is for x, y and 1 is for joint confidence - self.pose = np.zeros((num_joints, 2 + 1 + tag_size), dtype=np.float32) - self.pose_tag = np.zeros(tag_size, dtype=np.float32) - self.valid_points_num = 0 - self.c = np.zeros(2, dtype=np.float32) - - def add(self, idx, joint, tag): - self.pose[idx] = joint - self.c = self.c * self.valid_points_num + joint[:2] - self.pose_tag = (self.pose_tag * self.valid_points_num) + tag - self.valid_points_num += 1 - self.c /= self.valid_points_num - self.pose_tag /= self.valid_points_num - - @property - def tag(self): - if self.valid_points_num > 0: - return self.pose_tag - return None - - @property - def center(self): - if self.valid_points_num > 0: - return self.c - return None - - -class AssociativeEmbeddingDecoder: - def __init__(self, num_joints, max_num_people, detection_threshold, use_detection_val, - ignore_too_much, tag_threshold, pose_threshold, - adjust=True, refine=True, delta=0.0, joints_order=None, - dist_reweight=True): - self.num_joints = num_joints - self.max_num_people = max_num_people - self.detection_threshold = detection_threshold - self.tag_threshold = tag_threshold - self.pose_threshold = pose_threshold - self.use_detection_val = use_detection_val - self.ignore_too_much = ignore_too_much - - if self.num_joints == 17 and joints_order is None: - self.joint_order = (0, 1, 2, 3, 4, 5, 6, 11, 12, 7, 8, 9, 10, 13, 14, 15, 16) - else: - self.joint_order = list(np.arange(self.num_joints)) - - self.do_adjust = adjust - self.do_refine = refine - self.dist_reweight = dist_reweight - self.delta = delta - - @staticmethod - def _max_match(scores): - r, c = linear_sum_assignment(scores) - return np.stack((r, c), axis=1) - - def _match_by_tag(self, inp): - tag_k, loc_k, val_k = inp - embd_size = tag_k.shape[2] - all_joints = np.concatenate((loc_k, val_k[..., None], tag_k), -1) - - poses = [] - for idx in self.joint_order: - tags = tag_k[idx] - joints = all_joints[idx] - mask = joints[:, 2] > self.detection_threshold - tags = tags[mask] - joints = joints[mask] - - if len(poses) == 0: - for tag, joint in zip(tags, joints): - pose = Pose(self.num_joints, embd_size) - pose.add(idx, joint, tag) - poses.append(pose) - continue - - if joints.shape[0] == 0 or (self.ignore_too_much and len(poses) == self.max_num_people): - continue - - poses_tags = np.stack([p.tag for p in poses], axis=0) - diff = tags[:, None] - poses_tags[None, :] - diff_normed = np.linalg.norm(diff, ord=2, axis=2) - diff_saved = np.copy(diff_normed) - - if self.dist_reweight: - # Reweight cost matrix to prefer nearby points among all that are close enough in a tag space. - centers = np.stack([p.center for p in poses], axis=0)[None] - dists = np.linalg.norm(joints[:, :2][:, None, :] - centers, ord=2, axis=2) - close_tags_masks = diff_normed < self.tag_threshold - min_dists = np.min(dists, axis=0, keepdims=True) - dists /= min_dists + 1e-10 - diff_normed[close_tags_masks] *= dists[close_tags_masks] - - if self.use_detection_val: - diff_normed = np.round(diff_normed) * 100 - joints[:, 2:3] - num_added = diff.shape[0] - num_grouped = diff.shape[1] - if num_added > num_grouped: - diff_normed = np.pad(diff_normed, ((0, 0), (0, num_added - num_grouped)), - mode='constant', constant_values=1e10) - - pairs = self._max_match(diff_normed) - for row, col in pairs: - if row < num_added and col < num_grouped and diff_saved[row][col] < self.tag_threshold: - poses[col].add(idx, joints[row], tags[row]) - else: - pose = Pose(self.num_joints, embd_size) - pose.add(idx, joints[row], tags[row]) - poses.append(pose) - - ans = np.asarray([p.pose for p in poses], dtype=np.float32).reshape(-1, self.num_joints, 2 + 1 + embd_size) - tags = np.asarray([p.tag for p in poses], dtype=np.float32).reshape(-1, embd_size) - return ans, tags - - def top_k(self, heatmaps, tags): - N, K, H, W = heatmaps.shape - heatmaps = heatmaps.reshape(N, K, -1) - ind = heatmaps.argpartition(-self.max_num_people, axis=2)[:, :, -self.max_num_people:] - val_k = np.take_along_axis(heatmaps, ind, axis=2) - subind = np.argsort(-val_k, axis=2) - ind = np.take_along_axis(ind, subind, axis=2) - val_k = np.take_along_axis(val_k, subind, axis=2) - - tags = tags.reshape(N, K, W * H, -1) - tag_k = [np.take_along_axis(tags[..., i], ind, axis=2) for i in range(tags.shape[3])] - tag_k = np.stack(tag_k, axis=3) - - x = ind % W - y = ind // W - loc_k = np.stack((x, y), axis=3) - return tag_k, loc_k, val_k - - @staticmethod - def adjust(ans, heatmaps): - H, W = heatmaps.shape[-2:] - for batch_idx, people in enumerate(ans): - for person in people: - for k, joint in enumerate(person): - heatmap = heatmaps[batch_idx, k] - px = int(joint[0]) - py = int(joint[1]) - if 1 < px < W - 1 and 1 < py < H - 1: - diff = np.array([ - heatmap[py, px + 1] - heatmap[py, px - 1], - heatmap[py + 1, px] - heatmap[py - 1, px] - ]) - joint[:2] += np.sign(diff) * .25 - return ans - - @staticmethod - def refine(heatmap, tag, keypoints, pose_tag=None): - K, H, W = heatmap.shape - if len(tag.shape) == 3: - tag = tag[..., None] - - if pose_tag is not None: - prev_tag = pose_tag - else: - tags = [] - for i in range(K): - if keypoints[i, 2] > 0: - x, y = keypoints[i][:2].astype(int) - tags.append(tag[i, y, x]) - prev_tag = np.mean(tags, axis=0) - - for i, (_heatmap, _tag) in enumerate(zip(heatmap, tag)): - if keypoints[i, 2] > 0: - continue - # Get position with the closest tag value to the pose tag. - diff = np.abs(_tag[..., 0] - prev_tag) + 0.5 - diff = diff.astype(np.int32).astype(_heatmap.dtype) - diff -= _heatmap - idx = diff.argmin() - y, x = np.divmod(idx, _heatmap.shape[-1]) - # Corresponding keypoint detection score. - val = _heatmap[y, x] - if val > 0: - keypoints[i, :3] = x, y, val - if 1 < x < W - 1 and 1 < y < H - 1: - diff = np.array([ - _heatmap[y, x + 1] - _heatmap[y, x - 1], - _heatmap[y + 1, x] - _heatmap[y - 1, x] - ]) - keypoints[i, :2] += np.sign(diff) * .25 - - return keypoints - - def __call__(self, heatmaps, tags, nms_heatmaps): - tag_k, loc_k, val_k = self.top_k(nms_heatmaps, tags) - ans = tuple(map(self._match_by_tag, zip(tag_k, loc_k, val_k))) # Call _match_by_tag() for each element in batch - ans, ans_tags = map(list, zip(*ans)) - - np.abs(heatmaps, out=heatmaps) - - if self.do_adjust: - ans = self.adjust(ans, heatmaps) - - if self.delta != 0.0: - for people in ans: - for person in people: - for joint in person: - joint[:2] += self.delta - - ans = ans[0] - scores = np.asarray([i[:, 2].mean() for i in ans]) - mask = scores > self.pose_threshold - ans = ans[mask] - scores = scores[mask] - - if self.do_refine: - heatmap_numpy = heatmaps[0] - tag_numpy = tags[0] - for i, pose in enumerate(ans): - ans[i] = self.refine(heatmap_numpy, tag_numpy, pose, ans_tags[0][i]) - - return ans, scores diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/image_model.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/image_model.py deleted file mode 100644 index 28d0343c..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/image_model.py +++ /dev/null @@ -1,163 +0,0 @@ -""" - Copyright (c) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from .model import Model -from .types import BooleanValue, ListValue, StringValue -from .utils import RESIZE_TYPES, pad_image, InputTransform - - -class ImageModel(Model): - '''An abstract wrapper for an image-based model - - The ImageModel has 1 or more inputs with images - 4D tensors with NHWC or NCHW layout. - It may support additional inputs - 2D tensors. - - The ImageModel implements basic preprocessing for an image provided as model input. - See `preprocess` description. - - The `postprocess` method must be implemented in a specific inherited wrapper. - - Attributes: - image_blob_names (List[str]): names of all image-like inputs (4D tensors) - image_info_blob_names (List[str]): names of all secondary inputs (2D tensors) - image_blob_name (str): name of the first image input - nchw_layout (bool): a flag whether the model input layer has NCHW layout - resize_type (str): the type for image resizing (see `RESIZE_TYPE` for info) - resize (function): resizing function corresponding to the `resize_type` - input_transform (InputTransform): instance of the `InputTransform` for image normalization - ''' - - def __init__(self, model_adapter, configuration=None, preload=False): - '''Image model constructor - - It extends the `Model` constructor. - - Args: - model_adapter (ModelAdapter): allows working with the specified executor - configuration (dict, optional): it contains values for parameters accepted by specific - wrapper (`confidence_threshold`, `labels` etc.) which are set as data attributes - preload (bool, optional): a flag whether the model is loaded to device while - initialization. If `preload=False`, the model must be loaded via `load` method before inference - - Raises: - WrapperError: if the wrapper failed to define appropriate inputs for images - ''' - super().__init__(model_adapter, configuration, preload) - self.image_blob_names, self.image_info_blob_names = self._get_inputs() - self.image_blob_name = self.image_blob_names[0] - - self.nchw_layout = self.inputs[self.image_blob_name].layout == 'NCHW' - if self.nchw_layout: - self.n, self.c, self.h, self.w = self.inputs[self.image_blob_name].shape - else: - self.n, self.h, self.w, self.c = self.inputs[self.image_blob_name].shape - self.resize = RESIZE_TYPES[self.resize_type] - self.input_transform = InputTransform(self.reverse_input_channels, self.mean_values, self.scale_values) - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'mean_values': ListValue( - default_value=None, - description='Normalization values, which will be subtracted from image channels for image-input layer during preprocessing' - ), - 'scale_values': ListValue( - default_value=None, - description='Normalization values, which will divide the image channels for image-input layer' - ), - 'reverse_input_channels': BooleanValue(default_value=False, description='Reverse the channel order'), - 'resize_type': StringValue( - default_value='standard', choices=tuple(RESIZE_TYPES.keys()), - description="Type of input image resizing" - ), - }) - return parameters - - def _get_inputs(self): - '''Defines the model inputs for images and additional info. - - Raises: - WrapperError: if the wrapper failed to define appropriate inputs for images - - Returns: - - list of inputs names for images - - list of inputs names for additional info - ''' - image_blob_names, image_info_blob_names = [], [] - for name, metadata in self.inputs.items(): - if len(metadata.shape) == 4: - image_blob_names.append(name) - elif len(metadata.shape) == 2: - image_info_blob_names.append(name) - else: - self.raise_error('Failed to identify the input for ImageModel: only 2D and 4D input layer supported') - if not image_blob_names: - self.raise_error('Failed to identify the input for the image: no 4D input layer found') - return image_blob_names, image_info_blob_names - - def preprocess(self, inputs): - '''Data preprocess method - - It performs basic preprocessing of a single image: - - Resizes the image to fit the model input size via the defined resize type - - Normalizes the image: subtracts means, divides by scales, switch channels BGR-RGB - - Changes the image layout according to the model input layout - - Also, it keeps the size of original image and resized one as `original_shape` and `resized_shape` - in the metadata dictionary. - - Note: - It supports only models with single image input. If the model has more image inputs or has - additional supported inputs, the `preprocess` should be overloaded in a specific wrapper. - - Args: - inputs (ndarray): a single image as 3D array in HWC layout - - Returns: - - the preprocessed image in the following format: - { - 'input_layer_name': preprocessed_image - } - - the input metadata, which might be used in `postprocess` method - ''' - image = inputs - meta = {'original_shape': image.shape} - resized_image = self.resize(image, (self.w, self.h)) - meta.update({'resized_shape': resized_image.shape}) - if self.resize_type == 'fit_to_window': - resized_image = pad_image(resized_image, (self.w, self.h)) - meta.update({'padded_shape': resized_image.shape}) - resized_image = self.input_transform(resized_image) - resized_image = self._change_layout(resized_image) - dict_inputs = {self.image_blob_name: resized_image} - return dict_inputs, meta - - def _change_layout(self, image): - '''Changes the input image layout to fit the layout of the model input layer. - - Args: - inputs (ndarray): a single image as 3D array in HWC layout - - Returns: - - the image with layout aligned with the model layout - ''' - if self.nchw_layout: - image = image.transpose((2, 0, 1)) # HWC->CHW - image = image.reshape((1, self.c, self.h, self.w)) - else: - image = image.reshape((1, self.h, self.w, self.c)) - return image diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/instance_segmentation.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/instance_segmentation.py deleted file mode 100644 index 86a800e7..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/instance_segmentation.py +++ /dev/null @@ -1,299 +0,0 @@ -""" - Copyright (c) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import cv2 -import numpy as np - -from .image_model import ImageModel -from .types import NumericalValue, ListValue, StringValue -from .utils import nms, load_labels - - -class MaskRCNNModel(ImageModel): - __model__ = 'MaskRCNN' - - def __init__(self, model_adapter, configuration, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number((1, 2), (3, 4, 5, 8)) - if self.path_to_labels: - self.labels = load_labels(self.path_to_labels) - self.is_segmentoly = len(self.inputs) == 2 - self.output_blob_name = self._get_outputs() - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'confidence_threshold': NumericalValue( - default_value=0.5, - description='Probability threshold for detections filtering' - ), - 'labels': ListValue(description="List of class labels"), - 'path_to_labels': StringValue( - description="Path to file with labels. Overrides the labels" - ), - }) - return parameters - - def _get_outputs(self): - if self.is_segmentoly: - return self._get_segmentoly_outputs() - outputs = {} - for layer_name in self.outputs: - if layer_name.startswith('TopK'): - continue - layer_shape = self.outputs[layer_name].shape - - if len(layer_shape) == 1: - outputs['labels'] = layer_name - elif len(layer_shape) == 2: - outputs['boxes'] = layer_name - elif len(layer_shape) == 3: - outputs['masks'] = layer_name - else: - self.raise_error("Unexpected output layer shape {} with name {}".format(layer_shape, layer_name)) - - return outputs - - def _get_segmentoly_outputs(self): - outputs = {} - for layer_name in self.outputs: - layer_shape = self.outputs[layer_name].shape - if layer_name == 'boxes' and len(layer_shape) == 2: - outputs['boxes'] = layer_name - elif layer_name == 'classes' and len(layer_shape) == 1: - outputs['labels'] = layer_name - elif layer_name == 'scores' and len(layer_shape) == 1: - outputs['scores'] = layer_name - elif layer_name == 'raw_masks' and len(layer_shape) == 4: - outputs['masks'] = layer_name - else: - self.raise_error("Unexpected output layer shape {} with name {}".format(layer_shape, layer_name)) - return outputs - - def preprocess(self, inputs): - dict_inputs, meta = super().preprocess(inputs) - input_image_size = meta['resized_shape'][:2] - if self.is_segmentoly: - assert len(self.image_info_blob_names) == 1 - input_image_info = np.asarray([[input_image_size[0], input_image_size[1], 1]], dtype=np.float32) - dict_inputs[self.image_info_blob_names[0]] = input_image_info - return dict_inputs, meta - - def postprocess(self, outputs, meta): - boxes = outputs[self.output_blob_name['boxes']] if self.is_segmentoly else \ - outputs[self.output_blob_name['boxes']][:, :4] - scores = outputs[self.output_blob_name['scores']] if self.is_segmentoly else \ - outputs[self.output_blob_name['boxes']][:, 4] - scale_x = meta['resized_shape'][1] / meta['original_shape'][1] - scale_y = meta['resized_shape'][0] / meta['original_shape'][0] - boxes[:, 0::2] /= scale_x - boxes[:, 1::2] /= scale_y - if self.is_segmentoly: - classes = outputs[self.output_blob_name['labels']].astype(np.uint32) - else: - classes = outputs[self.output_blob_name['labels']].astype(np.uint32) + 1 - masks = [] - for box, cls, raw_mask in zip(boxes, classes, outputs[self.output_blob_name['masks']]): - raw_cls_mask = raw_mask[cls, ...] if self.is_segmentoly else raw_mask - masks.append(self._segm_postprocess(box, raw_cls_mask, *meta['original_shape'][:-1])) - # Filter out detections with low confidence. - detections_filter = scores > self.confidence_threshold - scores = scores[detections_filter] - classes = classes[detections_filter] - boxes = boxes[detections_filter] - masks = [segm for segm, is_valid in zip(masks, detections_filter) if is_valid] - return scores, classes, boxes, masks - - @staticmethod - def _expand_box(box, scale): - w_half = (box[2] - box[0]) * .5 - h_half = (box[3] - box[1]) * .5 - x_c = (box[2] + box[0]) * .5 - y_c = (box[3] + box[1]) * .5 - w_half *= scale - h_half *= scale - box_exp = np.zeros(box.shape) - box_exp[0] = x_c - w_half - box_exp[2] = x_c + w_half - box_exp[1] = y_c - h_half - box_exp[3] = y_c + h_half - return box_exp - - def _segm_postprocess(self, box, raw_cls_mask, im_h, im_w): - # Add zero border to prevent upsampling artifacts on segment borders. - raw_cls_mask = np.pad(raw_cls_mask, ((1, 1), (1, 1)), 'constant', constant_values=0) - extended_box = self._expand_box(box, raw_cls_mask.shape[0] / (raw_cls_mask.shape[0] - 2.0)).astype(int) - w, h = np.maximum(extended_box[2:] - extended_box[:2] + 1, 1) - x0, y0 = np.clip(extended_box[:2], a_min=0, a_max=[im_w, im_h]) - x1, y1 = np.clip(extended_box[2:] + 1, a_min=0, a_max=[im_w, im_h]) - - raw_cls_mask = cv2.resize(raw_cls_mask.astype(np.float32), (w, h)) > 0.5 - mask = raw_cls_mask.astype(np.uint8) - # Put an object mask in an image mask. - im_mask = np.zeros((im_h, im_w), dtype=np.uint8) - im_mask[y0:y1, x0:x1] = mask[(y0 - extended_box[1]):(y1 - extended_box[1]), - (x0 - extended_box[0]):(x1 - extended_box[0])] - return im_mask - - -class YolactModel(ImageModel): - __model__ = 'Yolact' - - def __init__(self, model_adapter, configuration, preload=False): - super().__init__(model_adapter, configuration, preload) - if self.path_to_labels: - self.labels = load_labels(self.path_to_labels) - self._check_io_number(1, 4) - self.output_blob_name = self._get_outputs() - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'confidence_threshold': NumericalValue( - default_value=0.5, - description='Probability threshold for detections filtering' - ), - 'labels': ListValue(description="List of class labels"), - 'path_to_labels': StringValue( - description="Path to file with labels. Overrides the labels" - ), - }) - return parameters - - def _get_outputs(self): - outputs = {} - for layer_name in self.outputs: - layer_shape = self.outputs[layer_name].shape - if layer_name == 'boxes' and len(layer_shape) == 3: - outputs['boxes'] = layer_name - elif layer_name == 'conf' and len(layer_shape) == 3: - outputs['conf'] = layer_name - elif layer_name == 'proto' and len(layer_shape) == 4: - outputs['proto'] = layer_name - elif layer_name == 'mask' and len(layer_shape) == 3: - outputs['masks'] = layer_name - else: - self.raise_error("Unexpected output layer shape {} with name {}".format(layer_shape, layer_name)) - return outputs - - def postprocess(self, outputs, meta): - frame_height, frame_width = meta['original_shape'][:-1] - input_height, input_width = meta['resized_shape'][:-1] - scale_x = meta['resized_shape'][1] / meta['original_shape'][1] - scale_y = meta['resized_shape'][0] / meta['original_shape'][0] - - boxes = outputs['boxes'][0] - conf = np.transpose(outputs['conf'][0]) - masks = outputs['mask'][0] - proto = outputs['proto'][0] - num_classes = conf.shape[0] - idx_lst, cls_lst, scr_lst = [], [], [] - shift_x = (input_width - (frame_width * scale_x)) / frame_width - shift_y = (input_height - (frame_height * scale_y)) / frame_height - - for cls in range(1, num_classes): - cls_scores = conf[cls, :] - idx = np.arange(cls_scores.shape[0]) - conf_mask = cls_scores > self.confidence_threshold - - cls_scores = cls_scores[conf_mask] - idx = idx[conf_mask] - - if cls_scores.shape[0] == 0: - continue - x1, x2 = self._sanitize_coordinates(boxes[idx, 0], boxes[idx, 2], frame_width) - y1, y2 = self._sanitize_coordinates(boxes[idx, 1], boxes[idx, 3], frame_height) - keep = nms(x1, y1, x2, y2, cls_scores, 0.5) - - idx_lst.append(idx[keep]) - cls_lst.append(np.full(len(keep), cls)) - scr_lst.append(cls_scores[keep]) - - if not idx_lst: - return np.array([]), np.array([]), np.array([]), np.array([]) - idx = np.concatenate(idx_lst, axis=0) - classes = np.concatenate(cls_lst, axis=0) - scores = np.concatenate(scr_lst, axis=0) - - idx2 = np.argsort(scores, axis=0)[::-1] - scores = scores[idx2] - - idx = idx[idx2] - classes = classes[idx2] - - boxes = boxes[idx] - masks = masks[idx] - if np.size(boxes) > 0: - boxes, scores, classes, masks = self._segm_postprocess( - boxes, masks, scores, classes, proto, frame_width, frame_height, shift_x=shift_x, shift_y=shift_y - ) - return scores, classes, boxes, masks - - def _segm_postprocess(self, boxes, masks, score, classes, proto_data, w, h, shift_x=0, shift_y=0): - if self.confidence_threshold > 0: - keep = score > self.confidence_threshold - score = score[keep] - boxes = boxes[keep] - masks = masks[keep] - classes = classes[keep] - if np.size(score) == 0: - return [] * 4 - - masks = proto_data @ masks.T - masks = 1 / (1 + np.exp(-masks)) - masks = self._crop_mask(masks, boxes) - - masks = np.transpose(masks, (2, 0, 1)) - boxes[:, 0], boxes[:, 2] = self._sanitize_coordinates(boxes[:, 0], boxes[:, 2], w, shift_x) - boxes[:, 1], boxes[:, 3] = self._sanitize_coordinates(boxes[:, 1], boxes[:, 3], h, shift_y) - ready_masks = [] - - for mask in masks: - mask = cv2.resize(mask, (w, h), cv2.INTER_LINEAR) - mask = mask > 0.5 - ready_masks.append(mask.astype(np.uint8)) - - return boxes, score, classes, ready_masks - - def _crop_mask(self, masks, boxes, padding: int = 1): - h, w, n = np.shape(masks) - x1, x2 = self._sanitize_coordinates(boxes[:, 0], boxes[:, 2], w, padding=padding) - y1, y2 = self._sanitize_coordinates(boxes[:, 1], boxes[:, 3], h, padding=padding) - - rows = np.reshape( - np.repeat(np.reshape(np.repeat(np.arange(w, dtype=x1.dtype), h), (w, h)), n, axis=-1), (h, w, n) - ) - cols = np.reshape( - np.repeat(np.reshape(np.repeat(np.arange(h, dtype=x1.dtype), h), (w, h)), n, axis=-1), (h, w, n) - ) - rows = np.transpose(rows, (1, 0, 2)) - - masks_left = rows >= x1 - masks_right = rows < x2 - masks_up = cols >= y1 - masks_down = cols < y2 - crop_mask = masks_left * masks_right * masks_up * masks_down - return masks * crop_mask - - @staticmethod - def _sanitize_coordinates(_x1, _x2, img_size, shift=0, padding=0): - _x1 = (_x1 + shift / 2) * img_size - _x2 = (_x2 + shift / 2) * img_size - x1 = np.clip(_x1 - padding, 0, img_size) - x2 = np.clip(_x2 + padding, 0, img_size) - return x1, x2 diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/model.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/model.py deleted file mode 100644 index fdf6c3ae..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/model.py +++ /dev/null @@ -1,303 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import logging as log - - -class WrapperError(RuntimeError): - '''Special class for errors occurred in Model API wrappers''' - def __init__(self, wrapper_name, message): - super().__init__(f"{wrapper_name}: {message}") - - -class Model: - '''An abstract model wrapper - - The abstract model wrapper is free from any executor dependencies. - It sets the `ModelAdapter` instance with the provided model - and defines model inputs/outputs. - - Next, it loads the provided configuration variables and sets it as wrapper attributes. - The keys of the configuration dictionary should be presented in the `parameters` method. - - Also, it decorates the following adapter interface: - - Loading the model to the device - - The model reshaping - - Synchronous model inference - - Asynchronous model inference - - The `preprocess` and `postprocess` methods must be implemented in a specific inherited wrapper. - - Attributes: - logger (Logger): instance of the Logger - model_adapter (ModelAdapter): allows working with the specified executor - inputs (dict): keeps the model inputs names and `Metadata` structure for each one - outputs (dict): keeps the model outputs names and `Metadata` structure for each one - model_loaded (bool): a flag whether the model is loaded to device - ''' - - __model__ = None # Abstract wrapper has no name - - def __init__(self, model_adapter, configuration=None, preload=False): - '''Model constructor - - Args: - model_adapter (ModelAdapter): allows working with the specified executor - configuration (dict, optional): it contains values for parameters accepted by specific - wrapper (`confidence_threshold`, `labels` etc.) which are set as data attributes - preload (bool, optional): a flag whether the model is loaded to device while - initialization. If `preload=False`, the model must be loaded via `load` method before inference - - Raises: - WrapperError: if the wrapper configuration is incorrect - ''' - self.logger = log.getLogger() - self.model_adapter = model_adapter - self.inputs = self.model_adapter.get_input_layers() - self.outputs = self.model_adapter.get_output_layers() - for name, parameter in self.parameters().items(): - self.__setattr__(name, parameter.default_value) - self._load_config(configuration) - self.model_loaded = False - if preload: - self.load() - - @classmethod - def get_model(cls, name): - subclasses = [subclass for subclass in cls.get_subclasses() if subclass.__model__] - if cls.__model__: - subclasses.append(cls) - for subclass in subclasses: - if name.lower() == subclass.__model__.lower(): - return subclass - cls.raise_error('There is no model with name "{}" in list: {}'.format( - name, ', '.join([subclass.__model__ for subclass in subclasses]))) - - @classmethod - def create_model(cls, name, model_adapter, configuration=None, preload=False): - Model = cls.get_model(name) - return Model(model_adapter, configuration, preload) - - @classmethod - def get_subclasses(cls): - all_subclasses = [] - for subclass in cls.__subclasses__(): - all_subclasses.append(subclass) - all_subclasses.extend(subclass.get_subclasses()) - return all_subclasses - - @classmethod - def available_wrappers(cls): - available_classes = [cls] if cls.__model__ else [] - available_classes.extend(cls.get_subclasses()) - return [subclass.__model__ for subclass in available_classes if subclass.__model__] - - @classmethod - def parameters(cls): - '''Defines the description and type of configurable data parameters for the wrapper. - - See `types.py` to find available types of the data parameter. For each parameter - the type, default value and description must be provided. - - The example of possible data parameter: - 'confidence_threshold': NumericalValue( - default_value=0.5, description="Threshold value for detection box confidence" - ) - - The method must be implemented in each specific inherited wrapper. - - Returns: - - the dictionary with defined wrapper data parameters - ''' - parameters = {} - return parameters - - def _load_config(self, config): - '''Reads the configuration and creates data attributes - by setting the wrapper parameters with values from configuration. - - Args: - config (dict): the dictionary with keys to be set as data attributes - and its values. The example of the config is the following: - { - 'confidence_threshold': 0.5, - 'resize_type': 'fit_to_window', - } - - Note: - The config keys should be provided in `parameters` method for each wrapper, - then the default value of the parameter will be updated. If some key presented - in the config is not introduced in `parameters`, it will be omitted. - - Raises: - WrapperError: if the configuration is incorrect - ''' - if config is None: return - parameters = self.parameters() - for name, value in config.items(): - if name in parameters: - errors = parameters[name].validate(value) - if errors: - self.logger.error(f'Error with "{name}" parameter:') - for error in errors: - self.logger.error(f"\t{error}") - self.raise_error('Incorrect user configuration') - value = parameters[name].get_value(value) - self.__setattr__(name, value) - else: - self.logger.warning(f'The parameter "{name}" not found in {self.__model__} wrapper, will be omitted') - - def raise_error(self, message): - '''Raises the WrapperError. - - Args: - message (str): error message to be shown in the following format: - "WrapperName: message" - ''' - raise WrapperError(self.__model__, message) - - def preprocess(self, inputs): - '''Interface for preprocess method. - - Args: - inputs: raw input data, the data type is defined by wrapper - - Returns: - - the preprocessed data which is submitted to the model for inference - and has the following format: - { - 'input_layer_name_1': data_1, - 'input_layer_name_2': data_2, - ... - } - - the input metadata, which might be used in `postprocess` method - ''' - raise NotImplementedError - - def postprocess(self, outputs, meta): - '''Interface for postprocess method. - - Args: - outputs (dict): model raw output in the following format: - { - 'output_layer_name_1': raw_result_1, - 'output_layer_name_2': raw_result_2, - ... - } - meta (dict): the input metadata obtained from `preprocess` method - - Returns: - - postprocessed data in the format defined by wrapper - ''' - raise NotImplementedError - - def _check_io_number(self, number_of_inputs, number_of_outputs): - '''Checks whether the number of model inputs/outputs is supported. - - Args: - number_of_inputs (int, Tuple(int)): number of inputs supported by wrapper. - Use -1 to omit the check - number_of_outputs (int, Tuple(int)): number of outputs supported by wrapper. - Use -1 to omit the check - - Raises: - WrapperError: if the model has unsupported number of inputs/outputs - ''' - if not isinstance(number_of_inputs, tuple): - if len(self.inputs) != number_of_inputs and number_of_inputs != -1: - self.raise_error("Expected {} input blob{}, but {} found: {}".format( - number_of_inputs, 's' if number_of_inputs !=1 else '', - len(self.inputs), ', '.join(self.inputs) - )) - else: - if not len(self.inputs) in number_of_inputs: - self.raise_error("Expected {} or {} input blobs, but {} found: {}".format( - ', '.join(str(n) for n in number_of_inputs[:-1]), int(number_of_inputs[-1]), - len(self.inputs), ', '.join(self.inputs) - )) - - if not isinstance(number_of_outputs, tuple): - if len(self.outputs) != number_of_outputs and number_of_outputs != -1: - self.raise_error("Expected {} output blob{}, but {} found: {}".format( - number_of_outputs, 's' if number_of_outputs !=1 else '', - len(self.outputs), ', '.join(self.outputs) - )) - else: - if not len(self.outputs) in number_of_outputs: - self.raise_error("Expected {} or {} output blobs, but {} found: {}".format( - ', '.join(str(n) for n in number_of_outputs[:-1]), int(number_of_outputs[-1]), - len(self.outputs), ', '.join(self.outputs) - )) - - def __call__(self, inputs): - ''' - Applies preprocessing, synchronous inference, postprocessing routines while one call. - - Args: - inputs: raw input data, the data type is defined by wrapper - - Returns: - - postprocessed data in the format defined by wrapper - - the input metadata obtained from `preprocess` method - ''' - dict_data, input_meta = self.preprocess(inputs) - raw_result = self.infer_sync(dict_data) - return self.postprocess(raw_result, input_meta), input_meta - - def load(self, force=False): - if not self.model_loaded or force: - self.model_loaded = True - self.model_adapter.load_model() - - def reshape(self, new_shape): - if self.model_loaded: - self.logger.warning(f'{self.__model__}: the model already loaded to device, ', - 'should be reloaded after reshaping.') - self.model_loaded = False - self.model_adapter.reshape_model(new_shape) - self.inputs = self.model_adapter.get_input_layers() - self.outputs = self.model_adapter.get_output_layers() - - def infer_sync(self, dict_data): - if not self.model_loaded: - self.raise_error("The model is not loaded to the device. Please, create the wrapper " - "with preload=True option or call load() method before infer_sync()") - return self.model_adapter.infer_sync(dict_data) - - def infer_async(self, dict_data, callback_data): - if not self.model_loaded: - self.raise_error("The model is not loaded to the device. Please, create the wrapper " - "with preload=True option or call load() method before infer_async()") - self.model_adapter.infer_async(dict_data, callback_data) - - def is_ready(self): - return self.model_adapter.is_ready() - - def await_all(self): - self.model_adapter.await_all() - - def await_any(self): - self.model_adapter.await_any() - - def log_layers_info(self): - '''Prints the shape, precision and layout for all model inputs/outputs. - ''' - for name, metadata in self.inputs.items(): - self.logger.info('\tInput layer: {}, shape: {}, precision: {}, layout: {}'.format( - name, metadata.shape, metadata.precision, metadata.layout)) - for name, metadata in self.outputs.items(): - self.logger.info('\tOutput layer: {}, shape: {}, precision: {}, layout: {}'.format( - name, metadata.shape, metadata.precision, metadata.layout)) diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/monodepth.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/monodepth.py deleted file mode 100644 index a959bb1c..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/monodepth.py +++ /dev/null @@ -1,39 +0,0 @@ -""" - Copyright (C) 2018-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import cv2 - -from .segmentation import SegmentationModel - - -class MonoDepthModel(SegmentationModel): - __model__ = 'MonoDepth' - - def postprocess(self, outputs, meta): - result = outputs[self.output_blob_name].squeeze() - input_image_height = meta['original_shape'][0] - input_image_width = meta['original_shape'][1] - - result = cv2.resize(result, (input_image_width, input_image_height), interpolation=cv2.INTER_CUBIC) - - disp_min = result.min() - disp_max = result.max() - if disp_max - disp_min > 1e-6: - result = (result - disp_min) / (disp_max - disp_min) - else: - result.fill(0.5) - - return result diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/nanodet.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/nanodet.py deleted file mode 100644 index b40f3500..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/nanodet.py +++ /dev/null @@ -1,130 +0,0 @@ -""" - Copyright (c) 2022-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" -import math -import numpy as np - -from .types import NumericalValue -from .detection_model import DetectionModel -from .utils import Detection, softmax, nms, clip_detections - - -class NanoDet(DetectionModel): - __model__ = 'NanoDet' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number(1, 1) - self.output_blob_name = self._get_outputs() - self.reg_max = 7 - self.strides = [8, 16, 32] - self.ad = 0.5 - - def _get_outputs(self): - output_blob_name = next(iter(self.outputs)) - output_size = self.outputs[output_blob_name].shape - if len(output_size) != 3: - self.raise_error("Unexpected output blob shape {}. Only 3D output blob is supported".format(output_size)) - - return output_blob_name - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters['resize_type'].update_default_value('fit_to_window') - parameters['confidence_threshold'].update_default_value(0.5) - parameters.update({ - 'iou_threshold': NumericalValue(default_value=0.6, description="Threshold for NMS filtering"), - 'num_classes': NumericalValue(default_value=80, value_type=int, description="Number of classes") - }) - return parameters - - def postprocess(self, outputs, meta): - detections = self._parse_outputs(outputs, meta) - detections = self.rescale_detections(detections, meta) - return detections - - def _parse_outputs(self, outputs, meta): - output = outputs[self.output_blob_name][0] - - cls_scores = output[:, :self.num_classes] - bbox_preds = output[:, self.num_classes:] - input_height, input_width = meta['padded_shape'][:2] if meta.get('padded_shape') else meta['resized_shape'][:2] - - bboxes = self.get_bboxes(bbox_preds, input_height, input_width) - dets = [] - for label, score in enumerate(np.transpose(cls_scores)): - mask = score > self.confidence_threshold - filtered_boxes, score = bboxes[mask, :], score[mask] - if score.size == 0: - continue - x_mins, y_mins, x_maxs, y_maxs = filtered_boxes.T - keep = nms(x_mins, y_mins, x_maxs, y_maxs, score, self.iou_threshold, include_boundaries=True) - score = score[keep] - x_mins, y_mins, x_maxs, y_maxs = x_mins[keep], y_mins[keep], x_maxs[keep], y_maxs[keep] - labels = np.full_like(score, label, dtype=int) - dets += [Detection(*det) for det in zip(x_mins, y_mins, x_maxs, y_maxs, score, labels)] - return dets - - @staticmethod - def distance2bbox(points, distance, max_shape): - x1 = np.expand_dims(points[:, 0] - distance[:, 0], -1).clip(0, max_shape[1]) - y1 = np.expand_dims(points[:, 1] - distance[:, 1], -1).clip(0, max_shape[0]) - x2 = np.expand_dims(points[:, 0] + distance[:, 2], -1).clip(0, max_shape[1]) - y2 = np.expand_dims(points[:, 1] + distance[:, 3], -1).clip(0, max_shape[0]) - return np.concatenate((x1, y1, x2, y2), axis=-1) - - def get_single_level_center_point(self, featmap_size, stride): - h, w = featmap_size - x_range, y_range = (np.arange(w) + self.ad) * stride, (np.arange(h) + self.ad) * stride - y, x = np.meshgrid(y_range, x_range, indexing='ij') - return y.flatten(), x.flatten() - - def get_bboxes(self, reg_preds, input_height, input_width): - featmap_sizes = [(math.ceil(input_height / stride), math.ceil(input_width) / stride) for stride in self.strides] - list_center_priors = [] - for stride, featmap_size in zip(self.strides, featmap_sizes): - y, x = self.get_single_level_center_point(featmap_size, stride) - strides = np.full_like(x, stride) - list_center_priors.append(np.stack([x, y, strides, strides], axis=-1)) - center_priors = np.concatenate(list_center_priors, axis=0) - dist_project = np.linspace(0, self.reg_max, self.reg_max + 1) - x = np.dot(softmax(np.reshape(reg_preds, (*reg_preds.shape[:-1], 4, self.reg_max + 1)), -1, True), dist_project) - dis_preds = x * np.expand_dims(center_priors[:, 2], -1) - return self.distance2bbox(center_priors[:, :2], dis_preds, (input_height, input_width)) - - @staticmethod - def rescale_detections(detections, meta): - input_h, input_w, _ = meta['resized_shape'] - orig_h, orig_w, _ = meta['original_shape'] - w = orig_w / input_w - h = orig_h / input_h - - for detection in detections: - detection.xmin *= w - detection.xmax *= w - detection.ymin *= h - detection.ymax *= h - - return clip_detections(detections, meta['original_shape']) - - -class NanoDetPlus(NanoDet): - __model__ = 'NanoDet-Plus' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self.ad = 0 - self.strides = [8, 16, 32, 64] diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/open_pose.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/open_pose.py deleted file mode 100644 index f93c99a9..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/open_pose.py +++ /dev/null @@ -1,396 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import cv2 -import numpy as np -try: - from numpy.core.umath import clip -except ImportError: - from numpy import clip -import openvino.runtime.opset8 as opset8 - -from .image_model import ImageModel -from .types import NumericalValue - - -class OpenPose(ImageModel): - __model__ = 'OpenPose' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload=False) - self.pooled_heatmaps_blob_name = 'pooled_heatmaps' - self.heatmaps_blob_name = 'heatmaps' - self.pafs_blob_name = 'pafs' - - function = self.model_adapter.model - paf = function.get_output_op(0) - paf_shape = paf.output(0).get_shape() - heatmap = function.get_output_op(1) - - heatmap_shape = heatmap.output(0).get_shape() - if len(paf_shape) != 4 and len(heatmap_shape) != 4: - self.raise_error('OpenPose outputs must be 4-dimensional') - if paf_shape[2] != heatmap_shape[2] and paf_shape[3] != heatmap_shape[3]: - self.raise_error('Last two dimensions of OpenPose outputs must match') - if paf_shape[1] * 2 == heatmap_shape[1]: - paf, heatmap = heatmap, paf - elif paf_shape[1] != heatmap_shape[1] * 2: - self.raise_error('Size of second dimension of OpenPose of one output must be two times larger then size ' - 'of second dimension of another output') - - paf = paf.inputs()[0].get_source_output().get_node() - paf.get_output_tensor(0).set_names({self.pafs_blob_name}) - heatmap = heatmap.inputs()[0].get_source_output().get_node() - - heatmap.get_output_tensor(0).set_names({self.heatmaps_blob_name}) - - # Add keypoints NMS to the network. - # Heuristic NMS kernel size adjustment depending on the feature maps upsampling ratio. - p = int(np.round(6 / 7 * self.upsample_ratio)) - k = 2 * p + 1 - pooled_heatmap = opset8.max_pool(heatmap, kernel_shape=(k, k), dilations=(1, 1), pads_begin=(p, p), pads_end=(p, p), - strides=(1, 1), name=self.pooled_heatmaps_blob_name) - pooled_heatmap.output(0).get_tensor().set_names({self.pooled_heatmaps_blob_name}) - self.model_adapter.model.add_outputs([pooled_heatmap.output(0)]) - - self.inputs = self.model_adapter.get_input_layers() - self.outputs = self.model_adapter.get_output_layers() - - self.output_scale = self.inputs[self.image_blob_name].shape[-2] / self.outputs[self.heatmaps_blob_name].shape[-2] - - if self.target_size is None: - self.target_size = self.inputs[self.image_blob_name].shape[-2] - self.h = (self.target_size + self.size_divisor - 1) // self.size_divisor * self.size_divisor - input_width = round(self.target_size * self.aspect_ratio) - self.w = (input_width + self.size_divisor - 1) // self.size_divisor * self.size_divisor - default_input_shape = self.inputs[self.image_blob_name].shape - input_shape = {self.image_blob_name: (default_input_shape[:-2] + [self.h, self.w])} - self.logger.debug('\tReshape model from {} to {}'.format(default_input_shape, input_shape[self.image_blob_name])) - super().reshape(input_shape) - - if preload: - self.load() - - num_joints = self.outputs[self.heatmaps_blob_name].shape[1] - 1 # The last channel is for background - self.decoder = OpenPoseDecoder(num_joints, score_threshold=self.confidence_threshold) - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'target_size': NumericalValue(value_type=int, min=1), - 'aspect_ratio': NumericalValue(), - 'confidence_threshold': NumericalValue(), - 'upsample_ratio': NumericalValue(default_value=1, value_type=int), - 'size_divisor': NumericalValue(default_value=8, value_type=int), - }) - return parameters - - @staticmethod - def heatmap_nms(heatmaps, pooled_heatmaps): - return heatmaps * (heatmaps == pooled_heatmaps) - - @staticmethod - def _resize_image(frame, input_h): - h = frame.shape[0] - scale = input_h / h - return cv2.resize(frame, None, fx=scale, fy=scale) - - def preprocess(self, inputs): - img = self._resize_image(inputs, self.h) - h, w = img.shape[:2] - if self.w < w: - self.raise_error("The image aspect ratio doesn't fit current model shape") - if not (self.w - self.size_divisor < w <= self.w): - self.logger.warning("\tChosen model aspect ratio doesn't match image aspect ratio") - resize_img_scale = np.array((inputs.shape[1] / w, inputs.shape[0] / h), np.float32) - - img = np.pad(img, ((0, 0), (0, self.w - w), (0, 0)), - mode='constant', constant_values=0) - img = img.transpose((2, 0, 1)) # Change data layout from HWC to CHW - img = img[None] - meta = {'resize_img_scale': resize_img_scale} - return {self.image_blob_name: img}, meta - - def postprocess(self, outputs, meta): - heatmaps = outputs[self.heatmaps_blob_name] - pafs = outputs[self.pafs_blob_name] - pooled_heatmaps = outputs[self.pooled_heatmaps_blob_name] - nms_heatmaps = self.heatmap_nms(heatmaps, pooled_heatmaps) - poses, scores = self.decoder(heatmaps, nms_heatmaps, pafs) - # Rescale poses to the original image. - poses[:, :, :2] *= meta['resize_img_scale'] * self.output_scale - return poses, scores - - -class OpenPoseDecoder: - - BODY_PARTS_KPT_IDS = ((1, 2), (1, 5), (2, 3), (3, 4), (5, 6), (6, 7), (1, 8), (8, 9), (9, 10), (1, 11), - (11, 12), (12, 13), (1, 0), (0, 14), (14, 16), (0, 15), (15, 17), (2, 16), (5, 17)) - BODY_PARTS_PAF_IDS = (12, 20, 14, 16, 22, 24, 0, 2, 4, 6, 8, 10, 28, 30, 34, 32, 36, 18, 26) - - def __init__(self, num_joints=18, skeleton=BODY_PARTS_KPT_IDS, paf_indices=BODY_PARTS_PAF_IDS, - max_points=100, score_threshold=0.1, min_paf_alignment_score=0.05, delta=0.5): - self.num_joints = num_joints - self.skeleton = skeleton - self.paf_indices = paf_indices - self.max_points = max_points - self.score_threshold = score_threshold - self.min_paf_alignment_score = min_paf_alignment_score - self.delta = delta - - self.points_per_limb = 10 - self.grid = np.arange(self.points_per_limb, dtype=np.float32).reshape(1, -1, 1) - - def __call__(self, heatmaps, nms_heatmaps, pafs): - batch_size, _, h, w = heatmaps.shape - assert batch_size == 1, 'Batch size of 1 only supported' - - keypoints = self.extract_points(heatmaps, nms_heatmaps) - pafs = np.transpose(pafs, (0, 2, 3, 1)) - - if self.delta > 0: - for kpts in keypoints: - kpts[:, :2] += self.delta - clip(kpts[:, 0], 0, w - 1, out=kpts[:, 0]) - clip(kpts[:, 1], 0, h - 1, out=kpts[:, 1]) - - pose_entries, keypoints = self.group_keypoints(keypoints, pafs, pose_entry_size=self.num_joints + 2) - poses, scores = self.convert_to_coco_format(pose_entries, keypoints) - if len(poses) > 0: - poses = np.asarray(poses, dtype=np.float32) - poses = poses.reshape((poses.shape[0], -1, 3)) - else: - poses = np.empty((0, 17, 3), dtype=np.float32) - scores = np.empty(0, dtype=np.float32) - - return poses, scores - - def extract_points(self, heatmaps, nms_heatmaps): - batch_size, channels_num, h, w = heatmaps.shape - assert batch_size == 1, 'Batch size of 1 only supported' - assert channels_num >= self.num_joints - - xs, ys, scores = self.top_k(nms_heatmaps) - masks = scores > self.score_threshold - all_keypoints = [] - keypoint_id = 0 - for k in range(self.num_joints): - # Filter low-score points. - mask = masks[0, k] - x = xs[0, k][mask].ravel() - y = ys[0, k][mask].ravel() - score = scores[0, k][mask].ravel() - n = len(x) - if n == 0: - all_keypoints.append(np.empty((0, 4), dtype=np.float32)) - continue - # Apply quarter offset to improve localization accuracy. - x, y = self.refine(heatmaps[0, k], x, y) - clip(x, 0, w - 1, out=x) - clip(y, 0, h - 1, out=y) - # Pack resulting points. - keypoints = np.empty((n, 4), dtype=np.float32) - keypoints[:, 0] = x - keypoints[:, 1] = y - keypoints[:, 2] = score - keypoints[:, 3] = np.arange(keypoint_id, keypoint_id + n) - keypoint_id += n - all_keypoints.append(keypoints) - return all_keypoints - - def top_k(self, heatmaps): - N, K, _, W = heatmaps.shape - heatmaps = heatmaps.reshape(N, K, -1) - # Get positions with top scores. - ind = heatmaps.argpartition(-self.max_points, axis=2)[:, :, -self.max_points:] - scores = np.take_along_axis(heatmaps, ind, axis=2) - # Keep top scores sorted. - subind = np.argsort(-scores, axis=2) - ind = np.take_along_axis(ind, subind, axis=2) - scores = np.take_along_axis(scores, subind, axis=2) - y, x = np.divmod(ind, W) - return x, y, scores - - @staticmethod - def refine(heatmap, x, y): - h, w = heatmap.shape[-2:] - valid = np.logical_and(np.logical_and(x > 0, x < w - 1), np.logical_and(y > 0, y < h - 1)) - xx = x[valid] - yy = y[valid] - dx = np.sign(heatmap[yy, xx + 1] - heatmap[yy, xx - 1], dtype=np.float32) * 0.25 - dy = np.sign(heatmap[yy + 1, xx] - heatmap[yy - 1, xx], dtype=np.float32) * 0.25 - x = x.astype(np.float32) - y = y.astype(np.float32) - x[valid] += dx - y[valid] += dy - return x, y - - @staticmethod - def is_disjoint(pose_a, pose_b): - pose_a = pose_a[:-2] - pose_b = pose_b[:-2] - return np.all(np.logical_or.reduce((pose_a == pose_b, pose_a < 0, pose_b < 0))) - - def update_poses(self, kpt_a_id, kpt_b_id, all_keypoints, connections, pose_entries, pose_entry_size): - for connection in connections: - pose_a_idx = -1 - pose_b_idx = -1 - for j, pose in enumerate(pose_entries): - if pose[kpt_a_id] == connection[0]: - pose_a_idx = j - if pose[kpt_b_id] == connection[1]: - pose_b_idx = j - if pose_a_idx < 0 and pose_b_idx < 0: - # Create new pose entry. - pose_entry = np.full(pose_entry_size, -1, dtype=np.float32) - pose_entry[kpt_a_id] = connection[0] - pose_entry[kpt_b_id] = connection[1] - pose_entry[-1] = 2 - pose_entry[-2] = np.sum(all_keypoints[connection[0:2], 2]) + connection[2] - pose_entries.append(pose_entry) - elif pose_a_idx >= 0 and pose_b_idx >= 0 and pose_a_idx != pose_b_idx: - # Merge two poses are disjoint merge them, otherwise ignore connection. - pose_a = pose_entries[pose_a_idx] - pose_b = pose_entries[pose_b_idx] - if self.is_disjoint(pose_a, pose_b): - pose_a += pose_b - pose_a[:-2] += 1 - pose_a[-2] += connection[2] - del pose_entries[pose_b_idx] - elif pose_a_idx >= 0 and pose_b_idx >= 0: - # Adjust score of a pose. - pose_entries[pose_a_idx][-2] += connection[2] - elif pose_a_idx >= 0: - # Add a new limb into pose. - pose = pose_entries[pose_a_idx] - if pose[kpt_b_id] < 0: - pose[-2] += all_keypoints[connection[1], 2] - pose[kpt_b_id] = connection[1] - pose[-2] += connection[2] - pose[-1] += 1 - elif pose_b_idx >= 0: - # Add a new limb into pose. - pose = pose_entries[pose_b_idx] - if pose[kpt_a_id] < 0: - pose[-2] += all_keypoints[connection[0], 2] - pose[kpt_a_id] = connection[0] - pose[-2] += connection[2] - pose[-1] += 1 - return pose_entries - - @staticmethod - def connections_nms(a_idx, b_idx, affinity_scores): - # From all retrieved connections that share starting/ending keypoints leave only the top-scoring ones. - order = affinity_scores.argsort()[::-1] - affinity_scores = affinity_scores[order] - a_idx = a_idx[order] - b_idx = b_idx[order] - idx = [] - has_kpt_a = set() - has_kpt_b = set() - for t, (i, j) in enumerate(zip(a_idx, b_idx)): - if i not in has_kpt_a and j not in has_kpt_b: - idx.append(t) - has_kpt_a.add(i) - has_kpt_b.add(j) - idx = np.asarray(idx, dtype=np.int32) - return a_idx[idx], b_idx[idx], affinity_scores[idx] - - def group_keypoints(self, all_keypoints_by_type, pafs, pose_entry_size=20): - all_keypoints = np.concatenate(all_keypoints_by_type, axis=0) - pose_entries = [] - # For every limb. - for part_id, paf_channel in enumerate(self.paf_indices): - kpt_a_id, kpt_b_id = self.skeleton[part_id] - kpts_a = all_keypoints_by_type[kpt_a_id] - kpts_b = all_keypoints_by_type[kpt_b_id] - n = len(kpts_a) - m = len(kpts_b) - if n == 0 or m == 0: - continue - - # Get vectors between all pairs of keypoints, i.e. candidate limb vectors. - a = kpts_a[:, :2] - a = np.broadcast_to(a[None], (m, n, 2)) - b = kpts_b[:, :2] - vec_raw = (b[:, None, :] - a).reshape(-1, 1, 2) - - # Sample points along every candidate limb vector. - steps = (1 / (self.points_per_limb - 1) * vec_raw) - points = steps * self.grid + a.reshape(-1, 1, 2) - points = points.round().astype(dtype=np.int32) - x = points[..., 0].ravel() - y = points[..., 1].ravel() - - # Compute affinity score between candidate limb vectors and part affinity field. - part_pafs = pafs[0, :, :, paf_channel:paf_channel + 2] - field = part_pafs[y, x].reshape(-1, self.points_per_limb, 2) - vec_norm = np.linalg.norm(vec_raw, ord=2, axis=-1, keepdims=True) - vec = vec_raw / (vec_norm + 1e-6) - affinity_scores = (field * vec).sum(-1).reshape(-1, self.points_per_limb) - valid_affinity_scores = affinity_scores > self.min_paf_alignment_score - valid_num = valid_affinity_scores.sum(1) - affinity_scores = (affinity_scores * valid_affinity_scores).sum(1) / (valid_num + 1e-6) - success_ratio = valid_num / self.points_per_limb - - # Get a list of limbs according to the obtained affinity score. - valid_limbs = np.where(np.logical_and(affinity_scores > 0, success_ratio > 0.8))[0] - if len(valid_limbs) == 0: - continue - b_idx, a_idx = np.divmod(valid_limbs, n) - affinity_scores = affinity_scores[valid_limbs] - - # Suppress incompatible connections. - a_idx, b_idx, affinity_scores = self.connections_nms(a_idx, b_idx, affinity_scores) - connections = list(zip(kpts_a[a_idx, 3].astype(np.int32), - kpts_b[b_idx, 3].astype(np.int32), - affinity_scores)) - if len(connections) == 0: - continue - - # Update poses with new connections. - pose_entries = self.update_poses(kpt_a_id, kpt_b_id, all_keypoints, - connections, pose_entries, pose_entry_size) - - # Remove poses with not enough points. - pose_entries = np.asarray(pose_entries, dtype=np.float32).reshape(-1, pose_entry_size) - pose_entries = pose_entries[pose_entries[:, -1] >= 3] - return pose_entries, all_keypoints - - @staticmethod - def convert_to_coco_format(pose_entries, all_keypoints): - num_joints = 17 - coco_keypoints = [] - scores = [] - for pose in pose_entries: - if len(pose) == 0: - continue - keypoints = np.zeros(num_joints * 3) - reorder_map = [0, -1, 6, 8, 10, 5, 7, 9, 12, 14, 16, 11, 13, 15, 2, 1, 4, 3] - person_score = pose[-2] - for keypoint_id, target_id in zip(pose[:-2], reorder_map): - if target_id < 0: - continue - cx, cy, score = 0, 0, 0 # keypoint not found - if keypoint_id != -1: - cx, cy, score = all_keypoints[int(keypoint_id), 0:3] - keypoints[target_id * 3 + 0] = cx - keypoints[target_id * 3 + 1] = cy - keypoints[target_id * 3 + 2] = score - coco_keypoints.append(keypoints) - scores.append(person_score * max(0, (pose[-1] - 1))) # -1 for 'neck' - return np.asarray(coco_keypoints), np.asarray(scores) diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/retinaface.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/retinaface.py deleted file mode 100644 index 329a0da2..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/retinaface.py +++ /dev/null @@ -1,432 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import re - -import numpy as np -from itertools import product as product - -from .detection_model import DetectionModel -from .utils import DetectionWithLandmarks, Detection, nms, clip_detections - - -class RetinaFace(DetectionModel): - __model__ = 'RetinaFace' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number(1, (6, 9, 12)) - - self.detect_masks = len(self.outputs) == 12 - self.process_landmarks = len(self.outputs) > 6 - self.mask_threshold = 0.5 - self.postprocessor = RetinaFacePostprocessor(detect_attributes=self.detect_masks, - process_landmarks=self.process_landmarks) - - self.labels = ['Face'] if not self.detect_masks else ['Mask', 'No mask'] - - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters['resize_type'].update_default_value('standard') - parameters['confidence_threshold'].update_default_value(0.5) - return parameters - - def postprocess(self, outputs, meta): - scale_x = meta['resized_shape'][1] / meta['original_shape'][1] - scale_y = meta['resized_shape'][0] / meta['original_shape'][0] - - outputs = self.postprocessor.process_output(outputs, scale_x, scale_y, self.confidence_threshold, self.mask_threshold) - return clip_detections(outputs, meta['original_shape']) - - -class RetinaFacePyTorch(DetectionModel): - __model__ = 'RetinaFace-PyTorch' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number(1, (2, 3)) - - self.process_landmarks = len(self.outputs) == 3 - self.postprocessor = RetinaFacePyTorchPostprocessor(process_landmarks=self.process_landmarks) - - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters['resize_type'].update_default_value('standard') - parameters['confidence_threshold'].update_default_value(0.5) - parameters['labels'].update_default_value(['Face']) - return parameters - - def postprocess(self, outputs, meta): - scale_x = meta['resized_shape'][1] / meta['original_shape'][1] - scale_y = meta['resized_shape'][0] / meta['original_shape'][0] - - outputs = self.postprocessor.process_output(outputs, scale_x, scale_y, self.confidence_threshold, - meta['resized_shape'][:2]) - return clip_detections(outputs, meta['original_shape']) - - -class RetinaFacePostprocessor: - def __init__(self, detect_attributes=False, process_landmarks=True): - self._detect_masks = detect_attributes - self._process_landmarks = process_landmarks - _ratio = (1.,) - self._anchor_cfg = { - 32: {'SCALES': (32, 16), 'BASE_SIZE': 16, 'RATIOS': _ratio}, - 16: {'SCALES': (8, 4), 'BASE_SIZE': 16, 'RATIOS': _ratio}, - 8: {'SCALES': (2, 1), 'BASE_SIZE': 16, 'RATIOS': _ratio} - } - self._features_stride_fpn = [32, 16, 8] - self._anchors_fpn = dict(zip(self._features_stride_fpn, self.generate_anchors_fpn(cfg=self._anchor_cfg))) - self._num_anchors = dict(zip( - self._features_stride_fpn, [anchors.shape[0] for anchors in self._anchors_fpn.values()] - )) - self.landmark_std = 0.2 if detect_attributes else 1.0 - self.nms_threshold = 0.5 if process_landmarks else 0.3 - - @staticmethod - def generate_anchors_fpn(cfg): - def generate_anchors(base_size=16, ratios=(0.5, 1, 2), scales=2 ** np.arange(3, 6)): - base_anchor = np.array([1, 1, base_size, base_size]) - 1 - ratio_anchors = _ratio_enum(base_anchor, ratios) - anchors = np.vstack([_scale_enum(ratio_anchors[i, :], scales) for i in range(ratio_anchors.shape[0])]) - return anchors - - def _ratio_enum(anchor, ratios): - w, h, x_ctr, y_ctr = _generate_wh_ctrs(anchor) - size = w * h - size_ratios = size / ratios - ws = np.round(np.sqrt(size_ratios)) - hs = np.round(ws * ratios) - anchors = _make_anchors(ws, hs, x_ctr, y_ctr) - return anchors - - def _scale_enum(anchor, scales): - w, h, x_ctr, y_ctr = _generate_wh_ctrs(anchor) - ws = w * scales - hs = h * scales - anchors = _make_anchors(ws, hs, x_ctr, y_ctr) - return anchors - - def _generate_wh_ctrs(anchor): - w = anchor[2] - anchor[0] + 1 - h = anchor[3] - anchor[1] + 1 - x_ctr = anchor[0] + 0.5 * (w - 1) - y_ctr = anchor[1] + 0.5 * (h - 1) - return w, h, x_ctr, y_ctr - - def _make_anchors(ws, hs, x_ctr, y_ctr): - ws = ws[:, np.newaxis] - hs = hs[:, np.newaxis] - anchors = np.hstack(( - x_ctr - 0.5 * (ws - 1), y_ctr - 0.5 * (hs - 1), x_ctr + 0.5 * (ws - 1), y_ctr + 0.5 * (hs - 1) - )) - return anchors - - rpn_feat_stride = [int(k) for k in cfg] - rpn_feat_stride.sort(reverse=True) - anchors = [] - for stride in rpn_feat_stride: - feature_info = cfg[stride] - bs = feature_info['BASE_SIZE'] - __ratios = np.array(feature_info['RATIOS']) - __scales = np.array(feature_info['SCALES']) - anchors.append(generate_anchors(bs, __ratios, __scales)) - - return anchors - - def process_output(self, raw_output, scale_x, scale_y, face_prob_threshold, mask_prob_threshold): - bboxes_outputs = [raw_output[name][0] for name in raw_output if re.search('.bbox.', name)] - bboxes_outputs.sort(key=lambda x: x.shape[1]) - - scores_outputs = [raw_output[name][0] for name in raw_output if re.search('.cls.', name)] - scores_outputs.sort(key=lambda x: x.shape[1]) - - if self._process_landmarks: - landmarks_outputs = [raw_output[name][0] for name in raw_output if re.search('.landmark.', name)] - landmarks_outputs.sort(key=lambda x: x.shape[1]) - - if self._detect_masks: - type_scores_outputs = [raw_output[name][0] for name in raw_output if re.search('.type.', name)] - type_scores_outputs.sort(key=lambda x: x.shape[1]) - - proposals_list = [] - scores_list = [] - landmarks_list = [] - mask_scores_list = [] - for idx, s in enumerate(self._features_stride_fpn): - anchor_num = self._num_anchors[s] - scores = self._get_scores(scores_outputs[idx], anchor_num) - bbox_deltas = bboxes_outputs[idx] - height, width = bbox_deltas.shape[1], bbox_deltas.shape[2] - anchors_fpn = self._anchors_fpn[s] - anchors = self.anchors_plane(height, width, int(s), anchors_fpn) - anchors = anchors.reshape((height * width * anchor_num, 4)) - proposals = self._get_proposals(bbox_deltas, anchor_num, anchors) - threshold_mask = scores >= face_prob_threshold - - proposals_list.extend(proposals[threshold_mask, :]) - scores_list.extend(scores[threshold_mask]) - if self._process_landmarks: - landmarks = self._get_landmarks(landmarks_outputs[idx], anchor_num, anchors) - landmarks_list.extend(landmarks[threshold_mask, :]) - if self._detect_masks: - masks = self._get_mask_scores(type_scores_outputs[idx], anchor_num) - mask_scores_list.extend(masks[threshold_mask]) - - if len(scores_list) > 0: - proposals_list = np.array(proposals_list) - scores_list = np.array(scores_list) - landmarks_list = np.array(landmarks_list) - mask_scores_list = np.array(mask_scores_list) - x_mins, y_mins, x_maxs, y_maxs = proposals_list.T - keep = nms(x_mins, y_mins, x_maxs, y_maxs, scores_list, self.nms_threshold, - include_boundaries=not self._process_landmarks) - proposals_list = proposals_list[keep] - scores_list = scores_list[keep] - if self._process_landmarks: - landmarks_list = landmarks_list[keep] - if self._detect_masks: - mask_scores_list = mask_scores_list[keep] - - result = [] - if len(scores_list) != 0: - scores = np.reshape(scores_list, -1) - mask_scores_list = np.reshape(mask_scores_list, -1) - x_mins, y_mins, x_maxs, y_maxs = np.array(proposals_list).T # pylint: disable=E0633 - x_mins /= scale_x - x_maxs /= scale_x - y_mins /= scale_y - y_maxs /= scale_y - - result = [] - if self._process_landmarks: - landmarks_x_coords = np.array(landmarks_list)[:, :, ::2].reshape(len(landmarks_list), -1) / scale_x - landmarks_y_coords = np.array(landmarks_list)[:, :, 1::2].reshape(len(landmarks_list), -1) / scale_y - if self._detect_masks: - for i in range(len(scores_list)): - result.append(DetectionWithLandmarks(x_mins[i], y_mins[i], x_maxs[i], y_maxs[i], scores[i], - 0 if mask_scores_list[i] > mask_prob_threshold else 1, - landmarks_x_coords[i], landmarks_y_coords[i])) - else: - for i in range(len(scores_list)): - result.append(DetectionWithLandmarks(x_mins[i], y_mins[i], x_maxs[i], y_maxs[i], scores[i], 0, - landmarks_x_coords[i], landmarks_y_coords[i])) - else: - for i in range(len(scores_list)): - result.append(Detection(x_mins[i], y_mins[i], x_maxs[i], y_maxs[i], scores[i], 0)) - - return result - - def _get_proposals(self, bbox_deltas, anchor_num, anchors): - bbox_deltas = bbox_deltas.transpose((1, 2, 0)) - bbox_pred_len = bbox_deltas.shape[2] // anchor_num - bbox_deltas = bbox_deltas.reshape((-1, bbox_pred_len)) - proposals = self.bbox_pred(anchors, bbox_deltas) - return proposals - - @staticmethod - def _get_scores(scores, anchor_num): - scores = scores[anchor_num:, :, :] - scores = scores.transpose((1, 2, 0)).reshape(-1) - return scores - - @staticmethod - def _get_mask_scores(type_scores, anchor_num): - mask_scores = type_scores[anchor_num * 2:, :, :] - mask_scores = mask_scores.transpose((1, 2, 0)).reshape(-1) - return mask_scores - - def _get_landmarks(self, landmark_deltas, anchor_num, anchors): - landmark_pred_len = landmark_deltas.shape[0] // anchor_num - landmark_deltas = landmark_deltas.transpose((1, 2, 0)).reshape((-1, 5, landmark_pred_len // 5)) - landmark_deltas *= self.landmark_std - landmarks = self.landmark_pred(anchors, landmark_deltas) - return landmarks - - @staticmethod - def bbox_pred(boxes, box_deltas): - if boxes.shape[0] == 0: - return np.zeros((0, box_deltas.shape[1])) - - boxes = boxes.astype(float, copy=False) - widths = boxes[:, 2] - boxes[:, 0] + 1.0 - heights = boxes[:, 3] - boxes[:, 1] + 1.0 - ctr_x = boxes[:, 0] + 0.5 * (widths - 1.0) - ctr_y = boxes[:, 1] + 0.5 * (heights - 1.0) - dx = box_deltas[:, 0:1] - dy = box_deltas[:, 1:2] - dw = box_deltas[:, 2:3] - dh = box_deltas[:, 3:4] - pred_ctr_x = dx * widths[:, np.newaxis] + ctr_x[:, np.newaxis] - pred_ctr_y = dy * heights[:, np.newaxis] + ctr_y[:, np.newaxis] - pred_w = np.exp(dw) * widths[:, np.newaxis] - pred_h = np.exp(dh) * heights[:, np.newaxis] - pred_boxes = np.zeros(box_deltas.shape) - pred_boxes[:, 0:1] = pred_ctr_x - 0.5 * (pred_w - 1.0) - pred_boxes[:, 1:2] = pred_ctr_y - 0.5 * (pred_h - 1.0) - pred_boxes[:, 2:3] = pred_ctr_x + 0.5 * (pred_w - 1.0) - pred_boxes[:, 3:4] = pred_ctr_y + 0.5 * (pred_h - 1.0) - - if box_deltas.shape[1] > 4: - pred_boxes[:, 4:] = box_deltas[:, 4:] - - return pred_boxes - - @staticmethod - def anchors_plane(height, width, stride, base_anchors): - num_anchors = base_anchors.shape[0] - all_anchors = np.zeros((height, width, num_anchors, 4)) - for iw in range(width): - sw = iw * stride - for ih in range(height): - sh = ih * stride - for k in range(num_anchors): - all_anchors[ih, iw, k, 0] = base_anchors[k, 0] + sw - all_anchors[ih, iw, k, 1] = base_anchors[k, 1] + sh - all_anchors[ih, iw, k, 2] = base_anchors[k, 2] + sw - all_anchors[ih, iw, k, 3] = base_anchors[k, 3] + sh - - return all_anchors - - @staticmethod - def landmark_pred(boxes, landmark_deltas): - if boxes.shape[0] == 0: - return np.zeros((0, landmark_deltas.shape[1])) - boxes = boxes.astype(float, copy=False) - widths = boxes[:, 2] - boxes[:, 0] + 1.0 - heights = boxes[:, 3] - boxes[:, 1] + 1.0 - ctr_x = boxes[:, 0] + 0.5 * (widths - 1.0) - ctr_y = boxes[:, 1] + 0.5 * (heights - 1.0) - pred = landmark_deltas.copy() - for i in range(5): - pred[:, i, 0] = landmark_deltas[:, i, 0] * widths + ctr_x - pred[:, i, 1] = landmark_deltas[:, i, 1] * heights + ctr_y - - return pred - - -class RetinaFacePyTorchPostprocessor: - def __init__(self, process_landmarks=True): - self._process_landmarks = process_landmarks - self.nms_threshold = 0.5 if process_landmarks else 0.3 - self.variance = [0.1, 0.2] - - def process_output(self, raw_output, scale_x, scale_y, face_prob_threshold, image_size): - bboxes_output = [raw_output[name][0] for name in raw_output if re.search('.bbox.', name)][0] - - scores_output = [raw_output[name][0] for name in raw_output if re.search('.cls.', name)][0] - - if self._process_landmarks: - landmarks_output = [raw_output[name][0] for name in raw_output if re.search('.landmark.', name)][0] - - prior_data = self.generate_prior_data(image_size) - proposals = self._get_proposals(bboxes_output, prior_data, image_size) - scores = scores_output[:, 1] - filter_idx = np.where(scores > face_prob_threshold)[0] - proposals = proposals[filter_idx] - scores = scores[filter_idx] - if self._process_landmarks: - landmarks = self._get_landmarks(landmarks_output, prior_data, - image_size) - landmarks = landmarks[filter_idx] - - if np.size(scores) > 0: - - x_mins, y_mins, x_maxs, y_maxs = proposals.T - keep = nms(x_mins, y_mins, x_maxs, y_maxs, scores, self.nms_threshold, - include_boundaries=not self._process_landmarks) - - proposals = proposals[keep] - scores = scores[keep] - if self._process_landmarks: - landmarks = landmarks[keep] - - result = [] - if np.size(scores) != 0: - scores = np.reshape(scores, -1) - x_mins, y_mins, x_maxs, y_maxs = np.array(proposals).T # pylint: disable=E0633 - x_mins /= scale_x - x_maxs /= scale_x - y_mins /= scale_y - y_maxs /= scale_y - - result = [] - if self._process_landmarks: - landmarks_x_coords = np.array(landmarks)[:, ::2] / scale_x - landmarks_y_coords = np.array(landmarks)[:, 1::2] / scale_y - for x_min, y_min, x_max, y_max, score, landmarks_x, landmarks_y in zip( - x_mins, y_mins, x_maxs, y_maxs, scores, landmarks_x_coords, landmarks_y_coords): - result.append(DetectionWithLandmarks(x_min, y_min, x_max, y_max, score, 0, landmarks_x, - landmarks_y)) - else: - for x_min, y_min, x_max, y_max, score in zip(x_mins, y_mins, x_maxs, y_maxs, scores): - result.append(Detection(x_min, y_min, x_max, y_max, score, 0)) - - return result - - @staticmethod - def generate_prior_data(image_size): - global_min_sizes = [[16, 32], [64, 128], [256, 512]] - steps = [8, 16, 32] - anchors = [] - feature_maps = [[int(np.rint(image_size[0]/step)), int(np.rint(image_size[1]/step))] for step in steps] - for idx, feature_map in enumerate(feature_maps): - min_sizes = global_min_sizes[idx] - for i, j in product(range(feature_map[0]), range(feature_map[1])): - for min_size in min_sizes: - s_kx = min_size / image_size[1] - s_ky = min_size / image_size[0] - dense_cx = [x * steps[idx] / image_size[1] for x in [j + 0.5]] - dense_cy = [y * steps[idx] / image_size[0] for y in [i + 0.5]] - for cy, cx in product(dense_cy, dense_cx): - anchors += [cx, cy, s_kx, s_ky] - - priors = np.array(anchors).reshape((-1, 4)) - return priors - - def _get_proposals(self, raw_boxes, priors, image_size): - proposals = self.decode_boxes(raw_boxes, priors, self.variance) - proposals[:, ::2] = proposals[:, ::2] * image_size[1] - proposals[:, 1::2] = proposals[:, 1::2] * image_size[0] - return proposals - - @staticmethod - def decode_boxes(raw_boxes, priors, variance): - boxes = np.concatenate(( - priors[:, :2] + raw_boxes[:, :2] * variance[0] * priors[:, 2:], - priors[:, 2:] * np.exp(raw_boxes[:, 2:] * variance[1])), 1) - boxes[:, :2] -= boxes[:, 2:] / 2 - boxes[:, 2:] += boxes[:, :2] - return boxes - - def _get_landmarks(self, raw_landmarks, priors, image_size): - landmarks = self.decode_landmarks(raw_landmarks, priors, self.variance) - landmarks[:, ::2] = landmarks[:, ::2] * image_size[1] - landmarks[:, 1::2] = landmarks[:, 1::2] * image_size[0] - return landmarks - - @staticmethod - def decode_landmarks(raw_landmarks, priors, variance): - landmarks = np.concatenate((priors[:, :2] + raw_landmarks[:, :2] * variance[0] * priors[:, 2:], - priors[:, :2] + raw_landmarks[:, 2:4] * variance[0] * priors[:, 2:], - priors[:, :2] + raw_landmarks[:, 4:6] * variance[0] * priors[:, 2:], - priors[:, :2] + raw_landmarks[:, 6:8] * variance[0] * priors[:, 2:], - priors[:, :2] + raw_landmarks[:, 8:10] * variance[0] * priors[:, 2:]), 1) - return landmarks diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/segmentation.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/segmentation.py deleted file mode 100644 index 3621d599..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/segmentation.py +++ /dev/null @@ -1,82 +0,0 @@ -""" - Copyright (c) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import cv2 -import numpy as np - -from .image_model import ImageModel -from .types import ListValue, StringValue -from .utils import load_labels - - -class SegmentationModel(ImageModel): - __model__ = 'Segmentation' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number(1, 1) - if self.path_to_labels: - self.labels = load_labels(self.path_to_labels) - - self.output_blob_name = self._get_outputs() - - def _get_outputs(self): - layer_name = next(iter(self.outputs)) - layer_shape = self.outputs[layer_name].shape - - if len(layer_shape) == 3: - self.out_channels = 0 - elif len(layer_shape) == 4: - self.out_channels = layer_shape[1] - else: - self.raise_error("Unexpected output layer shape {}. Only 4D and 3D output layers are supported".format(layer_shape)) - - return layer_name - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'labels': ListValue(description="List of class labels"), - 'path_to_labels': StringValue(description="Path to file with labels. Overrides the labels, if they sets via 'labels' parameter") - }) - - return parameters - - def postprocess(self, outputs, meta): - predictions = outputs[self.output_blob_name].squeeze() - input_image_height = meta['original_shape'][0] - input_image_width = meta['original_shape'][1] - - if self.out_channels < 2: # assume the output is already ArgMax'ed - result = predictions.astype(np.uint8) - else: - result = np.argmax(predictions, axis=0).astype(np.uint8) - - result = cv2.resize(result, (input_image_width, input_image_height), 0, 0, interpolation=cv2.INTER_NEAREST) - return result - - -class SalientObjectDetectionModel(SegmentationModel): - __model__ = 'Salient_Object_Detection' - - def postprocess(self, outputs, meta): - input_image_height = meta['original_shape'][0] - input_image_width = meta['original_shape'][1] - result = outputs[self.output_blob_name].squeeze() - result = 1/(1 + np.exp(-result)) - result = cv2.resize(result, (input_image_width, input_image_height), 0, 0, interpolation=cv2.INTER_NEAREST) - return result diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/ssd.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/ssd.py deleted file mode 100644 index 88b72982..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/ssd.py +++ /dev/null @@ -1,150 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" -import numpy as np - -from .detection_model import DetectionModel -from .utils import Detection - - -class SSD(DetectionModel): - __model__ = 'SSD' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self.image_info_blob_name = self.image_info_blob_names[0] if len(self.image_info_blob_names) == 1 else None - self.output_parser = self._get_output_parser(self.image_blob_name) - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters['resize_type'].update_default_value('standard') - parameters['confidence_threshold'].update_default_value(0.5) - return parameters - - def preprocess(self, inputs): - dict_inputs, meta = super().preprocess(inputs) - if self.image_info_blob_name: - dict_inputs[self.image_info_blob_name] = np.array([[self.h, self.w, 1]]) - return dict_inputs, meta - - def postprocess(self, outputs, meta): - detections = self._parse_outputs(outputs, meta) - detections = self._resize_detections(detections, meta) - return detections - - def _get_output_parser(self, image_blob_name, bboxes='bboxes', labels='labels', scores='scores'): - try: - parser = SingleOutputParser(self.outputs) - self.logger.debug('\tUsing SSD model with single output parser') - return parser - except ValueError: - pass - - try: - parser = MultipleOutputParser(self.outputs, bboxes, scores, labels) - self.logger.debug('\tUsing SSD model with multiple output parser') - return parser - except ValueError: - pass - - try: - parser = BoxesLabelsParser(self.outputs, self.inputs[image_blob_name].shape[2:][::-1]) - self.logger.debug('\tUsing SSD model with "boxes-labels" output parser') - return parser - except ValueError: - pass - self.raise_error('Unsupported model outputs') - - def _parse_outputs(self, outputs, meta): - detections = self.output_parser(outputs) - - detections = [d for d in detections if d.score > self.confidence_threshold] - - return detections - - -def find_layer_by_name(name, layers): - suitable_layers = [layer_name for layer_name in layers if name in layer_name] - if not suitable_layers: - raise ValueError('Suitable layer for "{}" output is not found'.format(name)) - - if len(suitable_layers) > 1: - raise ValueError('More than 1 layer matched to "{}" output'.format(name)) - - return suitable_layers[0] - - -class SingleOutputParser: - def __init__(self, all_outputs): - if len(all_outputs) != 1: - raise ValueError('Network must have only one output.') - self.output_name, output_data = next(iter(all_outputs.items())) - last_dim = output_data.shape[-1] - if last_dim != 7: - raise ValueError('The last dimension of the output blob must be equal to 7, ' - 'got {} instead.'.format(last_dim)) - - def __call__(self, outputs): - return [Detection(xmin, ymin, xmax, ymax, score, label) - for _, label, score, xmin, ymin, xmax, ymax in outputs[self.output_name][0][0]] - - -class MultipleOutputParser: - def __init__(self, layers, bboxes_layer='bboxes', scores_layer='scores', labels_layer='labels'): - self.labels_layer = find_layer_by_name(labels_layer, layers) - self.scores_layer = find_layer_by_name(scores_layer, layers) - self.bboxes_layer = find_layer_by_name(bboxes_layer, layers) - - def __call__(self, outputs): - bboxes = outputs[self.bboxes_layer][0] - scores = outputs[self.scores_layer][0] - labels = outputs[self.labels_layer][0] - return [Detection(*bbox, score, label) for label, score, bbox in zip(labels, scores, bboxes)] - - -class BoxesLabelsParser: - def __init__(self, layers, input_size, labels_layer='labels', default_label=0): - try: - self.labels_layer = find_layer_by_name(labels_layer, layers) - except ValueError: - self.labels_layer = None - self.default_label = default_label - - self.bboxes_layer = self.find_layer_bboxes_output(layers) - self.input_size = input_size - - @staticmethod - def find_layer_bboxes_output(layers): - filter_outputs = [name for name, data in layers.items() if len(data.shape) == 2 and data.shape[-1] == 5] - if not filter_outputs: - raise ValueError('Suitable output with bounding boxes is not found') - if len(filter_outputs) > 1: - raise ValueError('More than 1 candidate for output with bounding boxes.') - return filter_outputs[0] - - def __call__(self, outputs): - bboxes = outputs[self.bboxes_layer] - scores = bboxes[:, 4] - bboxes = bboxes[:, :4] - bboxes[:, 0::2] /= self.input_size[0] - bboxes[:, 1::2] /= self.input_size[1] - if self.labels_layer: - labels = outputs[self.labels_layer] - else: - labels = np.full(len(bboxes), self.default_label, dtype=bboxes.dtype) - - detections = [Detection(*bbox, score, label) for label, score, bbox in zip(labels, scores, bboxes)] - return detections diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/tokens_bert.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/tokens_bert.py deleted file mode 100644 index 05bfcdc8..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/tokens_bert.py +++ /dev/null @@ -1,114 +0,0 @@ -""" - Copyright (c) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import unicodedata -import string - - -# A class to store context as text, its tokens and embedding vector -class ContextData: - def __init__(self, tokens_id, tokens_se, context=None, emb=None): - self.c_tokens_id = tokens_id - self.c_tokens_se = tokens_se - self.context = context - self.emb = emb - - -class ContextWindow: - def __init__(self, window_len, tokens_id, tokens_se): - self.tokens_id = tokens_id - self.tokens_se = tokens_se - self.window_len = window_len - self.stride = self.window_len // 2 # overlap by half - self.total_len = len(self.tokens_id) - self.s, self.e = 0, min(self.window_len, self.total_len) - - def move(self): - self.s = min(self.s + self.stride, self.total_len) - self.e = min(self.s + self.window_len, self.total_len) - - def is_over(self): - return self.e - self.s < self.stride - - def get_context_data(self, context=None): - return ContextData(self.tokens_id[self.s:self.e], self.tokens_se[self.s:self.e], - context=context) - - -# load vocabulary file for encoding -def load_vocab_file(vocab_file_name): - with open(vocab_file_name, "r", encoding="utf-8") as r: - return {t.rstrip("\n"): i for i, t in enumerate(r.readlines())} - - -# split word by vocab items and get tok codes -# iteratively return codes -def encode_by_voc(w, vocab): - # remove mark and control chars - def clean_word(w): - wo = "" # accumulator for output word - for c in unicodedata.normalize("NFD", w): - c_cat = unicodedata.category(c) - # remove mark nonspacing code and controls - if c_cat != "Mn" and c_cat[0] != "C": - wo += c - return wo - - w = clean_word(w) - - res = [] - for s0, e0 in split_to_words(w): - s, e = s0, e0 - tokens = [] - while e > s: - subword = w[s:e] if s == s0 else "##" + w[s:e] - if subword in vocab: - tokens.append(vocab[subword]) - s, e = e, e0 - else: - e -= 1 - if s < e0: - tokens = [vocab['[UNK]']] - res.extend(tokens) - return res - -#split big text into words by spaces -#iteratively return words -def split_to_words(text): - prev_is_sep = True # mark initial prev as space to start word from 0 char - for i, c in enumerate(text + " "): - is_punc = (c in string.punctuation or unicodedata.category(c)[0] == "P") - cur_is_sep = (c.isspace() or is_punc) - if prev_is_sep != cur_is_sep: - if prev_is_sep: - start = i - else: - yield start, i - del start - if is_punc: - yield i, i+1 - prev_is_sep = cur_is_sep - -# get big text and return list of token id and start-end positions for each id in original texts -def text_to_tokens(text, vocab): - tokens_id = [] - tokens_se = [] - for s, e in split_to_words(text): - for tok in encode_by_voc(text[s:e], vocab): - tokens_id.append(tok) - tokens_se.append((s, e)) - - return tokens_id, tokens_se diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/types.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/types.py deleted file mode 100644 index 79177461..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/types.py +++ /dev/null @@ -1,154 +0,0 @@ -""" - Copyright (C) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -class ConfigurableValueError(ValueError): - def __init__(self, message, prefix=None): - self.message = f'{prefix}: {message}' if prefix else message - super().__init__(self.message) - - -class BaseValue: - def __init__(self, description="No description available", default_value=None) -> None: - self.default_value = default_value - self.description = description - - def update_default_value(self, default_value): - self.default_value = default_value - - def validate(self, value): - return [] - - def get_value(self, value): - errors = self.validate(value) - if len(errors) == 0: - return value if value is not None else self.default_value - - def build_error(): - pass - - def __str__(self) -> str: - info = self.description - if self.default_value: - info += f"\nThe default value is '{self.default_value}'" - return info - - -class NumericalValue(BaseValue): - def __init__(self, value_type=float, choices=(), min=None, max=None, **kwargs) -> None: - super().__init__(**kwargs) - self.choices = choices - self.min = min - self.max = max - self.value_type = value_type - - def validate(self, value): - errors = super().validate(value) - if not value: - return errors - if not isinstance(value, self.value_type): - errors.append(ConfigurableValueError(f'Incorrect value type {type(value)}: should be {self.value_type}')) - return errors - if len(self.choices): - if value not in self.choices: - errors.append(ConfigurableValueError(f'Incorrect value {value}: out of allowable list - {self.choices}')) - if self.min is not None and value < self.min: - errors.append(ConfigurableValueError(f'Incorrect value {value}: less than minimum allowable {self.min}')) - if self.max is not None and value > self.max: - errors.append(ConfigurableValueError(f'Incorrect value {value}: bigger than maximum allowable {self.min}')) - return errors - - def __str__(self) -> str: - info = super().__str__() - info += f"\nAppropriate type is {self.value_type}" - if self.choices: - info += f"\nAppropriate values are {self.choices}" - return info - -class StringValue(BaseValue): - def __init__(self, choices=(), **kwargs): - super().__init__(**kwargs) - self.choices = choices - for choice in self.choices: - if not isinstance(choice, str): - raise ValueError("Incorrect option in choice list - {}.". format(choice)) - - def validate(self, value): - errors = super().validate(value) - if not value: - return errors - if not isinstance(value, str): - errors.append(ConfigurableValueError(f'Incorrect value type {type(value)}: should be "str"')) - if len(self.choices)>0 and value not in self.choices: - errors.append(ConfigurableValueError(f'Incorrect value {value}: out of allowable list - {self.choices}')) - return errors - - def __str__(self) -> str: - info = super().__str__() - info += "\nAppropriate type is str" - if self.choices: - info += f"\nAppropriate values are {self.choices}" - - return info - - -class BooleanValue(BaseValue): - def __init__(self, **kwargs) -> None: - super().__init__(**kwargs) - - def validate(self, value): - errors = super().validate(value) - if not value: - return errors - if not isinstance(value, bool): - errors.append(ConfigurableValueError(f'Incorrect value type - {type(value)}: should be "bool"')) - return errors - - -class ListValue(BaseValue): - def __init__(self, value_type=None, **kwargs) -> None: - super().__init__(**kwargs) - self.value_type = value_type - - def validate(self, value): - errors = super().validate(value) - if not value: - return errors - if not isinstance(value, (tuple, list)): - errors.append(ConfigurableValueError(f'Incorrect value type - {type(value)}: should be list or tuple')) - if self.value_type: - if isinstance(self.value_type, BaseValue): - for i, element in enumerate(value): - temp_errors = self.value_type.validate(element) - if len(temp_errors) > 0: - errors.extend([ConfigurableValueError(f'Incorrect #{i} element of the list'), *temp_errors]) - else: - for i, element in enumerate(value): - if not isinstance(element, self.value_type): - errors.append(ConfigurableValueError(f'Incorrect #{i} element type - {type(element)}: should be {self.value_type}')) - return errors - - -class DictValue(BaseValue): - def __init__(self, **kwargs) -> None: - super().__init__(**kwargs) - - def validate(self, value): - errors = super().validate(value) - if not value: - return errors - if not isinstance(value, dict): - errors.append(ConfigurableValueError(f'Incorrect value type - {type(value)}: should be "dict"')) - return errors diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/ultra_lightweight_face_detection.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/ultra_lightweight_face_detection.py deleted file mode 100644 index 8ce4f0a7..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/ultra_lightweight_face_detection.py +++ /dev/null @@ -1,76 +0,0 @@ -""" - Copyright (c) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" -import numpy as np - -from .detection_model import DetectionModel -from .types import NumericalValue -from .utils import Detection, nms - - -class UltraLightweightFaceDetection(DetectionModel): - __model__ = 'Ultra_LightWeight_Face_Detection' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number(1, 2) - self.labels = ['Face'] - self.bboxes_blob_name, self.scores_blob_name = self._get_outputs() - - def _get_outputs(self): - (bboxes_blob_name, bboxes_layer), (scores_blob_name, scores_layer) = self.outputs.items() - - if bboxes_layer.shape[1] != scores_layer.shape[1]: - self.raise_error("Expected the same second dimension for boxes and scores, but got {} and {}".format( - bboxes_layer.shape, scores_layer.shape)) - - if bboxes_layer.shape[2] == 4: - return bboxes_blob_name, scores_blob_name - elif scores_layer.shape[2] == 4: - return scores_blob_name, bboxes_blob_name - else: - self.raise_error("Expected shape [:,:,4] for bboxes output, but got {} and {}".format( - bboxes_layer.shape, scores_layer.shape)) - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'iou_threshold': NumericalValue(default_value=0.5, description="Threshold for NMS filtering"), - }) - parameters['resize_type'].update_default_value('standard') - parameters['confidence_threshold'].update_default_value(0.5) - parameters['labels'].update_default_value(['Face']) - return parameters - - def postprocess(self, outputs, meta): - detections = self._parse_outputs(outputs, meta) - detections = self._resize_detections(detections, meta) - return detections - - def _parse_outputs(self, outputs, meta): - boxes = outputs[self.bboxes_blob_name][0] - scores = outputs[self.scores_blob_name][0] - - score = np.transpose(scores)[1] - - mask = score > self.confidence_threshold - filtered_boxes, filtered_score = boxes[mask, :], score[mask] - - x_mins, y_mins, x_maxs, y_maxs = filtered_boxes.T - - keep = nms(x_mins, y_mins, x_maxs, y_maxs, filtered_score, self.iou_threshold) - - return [Detection(*det, 0) for det in zip(x_mins[keep], y_mins[keep], x_maxs[keep], y_maxs[keep], filtered_score[keep])] diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/utils.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/utils.py deleted file mode 100644 index 3bd2fed0..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/utils.py +++ /dev/null @@ -1,213 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import cv2 -import numpy as np -import math - - -class Detection: - def __init__(self, xmin, ymin, xmax, ymax, score, id): - self.xmin = xmin - self.ymin = ymin - self.xmax = xmax - self.ymax = ymax - self.score = score - self.id = id - - def bottom_left_point(self): - return self.xmin, self.ymin - - def top_right_point(self): - return self.xmax, self.ymax - - def get_coords(self): - return self.xmin, self.ymin, self.xmax, self.ymax - - -def clip_detections(detections, size): - for detection in detections: - detection.xmin = max(int(detection.xmin), 0) - detection.ymin = max(int(detection.ymin), 0) - detection.xmax = min(int(detection.xmax), size[1]) - detection.ymax = min(int(detection.ymax), size[0]) - return detections - - -class DetectionWithLandmarks(Detection): - def __init__(self, xmin, ymin, xmax, ymax, score, id, landmarks_x, landmarks_y): - super().__init__(xmin, ymin, xmax, ymax, score, id) - self.landmarks = [] - for x, y in zip(landmarks_x, landmarks_y): - self.landmarks.append((x, y)) - - -class OutputTransform: - def __init__(self, input_size, output_resolution): - self.output_resolution = output_resolution - if self.output_resolution: - self.new_resolution = self.compute_resolution(input_size) - - def compute_resolution(self, input_size): - self.input_size = input_size - size = self.input_size[::-1] - self.scale_factor = min(self.output_resolution[0] / size[0], - self.output_resolution[1] / size[1]) - return self.scale(size) - - def resize(self, image): - if not self.output_resolution: - return image - curr_size = image.shape[:2] - if curr_size != self.input_size: - self.new_resolution = self.compute_resolution(curr_size) - if self.scale_factor == 1: - return image - return cv2.resize(image, self.new_resolution) - - def scale(self, inputs): - if not self.output_resolution or self.scale_factor == 1: - return inputs - return (np.array(inputs) * self.scale_factor).astype(np.int32) - - -class InputTransform: - def __init__(self, reverse_input_channels=False, mean_values=None, scale_values=None): - self.reverse_input_channels = reverse_input_channels - self.is_trivial = not (reverse_input_channels or mean_values or scale_values) - self.means = np.array(mean_values, dtype=np.float32) if mean_values else np.array([0., 0., 0.]) - self.std_scales = np.array(scale_values, dtype=np.float32) if scale_values else np.array([1., 1., 1.]) - - def __call__(self, inputs): - if self.is_trivial: - return inputs - if self.reverse_input_channels: - inputs = cv2.cvtColor(inputs, cv2.COLOR_BGR2RGB) - return (inputs - self.means) / self.std_scales - - -def load_labels(label_file): - with open(label_file, 'r') as f: - labels_map = [x.strip() for x in f] - return labels_map - - -def resize_image(image, size, keep_aspect_ratio=False, interpolation=cv2.INTER_LINEAR): - if not keep_aspect_ratio: - resized_frame = cv2.resize(image, size, interpolation=interpolation) - else: - h, w = image.shape[:2] - scale = min(size[1] / h, size[0] / w) - resized_frame = cv2.resize(image, None, fx=scale, fy=scale, interpolation=interpolation) - return resized_frame - - -def resize_image_with_aspect(image, size, interpolation=cv2.INTER_LINEAR): - return resize_image(image, size, keep_aspect_ratio=True, interpolation=interpolation) - - -def pad_image(image, size): - h, w = image.shape[:2] - if h != size[1] or w != size[0]: - image = np.pad(image, ((0, size[1] - h), (0, size[0] - w), (0, 0)), - mode='constant', constant_values=0) - return image - - -def resize_image_letterbox(image, size, interpolation=cv2.INTER_LINEAR): - ih, iw = image.shape[0:2] - w, h = size - scale = min(w / iw, h / ih) - nw = int(iw * scale) - nh = int(ih * scale) - image = cv2.resize(image, (nw, nh), interpolation=interpolation) - dx = (w - nw) // 2 - dy = (h - nh) // 2 - resized_image = np.pad(image, ((dy, dy + (h - nh) % 2), (dx, dx + (w - nw) % 2), (0, 0)), - mode='constant', constant_values=0) - return resized_image - - -def crop_resize(image, size): - desired_aspect_ratio = size[1] / size[0] # width / height - if desired_aspect_ratio == 1: - if (image.shape[0] > image.shape[1]): - offset = (image.shape[0] - image.shape[1]) // 2 - cropped_frame = image[offset:image.shape[1] + offset] - else: - offset = (image.shape[1] - image.shape[0]) // 2 - cropped_frame = image[:, offset:image.shape[0] + offset] - elif desired_aspect_ratio < 1: - new_width = math.floor(image.shape[0] * desired_aspect_ratio) - offset = (image.shape[1] - new_width) // 2 - cropped_frame = image[:, offset:new_width + offset] - elif desired_aspect_ratio > 1: - new_height = math.floor(image.shape[1] / desired_aspect_ratio) - offset = (image.shape[0] - new_height) // 2 - cropped_frame = image[offset:new_height + offset] - - return cv2.resize(cropped_frame, size) - - -RESIZE_TYPES = { - 'crop' : crop_resize, - 'standard': resize_image, - 'fit_to_window': resize_image_with_aspect, - 'fit_to_window_letterbox': resize_image_letterbox, -} - - -INTERPOLATION_TYPES = { - 'LINEAR': cv2.INTER_LINEAR, - 'CUBIC': cv2.INTER_CUBIC, - 'NEAREST': cv2.INTER_NEAREST, - 'AREA': cv2.INTER_AREA, -} - - -def nms(x1, y1, x2, y2, scores, thresh, include_boundaries=False, keep_top_k=None): - b = 1 if include_boundaries else 0 - areas = (x2 - x1 + b) * (y2 - y1 + b) - order = scores.argsort()[::-1] - - if keep_top_k: - order = order[:keep_top_k] - - keep = [] - while order.size > 0: - i = order[0] - keep.append(i) - - xx1 = np.maximum(x1[i], x1[order[1:]]) - yy1 = np.maximum(y1[i], y1[order[1:]]) - xx2 = np.minimum(x2[i], x2[order[1:]]) - yy2 = np.minimum(y2[i], y2[order[1:]]) - - w = np.maximum(0.0, xx2 - xx1 + b) - h = np.maximum(0.0, yy2 - yy1 + b) - intersection = w * h - - union = (areas[i] + areas[order[1:]] - intersection) - overlap = np.divide(intersection, union, out=np.zeros_like(intersection, dtype=float), where=union != 0) - - order = order[np.where(overlap <= thresh)[0] + 1] - - return keep - - -def softmax(logits, axis=None, keepdims=False): - exp = np.exp(logits - np.max(logits)) - return exp / np.sum(exp, axis=axis, keepdims=keepdims) diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/yolo.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/yolo.py deleted file mode 100644 index 3187d70e..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/models/yolo.py +++ /dev/null @@ -1,519 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from collections import namedtuple -import numpy as np - -from .detection_model import DetectionModel -from .types import ListValue, NumericalValue -from .utils import Detection, clip_detections, nms, resize_image, INTERPOLATION_TYPES - -DetectionBox = namedtuple('DetectionBox', ["x", "y", "w", "h"]) - -ANCHORS = { - 'YOLOV3': [10.0, 13.0, 16.0, 30.0, 33.0, 23.0, - 30.0, 61.0, 62.0, 45.0, 59.0, 119.0, - 116.0, 90.0, 156.0, 198.0, 373.0, 326.0], - 'YOLOV4': [12.0, 16.0, 19.0, 36.0, 40.0, 28.0, - 36.0, 75.0, 76.0, 55.0, 72.0, 146.0, - 142.0, 110.0, 192.0, 243.0, 459.0, 401.0], - 'YOLOV4-TINY': [10.0, 14.0, 23.0, 27.0, 37.0, 58.0, - 81.0, 82.0, 135.0, 169.0, 344.0, 319.0], - 'YOLOF' : [16.0, 16.0, 32.0, 32.0, 64.0, 64.0, - 128.0, 128.0, 256.0, 256.0, 512.0, 512.0] -} - -def permute_to_N_HWA_K(tensor, K, output_layout): - """ - Transpose/reshape a tensor from (N, (A x K), H, W) to (N, (HxWxA), K) - """ - assert tensor.ndim == 4, tensor.shape - if output_layout == 'NHWC': - tensor = tensor.transpose(0, 3, 1, 2) - N, _, H, W = tensor.shape - tensor = tensor.reshape(N, -1, K, H, W) - tensor = tensor.transpose(0, 3, 4, 1, 2) - tensor = tensor.reshape(N, -1, K) - return tensor - -def sigmoid(x): - return 1. / (1. + np.exp(-x)) - - -class YOLO(DetectionModel): - __model__ = 'YOLO' - - class Params: - # Magic numbers are copied from yolo samples - def __init__(self, param, sides): - self.num = param.get('num', 3) - self.coords = param.get('coord', 4) - self.classes = param.get('classes', 80) - self.bbox_size = self.coords + self.classes + 1 - self.sides = sides - self.anchors = param.get('anchors', ANCHORS['YOLOV3']) - - self.use_input_size = False - self.output_layout = 'NCHW' - - mask = param.get('mask', None) - if mask: - self.num = len(mask) - - masked_anchors = [] - for idx in mask: - masked_anchors += [self.anchors[idx * 2], self.anchors[idx * 2 + 1]] - self.anchors = masked_anchors - - self.use_input_size = True # Weak way to determine but the only one. - - def __init__(self, model_adapter, configuration, preload=False): - super().__init__(model_adapter, configuration, preload) - self.is_tiny = len(self.outputs) == 2 # Weak way to distinguish between YOLOv4 and YOLOv4-tiny - - self._check_io_number(1, -1) - - self.yolo_layer_params = self._get_output_info() - - def _get_output_info(self): - output_info = {} - yolo_regions = self.model_adapter.operations_by_type('RegionYolo') - for name, info in self.outputs.items(): - shape = info.shape - if len(shape) == 2: - # we use 32x32 cell as default, cause 1D tensor is V2 specific - cx = self.w // 32 - cy = self.h // 32 - - bboxes = shape[1] // (cx*cy) - if self.w % 32 != 0 or self.h % 32 != 0 or shape[1] % (cx*cy) != 0: - self.raise_error('The cannot reshape 2D output tensor into 4D') - shape = (shape[0], bboxes, cy, cx) - meta = info.meta - if info.type != 'RegionYolo' and yolo_regions: - for region_name in yolo_regions: - if region_name in name: - meta = yolo_regions[region_name].meta - params = self.Params(meta, shape[2:4]) - output_info[name] = (shape, params) - return output_info - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'iou_threshold': NumericalValue(default_value=0.5, description="Threshold for NMS filtering"), - }) - parameters['resize_type'].update_default_value('fit_to_window_letterbox') - parameters['confidence_threshold'].update_default_value(0.5) - return parameters - - def postprocess(self, outputs, meta): - detections = self._parse_outputs(outputs, meta) - detections = self._resize_detections(detections, meta) - return detections - - def _parse_yolo_region(self, predictions, input_size, params): - # ------------------------------------------ Extracting layer parameters --------------------------------------- - objects = [] - size_normalizer = input_size if params.use_input_size else params.sides - predictions = permute_to_N_HWA_K(predictions, params.bbox_size, params.output_layout) - # ------------------------------------------- Parsing YOLO Region output --------------------------------------- - for prediction in predictions: - # Getting probabilities from raw outputs - class_probabilities = self._get_probabilities(prediction, params.classes) - - # filter out the proposals with low confidence score - keep_idxs = np.nonzero(class_probabilities > self.confidence_threshold)[0] - class_probabilities = class_probabilities[keep_idxs] - obj_indx = keep_idxs // params.classes - class_idx = keep_idxs % params.classes - - for ind, obj_ind in enumerate(obj_indx): - row, col, n = self._get_location(obj_ind, params.sides[1], params.num) - - # Process raw value to get absolute coordinates of boxes - raw_box = self._get_raw_box(prediction, obj_ind) - predicted_box = self._get_absolute_det_box(raw_box, row, col, params.anchors[2 * n:2 * n + 2], - params.sides, size_normalizer) - - # Define class_label and cofidence - label = class_idx[ind] - confidence = class_probabilities[ind] - objects.append(Detection(predicted_box.x - predicted_box.w / 2, - predicted_box.y - predicted_box.h / 2, - predicted_box.x + predicted_box.w / 2, - predicted_box.y + predicted_box.h / 2, - confidence.item(), label.item())) - - return objects - - @staticmethod - def _get_probabilities(prediction, classes): - object_probabilities = prediction[:, 4].flatten() - class_probabilities = prediction[:, 5:].flatten() - class_probabilities *= np.repeat(object_probabilities, classes) - return class_probabilities - - @staticmethod - def _get_location(obj_ind, cells, num): - row = obj_ind // (cells * num) - col = (obj_ind - row * cells * num) // num - n = (obj_ind - row * cells * num) % num - return row, col, n - - @staticmethod - def _get_raw_box(prediction, obj_ind): - return DetectionBox(*prediction[obj_ind, :4]) - - @staticmethod - def _get_absolute_det_box(box, row, col, anchors, coord_normalizer, size_normalizer): - x = (col + box.x) / coord_normalizer[1] - y = (row + box.y) / coord_normalizer[0] - width = np.exp(box.w) * anchors[0] / size_normalizer[1] - height = np.exp(box.h) * anchors[1] / size_normalizer[0] - - return DetectionBox(x, y, width, height) - - @staticmethod - def _filter(detections, iou_threshold): - def iou(box_1, box_2): - width_of_overlap_area = min(box_1.xmax, box_2.xmax) - max(box_1.xmin, box_2.xmin) - height_of_overlap_area = min(box_1.ymax, box_2.ymax) - max(box_1.ymin, box_2.ymin) - if width_of_overlap_area < 0 or height_of_overlap_area < 0: - area_of_overlap = 0 - else: - area_of_overlap = width_of_overlap_area * height_of_overlap_area - box_1_area = (box_1.ymax - box_1.ymin) * (box_1.xmax - box_1.xmin) - box_2_area = (box_2.ymax - box_2.ymin) * (box_2.xmax - box_2.xmin) - area_of_union = box_1_area + box_2_area - area_of_overlap - if area_of_union == 0: - return 0 - return area_of_overlap / area_of_union - - detections = sorted(detections, key=lambda obj: obj.score, reverse=True) - for i in range(len(detections)): - if detections[i].score == 0: - continue - for j in range(i + 1, len(detections)): - # We perform IOU only on objects of same class - if detections[i].id != detections[j].id: - continue - - if iou(detections[i], detections[j]) > iou_threshold: - detections[j].score = 0 - - return [det for det in detections if det.score > 0] - - def _parse_outputs(self, outputs, meta): - detections = [] - for layer_name in self.yolo_layer_params.keys(): - out_blob = outputs[layer_name] - layer_params = self.yolo_layer_params[layer_name] - out_blob.shape = layer_params[0] - detections += self._parse_yolo_region(out_blob, meta['resized_shape'], layer_params[1]) - - detections = self._filter(detections, self.iou_threshold) - return detections - - -class YoloV4(YOLO): - __model__ = 'YOLOV4' - - class Params: - def __init__(self, classes, num, sides, anchors, mask, layout): - self.num = num - self.coords = 4 - self.classes = classes - self.bbox_size = self.coords + self.classes + 1 - self.sides = sides - self.output_layout = layout - masked_anchors = [] - for idx in mask: - masked_anchors += [anchors[idx * 2], anchors[idx * 2 + 1]] - self.anchors = masked_anchors - self.use_input_size = True - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - - def _get_output_info(self): - if not self.anchors: - self.anchors = ANCHORS['YOLOV4-TINY'] if self.is_tiny else ANCHORS['YOLOV4'] - if not self.masks: - self.masks = [1, 2, 3, 3, 4, 5] if self.is_tiny else [0, 1, 2, 3, 4, 5, 6, 7, 8] - - outputs = sorted(self.outputs.items(), key=lambda x: x[1].shape[2], reverse=True) - - output_info = {} - num = 3 - for i, (name, layer) in enumerate(outputs): - shape = layer.shape - if shape[2] == shape[3]: - channels, sides, layout = shape[1], shape[2:4], 'NCHW' - else: - channels, sides, layout = shape[3], shape[1:3], 'NHWC' - classes = channels // num - 5 - if channels % num != 0: - self.raise_error("The output blob {} has wrong 2nd dimension".format(name)) - yolo_params = self.Params(classes, num, sides, self.anchors, self.masks[i*num : (i+1)*num], layout) - output_info[name] = (shape, yolo_params) - return output_info - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'anchors': ListValue(description="List of custom anchor values"), - 'masks': ListValue(description="List of mask, applied to anchors for each output layer"), - }) - return parameters - - @staticmethod - def _get_probabilities(prediction, classes): - object_probabilities = sigmoid(prediction[:, 4].flatten()) - class_probabilities = sigmoid(prediction[:, 5:].flatten()) - class_probabilities *= np.repeat(object_probabilities, classes) - return class_probabilities - - @staticmethod - def _get_raw_box(prediction, obj_ind): - bbox = prediction[obj_ind, :4] - x, y = sigmoid(bbox[:2]) - width, height = bbox[2:] - return DetectionBox(x, y, width, height) - - -class YOLOF(YOLO): - __model__ = 'YOLOF' - - class Params: - def __init__(self, classes, num, sides, anchors): - self.num = num - self.coords = 4 - self.classes = classes - self.bbox_size = self.coords + self.classes - self.sides = sides - self.anchors = anchors - self.output_layout = 'NCHW' - self.use_input_size = True - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - - def _get_output_info(self): - anchors = ANCHORS['YOLOF'] - - output_info = {} - num = 6 - for name, layer in self.outputs.items(): - shape = layer.shape - classes = shape[1] // num - 4 - yolo_params = self.Params(classes, num, shape[2:4], anchors) - output_info[name] = (shape, yolo_params) - return output_info - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters['resize_type'].update_default_value('standard') - return parameters - - @staticmethod - def _get_probabilities(prediction, classes): - return sigmoid(prediction[:, 4:].flatten()) - - @staticmethod - def _get_absolute_det_box(box, row, col, anchors, coord_normalizer, size_normalizer): - anchor_x = anchors[0] / size_normalizer[0] - anchor_y = anchors[1] / size_normalizer[1] - x = box.x * anchor_x + col / coord_normalizer[1] - y = box.y * anchor_y + row / coord_normalizer[0] - width = np.exp(box.w) * anchor_x - height = np.exp(box.h) * anchor_y - - return DetectionBox(x, y, width, height) - - -class YOLOX(DetectionModel): - __model__ = 'YOLOX' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self._check_io_number(1, 1) - self.output_blob_name = next(iter(self.outputs)) - - self.expanded_strides = [] - self.grids = [] - self.set_strides_grids() - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters.update({ - 'iou_threshold': NumericalValue(default_value=0.65, description="Threshold for NMS filtering"), - }) - parameters['confidence_threshold'].update_default_value(0.5) - return parameters - - def preprocess(self, inputs): - image = inputs - resized_image = resize_image(image, (self.w, self.h), keep_aspect_ratio=True) - - padded_image = np.ones((self.h, self.w, 3), dtype=np.uint8) * 114 - padded_image[: resized_image.shape[0], : resized_image.shape[1]] = resized_image - - meta = {'original_shape': image.shape, - 'scale': min(self.w / image.shape[1], self.h / image.shape[0])} - - preprocessed_image = self.input_transform(padded_image) - preprocessed_image = preprocessed_image.transpose((2, 0, 1)) # Change data layout from HWC to CHW - preprocessed_image = preprocessed_image.reshape((self.n, self.c, self.h, self.w)) - - dict_inputs = {self.image_blob_name: preprocessed_image} - return dict_inputs, meta - - def postprocess(self, outputs, meta): - output = outputs[self.output_blob_name][0] - - if np.size(self.expanded_strides) != 0 and np.size(self.grids) != 0: - output[..., :2] = (output[..., :2] + self.grids) * self.expanded_strides - output[..., 2:4] = np.exp(output[..., 2:4]) * self.expanded_strides - - valid_predictions = output[output[..., 4] > self.confidence_threshold] - valid_predictions[:, 5:] *= valid_predictions[:, 4:5] - - boxes = self.xywh2xyxy(valid_predictions[:, :4]) / meta['scale'] - i, j = (valid_predictions[:, 5:] > self.confidence_threshold).nonzero() - x_mins, y_mins, x_maxs, y_maxs = boxes[i].T - scores = valid_predictions[i, j + 5] - - keep_nms = nms(x_mins, y_mins, x_maxs, y_maxs, scores, self.iou_threshold, include_boundaries=True) - - detections = [Detection(*det) for det in zip(x_mins[keep_nms], y_mins[keep_nms], x_maxs[keep_nms], - y_maxs[keep_nms], scores[keep_nms], j[keep_nms])] - return clip_detections(detections, meta['original_shape']) - - def set_strides_grids(self): - grids = [] - expanded_strides = [] - - strides = [8, 16, 32] - - hsizes = [self.h // stride for stride in strides] - wsizes = [self.w // stride for stride in strides] - - for hsize, wsize, stride in zip(hsizes, wsizes, strides): - xv, yv = np.meshgrid(np.arange(wsize), np.arange(hsize)) - grid = np.stack((xv, yv), 2).reshape(1, -1, 2) - grids.append(grid) - shape = grid.shape[:2] - expanded_strides.append(np.full((*shape, 1), stride)) - - self.grids = np.concatenate(grids, 1) - self.expanded_strides = np.concatenate(expanded_strides, 1) - - @staticmethod - def xywh2xyxy(x): - y = np.copy(x) - y[:, 0] = x[:, 0] - x[:, 2] / 2 - y[:, 1] = x[:, 1] - x[:, 3] / 2 - y[:, 2] = x[:, 0] + x[:, 2] / 2 - y[:, 3] = x[:, 1] + x[:, 3] / 2 - return y - - -class YoloV3ONNX(DetectionModel): - __model__ = 'YOLOv3-ONNX' - - def __init__(self, model_adapter, configuration=None, preload=False): - super().__init__(model_adapter, configuration, preload) - self.image_info_blob_name = self.image_info_blob_names[0] if len(self.image_info_blob_names) == 1 else None - self._check_io_number(2, 3) - self.classes = 80 - self.bboxes_blob_name, self.scores_blob_name, self.indices_blob_name = self._get_outputs() - - def _get_outputs(self): - bboxes_blob_name = None - scores_blob_name = None - indices_blob_name = None - for name, layer in self.outputs.items(): - if layer.shape[-1] == 3: - indices_blob_name = name - elif layer.shape[2] == 4: - bboxes_blob_name = name - elif layer.shape[1] == self.classes: - scores_blob_name = name - else: - self.raise_error("Expected shapes [:,:,4], [:,{},:] and [:,3] for outputs, but got {}, {} and {}" - .format(self.classes, *[output.shape for output in self.outputs.values()])) - if self.outputs[bboxes_blob_name].shape[1] != self.outputs[scores_blob_name].shape[2]: - self.raise_error("Expected the same dimension for boxes and scores, but got {} and {}".format( - self.outputs[bboxes_blob_name].shape[1], self.outputs[scores_blob_name].shape[2])) - return bboxes_blob_name, scores_blob_name, indices_blob_name - - @classmethod - def parameters(cls): - parameters = super().parameters() - parameters['resize_type'].update_default_value('fit_to_window_letterbox') - parameters['confidence_threshold'].update_default_value(0.5) - return parameters - - def preprocess(self, inputs): - image = inputs - meta = {'original_shape': image.shape} - resized_image = self.resize(image, (self.w, self.h), interpolation=INTERPOLATION_TYPES['CUBIC']) - meta.update({'resized_shape': resized_image.shape}) - resized_image = self._change_layout(resized_image) - dict_inputs = { - self.image_blob_name: resized_image, - self.image_info_blob_name: np.array([[image.shape[0], image.shape[1]]], dtype=np.float32) - } - return dict_inputs, meta - - def postprocess(self, outputs, meta): - detections = self._parse_outputs(outputs) - detections = clip_detections(detections, meta['original_shape']) - return detections - - def _parse_outputs(self, outputs): - boxes = outputs[self.bboxes_blob_name][0] - scores = outputs[self.scores_blob_name][0] - indices = outputs[self.indices_blob_name] if len( - outputs[self.indices_blob_name].shape) == 2 else outputs[self.indices_blob_name][0] - - out_boxes, out_scores, out_classes = [], [], [] - for idx_ in indices: - if idx_[0] == -1: - break - out_classes.append(idx_[1]) - out_scores.append(scores[tuple(idx_[1:])]) - out_boxes.append(boxes[idx_[2]]) - transposed_boxes = np.array(out_boxes).T if out_boxes else ([], [], [], []) - mask = np.array(out_scores) > self.confidence_threshold - - if mask.size == 0: - return [] - - out_classes, out_scores, transposed_boxes = (np.array(out_classes)[mask], np.array(out_scores)[mask], - transposed_boxes[:, mask]) - - x_mins = transposed_boxes[1] - y_mins = transposed_boxes[0] - x_maxs = transposed_boxes[3] - y_maxs = transposed_boxes[2] - - detections = [Detection(*det) for det in zip(x_mins, y_mins, x_maxs, - y_maxs, out_scores, out_classes)] - - return detections diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/performance_metrics.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/performance_metrics.py deleted file mode 100644 index b6b9add6..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/performance_metrics.py +++ /dev/null @@ -1,102 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import logging as log -from time import perf_counter - -import cv2 - - -def put_highlighted_text(frame, message, position, font_face, font_scale, color, thickness): - cv2.putText(frame, message, position, font_face, font_scale, (255, 255, 255), thickness + 1) # white border - cv2.putText(frame, message, position, font_face, font_scale, color, thickness) - - -class Statistic: - def __init__(self): - self.latency = 0.0 - self.period = 0.0 - self.frame_count = 0 - - def combine(self, other): - self.latency += other.latency - self.period += other.period - self.frame_count += other.frame_count - - -class PerformanceMetrics: - def __init__(self, time_window=1.0): - # 'time_window' defines the length of the timespan over which the 'current fps' value is calculated - self.time_window_size = time_window - self.last_moving_statistic = Statistic() - self.current_moving_statistic = Statistic() - self.total_statistic = Statistic() - self.last_update_time = None - - def update(self, last_request_start_time, frame=None): - current_time = perf_counter() - - if self.last_update_time is None: - self.last_update_time = last_request_start_time - - self.current_moving_statistic.latency += current_time - last_request_start_time - self.current_moving_statistic.period = current_time - self.last_update_time - self.current_moving_statistic.frame_count += 1 - - if current_time - self.last_update_time > self.time_window_size: - self.last_moving_statistic = self.current_moving_statistic - self.total_statistic.combine(self.last_moving_statistic) - self.current_moving_statistic = Statistic() - self.last_update_time = current_time - - if frame is not None: - self.paint_metrics(frame) - - def paint_metrics(self, frame, position=(15, 30), font_scale=0.75, color=(200, 10, 10), thickness=2): - # Draw performance stats over frame - current_latency, current_fps = self.get_last() - if current_latency is not None: - put_highlighted_text(frame, "Latency: {:.1f} ms".format(current_latency * 1e3), - position, cv2.FONT_HERSHEY_COMPLEX, font_scale, color, thickness) - if current_fps is not None: - put_highlighted_text(frame, "FPS: {:.1f}".format(current_fps), - (position[0], position[1]+30), cv2.FONT_HERSHEY_COMPLEX, font_scale, color, thickness) - - def get_last(self): - return (self.last_moving_statistic.latency / self.last_moving_statistic.frame_count - if self.last_moving_statistic.frame_count != 0 - else None, - self.last_moving_statistic.frame_count / self.last_moving_statistic.period - if self.last_moving_statistic.period != 0.0 - else None) - - def get_total(self): - frame_count = self.total_statistic.frame_count + self.current_moving_statistic.frame_count - return (((self.total_statistic.latency + self.current_moving_statistic.latency) / frame_count) - if frame_count != 0 - else None, - (frame_count / (self.total_statistic.period + self.current_moving_statistic.period)) - if frame_count != 0 - else None) - - def get_latency(self): - return self.get_total()[0] * 1e3 - - def log_total(self): - total_latency, total_fps = self.get_total() - log.info('Metrics report:') - log.info("\tLatency: {:.1f} ms".format(total_latency * 1e3) if total_latency is not None else "\tLatency: N/A") - log.info("\tFPS: {:.1f}".format(total_fps) if total_fps is not None else "\tFPS: N/A") diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/pipelines/__init__.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/pipelines/__init__.py deleted file mode 100644 index 4716beb2..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/pipelines/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .async_pipeline import AsyncPipeline, get_user_config, parse_devices - -__all__ = [ - 'AsyncPipeline', - 'get_user_config', - 'parse_devices', -] diff --git a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/pipelines/async_pipeline.py b/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/pipelines/async_pipeline.py deleted file mode 100644 index 7b30f503..00000000 --- a/configs/opencv-ovms/demos/common/python/openvino/model_zoo/model_api/pipelines/async_pipeline.py +++ /dev/null @@ -1,136 +0,0 @@ -""" - Copyright (C) 2020-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from time import perf_counter -from typing import Dict, Set - -from ..performance_metrics import PerformanceMetrics - - -def parse_devices(device_string): - colon_position = device_string.find(':') - if colon_position != -1: - device_type = device_string[:colon_position] - if device_type == 'HETERO' or device_type == 'MULTI': - comma_separated_devices = device_string[colon_position + 1:] - devices = comma_separated_devices.split(',') - for device in devices: - parenthesis_position = device.find(':') - if parenthesis_position != -1: - device = device[:parenthesis_position] - return devices - return (device_string,) - - -def parse_value_per_device(devices: Set[str], values_string: str)-> Dict[str, int]: - """Format: :,: or just """ - values_string_upper = values_string.upper() - result = {} - device_value_strings = values_string_upper.split(',') - for device_value_string in device_value_strings: - device_value_list = device_value_string.split(':') - if len(device_value_list) == 2: - if device_value_list[0] in devices: - result[device_value_list[0]] = int(device_value_list[1]) - elif len(device_value_list) == 1 and device_value_list[0] != '': - for device in devices: - result[device] = int(device_value_list[0]) - elif device_value_list[0] != '': - raise RuntimeError(f'Unknown string format: {values_string}') - return result - - -def get_user_config(flags_d: str, flags_nstreams: str, flags_nthreads: int)-> Dict[str, str]: - config = {} - - devices = set(parse_devices(flags_d)) - - device_nstreams = parse_value_per_device(devices, flags_nstreams) - for device in devices: - if device == 'CPU': # CPU supports a few special performance-oriented keys - # limit threading for CPU portion of inference - if flags_nthreads: - config['CPU_THREADS_NUM'] = str(flags_nthreads) - - config['CPU_BIND_THREAD'] = 'NO' - - # for CPU execution, more throughput-oriented execution via streams - config['CPU_THROUGHPUT_STREAMS'] = str(device_nstreams[device]) \ - if device in device_nstreams else 'CPU_THROUGHPUT_AUTO' - elif device == 'GPU': - config['GPU_THROUGHPUT_STREAMS'] = str(device_nstreams[device]) \ - if device in device_nstreams else 'GPU_THROUGHPUT_AUTO' - if 'MULTI' in flags_d and 'CPU' in devices: - # multi-device execution with the CPU + GPU performs best with GPU throttling hint, - # which releases another CPU thread (that is otherwise used by the GPU driver for active polling) - config['GPU_PLUGIN_THROTTLE'] = '1' - return config - - -class AsyncPipeline: - def __init__(self, model): - self.model = model - self.model.load() - - self.completed_results = {} - self.callback_exceptions = [] - self.model.model_adapter.set_callback(self.callback) - - self.preprocess_metrics = PerformanceMetrics() - self.inference_metrics = PerformanceMetrics() - self.postprocess_metrics = PerformanceMetrics() - - def callback(self, request, callback_args): - try: - get_result_fn, (id, meta, preprocessing_meta, start_time) = callback_args - self.completed_results[id] = (get_result_fn(request), meta, preprocessing_meta, start_time) - except Exception as e: - self.callback_exceptions.append(e) - - def submit_data(self, inputs, id, meta={}): - preprocessing_start_time = perf_counter() - inputs, preprocessing_meta = self.model.preprocess(inputs) - self.preprocess_metrics.update(preprocessing_start_time) - - infer_start_time = perf_counter() - callback_data = id, meta, preprocessing_meta, infer_start_time - self.model.infer_async(inputs, callback_data) - - def get_raw_result(self, id): - if id in self.completed_results: - return self.completed_results.pop(id) - return None - - def get_result(self, id): - result = self.get_raw_result(id) - if result: - raw_result, meta, preprocess_meta, infer_start_time = result - self.inference_metrics.update(infer_start_time) - - postprocessing_start_time = perf_counter() - result = self.model.postprocess(raw_result, preprocess_meta), {**meta, **preprocess_meta} - self.postprocess_metrics.update(postprocessing_start_time) - return result - return None - - def is_ready(self): - return self.model.is_ready() - - def await_all(self): - self.model.await_all() - - def await_any(self): - self.model.await_any() diff --git a/configs/opencv-ovms/demos/common/python/requirements.txt b/configs/opencv-ovms/demos/common/python/requirements.txt deleted file mode 100644 index 3af44574..00000000 --- a/configs/opencv-ovms/demos/common/python/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -numpy>=1.16.6 -opencv-python -scipy>=1.5.4 diff --git a/configs/opencv-ovms/demos/common/python/requirements_ovms.txt b/configs/opencv-ovms/demos/common/python/requirements_ovms.txt deleted file mode 100644 index a2447ca0..00000000 --- a/configs/opencv-ovms/demos/common/python/requirements_ovms.txt +++ /dev/null @@ -1 +0,0 @@ -ovmsclient diff --git a/configs/opencv-ovms/demos/common/python/setup.py b/configs/opencv-ovms/demos/common/python/setup.py deleted file mode 100755 index 4cc5808b..00000000 --- a/configs/opencv-ovms/demos/common/python/setup.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python3 -""" - Copyright (c) 2021-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -""" -Use this script to create a wheel for Open Model Zoo -model API. The installation of wheel is described in -`/demos/README.md` -""" - -from pathlib import Path -from setuptools import setup, find_packages - - -SETUP_DIR = Path(__file__).resolve().parent - -with open(SETUP_DIR / 'requirements.txt') as f: - required = f.read().splitlines() - -with open(SETUP_DIR / 'requirements_ovms.txt') as f: - ovms_required = f.read().splitlines() - -packages = find_packages(str(SETUP_DIR)) -packages.remove('visualizers') -package_dir = {'openvino': str(SETUP_DIR / 'openvino')} - -setup( - name='openmodelzoo-modelapi', - version='0.0.0', - author='Intel® Corporation', - license='OSI Approved :: Apache Software License', - url='https://github.com/openvinotoolkit/open_model_zoo/tree/develop/demos/common/python/openvino', - description='Model API: model wrappers and pipelines from Open Model Zoo', - python_requires = ">=3.7", - classifiers=[ - 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python :: 3', - ], - packages=packages, - package_dir=package_dir, - install_requires=required, - extras_require={'ovms': ovms_required} -) diff --git a/configs/opencv-ovms/demos/common/python/visualizers/__init__.py b/configs/opencv-ovms/demos/common/python/visualizers/__init__.py deleted file mode 100644 index 112eb548..00000000 --- a/configs/opencv-ovms/demos/common/python/visualizers/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -""" - Copyright (C) 2022-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from .drawing_utils import ColorPalette -from .instance_segmentation import InstanceSegmentationVisualizer - -__all__ = [ - 'ColorPalette', - 'InstanceSegmentationVisualizer', -] diff --git a/configs/opencv-ovms/demos/common/python/visualizers/drawing_utils.py b/configs/opencv-ovms/demos/common/python/visualizers/drawing_utils.py deleted file mode 100644 index e420c3a4..00000000 --- a/configs/opencv-ovms/demos/common/python/visualizers/drawing_utils.py +++ /dev/null @@ -1,61 +0,0 @@ -""" - Copyright (c) 2022-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import random -import colorsys - -import numpy as np - - -class ColorPalette: - def __init__(self, n, rng=None): - if n == 0: - raise ValueError('ColorPalette accepts only the positive number of colors') - if rng is None: - rng = random.Random(0xACE) # nosec - disable B311:random check - - candidates_num = 100 - hsv_colors = [(1.0, 1.0, 1.0)] - for _ in range(1, n): - colors_candidates = [(rng.random(), rng.uniform(0.8, 1.0), rng.uniform(0.5, 1.0)) - for _ in range(candidates_num)] - min_distances = [self.min_distance(hsv_colors, c) for c in colors_candidates] - arg_max = np.argmax(min_distances) - hsv_colors.append(colors_candidates[arg_max]) - - self.palette = [self.hsv2rgb(*hsv) for hsv in hsv_colors] - - @staticmethod - def dist(c1, c2): - dh = min(abs(c1[0] - c2[0]), 1 - abs(c1[0] - c2[0])) * 2 - ds = abs(c1[1] - c2[1]) - dv = abs(c1[2] - c2[2]) - return dh * dh + ds * ds + dv * dv - - @classmethod - def min_distance(cls, colors_set, color_candidate): - distances = [cls.dist(o, color_candidate) for o in colors_set] - return np.min(distances) - - @staticmethod - def hsv2rgb(h, s, v): - return tuple(round(c * 255) for c in colorsys.hsv_to_rgb(h, s, v)) - - def __getitem__(self, n): - return self.palette[n % len(self.palette)] - - def __len__(self): - return len(self.palette) diff --git a/configs/opencv-ovms/demos/common/python/visualizers/instance_segmentation.py b/configs/opencv-ovms/demos/common/python/visualizers/instance_segmentation.py deleted file mode 100644 index d5d4252b..00000000 --- a/configs/opencv-ovms/demos/common/python/visualizers/instance_segmentation.py +++ /dev/null @@ -1,91 +0,0 @@ -""" - Copyright (c) 2022-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import cv2 -import numpy as np - -from .drawing_utils import ColorPalette - - -class InstanceSegmentationVisualizer: - def __init__(self, labels=None, show_boxes=False, show_scores=False): - colors_num = len(labels) if labels else 80 - self.labels = labels - self.palette = ColorPalette(colors_num) - self.show_boxes = show_boxes - self.show_scores = show_scores - - def __call__(self, image, boxes, classes, scores, output_transform, masks=None, ids=None, texts=None): - result = image.copy() - - if masks is not None: - result = self.overlay_masks(result, masks, ids) - if self.show_boxes: - result = self.overlay_boxes(result, output_transform, boxes, classes) - - result = self.overlay_labels(result, output_transform, boxes, classes, scores, texts) - return result - - def overlay_masks(self, image, masks, ids=None): - segments_image = image.copy() - aggregated_mask = np.zeros(image.shape[:2], dtype=np.uint8) - aggregated_colored_mask = np.zeros(image.shape, dtype=np.uint8) - all_contours = [] - - for i, mask in enumerate(masks): - contours = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2] - if contours: - all_contours.append(contours[0]) - - mask_color = self.palette[i if ids is None else ids[i]] - cv2.bitwise_or(aggregated_mask, mask, dst=aggregated_mask) - cv2.bitwise_or(aggregated_colored_mask, mask_color, dst=aggregated_colored_mask, mask=mask) - - # Fill the area occupied by all instances with a colored instances mask image - cv2.bitwise_and(segments_image, (0, 0, 0), dst=segments_image, mask=aggregated_mask) - cv2.bitwise_or(segments_image, aggregated_colored_mask, dst=segments_image, mask=aggregated_mask) - - cv2.addWeighted(image, 0.5, segments_image, 0.5, 0, dst=image) - cv2.drawContours(image, all_contours, -1, (0, 0, 0)) - return image - - def overlay_boxes(self, image, output_transform, boxes, classes): - image = output_transform.resize(image) - for box, class_id in zip(boxes, classes): - color = self.palette[class_id] - box = box.astype(int) - top_left, bottom_right = box[:2], box[2:] - top_left, bottom_right = output_transform.scale([top_left, bottom_right]) - image = cv2.rectangle(image, top_left, bottom_right, color, 2) - return image - - def overlay_labels(self, image, output_transform, boxes, classes, scores, texts=None): - if texts: - labels = texts - elif self.labels: - labels = (self.labels[class_id] for class_id in classes) - else: - raise RuntimeError('InstanceSegmentationVisualizer must contain either labels or texts to display') - template = '{}: {:.2f}' if self.show_scores else '{}' - - for box, score, label in zip(boxes, scores, labels): - text = template.format(label, score) - textsize = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)[0] - top_left, bottom_right = box[:2], box[2:] - top_left, bottom_right = output_transform.scale([top_left, bottom_right]) - position = ((top_left + bottom_right - textsize) / 2).astype(np.int32) - cv2.putText(image, text, position, cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1) - return image diff --git a/configs/opencv-ovms/demos/instance_segmentation/python/Makefile b/configs/opencv-ovms/demos/instance_segmentation/python/Makefile deleted file mode 100644 index 0effed0c..00000000 --- a/configs/opencv-ovms/demos/instance_segmentation/python/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright © 2023 Intel Corporation. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -.PHONY: build - -build: - docker build --tag instance-segmentation:dev . \ No newline at end of file diff --git a/configs/opencv-ovms/demos/instance_segmentation/python/coco_80cl_bkgr.txt b/configs/opencv-ovms/demos/instance_segmentation/python/coco_80cl_bkgr.txt deleted file mode 100644 index 9e369434..00000000 --- a/configs/opencv-ovms/demos/instance_segmentation/python/coco_80cl_bkgr.txt +++ /dev/null @@ -1,81 +0,0 @@ -__background__ -person -bicycle -car -motorcycle -airplane -bus -train -truck -boat -trafficlight -firehydrant -stopsign -parkingmeter -bench -bird -cat -dog -horse -sheep -cow -elephant -bear -zebra -giraffe -backpack -umbrella -handbag -tie -suitcase -frisbee -skis -snowboard -sportsball -kite -baseballbat -baseballglove -skateboard -surfboard -tennisracket -bottle -wineglass -cup -fork -knife -spoon -bowl -banana -apple -sandwich -orange -broccoli -carrot -hotdog -pizza -donut -cake -chair -couch -pottedplant -bed -diningtable -toilet -tv -laptop -mouse -remote -keyboard -cellphone -microwave -oven -toaster -sink -refrigerator -book -clock -vase -scissors -teddybear -hairdrier -toothbrush diff --git a/configs/opencv-ovms/demos/instance_segmentation/python/entrypoint.sh b/configs/opencv-ovms/demos/instance_segmentation/python/entrypoint.sh deleted file mode 100755 index 1c950121..00000000 --- a/configs/opencv-ovms/demos/instance_segmentation/python/entrypoint.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -MQTT="${MQTT:=}" - -if [ "$MQTT" != "" ] -then - mqttArgs="--mqtt ${MQTT}" -fi - -echo "Note: Pipeline log and results are available at location - ./results" - -python3 instance_segmentation/python/instance_segmentation_demo.py -m localhost:"$GRPC_PORT"/models/instance-segmentation-security-1040 \ ---label instance_segmentation/python/coco_80cl_bkgr.txt -i $INPUTSRC \ ---adapter ovms -t 0.85 --show_scores --show_boxes --output_resolution 1280x720 $mqttArgs 2>&1 | tee >/tmp/results/r$cid_count.jsonl >(stdbuf -oL sed -n -e 's/^.*fps: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid_count.log) \ No newline at end of file diff --git a/configs/opencv-ovms/demos/instance_segmentation/python/instance_segmentation_demo.py b/configs/opencv-ovms/demos/instance_segmentation/python/instance_segmentation_demo.py deleted file mode 100644 index 9cdbedbd..00000000 --- a/configs/opencv-ovms/demos/instance_segmentation/python/instance_segmentation_demo.py +++ /dev/null @@ -1,319 +0,0 @@ -#!/usr/bin/env python3 -""" - Copyright (c) 2019-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import logging as log -import sys -from time import perf_counter -from argparse import ArgumentParser -from pathlib import Path -import time - -import cv2 - -from instance_segmentation_demo.tracker import StaticIOUTracker - -import paho.mqtt.client as mqtt -import json - -sys.path.append(str(Path(__file__).resolve().parents[2] / 'common/python')) -sys.path.append(str(Path(__file__).resolve().parents[2] / 'common/python/openvino/model_zoo')) - -from model_api.models import MaskRCNNModel, YolactModel, OutputTransform -from model_api.adapters import create_core, OpenvinoAdapter, OVMSAdapter -from model_api.pipelines import get_user_config, AsyncPipeline -from model_api.performance_metrics import PerformanceMetrics - -import os -import monitors -import subprocess -from images_capture import open_images_capture -from helpers import resolution, log_latency_per_stage -from visualizers import InstanceSegmentationVisualizer - - -log.basicConfig(format='[ %(levelname)s ] %(message)s', level=log.DEBUG, stream=sys.stdout) - -def build_argparser(): - parser = ArgumentParser() - args = parser.add_argument_group('Options') - args.add_argument('-m', '--model', required=True, - help='Required. Path to an .xml file with a trained model ' - 'or address of model inference service if using ovms adapter.') - args.add_argument('-mqtt', '--mqtt', - help='Optional. Set mqtt broker host to publish results. Example: 127.0.0.1:1883',type=str) - args.add_argument('--adapter', default='openvino', choices=('openvino', 'ovms'), - help='Optional. Specify the model adapter. Default is openvino.') - args.add_argument('-i', '--input', required=True, - help='Required. An input to process. The input must be a single image, ' - 'a folder of images, video file or camera id.') - args.add_argument('-d', '--device', default='CPU', - help='Optional. Specify the target device to infer on; CPU or GPU is ' - 'acceptable. The demo will look for a suitable plugin for device specified. ' - 'Default value is CPU.') - - common_model_args = parser.add_argument_group('Common model options') - common_model_args.add_argument('--labels', required=True, - help='Required. Path to a text file with class labels.') - common_model_args.add_argument('-t', '--prob_threshold', default=0.5, type=float, - help='Optional. Probability threshold for detections filtering.') - common_model_args.add_argument('--no_track', action='store_true', - help='Optional. Disable object tracking for video/camera input.') - common_model_args.add_argument('--show_scores', action='store_true', - help='Optional. Show detection scores.') - common_model_args.add_argument('--show_boxes', action='store_true', - help='Optional. Show bounding boxes.') - common_model_args.add_argument('--layout', type=str, default=None, - help='Optional. Model inputs layouts. ' - 'Format "[]" or "[],[]" in case of more than one input. ' - 'To define layout you should use only capital letters') - - infer_args = parser.add_argument_group('Inference options') - infer_args.add_argument('-nireq', '--num_infer_requests', default=0, type=int, - help='Optional. Number of infer requests') - infer_args.add_argument('-nstreams', '--num_streams', default='', - help='Optional. Number of streams to use for inference on the CPU or/and GPU in throughput ' - 'mode (for HETERO and MULTI device cases use format ' - ':,: or just ).') - infer_args.add_argument('-nthreads', '--num_threads', default=None, type=int, - help='Optional. Number of threads to use for inference on CPU (including HETERO cases).') - - io_args = parser.add_argument_group('Input/output options') - io_args.add_argument('--loop', action='store_true', - help='Optional. Enable reading the input in a loop.') - io_args.add_argument('-o', '--output', - help='Optional. Name of the output file(s) to save.') - io_args.add_argument('-limit', '--output_limit', default=1000, type=int, - help='Optional. Number of frames to store in output. ' - 'If 0 is set, all frames are stored.') - io_args.add_argument('--no_show', action='store_true', - help="Optional. Don't show output.") - io_args.add_argument('--output_resolution', default=None, type=resolution, - help='Optional. Specify the maximum output window resolution ' - 'in (width x height) format. Example: 1280x720. ' - 'Input frame size used by default.') - io_args.add_argument('-u', '--utilization_monitors', - help='Optional. List of monitors to show initially.') - - debug_args = parser.add_argument_group('Debug options') - debug_args.add_argument('-r', '--raw_output_message', action='store_true', - help='Optional. Output inference results raw values showing.') - return parser - - -def get_model(model_adapter, configuration): - inputs = model_adapter.get_input_layers() - outputs = model_adapter.get_output_layers() - if len(inputs) == 1 and len(outputs) == 4 and 'proto' in outputs.keys(): - return YolactModel(model_adapter, configuration) - return MaskRCNNModel(model_adapter, configuration) - - -def print_raw_results(boxes, classes, labels, scores, frame_id): - data = [] - for box, cls, score in zip(boxes, classes, scores): - det_label = labels[cls] if labels and len(labels) >= cls else '#{}'.format(cls) - json_object = { - "label": det_label, - "score": float(score), - "xmin": float(box[0]), - "ymin": float(box[1]), - "xmax": float(box[2]), - "ymax": float(box[3]) - } - data.append(json_object) - json_array = json.dumps(data) - return json_array - -def main(): - - args = build_argparser().parse_args() - - cap = open_images_capture(args.input, args.loop) - - containerName = os.environ.get("CONTAINER_NAME", "segmentation") - client = None - # Connect to MQTT - if args.mqtt: - try: - mqttInfo = args.mqtt.split(':',1) - client = mqtt.Client(containerName) - if len(mqttInfo) == 2: - client.connect(mqttInfo[0],int(mqttInfo[1]),60) - client.loop_start() - print(f"connected to mqtt: {args.mqtt}") - except Exception as e: - print("Connection failed to mqtt: {}".format(e)) - - # Overwritting --no_show - render = os.environ.get("RENDER_MODE", "0") - if render == "1": - args.no_show = False - elif render == "0": - args.no_show = True - - if args.adapter == 'openvino': - plugin_config = get_user_config(args.device, args.num_streams, args.num_threads) - model_adapter = OpenvinoAdapter(create_core(), args.model, device=args.device, plugin_config=plugin_config, - max_num_requests=args.num_infer_requests, - model_parameters={'input_layouts': args.layout}) - elif args.adapter == 'ovms': - model_adapter = OVMSAdapter(args.model) - - configuration = { - 'confidence_threshold': args.prob_threshold, - 'path_to_labels': args.labels, - } - model = get_model(model_adapter, configuration) - model.log_layers_info() - - pipeline = AsyncPipeline(model) - - next_frame_id = 0 - next_frame_id_to_show = 0 - - tracker = None - if not args.no_track and cap.get_type() in {'VIDEO', 'CAMERA'}: - tracker = StaticIOUTracker() - visualizer = InstanceSegmentationVisualizer(model.labels, args.show_boxes, args.show_scores) - - metrics = PerformanceMetrics() - render_metrics = PerformanceMetrics() - presenter = None - output_transform = None - video_writer = cv2.VideoWriter() - - while True: - if pipeline.is_ready(): - # Get new image/frame - start_time = perf_counter() - status,frame = cap.read() - # If errors during decoding, then retry grab new image/frame - if not(status): - st = time.time() - for retry in range(3): - try: - cap = open_images_capture(args.input, args.loop) - print("time lost due to reinitialization: ", time.time() - st) - break # If successful, exit the loop - except Exception as e: - print(f"Error on attempt reinitialization {retry + 1}: {e}") - if retry < 2: - print("Retrying...") - time.sleep(1) - else: - print("Max retries reached. Exiting.") - raise RuntimeError("Can't reinitialize image capture") - continue - if frame is None: - if next_frame_id == 0: - raise ValueError("Can't read an image from the input") - break - if next_frame_id == 0: - output_transform = OutputTransform(frame.shape[:2], args.output_resolution) - if args.output_resolution: - output_resolution = output_transform.new_resolution - else: - output_resolution = (frame.shape[1], frame.shape[0]) - presenter = monitors.Presenter(args.utilization_monitors, 55, - (round(output_resolution[0] / 4), round(output_resolution[1] / 8))) - if args.output and not video_writer.open(args.output, cv2.VideoWriter_fourcc(*'MJPG'), - cap.fps(), output_resolution): - raise RuntimeError("Can't open video writer") - # Submit for inference - pipeline.submit_data(frame, next_frame_id, {'frame': frame, 'start_time': start_time}) - next_frame_id += 1 - else: - # Wait for empty request - pipeline.await_any() - - if pipeline.callback_exceptions: - raise pipeline.callback_exceptions[0] - # Process all completed requests - results = pipeline.get_result(next_frame_id_to_show) - if results: - (scores, classes, boxes, masks), frame_meta = results - frame = frame_meta['frame'] - start_time = frame_meta['start_time'] - - if args.mqtt: - json_objects = print_raw_results(boxes, classes, model.labels, scores, next_frame_id_to_show) - client.publish(containerName,json_objects) - - rendering_start_time = perf_counter() - masks_tracks_ids = tracker(masks, classes) if tracker else None - frame = visualizer(frame, boxes, classes, scores, output_transform, masks, masks_tracks_ids) - render_metrics.update(rendering_start_time) - - presenter.drawGraphs(frame) - metrics.update(start_time, frame) - - total_latency, total_fps = metrics.get_total() - print("Processing time: {:.2f} ms; fps: {:.2f}".format(total_latency * 1e3,total_fps)) - - if video_writer.isOpened() and (args.output_limit <= 0 or next_frame_id_to_show <= args.output_limit - 1): - video_writer.write(frame) - next_frame_id_to_show += 1 - - if not args.no_show: - cv2.imshow('Instance Segmentation results', frame) - key = cv2.waitKey(1) - if key == 27 or key == 'q' or key == 'Q': - break - presenter.handleKey(key) - - pipeline.await_all() - if pipeline.callback_exceptions: - raise pipeline.callback_exceptions[0] - # Process completed requests - for next_frame_id_to_show in range(next_frame_id_to_show, next_frame_id): - results = pipeline.get_result(next_frame_id_to_show) - (scores, classes, boxes, masks), frame_meta = results - frame = frame_meta['frame'] - start_time = frame_meta['start_time'] - - if args.raw_output_message: - print_raw_results(boxes, classes, scores, next_frame_id_to_show) - - rendering_start_time = perf_counter() - masks_tracks_ids = tracker(masks, classes) if tracker else None - frame = visualizer(frame, boxes, classes, scores, masks, masks_tracks_ids) - render_metrics.update(rendering_start_time) - - presenter.drawGraphs(frame) - metrics.update(start_time, frame) - - if video_writer.isOpened() and (args.output_limit <= 0 or next_frame_id_to_show <= args.output_limit - 1): - video_writer.write(frame) - - if not args.no_show: - cv2.imshow('Instance Segmentation results', frame) - cv2.waitKey(1) - out.write(frame) - - metrics.log_total() - log_latency_per_stage(cap.reader_metrics.get_latency(), - pipeline.preprocess_metrics.get_latency(), - pipeline.inference_metrics.get_latency(), - pipeline.postprocess_metrics.get_latency(), - render_metrics.get_latency()) - for rep in presenter.reportMeans(): - log.info(rep) - print(rep) - client.disconnect() - -if __name__ == '__main__': - sys.exit(main() or 0) \ No newline at end of file diff --git a/configs/opencv-ovms/demos/instance_segmentation/python/instance_segmentation_demo/__init__.py b/configs/opencv-ovms/demos/instance_segmentation/python/instance_segmentation_demo/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/configs/opencv-ovms/demos/instance_segmentation/python/instance_segmentation_demo/tracker.py b/configs/opencv-ovms/demos/instance_segmentation/python/instance_segmentation_demo/tracker.py deleted file mode 100644 index 90f61363..00000000 --- a/configs/opencv-ovms/demos/instance_segmentation/python/instance_segmentation_demo/tracker.py +++ /dev/null @@ -1,97 +0,0 @@ -""" - Copyright (c) 2019-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import numpy as np - - -class StaticIOUTracker(object): - def __init__(self, iou_threshold=0.5, age_threshold=10): - super().__init__() - self.history = [] - self.history_areas = [] - self.history_classes = [] - self.ids = [] - self.age = [] - self.iou_threshold = iou_threshold - self.age_threshold = age_threshold - self.last_id = 0 - - def affinity(self, masks, classes): - areas = [np.count_nonzero(mask) for mask in masks] - affinity_matrix = np.zeros((len(masks), len(self.history)), dtype=np.float32) - for i, (history_mask, history_area, history_class) in \ - enumerate(zip(self.history, self.history_areas, self.history_classes)): - for j, (mask, area, cls) in enumerate(zip(masks, areas, classes)): - if cls != history_class: - continue - intersection = np.count_nonzero(np.logical_and(history_mask, mask)) - union = history_area + area - intersection - iou = intersection / union - affinity_matrix[j, i] = iou - return affinity_matrix, areas - - def __call__(self, masks, classes): - # Get affinity with history. - affinity_matrix, areas = self.affinity(masks, classes) - - # Make assignment of currents masks to existing tracks. - assignment = [] - indices = np.arange(len(self.history)) - for i in range(len(masks)): - j = 0 - affinity_score = -1.0 - if affinity_matrix.shape[1] > 0: - j = np.argmax(affinity_matrix[i]) - affinity_score = affinity_matrix[i, j] - if affinity_score > self.iou_threshold: - assignment.append(indices[j]) - affinity_matrix = np.delete(affinity_matrix, j, 1) - indices = np.delete(indices, j) - else: - assignment.append(None) - - # Increase age for existing tracks. - for i in range(len(self.age)): - self.age[i] += 1 - - # Update existing tracks. - for i, j in enumerate(assignment): - if j is not None: - self.history[j] = masks[i] - self.history_areas[j] = areas[i] - self.age[j] = 0 - assignment[i] = self.ids[j] - - # Prune out too old tracks. - alive = tuple(i for i, age in enumerate(self.age) if age < self.age_threshold) - self.history = [self.history[i] for i in alive] - self.history_areas = [self.history_areas[i] for i in alive] - self.history_classes = [self.history_classes[i] for i in alive] - self.age = [self.age[i] for i in alive] - self.ids = [self.ids[i] for i in alive] - - # Save new tracks. - for i, j in enumerate(assignment): - if j is None: - self.history.append(masks[i]) - self.history_areas.append(areas[i]) - self.history_classes.append(classes[i]) - self.age.append(0) - self.ids.append(self.last_id) - assignment[i] = self.last_id - self.last_id += 1 - - return assignment diff --git a/configs/opencv-ovms/demos/object_detection/python/entrypoint.sh b/configs/opencv-ovms/demos/object_detection/python/entrypoint.sh deleted file mode 100755 index 9c3471a4..00000000 --- a/configs/opencv-ovms/demos/object_detection/python/entrypoint.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -MQTT="${MQTT:=}" - -if [ "$MQTT" != "" ] -then - mqttArgs="--mqtt ${MQTT}" -fi - -echo "Note: Pipeline log and results are available at location - ./results" - -python3 object_detection/python/object_detection_demo.py -m localhost:"$GRPC_PORT"/models/"$DETECTION_MODEL_NAME" \ ---label object_detection/python/labels/"$DETECTION_LABEL_FILE" -i "$INPUTSRC" \ ---adapter ovms -t "$DETECTION_THRESHOLD" -at "$DETECTION_ARCHITECTURE_TYPE" --output_resolution "$DETECTION_OUTPUT_RESOLUTION" \ -$mqttArgs 2>&1 | tee >/tmp/results/r$cid_count.jsonl >(stdbuf -oL sed -n -e 's/^.*fps: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid_count.log) \ No newline at end of file diff --git a/configs/opencv-ovms/demos/object_detection/python/labels/coco_91cl_bkgr.txt b/configs/opencv-ovms/demos/object_detection/python/labels/coco_91cl_bkgr.txt deleted file mode 100644 index 05ce2611..00000000 --- a/configs/opencv-ovms/demos/object_detection/python/labels/coco_91cl_bkgr.txt +++ /dev/null @@ -1,92 +0,0 @@ -__background__ -person -bicycle -car -motorcycle -airplan -bus -train -truck -boat -traffic light -fire hydrant -street sign -stop sign -parking meter -bench -bird -cat -dog -horse -sheep -cow -elephant -bear -zebra -giraffe -hat -backpack -umbrella -shoe -eye glasses -handbag -tie -suitcase -frisbee -skis -snowboard -sports ball -kite -baseball bat -baseball glove -skateboard -surfboard -tennis racket -bottle -plate -wine glass -cup -fork -knife -spoon -bowl -banana -apple -sandwich -orange -broccoli -carrot -hot dog -pizza -donut -cake -chair -couch -potted plant -bed -mirror -dining table -window -desk -toilet -door -tv -laptop -mouse -remote -keyboard -cell phone -microwave -oven -toaster -sink -refrigerator -blender -book -clock -vase -scissors -teddy bear -hair drier -toothbrush -hair brush \ No newline at end of file diff --git a/configs/opencv-ovms/demos/object_detection/python/object_detection_demo.py b/configs/opencv-ovms/demos/object_detection/python/object_detection_demo.py deleted file mode 100755 index 48b647cf..00000000 --- a/configs/opencv-ovms/demos/object_detection/python/object_detection_demo.py +++ /dev/null @@ -1,364 +0,0 @@ -#!/usr/bin/env python3 -""" - Copyright (C) 2018-2023 Intel Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import logging as log -import sys -from argparse import ArgumentParser, SUPPRESS -from pathlib import Path -from time import perf_counter -import json -import time - -import cv2 -import os - -sys.path.append(str(Path(__file__).resolve().parents[2] / 'common/python')) -sys.path.append(str(Path(__file__).resolve().parents[2] / 'common/python/openvino/model_zoo')) - -from model_api.models import DetectionModel, DetectionWithLandmarks, RESIZE_TYPES, OutputTransform -from model_api.performance_metrics import PerformanceMetrics -from model_api.pipelines import get_user_config, AsyncPipeline -from model_api.adapters import create_core, OpenvinoAdapter, OVMSAdapter - -import monitors -from images_capture import open_images_capture -from helpers import resolution, log_latency_per_stage -from visualizers import ColorPalette -import paho.mqtt.client as mqtt - -log.basicConfig(format='[ %(levelname)s ] %(message)s', level=log.DEBUG, stream=sys.stdout) - - -def build_argparser(): - parser = ArgumentParser(add_help=False) - args = parser.add_argument_group('Options') - args.add_argument('-h', '--help', action='help', default=SUPPRESS, help='Show this help message and exit.') - args.add_argument('-mqtt', '--mqtt', - help='Optional. Set mqtt broker host to publish results. Example: 127.0.0.1:1883',type=str) - args.add_argument('-m', '--model', required=True, - help='Required. Path to an .xml file with a trained model ' - 'or address of model inference service if using ovms adapter.') - available_model_wrappers = [name.lower() for name in DetectionModel.available_wrappers()] - args.add_argument('-at', '--architecture_type', help='Required. Specify model\' architecture type.', - type=str, required=True, choices=available_model_wrappers) - args.add_argument('--adapter', help='Optional. Specify the model adapter. Default is openvino.', - default='openvino', type=str, choices=('openvino', 'ovms')) - args.add_argument('-i', '--input', required=True, - help='Required. An input to process. The input must be a single image, ' - 'a folder of images, video file or camera id.') - args.add_argument('-d', '--device', default='CPU', type=str, - help='Optional. Specify the target device to infer on; CPU or GPU is ' - 'acceptable. The demo will look for a suitable plugin for device specified. ' - 'Default value is CPU.') - - common_model_args = parser.add_argument_group('Common model options') - common_model_args.add_argument('--labels', help='Optional. Labels mapping file.', default=None, type=str) - common_model_args.add_argument('-t', '--prob_threshold', default=0.5, type=float, - help='Optional. Probability threshold for detections filtering.') - common_model_args.add_argument('--resize_type', default=None, choices=RESIZE_TYPES.keys(), - help='Optional. A resize type for model preprocess. By default used model predefined type.') - common_model_args.add_argument('--input_size', default=(600, 600), type=int, nargs=2, - help='Optional. The first image size used for CTPN model reshaping. ' - 'Default: 600 600. Note that submitted images should have the same resolution, ' - 'otherwise predictions might be incorrect.') - common_model_args.add_argument('--anchors', default=None, type=float, nargs='+', - help='Optional. A space separated list of anchors. ' - 'By default used default anchors for model. Only for YOLOV4 architecture type.') - common_model_args.add_argument('--masks', default=None, type=int, nargs='+', - help='Optional. A space separated list of mask for anchors. ' - 'By default used default masks for model. Only for YOLOV4 architecture type.') - common_model_args.add_argument('--layout', type=str, default=None, - help='Optional. Model inputs layouts. ' - 'Ex. NCHW or input0:NCHW,input1:NC in case of more than one input.') - common_model_args.add_argument('--num_classes', default=None, type=int, - help='Optional. Number of detected classes. Only for NanoDet, NanoDetPlus ' - 'architecture types.') - - infer_args = parser.add_argument_group('Inference options') - infer_args.add_argument('-nireq', '--num_infer_requests', help='Optional. Number of infer requests', - default=0, type=int) - infer_args.add_argument('-nstreams', '--num_streams', - help='Optional. Number of streams to use for inference on the CPU or/and GPU in throughput ' - 'mode (for HETERO and MULTI device cases use format ' - ':,: or just ).', - default='', type=str) - infer_args.add_argument('-nthreads', '--num_threads', default=None, type=int, - help='Optional. Number of threads to use for inference on CPU (including HETERO cases).') - - io_args = parser.add_argument_group('Input/output options') - io_args.add_argument('--loop', default=False, action='store_true', - help='Optional. Enable reading the input in a loop.') - io_args.add_argument('-o', '--output', required=False, - help='Optional. Name of the output file(s) to save.') - io_args.add_argument('-limit', '--output_limit', required=False, default=1000, type=int, - help='Optional. Number of frames to store in output. ' - 'If 0 is set, all frames are stored.') - io_args.add_argument('--no_show', help="Optional. Don't show output.", action='store_true') - io_args.add_argument('--output_resolution', default=None, type=resolution, - help='Optional. Specify the maximum output window resolution ' - 'in (width x height) format. Example: 1280x720. ' - 'Input frame size used by default.') - io_args.add_argument('-u', '--utilization_monitors', default='', type=str, - help='Optional. List of monitors to show initially.') - - input_transform_args = parser.add_argument_group('Input transform options') - input_transform_args.add_argument('--reverse_input_channels', default=False, action='store_true', - help='Optional. Switch the input channels order from ' - 'BGR to RGB.') - input_transform_args.add_argument('--mean_values', default=None, type=float, nargs=3, - help='Optional. Normalize input by subtracting the mean ' - 'values per channel. Example: 255.0 255.0 255.0') - input_transform_args.add_argument('--scale_values', default=None, type=float, nargs=3, - help='Optional. Divide input by scale values per channel. ' - 'Division is applied after mean values subtraction. ' - 'Example: 255.0 255.0 255.0') - - debug_args = parser.add_argument_group('Debug options') - debug_args.add_argument('-r', '--raw_output_message', help='Optional. Output inference results raw values showing.', - default=False, action='store_true') - return parser - - -def draw_detections(frame, detections, palette, labels, output_transform): - frame = output_transform.resize(frame) - for detection in detections: - class_id = int(detection.id) - color = palette[class_id] - det_label = labels[class_id] if labels and len(labels) >= class_id else '#{}'.format(class_id) - xmin, ymin, xmax, ymax = detection.get_coords() - xmin, ymin, xmax, ymax = output_transform.scale([xmin, ymin, xmax, ymax]) - cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), color, 2) - cv2.putText(frame, '{} {:.1%}'.format(det_label, detection.score), - (xmin, ymin - 7), cv2.FONT_HERSHEY_COMPLEX, 0.6, color, 1) - if isinstance(detection, DetectionWithLandmarks): - for landmark in detection.landmarks: - landmark = output_transform.scale(landmark) - cv2.circle(frame, (int(landmark[0]), int(landmark[1])), 2, (0, 255, 255), 2) - return frame - - -def print_raw_results(detections, labels, frame_id): - data = [] - for detection in detections: - xmin, ymin, xmax, ymax = detection.get_coords() - class_id = int(detection.id) - det_label = labels[class_id] if labels and len(labels) >= class_id else '#{}'.format(class_id) - json_object = { - "label": det_label, - "score": float(detection.score), - "xmin": xmin, - "ymin": ymin, - "xmax": xmax, - "ymax": ymax - } - data.append(json_object) - json_array = json.dumps(data) - return json_array - -def main(): - args = build_argparser().parse_args() - if args.architecture_type != 'yolov4' and args.anchors: - log.warning('The "--anchors" option works only for "-at==yolov4". Option will be omitted') - if args.architecture_type != 'yolov4' and args.masks: - log.warning('The "--masks" option works only for "-at==yolov4". Option will be omitted') - if args.architecture_type not in ['nanodet', 'nanodet-plus'] and args.num_classes: - log.warning('The "--num_classes" option works only for "-at==nanodet" and "-at==nanodet-plus". Option will be omitted') - - containerName = os.environ.get("CONTAINER_NAME", "object_detection") - client = None - # Connect to MQTT - if args.mqtt: - try: - mqttInfo = args.mqtt.split(':',1) - client = mqtt.Client(containerName) - if len(mqttInfo) == 2: - client.connect(mqttInfo[0],int(mqttInfo[1]),60) - client.loop_start() - print(f"connected to mqtt: {args.mqtt}") - except Exception as e: - print("Connection failed to mqtt: {}".format(e)) - - cap = open_images_capture(args.input, args.loop) - - # Overwritting --no_show - render = os.environ.get("RENDER_MODE", "0") - if render == "1": - args.no_show = False - elif render == "0": - args.no_show = True - - if args.adapter == 'openvino': - plugin_config = get_user_config(args.device, args.num_streams, args.num_threads) - model_adapter = OpenvinoAdapter(create_core(), args.model, device=args.device, plugin_config=plugin_config, - max_num_requests=args.num_infer_requests, model_parameters = {'input_layouts': args.layout}) - elif args.adapter == 'ovms': - model_adapter = OVMSAdapter(args.model) - - if (args.prob_threshold < 0.0) or (args.prob_threshold > 1.0): - print("Detection threshold: {}, is confidence threshold value in floating point that needs to be between 0.0 to 1.0.".format(args.prob_threshold)) - return 1 - - configuration = { - 'resize_type': args.resize_type, - 'mean_values': args.mean_values, - 'scale_values': args.scale_values, - 'reverse_input_channels': args.reverse_input_channels, - 'path_to_labels': args.labels, - 'confidence_threshold': args.prob_threshold, - 'input_size': args.input_size, # The CTPN specific - 'num_classes': args.num_classes, # The NanoDet and NanoDetPlus specific - } - model = DetectionModel.create_model(args.architecture_type, model_adapter, configuration) - model.log_layers_info() - - detector_pipeline = AsyncPipeline(model) - - next_frame_id = 0 - next_frame_id_to_show = 0 - - palette = ColorPalette(len(model.labels) if model.labels else 100) - metrics = PerformanceMetrics() - render_metrics = PerformanceMetrics() - presenter = None - output_transform = None - video_writer = cv2.VideoWriter() - - while True: - if detector_pipeline.callback_exceptions: - raise detector_pipeline.callback_exceptions[0] - # Process all completed requests - results = detector_pipeline.get_result(next_frame_id_to_show) - if results: - objects, frame_meta = results - frame = frame_meta['frame'] - start_time = frame_meta['start_time'] - presenter.drawGraphs(frame) - rendering_start_time = perf_counter() - frame = draw_detections(frame, objects, palette, model.labels, output_transform) - render_metrics.update(rendering_start_time) - metrics.update(start_time, frame) - - if video_writer.isOpened() and (args.output_limit <= 0 or next_frame_id_to_show <= args.output_limit-1): - video_writer.write(frame) - next_frame_id_to_show += 1 - - total_latency, total_fps = metrics.get_total() - print("Processing time: {:.2f} ms; fps: {:.2f}".format(total_latency * 1e3,total_fps)) - - # Publish results to mqtt - if args.mqtt: - json_objects = print_raw_results(objects, model.labels, next_frame_id_to_show) - client.publish(containerName,json_objects) - - if not args.no_show: - cv2.imshow('Detection Results', frame) - key = cv2.waitKey(1) - - ESC_KEY = 27 - # Quit. - if key in {ord('q'), ord('Q'), ESC_KEY}: - break - presenter.handleKey(key) - continue - - if detector_pipeline.is_ready(): - # Get new image/frame - start_time = perf_counter() - status,frame = cap.read() - # If errors during decoding, then retry grab new image/frame - if not(status): - st = time.time() - for retry in range(3): - try: - cap = open_images_capture(args.input, args.loop) - print("time lost due to reinitialization: ", time.time() - st) - break # If successful, exit the loop - except Exception as e: - print(f"Error on attempt reinitialization {retry + 1}: {e}") - if retry < 2: - print("Retrying...") - time.sleep(1) - else: - print("Max retries reached. Exiting.") - raise RuntimeError("Can't reinitialize image capture") - continue - if frame is None: - if next_frame_id == 0: - raise ValueError("Can't read an image from the input") - break - if next_frame_id == 0: - output_transform = OutputTransform(frame.shape[:2], args.output_resolution) - if args.output_resolution: - output_resolution = output_transform.new_resolution - else: - output_resolution = (frame.shape[1], frame.shape[0]) - presenter = monitors.Presenter(args.utilization_monitors, 55, - (round(output_resolution[0] / 4), round(output_resolution[1] / 8))) - if args.output and not video_writer.open(args.output, cv2.VideoWriter_fourcc(*'MJPG'), - cap.fps(), output_resolution): - raise RuntimeError("Can't open video writer") - # Submit for inference - detector_pipeline.submit_data(frame, next_frame_id, {'frame': frame, 'start_time': start_time}) - next_frame_id += 1 - else: - # Wait for empty request - detector_pipeline.await_any() - - detector_pipeline.await_all() - if detector_pipeline.callback_exceptions: - raise detector_pipeline.callback_exceptions[0] - # Process completed requests - for next_frame_id_to_show in range(next_frame_id_to_show, next_frame_id): - results = detector_pipeline.get_result(next_frame_id_to_show) - objects, frame_meta = results - frame = frame_meta['frame'] - start_time = frame_meta['start_time'] - - if len(objects) and args.raw_output_message: - print_raw_results(objects, model.labels, next_frame_id_to_show) - - presenter.drawGraphs(frame) - rendering_start_time = perf_counter() - frame = draw_detections(frame, objects, palette, model.labels, output_transform) - render_metrics.update(rendering_start_time) - metrics.update(start_time, frame) - - if video_writer.isOpened() and (args.output_limit <= 0 or next_frame_id_to_show <= args.output_limit-1): - video_writer.write(frame) - - if not args.no_show: - cv2.imshow('Detection Results', frame) - key = cv2.waitKey(1) - - ESC_KEY = 27 - # Quit. - if key in {ord('q'), ord('Q'), ESC_KEY}: - break - presenter.handleKey(key) - - metrics.log_total() - log_latency_per_stage(cap.reader_metrics.get_latency(), - detector_pipeline.preprocess_metrics.get_latency(), - detector_pipeline.inference_metrics.get_latency(), - detector_pipeline.postprocess_metrics.get_latency(), - render_metrics.get_latency()) - for rep in presenter.reportMeans(): - log.info(rep) - client.disconnect() - -if __name__ == '__main__': - sys.exit(main() or 0) diff --git a/configs/opencv-ovms/demos/requirements.txt b/configs/opencv-ovms/demos/requirements.txt deleted file mode 100644 index 0c7016a2..00000000 --- a/configs/opencv-ovms/demos/requirements.txt +++ /dev/null @@ -1,19 +0,0 @@ -inflect>=5.3.0 -librosa>=0.8.0;python_version < '3.11' -matplotlib>=3.3.4,<3.8 -pyparsing<3.0 -motmetrics>=1.2.0 -nibabel>=3.2.1 -numpy>=1.16.6 -opencv-python -pillow>=8.1.2 -pyyaml>=5.4.1 -scikit-learn>=0.24.1 -scipy>=1.5.4 -sympy>=1.8 -tensorboardX>=2.1 -tokenizers~=0.10.1;python_version<"3.7" -tokenizers>=0.10.1;python_version>="3.7" -tqdm>=4.54.1 -ovmsclient==2023.0 -paho-mqtt==1.6.1 \ No newline at end of file diff --git a/configs/opencv-ovms/envs/capi_face_detection.env b/configs/opencv-ovms/envs/capi_face_detection.env deleted file mode 100644 index 5b49a90d..00000000 --- a/configs/opencv-ovms/envs/capi_face_detection.env +++ /dev/null @@ -1,12 +0,0 @@ -RENDER_PORTRAIT_MODE=0 -GST_DEBUG=0 -USE_ONEVPL=1 -PIPELINE_EXEC_PATH=pipelines/face_detection/face_detection -GST_VAAPI_DRM_DEVICE=/dev/dri/renderD128 -TARGET_GPU_DEVICE=--privileged -LOG_LEVEL=0 -RENDER_MODE=1 -cl_cache_dir=/home/intel/gst-ovms/.cl-cache -WINDOW_WIDTH=1920 -WINDOW_HEIGHT=1080 -DETECTION_THRESHOLD=0.9 \ No newline at end of file diff --git a/configs/opencv-ovms/envs/capi_yolov5.env b/configs/opencv-ovms/envs/capi_yolov5.env deleted file mode 100644 index d98d7e10..00000000 --- a/configs/opencv-ovms/envs/capi_yolov5.env +++ /dev/null @@ -1,12 +0,0 @@ -RENDER_PORTRAIT_MODE=0 -GST_DEBUG=0 -USE_ONEVPL=1 -PIPELINE_EXEC_PATH=pipelines/capi_yolov5/capi_yolov5 -GST_VAAPI_DRM_DEVICE=/dev/dri/renderD128 -TARGET_GPU_DEVICE=--privileged -LOG_LEVEL=0 -RENDER_MODE=1 -cl_cache_dir=/home/intel/gst-ovms/.cl-cache -WINDOW_WIDTH=1920 -WINDOW_HEIGHT=1080 -DETECTION_THRESHOLD=0.7 \ No newline at end of file diff --git a/configs/opencv-ovms/envs/capi_yolov5_ensemble.env b/configs/opencv-ovms/envs/capi_yolov5_ensemble.env deleted file mode 100644 index c0d927fd..00000000 --- a/configs/opencv-ovms/envs/capi_yolov5_ensemble.env +++ /dev/null @@ -1,13 +0,0 @@ -RENDER_PORTRAIT_MODE=0 -GST_DEBUG=1 -USE_ONEVPL=1 -PIPELINE_EXEC_PATH=pipelines/capi_yolov5_ensemble/capi_yolov5_ensemble -GST_VAAPI_DRM_DEVICE=/dev/dri/renderD128 -TARGET_GPU_DEVICE=--privileged -LOG_LEVEL=0 -RENDER_MODE=1 -cl_cache_dir=/home/intel/gst-ovms/.cl-cache -WINDOW_WIDTH=1280 -WINDOW_HEIGHT=720 -DETECTION_THRESHOLD=0.7 -BARCODE=1 \ No newline at end of file diff --git a/configs/opencv-ovms/envs/capi_yolov8_ensemble.env b/configs/opencv-ovms/envs/capi_yolov8_ensemble.env deleted file mode 100644 index ddc2e90c..00000000 --- a/configs/opencv-ovms/envs/capi_yolov8_ensemble.env +++ /dev/null @@ -1,15 +0,0 @@ -RENDER_PORTRAIT_MODE=0 -GST_DEBUG=1 -USE_ONEVPL=1 -PIPELINE_EXEC_PATH=pipelines/capi_yolov8_ensemble/capi_yolov8_ensemble -GST_VAAPI_DRM_DEVICE=/dev/dri/renderD128 -TARGET_GPU_DEVICE=--privileged -NO_BASH_C=1 -INPUT_TYPE=RTSP_H264 -LOG_LEVEL=0 -RENDER_MODE=1 -cl_cache_dir=/home/intel/gst-ovms/.cl-cache -WINDOW_WIDTH=1280 -WINDOW_HEIGHT=720 -DETECTION_THRESHOLD=0.5 -DC=0 diff --git a/configs/opencv-ovms/envs/classification.env b/configs/opencv-ovms/envs/classification.env deleted file mode 100644 index f112524b..00000000 --- a/configs/opencv-ovms/envs/classification.env +++ /dev/null @@ -1,5 +0,0 @@ -CLASSIFICATION_MODEL_NAME=efficientnetb0_FP32INT8 -CLASSIFICATION_LABEL_FILE=imagenet_2012.txt -CLASSIFICATION_OUTPUT_RESOLUTION=1920x1080 -MQTT= -RENDER_MODE=1 diff --git a/configs/opencv-ovms/envs/grpc_python.env b/configs/opencv-ovms/envs/grpc_python.env deleted file mode 100644 index 519c7d5b..00000000 --- a/configs/opencv-ovms/envs/grpc_python.env +++ /dev/null @@ -1,3 +0,0 @@ -DEVICE=CPU -GRPC_PORT=9000 -DETECTION_MODEL_NAME=instance-segmentation-security-1040 \ No newline at end of file diff --git a/configs/opencv-ovms/envs/gst.env b/configs/opencv-ovms/envs/gst.env deleted file mode 100644 index db0c07c9..00000000 --- a/configs/opencv-ovms/envs/gst.env +++ /dev/null @@ -1,5 +0,0 @@ -COLOR_WIDTH=1920 -COLOR_HEIGHT=1080 -COLOR_FRAMERATE=15 -OCR_SPECIFIED=5 -BATCH_SIZE=0 \ No newline at end of file diff --git a/configs/opencv-ovms/envs/object_detection.env b/configs/opencv-ovms/envs/object_detection.env deleted file mode 100644 index a684eb78..00000000 --- a/configs/opencv-ovms/envs/object_detection.env +++ /dev/null @@ -1,7 +0,0 @@ -DETECTION_MODEL_NAME=ssd_mobilenet_v1_coco -DETECTION_LABEL_FILE=coco_91cl_bkgr.txt -DETECTION_ARCHITECTURE_TYPE=ssd -DETECTION_OUTPUT_RESOLUTION=1920x1080 -DETECTION_THRESHOLD=0.50 -MQTT= -RENDER_MODE=1 diff --git a/configs/opencv-ovms/envs/ovms_server.env b/configs/opencv-ovms/envs/ovms_server.env deleted file mode 100644 index 57be3c95..00000000 --- a/configs/opencv-ovms/envs/ovms_server.env +++ /dev/null @@ -1 +0,0 @@ -server_cl_cache_dir=/home/pipeline-server/.cl-cache diff --git a/configs/opencv-ovms/envs/yolov5-cpu.env b/configs/opencv-ovms/envs/yolov5-cpu.env deleted file mode 100644 index f485e4d4..00000000 --- a/configs/opencv-ovms/envs/yolov5-cpu.env +++ /dev/null @@ -1,16 +0,0 @@ -GST_PIPELINE_LAUNCH=/home/pipeline-server/framework-pipelines/yolov5_pipeline/yolov5s.sh -OCR_DEVICE= -LOG_LEVEL=ERROR -GST_DEBUG=0 -LOW_POWER= -CPU_ONLY= -AUTO_SCALE_FLEX_140= -CPU_SW_DECODER="force-sw-decoders=1" -DECODE="decodebin force-sw-decoders=1" -DEVICE=CPU -PRE_PROCESS= -AGGREGATE="" -DETECTION_OPTIONS="gpu-throughput-streams=4 nireq=4 batch-size=1" -CLASSIFICATION_OPTIONS="reclassify-interval=1 $DETECTION_OPTIONS" -OCR_RECLASSIFY_INTERVAL=5 -BARCODE_RECLASSIFY_INTERVAL=5 \ No newline at end of file diff --git a/configs/opencv-ovms/envs/yolov5-gpu.env b/configs/opencv-ovms/envs/yolov5-gpu.env deleted file mode 100644 index 617edc66..00000000 --- a/configs/opencv-ovms/envs/yolov5-gpu.env +++ /dev/null @@ -1,18 +0,0 @@ -GST_PIPELINE_LAUNCH=/home/pipeline-server/framework-pipelines/yolov5_pipeline/yolov5s.sh -OCR_DEVICE= -LOG_LEVEL=ERROR -GST_DEBUG=0 -LOW_POWER= -CPU_ONLY= -AUTO_SCALE_FLEX_140= -DECODE="vaapidecodebin" -DEVICE=GPU -PRE_PROCESS="pre-process-backend=vaapi-surface-sharing pre-process-config=VAAPI_FAST_SCALE_LOAD_FACTOR=1" -AGGREGATE= -VA_SURFACE="! \"video/x-raw(memory:VASurface)\"" -PARALLEL_PIPELINE= -PARALLEL_AGGRAGATE= -DETECTION_OPTIONS="gpu-throughput-streams=4 nireq=4 batch-size=1" -CLASSIFICATION_OPTIONS="reclassify-interval=1 $DETECTION_OPTIONS" -OCR_RECLASSIFY_INTERVAL=5 -BARCODE_RECLASSIFY_INTERVAL=5 diff --git a/configs/opencv-ovms/grpc_go/.dockerignore b/configs/opencv-ovms/grpc_go/.dockerignore deleted file mode 100644 index 5cf92721..00000000 --- a/configs/opencv-ovms/grpc_go/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -Findings.md -Makefile -README.md diff --git a/configs/opencv-ovms/grpc_go/Dockerfile b/configs/opencv-ovms/grpc_go/Dockerfile deleted file mode 100644 index ae16c6af..00000000 --- a/configs/opencv-ovms/grpc_go/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -FROM gocv/opencv:4.7.0 AS builder - -RUN apt-get update && \ - apt-get -y install git unzip build-essential autoconf libtool protobuf-compiler libprotobuf-dev --fix-missing && \ - rm -rf /var/lib/apt/lists/* - -RUN mkdir /app -WORKDIR /app - - -RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.31.0 -RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 - -# Compile API -RUN wget https://raw.githubusercontent.com/openvinotoolkit/model_server/main/src/kfserving_api/grpc_predict_v2.proto -RUN echo 'option go_package = "./grpc-client";' >> grpc_predict_v2.proto -RUN protoc --go_out="./" --go-grpc_out="./" ./grpc_predict_v2.proto - -COPY . . - -RUN go mod tidy -RUN go build -o grpc-go && chmod +x entrypoint.sh diff --git a/configs/opencv-ovms/grpc_go/Findings.md b/configs/opencv-ovms/grpc_go/Findings.md deleted file mode 100644 index 3c57d4bc..00000000 --- a/configs/opencv-ovms/grpc_go/Findings.md +++ /dev/null @@ -1,26 +0,0 @@ -# OVMS+GOCV Findings - -1. Fully capable of connecting to OVMS via Kserve API using GRPC -2. Able to send input to the model and receive the output from the model -3. There is no blocks using this to communicate to OVMS using this method - - - -## Drawbacks - -1. YOLOV5 does not look to be supported by openvino - - There are alot of post processing of the tensor output that needs to be done - - To get through this, team will need a through understanding of the model - - - -## Workarounds - -- If attempting to process yolov5 output - - Reshape each tensor output to [1,3,52,52,85], [1,3,26,26,85], [1,3,13,13,85] respectively. It would be easier to retrieve the values for [x,y,w,h,conf,pred(class), pred(class) are next 80 probabilities for a specific object - - - -# Conclusion - -if we are using this to approach for a distributed architecture, this would be far easier if we use models that are supported by openvino as this would should require less post processing. If this is not possible, there will be a large learning curve to understand the model and how to parse the output from openvio. \ No newline at end of file diff --git a/configs/opencv-ovms/grpc_go/Makefile b/configs/opencv-ovms/grpc_go/Makefile deleted file mode 100644 index 1f890a48..00000000 --- a/configs/opencv-ovms/grpc_go/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright © 2023 Intel Corporation. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -.PHONY: build - -build: - docker build --tag grpc_go:dev . \ No newline at end of file diff --git a/configs/opencv-ovms/grpc_go/README.md b/configs/opencv-ovms/grpc_go/README.md deleted file mode 100644 index f50a3e4a..00000000 --- a/configs/opencv-ovms/grpc_go/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docker Run Command Examples -docker run --network host --privileged --rm -v `pwd`/results:/app/results --name dev -p 8080:8080 grpc_go:dev - -docker run --network host --privileged --rm -v `pwd`/results:/app/results --name dev -p 8080:8080 -it grpc_go:dev /bin/bash - - -docker run --rm -d -v $(pwd)/models:/models -p 9000:9000 openvino/model_server:latest --model_name resnet --model_path /models/resnet --port 9000 --layout NHWC:NCHW --plugin_config '{"PERFORMANCE_HINT":"LATENCY"}' - -docker run --rm -d -v $(pwd)/models:/models -p 8001:8001 -p 9000:9000 --name ovms openvino/model_server:2022.3 --model_name yolov5 --model_path /models/yolov5ovms --rest_port 8001 --port 9000 --layout NHWC:NCHW --plugin_config '{"PERFORMANCE_HINT":"LATENCY"}' - -./grpc-go -i rtsp://127.0.0.1:8554/camera_0 -u 127.0.0.1:9000 \ No newline at end of file diff --git a/configs/opencv-ovms/grpc_go/entrypoint.sh b/configs/opencv-ovms/grpc_go/entrypoint.sh deleted file mode 100755 index c3a9fb6a..00000000 --- a/configs/opencv-ovms/grpc_go/entrypoint.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -containerDisplayPort=8080 -displayPortNum=$(( $cid_count + $containerDisplayPort )) -echo "displayPortNum=$displayPortNum" - -echo "Note: Pipeline log and results are available at location - ./results" - -if [ ! -z "$DEBUG" ] -then - ./grpc-go -i $INPUTSRC -u 127.0.0.1:$GRPC_PORT -h 0.0.0.0:$displayPortNum -else - ./grpc-go -i $INPUTSRC -u 127.0.0.1:$GRPC_PORT -h 0.0.0.0:$displayPortNum 2>&1 | tee >/tmp/results/r$cid_count.jsonl >(stdbuf -oL sed -n -e 's/^.*fps: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid_count.log) -fi \ No newline at end of file diff --git a/configs/opencv-ovms/grpc_go/go.mod b/configs/opencv-ovms/grpc_go/go.mod deleted file mode 100644 index e6f68ca4..00000000 --- a/configs/opencv-ovms/grpc_go/go.mod +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright © 2023 Intel Corporation. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -module videoProcess - -go 1.20 - -require ( - github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e - gocv.io/x/gocv v0.32.1 - google.golang.org/grpc v1.59.0 -) - -require ( - github.com/golang/protobuf v1.5.3 // indirect - golang.org/x/net v0.14.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/protobuf v1.31.0 // indirect -) diff --git a/configs/opencv-ovms/grpc_go/go.sum b/configs/opencv-ovms/grpc_go/go.sum deleted file mode 100644 index 2b49a5d9..00000000 --- a/configs/opencv-ovms/grpc_go/go.sum +++ /dev/null @@ -1,25 +0,0 @@ -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e h1:xCcwD5FOXul+j1dn8xD16nbrhJkkum/Cn+jTd/u1LhY= -github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e/go.mod h1:eagM805MRKrioHYuU7iKLUyFPVKqVV6um5DAvCkUtXs= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -gocv.io/x/gocv v0.32.1 h1:BC9hHs5+47nVgySUFVKntc6RsF3SULFzqk6OV9xz+C0= -gocv.io/x/gocv v0.32.1/go.mod h1:oc6FvfYqfBp99p+yOEzs9tbYF9gOrAQSeL/dyIPefJU= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/configs/opencv-ovms/grpc_go/main.go b/configs/opencv-ovms/grpc_go/main.go deleted file mode 100644 index ad5dbb58..00000000 --- a/configs/opencv-ovms/grpc_go/main.go +++ /dev/null @@ -1,151 +0,0 @@ -/********************************************************************* - * Copyright (c) Intel Corporation 2023 - * SPDX-License-Identifier: Apache-2.0 - **********************************************************************/ - -package main - -import ( - "fmt" - "image" - "image/color" - "log" - "net/http" - "os" - "time" - grpc_client "videoProcess/grpc-client" - "videoProcess/pkg/ovms" - "videoProcess/pkg/yolov5" - "videoProcess/utilities" - - "github.com/hybridgroup/mjpeg" - "gocv.io/x/gocv" - "google.golang.org/grpc" -) - -const ( - RETRY = time.Millisecond - MAX_RETRY = 10 -) - -func main() { - FLAGS := utilities.ParseFlags() - - webcam, err := gocv.OpenVideoCapture(FLAGS.InputSrc) // /dev/video4 - if err != nil { - errMsg := fmt.Errorf("failed to open device: %s", FLAGS.InputSrc) - fmt.Println(errMsg) - } - defer webcam.Close() - - camHeight := float32(webcam.Get(gocv.VideoCaptureFrameHeight)) - camWidth := float32(webcam.Get(gocv.VideoCaptureFrameWidth)) - - img := gocv.NewMat() - defer img.Close() - - // // Connect to gRPC server - conn, err := grpc.Dial(FLAGS.URL, grpc.WithInsecure()) - if err != nil { - log.Fatalf("Couldn't connect to endpoint %s: %v", FLAGS.URL, err) - } - defer conn.Close() - - // // Create client from gRPC server connection - client := grpc_client.NewGRPCInferenceServiceClient(conn) - - // create the mjpeg stream - stream := mjpeg.NewStream() - - go runModelServer(&client, webcam, &img, FLAGS.ModelName, FLAGS.ModelVersion, stream, camWidth, camHeight) - fmt.Println("Capturing. Point your browser to " + FLAGS.Host) - - // start http server - http.Handle("/", stream) - log.Fatal("http server failed: ", http.ListenAndServe(FLAGS.Host, nil)) - -} - -func runModelServer(client *grpc_client.GRPCInferenceServiceClient, webcam *gocv.VideoCapture, img *gocv.Mat, modelname string, - modelVersion string, stream *mjpeg.Stream, camWidth float32, camHeight float32) { - var aggregateLatencyAfterInfer float64 - var frameNum float64 - - initTime := float64(time.Now().UnixMilli()) - for webcam.IsOpened() { - if ok := webcam.Read(img); !ok { - // retry once after 1 millisecond - time.Sleep(RETRY) - continue - } - if img.Empty() { - continue - } - frameNum++ - - start := float64(time.Now().UnixMilli()) - fp32Image := gocv.NewMat() - defer fp32Image.Close() - - // resize image to yolov5 model specifications - gocv.Resize(*img, &fp32Image, image.Point{int(yolov5.Input_shape[1]), int(yolov5.Input_shape[2])}, 0, 0, 3) - - // convert to image matrix to use float32 - fp32Image.ConvertTo(&fp32Image, gocv.MatTypeCV32F) - imgToBytes, _ := fp32Image.DataPtrFloat32() - - // retry if error found to ovms server - var err error - var inferResponse *ovms.TensorOutputs - retryCnt := 0 - for { - if retryCnt > MAX_RETRY { - // there is something broken sending request to the model server, cannot continue... - fmt.Println("model infer request error after max retry count: ", MAX_RETRY, "exiting...") - os.Exit(1) - } - - inferResponse, err = ovms.ModelInferRequest(*client, imgToBytes, modelname, modelVersion) - if err != nil { - retryCnt++ - fmt.Println("ovms model infer request error ", err, " retry count: ", retryCnt) - } else { - break - } - } - - afterInfer := float64(time.Now().UnixMilli()) - aggregateLatencyAfterInfer += afterInfer - start - - detectedObjects := yolov5.DetectedObjects{} - - // temp code: - output := ovms.TensorOutputs{ - RawData: [][]byte{(*inferResponse).RawData[0]}, - DataShapes: [][]int64{(*inferResponse).DataShapes[0]}, - } - output.ParseRawData() - err = detectedObjects.Postprocess(output, camWidth, camHeight) - if err != nil { - fmt.Printf("post process failed: %v\n", err) - } - - detectedObjects = detectedObjects.FinalPostProcessAdvanced() - - // Print after processing latency - afterFinalProcess := float64(time.Now().UnixMilli()) - processTime := afterFinalProcess - start - avgFps := frameNum / ((afterFinalProcess - initTime) / 1000.0) - averageFPSStr := fmt.Sprintf("%v\n", avgFps) - fmt.Printf("Processing time: %v ms; fps: %s", processTime, averageFPSStr) - - // add bounding boxes to resized image - detectedObjects.AddBoxesToFrame(&fp32Image, color.RGBA{0, 255, 0, 0}, camWidth, camWidth) - - buf, _ := gocv.IMEncode(".jpg", fp32Image) - stream.UpdateJPEG(buf.GetBytes()) - buf.Close() - - } - -} diff --git a/configs/opencv-ovms/grpc_go/pkg/ovms/inferRequest.go b/configs/opencv-ovms/grpc_go/pkg/ovms/inferRequest.go deleted file mode 100644 index 62ca011d..00000000 --- a/configs/opencv-ovms/grpc_go/pkg/ovms/inferRequest.go +++ /dev/null @@ -1,59 +0,0 @@ -/********************************************************************* - * Copyright (c) Intel Corporation 2023 - * SPDX-License-Identifier: Apache-2.0 - **********************************************************************/ - -package ovms - -import ( - "context" - "fmt" - "time" - - grpc_client "videoProcess/grpc-client" -) - -var ( - defaultInputShape = []int64{1, 416, 416, 3} -) - -func ModelInferRequest(client grpc_client.GRPCInferenceServiceClient, image []float32, modelName string, modelVersion string) (*TensorOutputs, error) { - // Create context for our request with 10 second timeout - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - // Create request input tensors - inferInputs := []*grpc_client.ModelInferRequest_InferInputTensor{ - &grpc_client.ModelInferRequest_InferInputTensor{ - Name: "images", - Datatype: "FP32", - Shape: defaultInputShape, - Contents: &grpc_client.InferTensorContents{ - Fp32Contents: image, - }, - }, - } - - // Create inference request for specific model/version - modelInferRequest := grpc_client.ModelInferRequest{ - ModelName: modelName, - ModelVersion: modelVersion, - Inputs: inferInputs, - } - - // Submit inference request to server - modelInferResponse, err := client.ModelInfer(ctx, &modelInferRequest) - if err != nil { - // we don't want the pipeline to quit due to log.Fatal's exit - fmt.Println("Error processing InferRequest: ", err) - return nil, fmt.Errorf("Error on processing InferRequest: %v", err) - } - - responseOutputs := TensorOutputs{ - RawData: modelInferResponse.RawOutputContents, - DataShapes: GetAllShapes(modelInferResponse), - } - - responseOutputs.ParseRawData() - return &responseOutputs, nil -} diff --git a/configs/opencv-ovms/grpc_go/pkg/ovms/inferResponse.go b/configs/opencv-ovms/grpc_go/pkg/ovms/inferResponse.go deleted file mode 100644 index 6b073e40..00000000 --- a/configs/opencv-ovms/grpc_go/pkg/ovms/inferResponse.go +++ /dev/null @@ -1,18 +0,0 @@ -/********************************************************************* - * Copyright (c) Intel Corporation 2023 - * SPDX-License-Identifier: Apache-2.0 - **********************************************************************/ - -package ovms - -import ( - grpc_client "videoProcess/grpc-client" -) - -func GetAllShapes(response *grpc_client.ModelInferResponse) [][]int64 { - shapes := [][]int64{} - for _, output := range response.GetOutputs() { - shapes = append(shapes, output.Shape) - } - return shapes -} diff --git a/configs/opencv-ovms/grpc_go/pkg/ovms/metadataRequest.go b/configs/opencv-ovms/grpc_go/pkg/ovms/metadataRequest.go deleted file mode 100644 index aaf0794e..00000000 --- a/configs/opencv-ovms/grpc_go/pkg/ovms/metadataRequest.go +++ /dev/null @@ -1,32 +0,0 @@ -/********************************************************************* - * Copyright (c) Intel Corporation 2023 - * SPDX-License-Identifier: Apache-2.0 - **********************************************************************/ - -package ovms - -import ( - "context" - "log" - "time" - - grpc_client "videoProcess/grpc-client" -) - -func ModelMetadataRequest(client grpc_client.GRPCInferenceServiceClient, modelName string, modelVersion string) *grpc_client.ModelMetadataResponse { - // Create context for our request with 10 second timeout - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - // Create status request for a given model - modelMetadataRequest := grpc_client.ModelMetadataRequest{ - Name: modelName, - Version: modelVersion, - } - // Submit modelMetadata request to server - modelMetadataResponse, err := client.ModelMetadata(ctx, &modelMetadataRequest) - if err != nil { - log.Fatalf("Couldn't get server model metadata: %v", err) - } - return modelMetadataResponse -} diff --git a/configs/opencv-ovms/grpc_go/pkg/ovms/tensorOutput.go b/configs/opencv-ovms/grpc_go/pkg/ovms/tensorOutput.go deleted file mode 100644 index 2004a4f8..00000000 --- a/configs/opencv-ovms/grpc_go/pkg/ovms/tensorOutput.go +++ /dev/null @@ -1,73 +0,0 @@ -/********************************************************************* - * Copyright (c) Intel Corporation 2023 - * SPDX-License-Identifier: Apache-2.0 - **********************************************************************/ - -package ovms - -import ( - "fmt" - - "gocv.io/x/gocv" -) - -type TensorOutput struct { - //name string - shape []int64 - data *gocv.Mat -} - -type TensorOutputs struct { - RawData [][]byte - DataShapes [][]int64 - outputs []TensorOutput -} - -func NewTensorOutputs(rawBytes [][]byte, dataShapes [][]int64) *TensorOutputs { - return &TensorOutputs{ - RawData: rawBytes, - DataShapes: dataShapes, - outputs: []TensorOutput{}, - } -} - -func (tOutputs *TensorOutputs) GetOutputs() []TensorOutput { - return tOutputs.outputs -} - -func (tOutputs *TensorOutputs) ParseRawData() error { - lenOfShapes := len(tOutputs.DataShapes) - - if lenOfShapes != len(tOutputs.RawData) { - return fmt.Errorf("len of data shapes and rawdata do not match") - } - - for i := 0; i < lenOfShapes; i++ { - rows := int(tOutputs.DataShapes[i][1] * tOutputs.DataShapes[i][2] * tOutputs.DataShapes[i][3]) - dataMat, err := gocv.NewMatFromBytes(rows, 1, gocv.MatTypeCV32F, tOutputs.RawData[i]) - if err != nil { - return fmt.Errorf("failed to create gocv.Mat from bytes") - } - - tensorOutput := TensorOutput{ - shape: tOutputs.DataShapes[i], - data: &dataMat, - } - - tOutputs.outputs = append(tOutputs.outputs, tensorOutput) - - } - return nil -} - -func (tensor *TensorOutput) ToFloat32() ([]float32, error) { - return tensor.data.DataPtrFloat32() -} - -func (tensor *TensorOutput) GetData() *gocv.Mat { - return tensor.data -} - -func (tensor *TensorOutput) GetShape() []int64 { - return tensor.shape -} diff --git a/configs/opencv-ovms/grpc_go/pkg/ovms/tensorOutput_test.go b/configs/opencv-ovms/grpc_go/pkg/ovms/tensorOutput_test.go deleted file mode 100644 index 555624b4..00000000 --- a/configs/opencv-ovms/grpc_go/pkg/ovms/tensorOutput_test.go +++ /dev/null @@ -1,75 +0,0 @@ -/********************************************************************* - * Copyright (c) Intel Corporation 2023 - * SPDX-License-Identifier: Apache-2.0 - **********************************************************************/ - -package ovms - -import ( - "bytes" - "encoding/binary" - "fmt" - "testing" -) - -func helper_float32toByte(f float64) []byte { - float32Val := float32(f) - var buf bytes.Buffer - err := binary.Write(&buf, binary.LittleEndian, float32Val) - if err != nil { - fmt.Println("binary.Write failed:", err) - } - return buf.Bytes() -} - -func TestTensorOutputs_ParseRawData(t *testing.T) { - type fields struct { - rawData [][]byte - dataShapes [][]int64 - outputs []TensorOutput - } - tests := []struct { - name string - fields fields - wantErr bool - }{ - // TODO: Add test cases. - { - name: "happy Path", - fields: fields{ - rawData: [][]byte{ - helper_float32toByte(0.5), - }, - dataShapes: [][]int64{ - {1, 1, 1}, - }, - }, - wantErr: false, - }, - { - name: "len of shape and rawoutput mismatch", - fields: fields{ - rawData: [][]byte{ - helper_float32toByte(0.5), - helper_float32toByte(0.5), - }, - dataShapes: [][]int64{ - {1, 1, 2}, - }, - }, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tOutputs := &TensorOutputs{ - RawData: tt.fields.rawData, - DataShapes: tt.fields.dataShapes, - outputs: tt.fields.outputs, - } - if err := tOutputs.ParseRawData(); (err != nil) != tt.wantErr { - t.Errorf("TensorOutputs.ParseRawData() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} diff --git a/configs/opencv-ovms/grpc_go/pkg/yolov5/consts.go b/configs/opencv-ovms/grpc_go/pkg/yolov5/consts.go deleted file mode 100644 index 11e81d9f..00000000 --- a/configs/opencv-ovms/grpc_go/pkg/yolov5/consts.go +++ /dev/null @@ -1,128 +0,0 @@ -/********************************************************************* - * Copyright (c) Intel Corporation 2023 - * SPDX-License-Identifier: Apache-2.0 - **********************************************************************/ - -package yolov5 - -const ( - outputSize = 4 - confidence_threshold = .5 - boxiou_threshold = .4 - iou_threshold = 0.4 - classes = 80 -) - -var ( - Input_shape = []int64{1, 416, 416, 3} - // Anchors by region/output layer - Anchors_52 = []float32{ - 10.0, - 13.0, - 16.0, - 30.0, - 33.0, - 23.0, - } - - Anchors_26 = []float32{ - 30.0, - 61.0, - 62.0, - 45.0, - 59.0, - 119.0, - } - - Anchors_13 = []float32{ - 116.0, - 90.0, - 156.0, - 198.0, - 373.0, - 326.0, - } - - Labels = []string{ - "person", - "bicycle", - "car", - "motorbike", - "aeroplane", - "bus", - "train", - "truck", - "boat", - "traffic light", - "fire hydrant", - "stop sign", - "parking meter", - "bench", - "bird", - "cat", - "dog", - "horse", - "sheep", - "cow", - "elephant", - "bear", - "zebra", - "giraffe", - "backpack", - "umbrella", - "handbag", - "tie", - "suitcase", - "frisbee", - "skis", - "snowboard", - "sports ball", - "kite", - "baseball bat", - "baseball glove", - "skateboard", - "surfboard", - "tennis racket", - "bottle", - "wine glass", - "cup", - "fork", - "knife", - "spoon", - "bowl", - "banana", - "apple", - "sandwich", - "orange", - "broccoli", - "carrot", - "hot dog", - "pizza", - "donut", - "cake", - "chair", - "sofa", - "pottedplant", - "bed", - "diningtable", - "toilet", - "tvmonitor", - "laptop", - "mouse", - "remote", - "keyboard", - "cell phone", - "microwave", - "oven", - "toaster", - "sink", - "refrigerator", - "book", - "clock", - "vase", - "scissors", - "teddy bear", - "hair drier", - "toothbrush", - } -) diff --git a/configs/opencv-ovms/grpc_go/pkg/yolov5/detectedObject.go b/configs/opencv-ovms/grpc_go/pkg/yolov5/detectedObject.go deleted file mode 100644 index 3e5c6467..00000000 --- a/configs/opencv-ovms/grpc_go/pkg/yolov5/detectedObject.go +++ /dev/null @@ -1,205 +0,0 @@ -/********************************************************************* - * Copyright (c) Intel Corporation 2023 - * SPDX-License-Identifier: Apache-2.0 - **********************************************************************/ - -package yolov5 - -import ( - "image" - "image/color" - "sort" - - "videoProcess/pkg/ovms" - "videoProcess/utilities" - - "gocv.io/x/gocv" -) - -type DetectedObject struct { - frameId int - x float32 - y float32 - width float32 - height float32 - confidence float32 - classId int - classText string -} - -type DetectedObjects struct { - Objects []DetectedObject - scale_h float32 - scale_w float32 - boundingBoxThickness int -} - -func (dObj *DetectedObject) BoundingBox(camWidth float32, - camHeight float32) image.Rectangle { - - return image.Rect( - int(dObj.x*(416.0/camWidth)), - int(dObj.y*(416.0/camHeight)), - int((dObj.x+dObj.width)*(416.0/camWidth)), - int((dObj.y+dObj.height)*(416.0/camHeight)), - ) - -} - -func (dObj *DetectedObject) GetConfidence() float32 { - return dObj.confidence -} -func (dObj *DetectedObject) GetClassId() int { - return dObj.classId -} -func (dObj *DetectedObject) GetClassText() string { - return dObj.classText -} -func (dObj *DetectedObject) GetFrameId() int { - return dObj.frameId -} - -func (dObjs *DetectedObjects) AddBoxesToFrame(frame *gocv.Mat, boxColor color.RGBA, camWidth float32, camHeight float32) { - for _, obj := range dObjs.Objects { - gocv.Rectangle(frame, - obj.BoundingBox(camWidth, camHeight), - boxColor, - dObjs.boundingBoxThickness) - } - -} - -func (dObjs *DetectedObjects) intersectionOverUnion(object1 DetectedObject, object2 DetectedObject) float32 { - var intersectionArea float32 - - overlappingWidth := utilities.Min(object1.x+object1.width, object2.x+object2.width) - utilities.Max(object1.x, object2.x) - overlappingHeight := utilities.Min(object1.y+object1.height, object2.y+object2.height) - utilities.Max(object1.y, object2.y) - - if overlappingWidth < 0 || overlappingHeight < 0 { - intersectionArea = 0 - } else { - intersectionArea = overlappingHeight * overlappingWidth - } - unionArea := object1.width*object1.height + object2.width*object2.height - intersectionArea - return intersectionArea / unionArea -} - -func (dObjs *DetectedObjects) FinalPostProcessClassic() DetectedObjects { - // Classic postprocessing - sort.SliceStable(dObjs.Objects, func(i, j int) bool { - return dObjs.Objects[i].confidence > dObjs.Objects[j].confidence - }) - - outDetectedResults := DetectedObjects{} - - for i := 1; i < len(dObjs.Objects); i++ { - if dObjs.Objects[i].confidence == 0 { - continue - } - for j := i + 1; j < len(dObjs.Objects); j++ { - if dObjs.intersectionOverUnion(dObjs.Objects[i], dObjs.Objects[j]) >= boxiou_threshold { - dObjs.Objects[j].confidence = 0 - } - outDetectedResults.Objects = append(outDetectedResults.Objects, dObjs.Objects[i]) - } - - } - return outDetectedResults -} - -func (dObjs *DetectedObjects) FinalPostProcessAdvanced() DetectedObjects { - // Advanced postprocessing - // Checking IOU threshold conformance - // For every i-th object we're finding all objects it intersects with, and comparing confidence - // If i-th object has greater confidence than all others, we include it into result - outDetectedResults := DetectedObjects{} - for _, obj1 := range dObjs.Objects { - - isGoodResult := true - for _, obj2 := range dObjs.Objects { - if obj1.classId == obj2.classId && obj1.confidence < obj2.confidence && - dObjs.intersectionOverUnion(obj1, obj2) >= boxiou_threshold { // if obj1 is the same as obj2, condition - // expression will evaluate to false anyway - isGoodResult = false - break - } - } - if isGoodResult { - outDetectedResults.Objects = append(outDetectedResults.Objects, obj1) - } - - } - return outDetectedResults -} - -func (dObjs *DetectedObjects) calculateEntryIndex(totalCells int, lcoords int, lclasses int, location int, entry int) int { - n := location / totalCells - loc := location % totalCells - return (n*(lcoords+lclasses)+entry)*totalCells + loc -} - -func (dObjs *DetectedObjects) getClassLabelText(classIndex int) string { - if classIndex > 80 { - return "" - } - - return Labels[classIndex] -} - -func (dObjs *DetectedObjects) Postprocess(tensorOutputs ovms.TensorOutputs, camWidth float32, camHeight float32) error { - regionCoordsCount := 3 - regionNum := 3 - original_im_w := camWidth - original_im_h := camHeight - for _, tensor := range tensorOutputs.GetOutputs() { - - sideH := int(tensor.GetShape()[2]) // int(output_shape[2]) - sideW := int(tensor.GetShape()[3]) // int(output_shape[3]) - - scaleH := int(Input_shape[1]) - scaleW := int(Input_shape[2]) - - entriesNum := sideW * sideH - outData, _ := tensor.ToFloat32() - for i := 1; i < entriesNum; i++ { - row := i / sideW - col := i % sideW - for n := 1; n < regionNum; n++ { - - obj_index := dObjs.calculateEntryIndex(entriesNum, regionCoordsCount, classes+1 /* + confidence byte */, n*entriesNum+i, regionCoordsCount) - box_index := dObjs.calculateEntryIndex(entriesNum, regionCoordsCount, classes+1, n*entriesNum+i, 0) - outdata := outData[obj_index] - scale := utilities.Sigmoid(outdata) - - if scale >= confidence_threshold { - x := (float32(col) + utilities.Sigmoid(outData[box_index+0*entriesNum])) / float32(sideW) * float32(original_im_w) - y := (float32(row) + utilities.Sigmoid(outData[box_index+1*entriesNum])) / float32(sideH) * float32(original_im_h) - height := (utilities.ExpPow(outData[box_index+3*entriesNum]) * Anchors_13[2*n+1] * float32(original_im_h)) / float32(scaleH) - width := utilities.ExpPow(outData[box_index+2*entriesNum]) * Anchors_13[2*n] * float32(original_im_w) / float32(scaleW) - - obj := DetectedObject{} - obj.x = utilities.Clamp(x-width/2.0, 0.0, float32(original_im_w)) - obj.y = utilities.Clamp(y-height/2.0, 0.0, float32(original_im_h)) - obj.width = utilities.Clamp(width, 0.0, float32(original_im_w)-obj.x) - obj.height = utilities.Clamp(height, 0.0, float32(original_im_h)-obj.y) - - for j := 1; j < classes; j++ { - class_index := dObjs.calculateEntryIndex(entriesNum, regionCoordsCount, classes+1, n*entriesNum+i, regionCoordsCount+1+j) - prob := scale * utilities.Sigmoid(outData[class_index]) - - if prob >= confidence_threshold { - obj.confidence = prob - obj.classId = j - obj.classText = dObjs.getClassLabelText(j) - - dObjs.Objects = append(dObjs.Objects, obj) - - } - } - - } - } - } - } - return nil -} diff --git a/configs/opencv-ovms/grpc_go/stream_density_run.sh b/configs/opencv-ovms/grpc_go/stream_density_run.sh deleted file mode 100755 index eb4a3b70..00000000 --- a/configs/opencv-ovms/grpc_go/stream_density_run.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -/app/stream_density.sh /app/entrypoint.sh diff --git a/configs/opencv-ovms/grpc_go/utilities/flags.go b/configs/opencv-ovms/grpc_go/utilities/flags.go deleted file mode 100644 index 53bcb639..00000000 --- a/configs/opencv-ovms/grpc_go/utilities/flags.go +++ /dev/null @@ -1,31 +0,0 @@ -/********************************************************************* - * Copyright (c) Intel Corporation 2023 - * SPDX-License-Identifier: Apache-2.0 - **********************************************************************/ - -package utilities - -import "flag" - -type Flags struct { - InputSrc string - ModelName string - ModelVersion string - URL string - Labels string - Host string - Output string -} - -func ParseFlags() Flags { - var flags Flags - flag.StringVar(&flags.InputSrc, "i", "coca-cola-4465029.mp4", "Input src string") - flag.StringVar(&flags.ModelName, "n", "yolov5s", "Name of model being served. ") - flag.StringVar(&flags.ModelVersion, "v", "", "Version of model. ") - flag.StringVar(&flags.URL, "u", "localhost:9000", "Inference Server URL. ") - flag.StringVar(&flags.Labels, "l", "", "Path to a file with a list of labels.") - flag.StringVar(&flags.Host, "h", "0.0.0.0:8080", "Restream host location") - flag.StringVar(&flags.Output, "o", "/tmp/results", "Results output directory") - flag.Parse() - return flags -} diff --git a/configs/opencv-ovms/grpc_go/utilities/util.go b/configs/opencv-ovms/grpc_go/utilities/util.go deleted file mode 100644 index 6e8ed67a..00000000 --- a/configs/opencv-ovms/grpc_go/utilities/util.go +++ /dev/null @@ -1,42 +0,0 @@ -/********************************************************************* - * Copyright (c) Intel Corporation 2023 - * SPDX-License-Identifier: Apache-2.0 - **********************************************************************/ - -package utilities - -import "math" - -func ExpPow(val float32) float32 { - val_float64 := float64(val) - results := math.Exp(val_float64) - return float32(results) -} - -func Sigmoid(x float32) float32 { - return 1.0 / (1.0 + ExpPow(-x)) -} - -func Min(value1 float32, value2 float32) float32 { - if value1 < value2 { - return value1 - } - return value2 -} - -func Max(value1 float32, value2 float32) float32 { - if value1 > value2 { - return value1 - } - return value2 -} - -func Clamp(val float32, min float32, max float32) float32 { - if val < min { - return min - } - if val > max { - return max - } - return val -} diff --git a/configs/opencv-ovms/grpc_python/Dockerfile b/configs/opencv-ovms/grpc_python/Dockerfile deleted file mode 100644 index 8187c3d3..00000000 --- a/configs/opencv-ovms/grpc_python/Dockerfile +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -FROM ubuntu:20.04 -SHELL ["/bin/bash", "-o", "pipefail", "-c"] -RUN if [ -n "$HTTP_PROXY" ]; then echo "Acquire::http:Proxy \"$HTTP_PROXY\";" > /etc/apt/apt.conf; fi - -RUN apt-get update -y || true; DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - build-essential \ - git \ - python3 \ - python3-pip \ - python3-opencv && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* - -RUN git clone https://github.com/openvinotoolkit/model_server -WORKDIR /model_server/client/python/kserve-api/samples -RUN pip3 install -r requirements.txt; pip3 install opencv-python -WORKDIR /app -COPY . . diff --git a/configs/opencv-ovms/grpc_python/Makefile b/configs/opencv-ovms/grpc_python/Makefile deleted file mode 100644 index 70b8a884..00000000 --- a/configs/opencv-ovms/grpc_python/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright © 2023 Intel Corporation. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -.PHONY: build - -build: - docker build -t grpc_python:dev . \ No newline at end of file diff --git a/configs/opencv-ovms/grpc_python/grpc_postprocess.py b/configs/opencv-ovms/grpc_python/grpc_postprocess.py deleted file mode 100644 index c77fa1a8..00000000 --- a/configs/opencv-ovms/grpc_python/grpc_postprocess.py +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -import numpy as np -from tritonclient.utils import * - -DataTypeToContentsFieldName = { - 'BOOL' : 'bool_contents', - 'BYTES' : 'bytes_contents', - 'FP32' : 'fp32_contents', - 'FP64' : 'fp64_contents', - 'INT64' : 'int64_contents', - 'INT32' : 'int_contents', - 'UINT64' : 'uint64_contents', - 'UINT32' : 'uint_contents', - 'INT64' : 'int64_contents', - 'INT32' : 'int_contents', -} - -def as_numpy(response, name): - index = 0 - for output in response.outputs: - if output.name == name: - shape = [] - for value in output.shape: - shape.append(value) - datatype = output.datatype - field_name = DataTypeToContentsFieldName[datatype] - contents = getattr(output, "contents") - contents = getattr(contents, f"{field_name}") - if index < len(response.raw_output_contents): - np_array = np.frombuffer( - response.raw_output_contents[index], dtype=triton_to_np_dtype(output.datatype)) - elif len(contents) != 0: - np_array = np.array(contents, - copy=False) - else: - np_array = np.empty(0) - np_array = np_array.reshape(shape) - return np_array - else: - index += 1 - return None - -def postProcessMaskRCNN(response, duration): - # omz instance segmentation model has three outputs - output1 = as_numpy(response, "3523") - output2 = as_numpy(response, "3524") - output3 = as_numpy(response, "masks") - nu = np.array(output1) - nu2 = np.array(output2) - nu3 = np.array(output3) - # for object classification models show imagenet class - print('Processing time: {:.2f} ms; fps: {:.2f}'.format(round(np.average(duration), 2),round(1000 / np.average(duration), 2))) - return output1 - -def postProcessBit(response, duration): - output = as_numpy(response, "output_1") - nu = np.array(output) - print('Processing time: {:.2f} ms; fps: {:.2f}'.format(round(np.average(duration), 2),round(1000 / np.average(duration), 2))) - return output - -def postProcessYolov5s(response, duration): - output = as_numpy(response, "326/sink_port_0") - nu = np.array(output) - print('Processing time: {:.2f} ms; fps: {:.2f}'.format(round(np.average(duration), 2),round(1000 / np.average(duration), 2))) - return output \ No newline at end of file diff --git a/configs/opencv-ovms/grpc_python/grpc_python.py b/configs/opencv-ovms/grpc_python/grpc_python.py deleted file mode 100644 index 48cae1f4..00000000 --- a/configs/opencv-ovms/grpc_python/grpc_python.py +++ /dev/null @@ -1,122 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -import sys -sys.path.append("/model_server/demos/common/python") - -import argparse -import datetime -import cv2 -import grpc -from client_utils import print_statistics -from tritonclient.grpc import service_pb2, service_pb2_grpc -from grpc_postprocess import * - -def openInputSrc(input_src): - # OpenCV RTSP Stream - stream = cv2.VideoCapture(input_src) - if not stream.isOpened(): - print('Unable to open source:' + input_src) - exit(-1) - return stream - -def setupGRPC(address, port): - address = "{}:{}".format(address, port) - # Create gRPC stub for communicating with the server - channel = grpc.insecure_channel(address) - grpc_stub = service_pb2_grpc.GRPCInferenceServiceStub(channel) - return grpc_stub - -def getModelSize(model_name): - if model_name == "instance-segmentation-security-1040": - return [608,608] - elif model_name == "bit_64": - return [64,64] - elif model_name == "yolov5s": - return [416,416] - else: - return None - -def getInputName(model_name): - if model_name == "instance-segmentation-security-1040": - return "image" - elif model_name == "bit_64": - return "input_1" - elif model_name == "yolov5s": - return "images" - else: - return None - -def getOutputName(model_name): - if model_name == "instance-segmentation-security-1040": - return "mask" - elif model_name == "bit_64": - return "output_1" - elif model_name == "yolov5s": - return "326/sink_port_0" - else: - return None - -def inference(img_str, model_name, grpc_stub): - inputs = [] - inputs.append(service_pb2.ModelInferRequest().InferInputTensor()) - inputs[0].name = getInputName(model_name) - inputs[0].datatype = "BYTES" - inputs[0].shape.extend([1]) - inputs[0].contents.bytes_contents.append(img_str) - outputs = [] - outputs.append(service_pb2.ModelInferRequest().InferRequestedOutputTensor()) - outputs[0].name = getOutputName(model_name) - request = service_pb2.ModelInferRequest() - request.model_name = model_name - request.inputs.extend(inputs) - start_time = datetime.datetime.now() - request.outputs.extend(outputs) - response = grpc_stub.ModelInfer(request) - end_time = datetime.datetime.now() - duration = (end_time - start_time).total_seconds() * 1000 - return [response, duration] - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Sends requests via KServe gRPC API using images in format supported by OpenCV. It displays performance statistics and optionally the model accuracy') - parser.add_argument('--input_src', required=True, default='', help='input source for the inference pipeline') - parser.add_argument('--grpc_address',required=False, default='localhost', help='Specify url to grpc service. default:localhost') - parser.add_argument('--grpc_port',required=False, default=9000, help='Specify port to grpc service. default: 9000') - parser.add_argument('--model_name', default='instance-segmentation-security-1040', help='Define model name, must be same as is in service. default: resnet', - dest='model_name') - args = vars(parser.parse_args()) - - # print("Connect to stream") - stream = openInputSrc(args['input_src']) - - # print("Establish OVMS GRPc connection") - grpc_stub = setupGRPC(args['grpc_address'],args['grpc_port']) - - # print("Get the model size from OVMS metadata") - model_size = getModelSize(args['model_name']) - model_name = args['model_name'] - - # print("Begin inference loop") - while True: - try: - # get frame from OpenCV - _, frame = stream.read() - img = cv2.resize(frame, (model_size[0], model_size[1])) - img_str = cv2.imencode('.jpg', img)[1].tobytes() - - response = inference(img_str, args['model_name'], grpc_stub) - if model_name == "instance-segmentation-security-1040": - postProcessMaskRCNN(response[0], response[1]) - elif model_name == "bit_64": - postProcessBit(response[0], response[1]) - elif model_name == "yolov5s": - postProcessYolov5s(response[0], response[1]) - else: - print("Unsupported model_name: {}".format(model_name)) - exit(1) - except Exception as e: - print(e) - pass # nosec diff --git a/configs/opencv-ovms/grpc_python/grpc_python_test.py b/configs/opencv-ovms/grpc_python/grpc_python_test.py deleted file mode 100644 index cd0b5cba..00000000 --- a/configs/opencv-ovms/grpc_python/grpc_python_test.py +++ /dev/null @@ -1,87 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -import unittest -from grpc_python import * - -class TestOpenInputSrc(unittest.TestCase): - def test_inference(self): - self.assertTrue(openInputSrc("rtsp://127.0.0.1:8554/camera_0")) - -class TestSetupGRPC(unittest.TestCase): - def test_inference(self): - self.assertTrue(setupGRPC("127.0.0.1", "9000")) - -class TestGetModelSize(unittest.TestCase): - def test_inference(self): - self.assertEqual(getModelSize("model_name"), [608,608]) - -class TestInference(unittest.TestCase): - def test_inference(self): - # Get model size - model_size = getModelSize("instance-segmentation-security-1040") - # Get video stream - stream = openInputSrc("rtsp://127.0.0.1:8554/camera_0") - # Get frame from OpenCV - _, frame = stream.read() - img = cv2.resize(frame, (model_size[0], model_size[1])) - img_str = cv2.imencode('.jpg', img)[1].tobytes() - # Get GRPc - grpc_stub = setupGRPC("127.0.0.1", "9000") - response = inference(img_str,"instance-segmentation-security-1040", grpc_stub) - self.assertTrue(response) - -class TestAsNumpy(unittest.TestCase): - def test_inference(self): - # Get model size - model_size = getModelSize("instance-segmentation-security-1040") - # Get video stream - stream = openInputSrc("rtsp://127.0.0.1:8554/camera_0") - # Get frame from OpenCV - _, frame = stream.read() - img = cv2.resize(frame, (model_size[0], model_size[1])) - img_str = cv2.imencode('.jpg', img)[1].tobytes() - # Get GRPc - grpc_stub = setupGRPC("127.0.0.1", "9000") - response = inference(img_str,"instance-segmentation-security-1040", grpc_stub) - results = as_numpy(response[0], "3523") - self.assertTrue(len(results)) - -class TestPostProcessMaskRCNN(unittest.TestCase): - def test_inference(self): - # Get model size - model_size = getModelSize("instance-segmentation-security-1040") - # Get video stream - stream = openInputSrc("rtsp://127.0.0.1:8554/camera_0") - # Get frame from OpenCV - _, frame = stream.read() - img = cv2.resize(frame, (model_size[0], model_size[1])) - img_str = cv2.imencode('.jpg', img)[1].tobytes() - # Get GRPc - grpc_stub = setupGRPC("127.0.0.1", "9000") - response = inference(img_str,"instance-segmentation-security-1040", grpc_stub) - results = postProcessMaskRCNN(response[0], response[1]) - self.assertTrue(len(results)) - -# TODO: implement the bit process -# class TestPostProcessBit(unittest.TestCase): -# def test_inference(self): -# # Get model size -# model_size = getModelSize("instance-segmentation-security-1040") -# # Get video stream -# stream = openInputSrc("rtsp://127.0.0.1:8554/camera_0") -# # Get frame from OpenCV -# _, frame = stream.read() -# img = cv2.resize(frame, (model_size[0], model_size[1])) -# img_str = cv2.imencode('.jpg', img)[1].tobytes() -# # Get GRPc -# grpc_stub = setupGRPC("127.0.0.1", "9000") -# response = inference(img_str,"instance-segmentation-security-1040", grpc_stub) -# results = postProcessBit(response[0], response[1]) -# self.assertTrue(len(results)) - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/configs/opencv-ovms/grpc_python/run_grpc_python.sh b/configs/opencv-ovms/grpc_python/run_grpc_python.sh deleted file mode 100755 index 23097285..00000000 --- a/configs/opencv-ovms/grpc_python/run_grpc_python.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# https://github.com/openvinotoolkit/model_server/tree/main/client/python/kserve-api/samples -GRPC_PORT="${GRPC_PORT:=9000}" -cid_count="${cid_count:=0}" - -while :; do - case $1 in - --model_name) - if [ "$2" ]; then - DETECTION_MODEL_NAME=$2 - shift - else - error 'ERROR: "--model_name" requires an argument' - fi - ;; - -?*) - error "ERROR: Unknown option $1" - ;; - ?*) - error "ERROR: Unknown option $1" - ;; - *) - break - ;; - esac - - shift - -done - -echo "running grpcpython with GRPC_PORT=$GRPC_PORT, DETECTION_MODEL_NAME:$DETECTION_MODEL_NAME" - -# Run the grpc python client -python3 ./grpc_python.py --input_src "$INPUTSRC" --grpc_address 127.0.0.1 --grpc_port "$GRPC_PORT" --model_name "$DETECTION_MODEL_NAME" \ -2>&1 | tee >/tmp/results/r$cid_count.jsonl >(stdbuf -oL sed -n -e 's/^.*fps: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid_count.log) diff --git a/configs/opencv-ovms/gst/extensions/OCR_post_processing.py b/configs/opencv-ovms/gst/extensions/OCR_post_processing.py deleted file mode 100644 index 6d57fdc1..00000000 --- a/configs/opencv-ovms/gst/extensions/OCR_post_processing.py +++ /dev/null @@ -1,66 +0,0 @@ -''' -* Copyright (C) 2023 Intel Corporation. -* -* SPDX-License-Identifier: Apache-2.0 -''' - -from json import decoder -import numpy as np -from gstgva import VideoFrame -from gi.repository import Gst, GObject -import sys -import gi -gi.require_version('Gst', '1.0') -Gst.init(sys.argv) - -# The net output is a blob with the shape 30, 1, 37 in the format W, B, L, where: -# W - output sequence length -# B - batch size -# # , where # - special blank character for CTC decoding algorithm. -# L - confidence distribution across alphanumeric symbols: 0123456789abcdefghijklmnopqrstuvwxyz -# The network output can be decoded by CTC Greedy Decoder/CTC Beam decoder - -# This extension implements CTC Greedy Decoder - -class OCR: - W = 16 - B = 1 - L = 37 - - ALPHABET = [ "#", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", - "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"] - - def __init__(self, threshold=0.5): - self.threshold = threshold - - def softmax(self, value): - e_value = np.exp(value - np.max(value)) - return e_value / e_value.sum() - - def process_frame(self, frame): - #return True - try: - for region in frame.regions(): - for tensor in region.tensors(): - label = "" - - if tensor["converter"] == "raw_data_copy": - #print("Found converter") - data = tensor.data() - data = data.reshape(self.W, self.L) - for i in range(self.W): - conf_list = self.softmax(data[i][:]) - x = self.softmax(conf_list) - highest_prob = max(x) - if highest_prob < self.threshold: - pass - index = np.where(x == highest_prob)[0][0] - if index == 0: - continue - label += OCR.ALPHABET[index] - if label: - tensor.set_label(label) - except Exception as e: - print(str(e)) - - return True diff --git a/configs/opencv-ovms/gst/extensions/barcode.py b/configs/opencv-ovms/gst/extensions/barcode.py deleted file mode 100644 index 7e861b5b..00000000 --- a/configs/opencv-ovms/gst/extensions/barcode.py +++ /dev/null @@ -1,178 +0,0 @@ -''' -* Copyright (C) 2023 Intel Corporation. -* -* SPDX-License-Identifier: Apache-2.0 -''' - -import zxingcpp -import pyzbar.pyzbar as pyzbar -from pyzbar.pyzbar import ZBarSymbol -#from server.common.utils import logging -from collections import OrderedDict -from dataclasses import dataclass -from abc import ABC, abstractmethod - -#logger = logging.get_logger('barcode', is_static=True) - - -@dataclass -class DetectedObject: - x: int - y: int - w: int - h: int - label: str - confidence: float - - -class BarcodeDecoder(ABC): - def __init__(self) -> None: - pass - - @abstractmethod - def decode(self, region_data): - pass - - def convert_bytestring(self, barcode): - if str(barcode): - return barcode - return barcode.decode('utf-8') - - -class PyZbar(BarcodeDecoder): - BARCODE_TYPES = [ZBarSymbol.EAN2, - ZBarSymbol.EAN5, - ZBarSymbol.EAN8, - ZBarSymbol.UPCE, - ZBarSymbol.ISBN10, - ZBarSymbol.UPCA, - ZBarSymbol.EAN13, - ZBarSymbol.ISBN13, - ZBarSymbol.COMPOSITE, - ZBarSymbol.I25, - ZBarSymbol.DATABAR, - ZBarSymbol.DATABAR_EXP, - ZBarSymbol.CODABAR, - ZBarSymbol.CODE39, - ZBarSymbol.PDF417, - ZBarSymbol.SQCODE, - ZBarSymbol.CODE93, - ZBarSymbol.CODE128] - - def __init__(self) -> None: - super().__init__() - - def decode(self, region_data): - barcodes = [] - decodedObjects = pyzbar.decode( - region_data, PyZbar.BARCODE_TYPES) - for barcode in decodedObjects: - (x, y, w, h) = barcode.rect - new_label = "barcode: {}".format( - self.convert_bytestring(barcode.data)) - barcode = DetectedObject(x, y, w, h, new_label, 0.9) - #logger.debug("Adding x {} y {} w {} h {} label {}".format( - # x, y, w, h, new_label)) - barcodes.append(barcode) - return barcodes - - -class ZxingCpp(BarcodeDecoder): - def __init__(self) -> None: - super().__init__() - - def decode(self, region_data): - barcodes = [] - barcode = zxingcpp.read_barcode( - region_data, zxingcpp.BarcodeFormat.UPCA) - if barcode is None: - return [] - (x, y, w, h) = (barcode.position.top_left.x, - barcode.position.top_left.y, 0, 0) - new_label = "barcode: {}".format( - self.convert_bytestring(barcode.text)) - barcode = DetectedObject(x, y, w, h, new_label, 0.9) - barcodes.append(barcode) - return barcodes - - -class LRUCache: - def __init__(self, max_tracked_objects): - self.data = OrderedDict() - self.capacity = max_tracked_objects - - def get(self, key: int) -> int: - if key not in self.data: - return None - else: - self.data.move_to_end(key) - return self.data[key] - - def put(self, key: int, value: int) -> None: - self.data[key] = value - self.data.move_to_end(key) - if len(self.data) > self.capacity: - self.data.popitem(last=False) - - -class BarcodeDetection: - SUPPORTED_LIBRARIES = ["pyzbar", "zxingcpp"] - - def __init__(self, disable=False, decode_type="zxingcpp", reclassify_interval=5, max_tracked_objects=20): - self.disable = disable - - self.reclassify_interval = reclassify_interval - self.frame_count = 0 - self.tracked_objects = LRUCache(max_tracked_objects) - - #if self.disable: - # logger.info("Barcode disabled") - - if decode_type == "pyzbar": - self.decoder = PyZbar() - elif decode_type == "zxingcpp": - self.decoder = ZxingCpp() - - def process_frame(self, frame): - - if self.disable: - return True - self.frame_count += 1 - skip_frame_processing = False - if self.reclassify_interval != -1 and (self.reclassify_interval == 0 or (self.frame_count % self.reclassify_interval != 0)): - skip_frame_processing = True - - regions = list(frame.regions()) - with frame.data() as frame_data: - for region in regions: - region_rect = region.rect() - (o_x, o_y, _, _) = region_rect - object_id = region.object_id() - - # Do not reclassify, re-use prior results - tracked_objects_list = self.tracked_objects.get(object_id) - if skip_frame_processing and tracked_objects_list: - for tracked in tracked_objects_list: - x, y, w, h, label, confidence = tracked.x, tracked.y, tracked.w, tracked.h, tracked.label, tracked.confidence - #logger.debug("Adding barcode region from tracked objects x {} y {} w {} h {} label {}".format( - # x, y, w, h, label)) - frame.add_region( - x+o_x, y+o_y, w, h, label, confidence) - return True - - region_data = frame_data[region_rect.y:region_rect.y + - region_rect.h, region_rect.x:region_rect.x+region_rect.w] - barcodes = self.decoder.decode(region_data) - tracked_barcodes = [] - for barcode in barcodes: - #logger.debug("Adding barcode region x {} y {} w {} h {} label {}".format( - # barcode.x+o_x, barcode.y+o_y, barcode.w, barcode.h, barcode.label)) - frame.add_region(barcode.x+o_x, barcode.y+o_y, barcode.w, barcode.h, - barcode.label, barcode.confidence) - tracked_object = DetectedObject( - barcode.x, barcode.y, barcode.w, barcode.h, barcode.label, barcode.confidence) - tracked_barcodes.append(tracked_object) - if tracked_barcodes: - self.tracked_objects.put(object_id, tracked_barcodes) - - return True diff --git a/configs/opencv-ovms/gst/extensions/object_removal_by_label.py b/configs/opencv-ovms/gst/extensions/object_removal_by_label.py deleted file mode 100644 index 2c5b728f..00000000 --- a/configs/opencv-ovms/gst/extensions/object_removal_by_label.py +++ /dev/null @@ -1,24 +0,0 @@ -''' -* Copyright (C) 2023 Intel Corporation. -* -* SPDX-License-Identifier: Apache-2.0 -''' - -class ObjectRemovalByLabel: - def __init__(self, - object_filter=["dining table", "chair", "person", "bed", "sink"]): - self._object_filter = object_filter - - def process_frame(self, frame): - if not self._object_filter: - return True - regions = list(frame.regions()) - removable_regions = [region for region in regions if region.label() in self._object_filter] - - orig_regions=list(frame.regions()) - removable_region_ids = [region.region_id() for region in removable_regions] - for region in orig_regions: - if region.region_id() in removable_region_ids: - frame.remove_region(region) - - return True diff --git a/configs/opencv-ovms/gst/extensions/remote_classify.py b/configs/opencv-ovms/gst/extensions/remote_classify.py deleted file mode 100644 index 884c6733..00000000 --- a/configs/opencv-ovms/gst/extensions/remote_classify.py +++ /dev/null @@ -1,211 +0,0 @@ -''' -* Copyright (C) 2023 Intel Corporation. -* -* SPDX-License-Identifier: Apache-2.0 -''' - -import cv2 -import ovmsclient -import numpy -import json -import threading -import time -import os -from multiprocessing import Process, Queue -from vaserving.common.utils import logging - -def softmax(logits, axis=None): - exp = numpy.exp(logits) - return exp / numpy.sum(exp, axis=axis) - -def process_result(region, result, model_name, labels=None): - result = softmax(result) - classification = numpy.argmax(result) - if region: - tensor = region.add_tensor("classification") - tensor["label_id"] = int(classification) - tensor["model_name"] = model_name - tensor["confidence"] = float(result[0][int(classification)]) - if labels: - tensor["label"] = labels[tensor["label_id"]] - else: - tensor["label"] = str(tensor["label_id"]) - -class OVMSClassify: - - def _process(self): - pid = os.getpid() - - try: - client = ovmsclient.make_grpc_client(self._model_server) - except Exception as error: - print("Can't connect to model server %s, %s"%(self._model_server,error)) - return - self._logger.info("{} Process: {} Connected to ovms-server: {}".format(self._stream, - pid, - self._model_server)) - try: - - while True: - image = self._input_queue.get() - if not image: - break - - result = client.predict(inputs={self._input_name:image[1]},model_name = self._model_name) - self._output_queue.put((image[0],result,image[2],time.time(),pid)) - except Exception as error: - print("Exception in request: %s" %(error)) - - self._output_queue.put((None,None,None,None,None)) - - del client - - self._logger.info("{} Process: {} Completed".format(self._stream,pid)) - - - def __del__(self): - for _ in self._processes: - self._input_queue.put(None) - - def __init__(self, - model_name="efficientnet-b0", - model_proc="/home/pipeline-server/models/efficientnet-b0/1/efficientnet-b0.json", - model_server="ovms-server:9000", - processes=16, - max_objects=None, - min_objects=None, - stream=None, - scale=True, - object_filter=[]): - self._model_server = model_server - self._model_name = model_name - self._input_queue = Queue() - self._output_queue = Queue() - self._labels = [] - self._start_time =time.time() - self._last_report_time = self._start_time - self._classify_count = 0 - self._latencies = 0 - self._frames = 0 - self._min_objects = min_objects - self._max_objects = max_objects - self._logger = logging.get_logger('remote-classify', is_static=True) - self._stream = stream - self._region_sizes = 0 - self._scale = scale - self._object_filter = object_filter - - if not stream: - self._stream = "" - - if model_proc: - with open(model_proc, 'r') as model_proc_file: - model_proc_data = json.load(model_proc_file) - self._labels = model_proc_data["output_postproc"][0]["labels"] - self._input_name = model_proc_data["input_preproc"][0]["layer_name"] - - self._processes = [] - - for _ in range(processes): - self._processes.append(Process(target=self._process,daemon=True)) - self._processes[-1].start() - - def process_frame(self, frame): - regions = list(frame.regions()) - if self._object_filter: - regions = [region for region in regions if region.label() in self._object_filter] - - if self._min_objects and len(regions) < self._min_objects: - for _ in range(len(regions),self._min_objects): - regions.append(frame.add_region(0,0,1,1,"fake",1.0,True)) - - if self._max_objects and len(regions)>self._max_objects: - regions=regions[0:self._max_objects] - - with frame.data() as frame_data: - for index, region in enumerate(regions): - if self._max_objects and index>self._max_objects: - break - region_rect = region.rect() - region_data = frame_data[ - region_rect.y:region_rect.y+region_rect.h, - region_rect.x:region_rect.x+region_rect.w - ] - if self._scale: - region_data = cv2.resize(region_data,(224,224)) - _,img = cv2.imencode(".jpeg",region_data) - self._region_sizes += len(img) - self._input_queue.put((index,bytes(img),time.time())) - - for i in range(len(regions)): - if self._max_objects and i>self._max_objects: - break - index,result,input_time,output_time,pid = self._output_queue.get() - if index is None: - raise Exception("Error sending request to model server") - self._latencies += output_time - input_time - process_result(regions[index], - result, - self._model_name, - self._labels) - - self._classify_count += len(regions) - self._frames += 1 - - if time.time()-self._last_report_time>1 and self._classify_count: - self._last_report_time=time.time() - self._logger.info("{} Classification IPS: {}, Average Latency: {}, Objects Per Frame: {}, Average Region Size: {}" .format - (self._stream, - self._classify_count/(self._last_report_time-self._start_time), - self._latencies / self._classify_count, - self._classify_count/self._frames, - self._region_sizes/self._classify_count)) - - return True - - - -class OVMSClassifyEncodeOnly: - - def __init__(self, - stream=None, - **kwargs): - self._start_time =time.time() - self._last_report_time = self._start_time - self._classify_count = 0 - self._latencies = 0 - self._logger = logging.get_logger('remote-classify', is_static=True) - self._stream = stream - if not stream: - self._stream = "" - - - def process_frame(self, frame): - with frame.data() as frame_data: - regions = list(frame.regions()) - for region in regions: - start = time.time() - region_rect = region.rect() - region_data = frame_data[ - region_rect.y:region_rect.y+region_rect.h, - region_rect.x:region_rect.x+region_rect.w - ] - _,img = cv2.imencode(".jpeg",region_data) - self._latencies += (time.time()-start) - - self._classify_count += len(regions) - if time.time()-self._last_report_time>1 and self._classify_count: - self._last_report_time=time.time() - self._logger.info("{} Encode IPS: {}, Average Latency: {}".format(self._stream, - self._classify_count/(self._last_report_time-self._start_time), - self._latencies / self._classify_count)) - - return True - - -class OVMSClassifyNoOp: - def __init__(self,**kwargs): - pass - def process_frame(self,frame): - return True - diff --git a/configs/opencv-ovms/gst/framework-pipelines/yolov5_pipeline/yolov5s_full.sh b/configs/opencv-ovms/gst/framework-pipelines/yolov5_pipeline/yolov5s_full.sh deleted file mode 100755 index 63df3556..00000000 --- a/configs/opencv-ovms/gst/framework-pipelines/yolov5_pipeline/yolov5s_full.sh +++ /dev/null @@ -1,31 +0,0 @@ - #!/bin/bash -# -# Copyright (C) 2024 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -DECODE="${DECODE:="decodebin force-sw-decoders=1"}" #decodebin|vaapidecodebin -DEVICE="${DEVICE:="CPU"}" #GPU|CPU|MULTI:GPU,CPU -PRE_PROCESS="${PRE_PROCESS:=""}" #""|pre-process-backend=vaapi-surface-sharing|pre-process-backend=vaapi-surface-sharing pre-process-config=VAAPI_FAST_SCALE_LOAD_FACTOR=1 -DETECTION_OPTIONS="${DETECTION_OPTIONS:=""}" # Extra detection model parameters ex. "" | gpu-throughput-streams=4 nireq=4 batch-size=1 -CLASSIFICATION_OPTIONS="${CLASSIFICATION_OPTIONS:="reclassify-interval=1 $DETECTION_OPTIONS"}" # Extra Classification model parameters ex. "" | reclassify-interval=1 batch-size=1 nireq=4 gpu-throughput-streams=4 -AGGREGATE="${AGGREGATE:=""}" # Aggregate function at the end of the pipeline ex. "" | gvametaaggregate name=aggregate -VA_SURFACE="${VA_SURFACE:=""}" # VA surface to use for shared memory ex. ""|! "video/x-raw(memory:VASurface)" (GPU only) -PARALLEL_PIPELINE="${PARALLEL_PIPELINE:=""}" # Run pipeline in parallel using the tee branch ex. ""|! tee name=branch ! queue -PARALLEL_AGGRAGATE="${PARALLEL_AGGRAGATE:=""}" # Aggregate parallel pipeline results together ex. "" | ! gvametaaggregate name=aggregate ! gvametaconvert name=metaconvert add-empty-results=true ! gvametapublish name=destination file-format=2 file-path=/tmp/results/r$cid_count.jsonl ! fpsdisplaysink video-sink=fakesink sync=true --verbose branch. ! queue ! -OCR_RECLASSIFY_INTERVAL="${OCR_RECLASSIFY_INTERVAL:=5}" -BARCODE_RECLASSIFY_INTERVAL="${BARCODE_RECLASSIFY_INTERVAL:=5}" - -if [ "$RENDER_MODE" == "1" ]; then - OUTPUT="${OUTPUT:="! videoconvert ! video/x-raw,format=I420 ! gvawatermark ! videoconvert ! fpsdisplaysink video-sink=ximagesink sync=true --verbose"}" -else - OUTPUT="${OUTPUT:="! fpsdisplaysink video-sink=fakesink sync=true --verbose"}" -fi - -echo "Run yolov5s with efficientnet classification, horizontal text detection, and barcode detection pipeline: BATCH_SIZE=$BATCH_SIZE" -gstLaunchCmd="gst-launch-1.0 $inputsrc ! $DECODE $VA_SURFACE ! gvadetect batch-size=$BATCH_SIZE model-instance-id=odmodel name=detection model=/home/pipeline-server/models/yolov5s/FP16-INT8/1/yolov5s.xml model-proc=/home/pipeline-server/models/yolov5s/FP16-INT8/1/yolov5s.json threshold=.5 device=$DEVICE $PRE_PROCESS $DETECTION_OPTIONS gpu-throughput-streams=4 nireq=4 batch-size=1 ! gvatrack name=tracking tracking-type=zero-term-imageless $PARALLEL_PIPELINE ! gvaclassify model-instance-id=clasifier labels=/home/pipeline-server/models/efficientnet-b0/1/imagenet_2012.txt model=/home/pipeline-server/models/efficientnet-b0/FP32-INT8/1/efficientnet-b0.xml model-proc=/home/pipeline-server/models/efficientnet-b0/efficientnet-b0.json reclassify-interval=1 device=$DEVICE inference-region=roi-list name=classification $PRE_PROCESS reclassify_interval=$OCR_RECLASSIFY_INTERVAL batch-size=8 nireq=4 gpu-throughput-streams=1 $PARALLEL_AGGRAGATE ! gvapython class=ObjectFilter module=/home/pipeline-server/extensions/tracked_object_filter.py kwarg=\"{\\\"reclassify_interval\\\": $OCR_RECLASSIFY_INTERVAL}\" name=tracked_object_filter ! gvadetect model-instance-id=ocr threshold=.2 model=/home/pipeline-server/models/horizontal-text-detection-0002/FP16-INT8/1/horizontal-text-detection-0002.xml model-proc=/home/pipeline-server/models/horizontal-text-detection-0002/FP16-INT8/1/horizontal-text-detection-0002.json name=text_detection device=$DEVICE inference-region=roi-list $PRE_PROCESS ! gvainference model-instance-id=ocr2 nireq=4 gpu-throughput-streams=2 batch-size=32 device=$DEVICE model=/home/pipeline-server/models/text-recognition-0012-mod/FP16-INT8/1/text-recognition-0012-mod.xml model-proc=/home/pipeline-server/models/text-recognition-0012-mod/FP16-INT8/1/text-recognition-0012-mod.json inference-region=roi-list name=text_recognition object-class=text ! gvapython class=OCR module=/home/pipeline-server/extensions/OCR_post_processing_0012.py name=ocr_postprocess $AGGREGATE ! gvapython name=barcode class=BarcodeDetection module=/home/pipeline-server/extensions/barcode_nv12_to_gray.py kwarg=\"{\\\"reclassify_interval\\\": $BARCODE_RECLASSIFY_INTERVAL}\" ! gvametaconvert name=metaconvert add-empty-results=true ! gvametapublish name=destination file-format=2 file-path=/tmp/results/r$cid_count.jsonl $OUTPUT 2>&1 | tee >/tmp/results/gst-launch_$cid_count.log >(stdbuf -oL sed -n -e 's/^.*current: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid_count.log)" - -echo "$gstLaunchCmd" - -eval $gstLaunchCmd diff --git a/configs/opencv-ovms/gst_capi/Dockerfile.ovms-capi-gst b/configs/opencv-ovms/gst_capi/Dockerfile.ovms-capi-gst deleted file mode 100644 index 1f5785e6..00000000 --- a/configs/opencv-ovms/gst_capi/Dockerfile.ovms-capi-gst +++ /dev/null @@ -1,91 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -# ----------------------------------------------------------- -ARG BASE_IMAGE=openvino/model_server:2023.1-gpu -FROM $BASE_IMAGE as release -ENV DEBIAN_FRONTEND=noninteractive -SHELL ["/bin/bash", "-c"] -WORKDIR / - -# Install dependencies for compiling ocv4.7.0 -ARG BUILD_DEPENDENCIES="cmake build-essential git-gui python3 python3-pip flex bison clang libgtk2.0-dev libhdf5-serial-dev libvtk9-dev libtbb2 libxml2 curl libpugixml1v5" - -ARG GSTREAMER="libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio gstreamer1.0-plugins-base-apps" - -RUN apt -y update && \ - apt install -y ${BUILD_DEPENDENCIES} ${GSTREAMER} && \ - rm -rf /var/lib/apt/lists/* && rm -rf /tmp/* - -# Install GPU drivers for Arc. Note replace arc with flex/max below -ARG DGPU_TYPE="arc" -RUN apt update -y; apt install -y wget curl vim gpg-agent; wget -qO - https://repositories.intel.com/graphics/intel-graphics.key | gpg --dearmor --output /usr/share/keyrings/intel-graphics.gpg; echo "deb [arch=amd64,i386 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/graphics/ubuntu jammy $DGPU_TYPE" | tee /etc/apt/sources.list.d/intel-gpu-jammy.list; apt update -y; DEBIAN_FRONTEND=noninteractive apt-get install -y \ -intel-opencl-icd intel-level-zero-gpu level-zero intel-media-va-driver-non-free libmfx1 libmfxgen1 libvpl2 libegl-mesa0 libegl1-mesa libegl1-mesa-dev libgbm1 libgl1-mesa-dev libgl1-mesa-dri libglapi-mesa libgles2-mesa-dev libglx-mesa0 libigdgmm12 libxatracker2 mesa-va-drivers mesa-vdpau-drivers mesa-vulkan-drivers va-driver-all vainfo libcanberra-gtk-module - -# Install GST dependencies -RUN apt -y update; DEBIAN_FRONTEND=noninteractive apt install -y libva-dev autoconf libtool libpciaccess-dev libssl-dev pkg-config libdrm-dev libgbm-dev libcogl-pango-dev libudev-dev lld libx11-xcb-dev libpciaccess-dev nasm yasm libx11-dev libxcb-present-dev libxcb-dri3-dev xorg xorg-dev libgl1-mesa-glx libgl1-mesa-dev meson libgudev-1.0-dev - -# Install OneVPL CPU & GPU Support -RUN apt -y update; DEBIAN_FRONTEND=noninteractive apt install -y wget unzip -RUN wget https://github.com/intel/libvpl/archive/refs/tags/v2023.3.1.zip && \ - unzip v2023.3.1.zip && \ - cd libvpl-2023.3.1; export VPL_INSTALL_DIR=/opt/intel/onevpl; mkdir _build; mkdir $VPL_INSTALL_DIR; cd _build; cmake .. -DCMAKE_INSTALL_PREFIX=$VPL_INSTALL_DIR; cmake --build . --config Release; cmake --build . --config Release --target install - -RUN wget https://github.com/oneapi-src/oneVPL-intel-gpu/archive/refs/tags/intel-onevpl-23.2.4.zip -RUN unzip intel-onevpl-23.2.4.zip -RUN cd oneVPL-intel-gpu*; mkdir build; cd build; cmake ..; make -j`nproc`; make install - -# Build OCV 4.7.0 with GST HW Accel -RUN opencv_branch=${opencv_branch:-4.7.0}; \ -work_dir=${work_dir:-/opt}; \ -current_working_dir=$(pwd); \ -cd $work_dir; \ -git clone https://github.com/opencv/opencv.git --depth 1 -b $opencv_branch $work_dir/opencv_repo; \ -git clone https://github.com/opencv/opencv_contrib.git; \ -cd $work_dir/opencv_contrib; git checkout -b 4.7.0 4.7.0; \ -cd $work_dir/opencv_repo; \ -mkdir -p $work_dir/opencv_repo/build; \ -cd $work_dir/opencv_repo/build; \ -cmake \ --D OPENCV_EXTRA_MODULES_PATH=/opt/opencv_contrib/modules \ --D VIDEOIO_PLUGIN_LIST=gstreamer \ --D WITH_GSTREAMER=ON \ --D WITH_FFMPEG=OFF \ --D CMAKE_BUILD_TYPE=Release \ --D CMAKE_INSTALL_PREFIX=/usr/lib \ --D OPENCV_LIB_INSTALL_PATH=x86_64-linux-gnu \ --D WITH_OPENJPEG=OFF \ --D WITH_JASPER=OFF \ --D WITH_OPENEXR=OFF \ --D WITH_TIFF=OFF \ --D WITH_GTK=ON $work_dir/opencv_repo && \ -make "-j10" && \ -make install - -RUN wget -O ovms.tar.gz https://github.com/openvinotoolkit/model_server/releases/download/v2023.1/ovms_ubuntu22.tar.gz -RUN tar -xf ovms.tar.gz -RUN rm /ovms/lib/*opencv*; - - -# Copy C-API sources -#RUN mv model_repo configs -RUN DEBIAN_FRONTEND=noninteractive apt install -y jq -y && \ - rm -rf /var/lib/apt/lists/* && rm -rf /tmp/* - -ENV LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/:/usr/local/lib/x86_64-linux-gnu/:/usr/local/lib:/ovms/lib:$LD_LIBRARY_PATH -COPY gst_capi/pipelines /home/intel/gst-ovms/pipelines -COPY gst_capi/launch-pipeline.sh /home/intel/gst-ovms/launch-pipeline.sh -COPY gst_capi/run_gst_capi.sh /home/intel/gst-ovms/run_gst_capi.sh -ARG PIPELINE_NAME -RUN echo $PIPELINE_NAME; cd /home/intel/gst-ovms/pipelines/$PIPELINE_NAME; make build - -USER ovms -ENV LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/:/usr/local/lib/x86_64-linux-gnu/:/usr/local/lib:/ovms/lib:$LD_LIBRARY_PATH - -# Enable HWA decoder for OpenCV using GST use cases -ENV OPENCV_FFMPEG_CAPTURE_OPTIONS="hw_decoders_any;vaapi" - -WORKDIR /home/intel/gst-ovms/ diff --git a/configs/opencv-ovms/gst_capi/Dockerfile.ovms.yolov8 b/configs/opencv-ovms/gst_capi/Dockerfile.ovms.yolov8 deleted file mode 100644 index fb03ef6d..00000000 --- a/configs/opencv-ovms/gst_capi/Dockerfile.ovms.yolov8 +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright (C) 2023-2024 Intel Corporation. -# -# -# ----------------------------------------------------------- - -# https://hub.docker.com/r/openvino/model_server -ARG BASE_IMAGE=openvino/model_server:2023.1-gpu -FROM $BASE_IMAGE as release - -USER root -WORKDIR / -ENV DEBIAN_FRONTEND=noninteractive -SHELL ["/bin/bash", "-c"] - -# Install build tools and media UMD -ARG BUILD_DEPENDENCIES="cmake build-essential git-gui python3 python3-pip flex bison clang libgtk2.0-dev libhdf5-serial-dev libvtk9-dev libtbb2 libxml2 curl libpugixml1v5 intel-media-va-driver-non-free libmfx1 libvpl2 libegl-mesa0 libegl1-mesa libegl1-mesa-dev libgbm1 libgl1-mesa-dev libgl1-mesa-dri libglapi-mesa libgles2-mesa-dev libglx-mesa0 libigdgmm12 libxatracker2 mesa-va-drivers mesa-vdpau-drivers mesa-vulkan-drivers va-driver-all vainfo libcanberra-gtk-module jq libopencv-dev python3-opencv gstreamer1.0-plugins-base-apps" -RUN apt -y update && \ - apt install -y ${BUILD_DEPENDENCIES} && \ - rm -rf /var/lib/apt/lists/* && rm -rf /tmp/* - -# Install GStramer -RUN apt update -y; apt install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio && \ - rm -rf /var/lib/apt/lists/* && rm -rf /tmp/* - -# Install MSDK/oneAPI oneVPL libs -ARG GPU_TYPE="client" -RUN apt update -y; apt install -y wget curl vim gpg-agent; wget -qO - https://repositories.intel.com/gpu/intel-graphics.key | gpg --dearmor --output /usr/share/keyrings/intel-graphics.gpg; echo "deb [arch=amd64,i386 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/gpu/ubuntu jammy $GPU_TYPE" | tee /etc/apt/sources.list.d/intel-gpu-jammy.list; apt update -y; DEBIAN_FRONTEND=noninteractive apt-get install -y libegl-mesa0 libegl1-mesa libegl1-mesa-dev libgbm1 libgl1-mesa-dev libgl1-mesa-dri libglapi-mesa libgles2-mesa-dev libglx-mesa0 libigdgmm12 libxatracker2 mesa-va-drivers mesa-vulkan-drivers libcanberra-gtk-module libmfx1 libmfxgen1 libvpl2 && \ - rm -rf /var/lib/apt/lists/* && rm -rf /tmp/* - -# Download OVMS C-API runtime -RUN apt update -y; apt install -y wget curl vim && \ - rm -rf /var/lib/apt/lists/* && rm -rf /tmp/* -RUN wget -O ovms.tar.gz https://github.com/openvinotoolkit/model_server/releases/download/v2023.2/ovms_ubuntu22.tar.gz -RUN tar -xf ovms.tar.gz - -# Copy C-API sources -ENV LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/:/usr/local/lib/x86_64-linux-gnu/:/usr/local/lib:/ovms/lib:$LD_LIBRARY_PATH -WORKDIR /tmp -RUN mkdir -p /app/gst-ovms/pipelines/ - -COPY capi_yolov8_ensemble /app/gst-ovms/pipelines/yolov8_ensemble - -RUN cd /app/gst-ovms/pipelines/yolov8_ensemble; make build - -USER ovms -WORKDIR /app/gst-ovms/pipelines - -# Enable HWA decoder for OpenCV using GST use cases -ENV OPENCV_FFMPEG_CAPTURE_OPTIONS="hw_decoders_any;vaapi" -ENTRYPOINT ["/bin/bash", "-c"] diff --git a/configs/opencv-ovms/gst_capi/Makefile b/configs/opencv-ovms/gst_capi/Makefile deleted file mode 100644 index eade023a..00000000 --- a/configs/opencv-ovms/gst_capi/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright © 2024 Intel Corporation. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -.PHONY: build_face_detection build_capi_yolov5 build_capi_yolov5_ensemble - -OVMS_CPP_DOCKER_IMAGE ?= openvino/model_server -OVMS_CPP_IMAGE_TAG ?= latest -DGPU_TYPE ?= arc # arc|flex - -build_face_detection: - # Build CAPI docker image - docker build $(NO_CACHE_OPTION) -f Dockerfile.ovms-capi-gst ../ \ - --build-arg http_proxy=$(HTTP_PROXY) \ - --build-arg https_proxy="$(HTTPS_PROXY)" \ - --build-arg no_proxy=$(NO_PROXY) \ - --build-arg BASE_IMAGE=ubuntu:22.04 \ - --build-arg DGPU_TYPE=$(DGPU_TYPE) \ - --build-arg PIPELINE_NAME=face_detection \ - --progress=plain \ - -t $(OVMS_CPP_DOCKER_IMAGE)-capi-gst-ovms-face_detection:$(OVMS_CPP_IMAGE_TAG) - -build_capi_yolov5: - # Build CAPI docker image - docker build $(NO_CACHE_OPTION) -f Dockerfile.ovms-capi-gst ../ \ - --build-arg http_proxy=$(HTTP_PROXY) \ - --build-arg https_proxy="$(HTTPS_PROXY)" \ - --build-arg no_proxy=$(NO_PROXY) \ - --build-arg BASE_IMAGE=ubuntu:22.04 \ - --build-arg DGPU_TYPE=$(DGPU_TYPE) \ - --build-arg PIPELINE_NAME=capi_yolov5 \ - --progress=plain \ - -t $(OVMS_CPP_DOCKER_IMAGE)-capi-gst-ovms-capi_yolov5:$(OVMS_CPP_IMAGE_TAG) - -build_capi_yolov5_ensemble: - docker build $(NO_CACHE_OPTION) -f Dockerfile.ovms-capi-gst ../ \ - --build-arg http_proxy=$(HTTP_PROXY) \ - --build-arg https_proxy="$(HTTPS_PROXY)" \ - --build-arg no_proxy=$(NO_PROXY) \ - --build-arg BASE_IMAGE=ubuntu:22.04 \ - --build-arg DGPU_TYPE=$(DGPU_TYPE) \ - --build-arg PIPELINE_NAME=capi_yolov5_ensemble \ - --progress=plain \ - -t $(OVMS_CPP_DOCKER_IMAGE)-capi-gst-ovms-capi_yolov5_ensemble:$(OVMS_CPP_IMAGE_TAG) - -build_capi_yolov8_ensemble: - docker build -f Dockerfile.ovms.yolov8 -t $(OVMS_CPP_DOCKER_IMAGE)-capi-gst-ovms-capi_yolov8_ensemble:$(OVMS_CPP_IMAGE_TAG) ./pipelines \ No newline at end of file diff --git a/configs/opencv-ovms/gst_capi/launch-pipeline.sh b/configs/opencv-ovms/gst_capi/launch-pipeline.sh deleted file mode 100755 index ff794138..00000000 --- a/configs/opencv-ovms/gst_capi/launch-pipeline.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -# bash_cmd="./launch-pipeline.sh - # $PIPELINE_EXEC_PATH $INPUTSRC $USE_ONEVPL $RENDER_MODE $RENDER_PORTRAIT_MODE" - -PIPELINE_EXEC_PATH=$1 -INPUTSRC=$2 -USE_ONEVPL=$3 -RENDER_MODE=$4 -RENDER_PORTRAIT_MODE=$5 -WINDOW_WIDTH=$6 -WINDOW_HEIGHT=$7 -DETECTION_THRESHOLD=$8 -BARCODE=$9 - -# Obtaining codec_type (avc or hevc) -is_avc=`gst-discoverer-1.0 "$INPUTSRC" | grep -i h.264 | wc -l` - -echo "./$PIPELINE_EXEC_PATH $INPUTSRC $USE_ONEVPL $RENDER_MODE $RENDER_PORTRAIT_MODE $is_avc $WINDOW_WIDTH $WINDOW_HEIGHT $DETECTION_THRESHOLD" "$BARCODE" -./"$PIPELINE_EXEC_PATH" "$INPUTSRC" "$USE_ONEVPL" "$RENDER_MODE" "$RENDER_PORTRAIT_MODE" "$is_avc" "$WINDOW_WIDTH" "$WINDOW_HEIGHT" "$DETECTION_THRESHOLD" "$BARCODE" \ No newline at end of file diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5/Makefile b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5/Makefile deleted file mode 100644 index 945e194f..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2023 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -.PHONY: build - -CV_LIBS = -L/usr/lib/x86_64-linux-gnu/ -L/usr/local/lib/x86_64-linux-gnu/ -L/ovms/lib/ -CV_INCLUDES = -I/usr/lib/include/opencv4 - -build: - g++ main.cpp -I/usr/include/gstreamer-1.0/usr/lib/x86_64-linux-gnu/ -I/usr/local/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gstreamer-1.0/ -I/ovms/include $(CV_INCLUDES) $(CV_LIBS) -L/usr/lib/x86_64-linux-gnu/gstreamer-1.0 -lgstbase-1.0 -lgobject-2.0 -lglib-2.0 -lgstreamer-1.0 -lgstapp-1.0 -lopencv_imgcodecs -lopencv_imgproc -lopencv_videoio -lopencv_core -lopencv_videoio_gstreamer -lovms_shared -lopencv_highgui -lpthread -fPIC --std=c++17 -o capi_yolov5 \ No newline at end of file diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5/main.cpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5/main.cpp deleted file mode 100644 index fb38775f..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5/main.cpp +++ /dev/null @@ -1,1152 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -// Utilized for GStramer hardware accelerated decode and pre-preprocessing -#include -#include -#include - -// Utilized for OpenCV based Rendering only -#include -#include -#include -#include - -// Utilized for infernece output layer post-processing -#include - -#include "ovms.h" // NOLINT - -using namespace std; -using namespace cv; - -std::mutex _mtx; -std::mutex _infMtx; -std::mutex _drawingMtx; -std::condition_variable _cvAllDecodersInitd; -bool _allDecodersInitd = false; - -typedef struct DetectedResult { - int frameId; - float x; - float y; - float width; - float height; - float confidence; - int classId; - std::string classText; -} DetectedResult; - -std::vector _detectedResults; -constexpr size_t DIM_COUNT = 4; -constexpr size_t SHAPE[DIM_COUNT] = {1,3,416,416}; - -// Anchors by region/output layer -const float anchor_width = 1920.0; -const float anchor_height = 1080.0; - -// Anchors by region/output layer -const float anchors_52[6] = { - 10.0, - 13.0, - 16.0, - 30.0, - 33.0, - 23.0 -}; - -const float anchors_26[6] = { - 30.0, - 61.0, - 62.0, - 45.0, - 59.0, - 119.0 -}; - -const float anchors_13[6] = { - 116.0, - 90.0, - 156.0, - 198.0, - 373.0, - 326.0 -}; - - -const std::string labels[80] = { - "person", - "bicycle", - "car", - "motorbike", - "aeroplane", - "bus", - "train", - "truck", - "boat", - "traffic light", - "fire hydrant", - "stop sign", - "parking meter", - "bench", - "bird", - "cat", - "dog", - "horse", - "sheep", - "cow", - "elephant", - "bear", - "zebra", - "giraffe", - "backpack", - "umbrella", - "handbag", - "tie", - "suitcase", - "frisbee", - "skis", - "snowboard", - "sports ball", - "kite", - "baseball bat", - "baseball glove", - "skateboard", - "surfboard", - "tennis racket", - "bottle", - "wine glass", - "cup", - "fork", - "knife", - "spoon", - "bowl", - "banana", - "apple", - "sandwich", - "orange", - "broccoli", - "carrot", - "hot dog", - "pizza", - "donut", - "cake", - "chair", - "sofa", - "pottedplant", - "bed", - "diningtable", - "toilet", - "tvmonitor", - "laptop", - "mouse", - "remote", - "keyboard", - "cell phone", - "microwave", - "oven", - "toaster", - "sink", - "refrigerator", - "book", - "clock", - "vase", - "scissors", - "teddy bear", - "hair drier", - "toothbrush" -}; - -class MediaPipelineServiceInterface { -public: - enum VIDEO_TYPE { - H265, - H264 - }; - - virtual ~MediaPipelineServiceInterface() {} - virtual const std::string getVideoDecodedPreProcessedPipeline(std::string mediaLocation, VIDEO_TYPE videoType, int video_width, int video_height, bool use_onevpl) = 0; - virtual const std::string getBroadcastPipeline() = 0; - virtual const std::string getRecordingPipeline() = 0; - - const std::string updateVideoDecodedPreProcessedPipeline(int video_width, int video_height, bool use_onevpl) - { - return getVideoDecodedPreProcessedPipeline(m_mediaLocation, m_videoType, video_width, video_height, use_onevpl); - } - -protected: - std::string m_mediaLocation; - VIDEO_TYPE m_videoType; - int m_videoWidth; - int m_videoHeight; -}; - -OVMS_Server* _srv; -OVMS_ServerSettings* _serverSettings = 0; -OVMS_ModelsSettings* _modelsSettings = 0; -int _server_grpc_port; -int _server_http_port; - -std::string _videoStreamPipeline; -MediaPipelineServiceInterface::VIDEO_TYPE _videoType = MediaPipelineServiceInterface::VIDEO_TYPE::H264; -int _detectorModel = 0; -bool _render = 0; -bool _use_onevpl = 0; -bool _renderPortrait = 0; -cv::Mat _presentationImg; -int _video_input_width = 0; // Get from media _img -int _video_input_height = 0; // Get from media _img -std::vector _vidcaps; -int _window_width = 1920; // default value -int _window_height = 1080; // default value -float _detection_threshold = 0.5; - -class GStreamerMediaPipelineService : public MediaPipelineServiceInterface { -public: - const std::string getVideoDecodedPreProcessedPipeline(std::string mediaLocation, VIDEO_TYPE videoType, int video_width, int video_height, bool use_onevpl) { - m_mediaLocation = mediaLocation; - m_videoType = videoType; - m_videoWidth = video_width; - m_videoHeight = video_height; - - if (mediaLocation.find("rtsp") != std::string::npos ) { - // video/x-raw(memory:VASurface),format=NV12 - switch (videoType) - { - case H264: - if (use_onevpl) - return "rtspsrc location=" + mediaLocation + " ! rtph264depay ! h264parse ! " + - "msdkh264dec ! msdkvpp scaling-mode=lowpower ! " + - "video/x-raw, width=" + std::to_string(video_width) + - ", height=" + std::to_string(video_height) + " ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - else - return "rtspsrc location=" + mediaLocation + " ! rtph264depay ! vaapidecodebin ! video/x-raw(memory:VASurface),format=NV12 ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - case H265: - if (use_onevpl) - return "rtspsrc location=" + mediaLocation + " ! rtph265depay ! h265parse ! " + - "msdkh265dec ! " + - "msdkvpp scaling-mode=lowpower ! " + - "video/x-raw, width=" + std::to_string(video_width) + - ", height=" + std::to_string(video_height) + " ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - else - return "rtspsrc location=" + mediaLocation + " ! rtph265depay ! vaapidecodebin ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=BGR ! appsink sync=0 drop=1"; - default: - std::cout << "Video type not supported!" << std::endl; - return ""; - } - } - else if (mediaLocation.find(".mp4") != std::string::npos ) { - switch (videoType) - { - case H264: - if (use_onevpl) - return "filesrc location=" + mediaLocation + " ! qtdemux ! h264parse ! " + - "msdkh264dec ! msdkvpp scaling-mode=lowpower ! " + - "video/x-raw, width=" + std::to_string(video_width) + ", height=" + std::to_string(video_height) + - " ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - else - return "filesrc location=" + mediaLocation + " ! qtdemux ! h264parse ! vaapidecodebin ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1"; - case H265: - if (use_onevpl) - return "filesrc location=" + mediaLocation + " ! qtdemux ! h265parse ! " + - "msdkh265dec ! msdkvpp scaling-mode=lowpower ! " + - " video/x-raw, width=" + std::to_string(video_width) + ", height=" + std::to_string(video_height) + - " ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - else - return "filesrc location=" + mediaLocation + " ! qtdemux ! h265parse ! vaapidecodebin ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1"; - default: - std::cout << "Video type not supported!" << std::endl; - return ""; - } - } - else { - std::cout << "Unknown media source specified " << mediaLocation << " !!" << std::endl; - return ""; - } - } - - const std::string getBroadcastPipeline() { - return "videotestsrc ! videoconvert,format=BGR ! video/x-raw ! appsink drop=1"; - } - - const std::string getRecordingPipeline() { - return "videotestsrc ! videoconvert,format=BGR ! video/x-raw ! appsink drop=1"; - } -protected: - -}; - -class ObjectDetectionInterface { -public: - const static size_t MODEL_DIM_COUNT = 4; - int64_t model_input_shape[MODEL_DIM_COUNT] = { 0 }; - - virtual ~ObjectDetectionInterface() {} - virtual const char* getModelName() = 0; - virtual const uint64_t getModelVersion() = 0; - virtual const char* getModelInputName() = 0; - virtual const size_t getModelDimCount() = 0; - virtual const std::vector getModelInputShape() = 0; - virtual const std::string getClassLabelText(int classIndex) = 0; - - virtual void postprocess(const int64_t* output_shape, const void* voutputData, const size_t *input_shape, const size_t bytesize, const uint32_t dimCount, std::vector &detectedResults) = 0; - virtual void displayGUIInferenceResults(cv::Mat analytics_frame, std::vector &results, int latency, int througput) = 0; - static inline float sigmoid(float x) { - return 1.f / (1.f + std::exp(-x)); - } - - static inline float linear(float x) { - return x; - } - - // ObjectDetectionInterface() {} - - double intersectionOverUnion(const DetectedResult& o1, const DetectedResult& o2) { - double overlappingWidth = std::fmin(o1.x + o1.width, o2.x + o2.width) - std::fmax(o1.x, o2.x); - double overlappingHeight = std::fmin(o1.y + o1.height, o2.y + o2.height) - std::fmax(o1.y, o2.y); - double intersectionArea = (overlappingWidth < 0 || overlappingHeight < 0) ? 0 : overlappingHeight * overlappingWidth; - double unionArea = o1.width * o1.height + o2.width * o2.height - intersectionArea; - return intersectionArea / unionArea; - } - - int calculateEntryIndex(int totalCells, int lcoords, size_t lclasses, int location, int entry) { - int n = location / totalCells; - int loc = location % totalCells; - return (n * (lcoords + lclasses) + entry) * totalCells + loc; - } - - void postprocess(std::vector &detectedResults, std::vector &outDetectedResults) - { - if (useAdvancedPostprocessing) { - // Advanced postprocessing - // Checking IOU threshold conformance - // For every i-th object we're finding all objects it intersects with, and comparing confidence - // If i-th object has greater confidence than all others, we include it into result - for (const auto& obj1 : detectedResults) { - bool isGoodResult = true; - for (const auto& obj2 : detectedResults) { - if (obj1.classId == obj2.classId && obj1.confidence < obj2.confidence && - intersectionOverUnion(obj1, obj2) >= boxiou_threshold) { // if obj1 is the same as obj2, condition - // expression will evaluate to false anyway - isGoodResult = false; - break; - } - } - if (isGoodResult) { - outDetectedResults.push_back(obj1); - } - } - } else { - // Classic postprocessing - std::sort(detectedResults.begin(), detectedResults.end(), [](const DetectedResult& x, const DetectedResult& y) { - return x.confidence > y.confidence; - }); - for (size_t i = 0; i < detectedResults.size(); ++i) { - if (detectedResults[i].confidence == 0) - continue; - for (size_t j = i + 1; j < detectedResults.size(); ++j) - if (intersectionOverUnion(detectedResults[i], detectedResults[j]) >= boxiou_threshold) - detectedResults[j].confidence = 0; - outDetectedResults.push_back(detectedResults[i]); - } //end for - } // end if - } // end postprocess filter - - -protected: - float confidence_threshold = .5; - float boxiou_threshold = .2; - float iou_threshold = 0.2; - int classes = 80; - bool useAdvancedPostprocessing = true; - -}; - -class Yolov5 : public ObjectDetectionInterface { -public: - - Yolov5() { - confidence_threshold = _detection_threshold; - classes = 80; - std::vector vmodel_input_shape = getModelInputShape(); - std::copy(vmodel_input_shape.begin(), vmodel_input_shape.end(), model_input_shape); - } - - const char* getModelName() { - return MODEL_NAME; - } - - const uint64_t getModelVersion() { - return MODEL_VERSION; - } - - const char* getModelInputName() { - return INPUT_NAME; - } - - const size_t getModelDimCount() { - return MODEL_DIM_COUNT; - } - - const std::vector getModelInputShape() { - std::vector shape{1,3,416,416}; - return shape; - } - - const std::string getClassLabelText(int classIndex) { - if (classIndex > 80) - return ""; - - return labels[classIndex].c_str(); - } - - void postprocess(const int64_t* output_shape, const void* voutputData, const size_t *input_shape, const size_t bytesize, const uint32_t dimCount, std::vector &detectedResults) - { - if (!voutputData || !output_shape) { - // nothing to do - return; - } - - const int regionCoordsCount = dimCount; - const int sideH = output_shape[2]; // NCHW - const int sideW = output_shape[3]; // NCHW - const int regionNum = 3; - const int scaleH = input_shape[2]; // NCHW - const int scaleW = input_shape[3]; // NCHW - - auto entriesNum = sideW * sideH; - const float* outData = reinterpret_cast(voutputData); - int original_im_w = _window_width; //TODO - int original_im_h = _window_height; - - auto postprocessRawData = sigmoid; //sigmoid or linear - - for (int i = 0; i < entriesNum; ++i) { - int row = i / sideW; - int col = i % sideW; - - for (int n = 0; n < regionNum; ++n) { - - int obj_index = calculateEntryIndex(entriesNum, regionCoordsCount, classes + 1 /* + confidence byte */, n * entriesNum + i,regionCoordsCount); - int box_index = calculateEntryIndex(entriesNum, regionCoordsCount, classes + 1, n * entriesNum + i, 0); - float outdata = outData[obj_index]; - float scale = postprocessRawData(outData[obj_index]); - - if (scale >= confidence_threshold) { - float x, y; - x = static_cast((col + postprocessRawData(outData[box_index + 0 * entriesNum])) / sideW * original_im_w); - y = static_cast((row + postprocessRawData(outData[box_index + 1 * entriesNum])) / sideH * original_im_h); - float height = static_cast(std::pow(2*postprocessRawData(outData[box_index + 3 * entriesNum]),2) * anchors_13[2 * n + 1] * original_im_h / scaleH ); - float width = static_cast(std::pow(2*postprocessRawData(outData[box_index + 2 * entriesNum]),2) * anchors_13[2 * n] * original_im_w / scaleW ); - - DetectedResult obj; - obj.x = std::clamp(x - width / 2, 0.f, static_cast(original_im_w)); - obj.y = std::clamp(y - height / 2, 0.f, static_cast(original_im_h)); - obj.width = std::clamp(width, 0.f, static_cast(original_im_w - obj.x)); - obj.height = std::clamp(height, 0.f, static_cast(original_im_h - obj.y)); - - for (int j = 0; j < classes; ++j) { - int class_index = calculateEntryIndex(entriesNum, regionCoordsCount, classes + 1, n * entriesNum + i, regionCoordsCount + 1 + j); - float prob = scale * postprocessRawData(outData[class_index]); - - if (prob >= confidence_threshold) { - obj.confidence = prob; - obj.classId = j; - obj.classText = getClassLabelText(j); - detectedResults.push_back(obj); - } - } - } // end else - } // end for - } // end for - } - // End of Yolov5 Post-Processing - - void displayGUIInferenceResults(cv::Mat analytics_frame, std::vector &results, int latency, int througput) - { - auto ttid = std::this_thread::get_id(); - std::stringstream ss; - ss << ttid; - std::string tid = ss.str(); - - for (auto & obj : results) { - const float x0 = obj.x; - const float y0 = obj.y; - const float x1 = obj.x + obj.width; - const float y1 = obj.y + obj.height; - - //printf("--------->coords: %f %f %f %f\n", x0, y0, x1, y1); - cv::rectangle( analytics_frame, - cv::Point( (int)(x0),(int)(y0) ), - cv::Point( (int)x1, (int)y1 ), - cv::Scalar(255, 0, 0), - 2, cv::LINE_8 ); - - cv::Size textsize = cv::getTextSize(obj.classText, cv::FONT_HERSHEY_PLAIN, 1, 0,0); - - cv::rectangle(analytics_frame, - cv::Point( (int)(x0),(int)(y0-20) ), - cv::Point((int)x0 + textsize.width, (int)y0 + textsize.height), - CV_RGB(0, 0, 0), - -1); - - cv::putText(analytics_frame, - obj.classText, - cv::Size((int)x0, (int)y0), - cv::FONT_HERSHEY_PLAIN, 1, CV_RGB(255, 255, 255), 1); - - } // end for - - cv::Mat presenter; - - { - std::lock_guard lock(_drawingMtx); - cv::imshow("OpenVINO Results " + tid, analytics_frame); - cv::waitKey(1); - } - } - - - private: - const char* MODEL_NAME = "yolov5"; - const uint64_t MODEL_VERSION = 0; - const char* INPUT_NAME = "images"; - }; - -GStreamerMediaPipelineService* _mediaService = NULL; -std::string _user_request; - -namespace { -volatile sig_atomic_t shutdown_request = 0; -} - -bool stringIsInteger(std::string strInput) { - std::string::const_iterator it = strInput.begin(); - while (it != strInput.end() && std::isdigit(*it)) ++it; - return !strInput.empty() && it == strInput.end(); -} - -bool stringIsFloat(std::string strInput) { - std::istringstream iss(strInput); - float f; - iss >> std::noskipws >> f; // noskipws considers leading whitespace invalid - return iss.eof() && !iss.fail(); -} - -bool setActiveModel(int detectionType, ObjectDetectionInterface** objDet) -{ - if (objDet == NULL) - return false; - *objDet = new Yolov5(); - return true; -} - -static void onInterrupt(int status) { - shutdown_request = 1; -} - -static void onTerminate(int status) { - shutdown_request = 1; -} - -static void onIllegal(int status) { - shutdown_request = 2; -} - -static void installSignalHandlers() { - static struct sigaction sigIntHandler; - sigIntHandler.sa_handler = onInterrupt; - sigemptyset(&sigIntHandler.sa_mask); - sigIntHandler.sa_flags = 0; - sigaction(SIGINT, &sigIntHandler, NULL); - - static struct sigaction sigTermHandler; - sigTermHandler.sa_handler = onTerminate; - sigemptyset(&sigTermHandler.sa_mask); - sigTermHandler.sa_flags = 0; - sigaction(SIGTERM, &sigTermHandler, NULL); - - static struct sigaction sigIllHandler; - sigIllHandler.sa_handler = onIllegal; - sigemptyset(&sigIllHandler.sa_mask); - sigIllHandler.sa_flags = 0; - sigaction(SIGILL, &sigIllHandler, NULL); -} - -void printInferenceResults(std::vector &results) -{ - for (auto & obj : results) { - std::cout << "Rect: [ " << obj.x << " , " << obj.y << " " << obj.width << ", " << obj.height << "] Class: " << obj.classText << "(" << obj.classId << ") Conf: " << obj.confidence << std::endl; - } -} - -// This function is responsible for generating a GST pipeline that -// decodes and resizes the video stream based on the desired window size or -// the largest analytics frame size needed if running headless -std::string getVideoPipelineText(std::string mediaPath, ObjectDetectionInterface* objDet, ObjectDetectionInterface* textDet) -{ - std::vector modelFrameShape = objDet->getModelInputShape(); - if (textDet) { - modelFrameShape = textDet->getModelInputShape(); - } - - int frame_width = modelFrameShape[3]; - int frame_height = modelFrameShape[2]; - - if (_render) - { - frame_width = _window_width; - frame_height = _window_height; - } - - return _mediaService->getVideoDecodedPreProcessedPipeline( - mediaPath, - _videoType, - frame_width, - frame_height, - _use_onevpl); -} - -bool createModelServer() -{ - if (_srv == NULL) - return false; - - OVMS_Status* res = OVMS_ServerStartFromConfigurationFile(_srv, _serverSettings, _modelsSettings); - - if (res) { - uint32_t code = 0; - const char* details = nullptr; - - OVMS_StatusCode(res, &code); - OVMS_StatusDetails(res, &details); - std::cerr << "ERROR: during start: code:" << code << "; details:" << details - << "; grpc_port: " << _server_grpc_port - << "; http_port: " << _server_http_port - << ";" << std::endl; - - OVMS_StatusDelete(res); - - if (_srv) - OVMS_ServerDelete(_srv); - - if (_modelsSettings) - OVMS_ModelsSettingsDelete(_modelsSettings); - - if (_serverSettings) - OVMS_ServerSettingsDelete(_serverSettings); - - return false; - } - - return true; -} - -bool loadGStreamer(GstElement** pipeline, GstElement** appsink, std::string mediaPath, ObjectDetectionInterface* _objDet) -{ - static int threadCnt = 0; - - std::cout << "loadGStreamer" << std::endl; - std::string videoPipelineText = getVideoPipelineText(mediaPath, _objDet, NULL); - std::cout << "--------------------------------------------------------------" << std::endl; - std::cout << "Opening Media Pipeline: " << videoPipelineText << std::endl; - std::cout << "--------------------------------------------------------------" << std::endl; - - *pipeline = gst_parse_launch (videoPipelineText.c_str(), NULL); - if (*pipeline == NULL) { - std::cout << "ERROR: Failed to parse GST pipeline. Quitting." << std::endl; - return false; - } - - std::string appsinkName = "appsink" + std::to_string(threadCnt++); - - *appsink = gst_bin_get_by_name (GST_BIN (*pipeline), appsinkName.c_str()); - - // Check if all elements were created - if (!(*appsink)) - { - printf("ERROR: Failed to initialize GST pipeline (missing %s) Quitting.\n", appsinkName.c_str()); - return false; - } - - GstStateChangeReturn gst_res; - - // Start pipeline so it could process incoming data - gst_res = gst_element_set_state(*pipeline, GST_STATE_PLAYING); - - if (gst_res != GST_STATE_CHANGE_SUCCESS && gst_res != GST_STATE_CHANGE_ASYNC ) { - printf("ERROR: StateChange not successful. Error Code: %d\n", gst_res); - return false; - } - - return true; -} - -// OVMS C-API is a global process (singleton design) wide server so can't create many of them -bool loadOVMS() -{ - OVMS_Status* res = NULL; - - OVMS_ServerSettingsNew(&_serverSettings); - OVMS_ModelsSettingsNew(&_modelsSettings); - OVMS_ServerNew(&_srv); - OVMS_ServerSettingsSetGrpcPort(_serverSettings, _server_grpc_port); - OVMS_ServerSettingsSetRestPort(_serverSettings, _server_http_port); - OVMS_ServerSettingsSetLogLevel(_serverSettings, OVMS_LOG_ERROR); - - char * ovmsCofigJsonFilePath = std::getenv("OVMS_MODEL_CONFIG_JSON"); - std::cout << "ovmsCofigJsonFilePath: "< channels; - cv::split(src, channels); - - for (auto &img : channels) { - img = img.reshape(1, 1); - } - - // Concatenate three vectors to one - cv::hconcat( channels, dst ); -} - -void run_stream(std::string mediaPath, GstElement* pipeline, GstElement* appsink, ObjectDetectionInterface* objDet) -{ - auto ttid = std::this_thread::get_id(); - std::stringstream ss; - ss << ttid; - std::string tid = ss.str(); - - // Wait for all decoder streams to init...otherwise causes a segfault when OVMS loads - // https://stackoverflow.com/questions/48271230/using-condition-variablenotify-all-to-notify-multiple-threads - std::unique_lock lk(_mtx); - _cvAllDecodersInitd.wait(lk, [] { return _allDecodersInitd;} ); - lk.unlock(); - - printf("Starting thread: %s\n", tid.c_str()) ; - - auto initTime = std::chrono::high_resolution_clock::now(); - unsigned long numberOfFrames = 0; - long long numberOfSkipFrames = 0; - OVMS_Status* res = NULL; - - while (!shutdown_request) { - auto startTime = std::chrono::high_resolution_clock::now(); - - const void* voutputData1; - size_t bytesize1 = 0; - uint32_t outputCount = 0; - uint32_t outputId; - OVMS_DataType datatype1 = (OVMS_DataType)42; - const int64_t* shape1{nullptr}; - size_t dimCount1 = 0; - OVMS_BufferType bufferType1 = (OVMS_BufferType)42; - uint32_t deviceId1 = 42; - const char* outputName1{nullptr}; - - GstSample *sample; - GstStructure *s; - GstBuffer *buffer; - GstMapInfo m; - - std::vector detectedResults; - std::vector detectedResultsFiltered; - - if (gst_app_sink_is_eos(GST_APP_SINK(appsink))) { - std::cout << "INFO: EOS " << std::endl; - return; - } - - sample = gst_app_sink_try_pull_sample (GST_APP_SINK(appsink), 50 * GST_SECOND); - - if (sample == nullptr) { - std::cout << "ERROR: No sample found" << std::endl; - return; - } - - GstCaps *caps; - caps = gst_sample_get_caps(sample); - - if (caps == nullptr) { - std::cout << "ERROR: No caps found for sample" << std::endl; - return; - } - - s = gst_caps_get_structure(caps, 0); - gst_structure_get_int(s, "width", &_video_input_width); - gst_structure_get_int(s, "height", &_video_input_height); - - buffer = gst_sample_get_buffer(sample); - gst_buffer_map(buffer, &m, GST_MAP_READ); - - if (m.size <= 0) { - std::cout << "ERROR: Invalid buffer size" << std::endl; - return; - } - - cv::Mat analytics_frame; - cv::Mat floatImage; - std::vector inputShape; - inputShape = objDet->getModelInputShape(); - - cv::Mat img(_video_input_height, _video_input_width, CV_8UC3, (void *) m.data); - - // When rendering is enabled then the input frame is resized to window size and not the needed model input size - if (_render) { - - if (dynamic_cast(objDet) != nullptr) - { - resize(img, analytics_frame, cv::Size(inputShape[2], inputShape[3]), 0, 0, cv::INTER_LINEAR); - hwc_to_chw(analytics_frame, analytics_frame); - analytics_frame.convertTo(floatImage, CV_32F); - } - else - { - printf("ERROR: Unknown model type\n"); - return; - } - } - else { - hwc_to_chw(img, analytics_frame); - analytics_frame.convertTo(floatImage, CV_32F); - } - - const int DATA_SIZE = floatImage.step[0] * floatImage.rows; - - OVMS_InferenceResponse* response = nullptr; - OVMS_InferenceRequest* request{nullptr}; - - // OD Inference - { - std::lock_guard lock(_infMtx); - - OVMS_InferenceRequestNew(&request, _srv, objDet->getModelName(), objDet->getModelVersion()); - - OVMS_InferenceRequestAddInput( - request, - objDet->getModelInputName(), - OVMS_DATATYPE_FP32, - objDet->model_input_shape, - objDet->getModelDimCount() - ); - - // run sync request - OVMS_InferenceRequestInputSetData( - request, - objDet->getModelInputName(), - reinterpret_cast(floatImage.data), - DATA_SIZE , - OVMS_BUFFERTYPE_CPU, - 0 - ); - - res = OVMS_Inference(_srv, request, &response); - - if (res != nullptr) { - std::cout << "OVMS_Inference failed " << std::endl; - uint32_t code = 0; - const char* details = 0; - OVMS_StatusCode(res, &code); - OVMS_StatusDetails(res, &details); - std::cout << "Error occured during inference. Code:" << code - << ", details:" << details << std::endl; - - OVMS_StatusDelete(res); - if (request) - OVMS_InferenceRequestDelete(request); - break; - } - } // end lock on inference request to server - - OVMS_InferenceResponseOutputCount(response, &outputCount); - outputId = outputCount - 1; - OVMS_InferenceResponseOutput(response, outputId, &outputName1, &datatype1, &shape1, &dimCount1, &voutputData1, &bytesize1, &bufferType1, &deviceId1); - - objDet->postprocess(shape1, voutputData1, SHAPE, bytesize1, dimCount1, detectedResults); - objDet->postprocess(detectedResults, detectedResultsFiltered); - // printInferenceResults(detectedResultsFiltered); - - numberOfSkipFrames++; - float fps = 0; - if (numberOfSkipFrames <= 120) // allow warm up for latency/fps measurements - { - initTime = std::chrono::high_resolution_clock::now(); - numberOfFrames = 0; - - //printf("Too early...Skipping frames..\n"); - } - else - { - numberOfFrames++; - - auto endTime = std::chrono::high_resolution_clock::now(); - auto latencyTime = ((std::chrono::duration_cast(endTime-startTime)).count()); - auto runningLatencyTime = ((std::chrono::duration_cast(endTime-initTime)).count()); - if (runningLatencyTime > 0) { // skip a few to account for init - fps = (float)numberOfFrames/(float)(runningLatencyTime/1000); // convert to seconds - } - - if (_render) - objDet->displayGUIInferenceResults(img, detectedResultsFiltered, latencyTime, fps); - - static int highest_latency_frame = 0; - static int lowest_latency_frame = 9999; - static int avg_latency_frame = 0; - static int total_latency_frames = 0; - - int frame_latency = chrono::duration_cast(endTime - startTime).count(); - - if (frame_latency > highest_latency_frame) - highest_latency_frame = frame_latency; - if (frame_latency < lowest_latency_frame) - lowest_latency_frame = frame_latency; - - total_latency_frames += frame_latency; - if (numberOfFrames % 30 == 0) { - avg_latency_frame = total_latency_frames / 30; - - time_t currTime = time(0); - struct tm tstruct; - char bCurrTime[80]; - tstruct = *localtime(&currTime); - // http://en.cppreference.com/w/cpp/chrono/c/strftime - strftime(bCurrTime, sizeof(bCurrTime), "%Y-%m-%d.%X", &tstruct); - - cout << detectedResultsFiltered.size() << " object(s) detected at " << bCurrTime << endl; - cout << "Avg. Pipeline Throughput FPS: " << ((isinf(fps)) ? "..." : std::to_string(fps)) << endl; - cout << "Avg. Pipeline Latency (ms): " << avg_latency_frame << endl; - cout << "Max. Pipeline Latency (ms): " << highest_latency_frame << endl; - cout << "Min. Pipeline Latency (ms): " << lowest_latency_frame << endl; - highest_latency_frame = 0; - lowest_latency_frame = 9999; - total_latency_frames = 0; - } - - } - - if (request) { - OVMS_InferenceRequestInputRemoveData(request, objDet->getModelInputName()); // doesn't help - OVMS_InferenceRequestRemoveInput(request, objDet->getModelInputName()); - OVMS_InferenceRequestDelete(request); - } - - if (response) { - OVMS_InferenceResponseDelete(response); - } - - gst_buffer_unmap(buffer, &m); - gst_sample_unref(sample); - - if (shutdown_request > 0) - break; - } // end while get frames - - std::cout << "Goodbye..." << std::endl; - - if (res != NULL) { - OVMS_StatusDelete(res); - res = NULL; - } - - if (objDet) { - delete objDet; - objDet = NULL; - } - - gst_element_set_state (pipeline, GST_STATE_NULL); - if (pipeline) - gst_object_unref(pipeline); - - if (appsink) - gst_object_unref(appsink); -} - -void print_usage(const char* programName) { - std::cout << "Usage: ./" << programName << " \n\n" - << "mediaLocation is an rtsp://127.0.0.1:8554/camera_0 url or a path to an *.mp4 file\n" - << "use_onevpl is 0 (libva - default) or 1 for onevpl\n" - << "render is 1 to launch render window or 0 (default) for headless\n" - << "render portrait is 1 for render swap the size of window width and height\n" - << "video_type is 0 for AVC or 1 for HEVC\n" - << "window_width is display window width\n" - << "window_height is display window height\n" - << "detection_threshold is confidence threshold value in floating point that needs to be between 0.0 to 1.0\n"; -} - -int get_running_servers() { - char buffer[128]; - string cmd = "echo $cid_count"; - std::string result = ""; - FILE* pipe = popen(cmd.c_str(), "r"); - - if (!pipe) - throw std::runtime_error("popen() failed!"); - - try - { - while (fgets(buffer, sizeof buffer, pipe) != NULL) - { - result += buffer; - } - } - catch (...) - { - pclose(pipe); - throw; - } - pclose(pipe); - return std::stoi(result.c_str()); -} - -int main(int argc, char** argv) { - std::cout << std::setprecision(2) << std::fixed; - std::cout << argv[0]<< argv[1]<< argv[2]<< argv[3]<< argv[4]<< argv[5]<< " \n\n"; - // Use GST pipelines for media HWA decode and pre-procesing - _mediaService = new GStreamerMediaPipelineService(); - - // get valid server port numbers - int running_servers = get_running_servers(); - _server_grpc_port = 9178 + running_servers; - _server_http_port = 11338 + running_servers; - - _videoStreamPipeline = "people-detection.mp4"; - - if (argc < 9) { - print_usage(argv[0]); - return 1; - } - - if (!stringIsInteger(argv[2]) || !stringIsInteger(argv[3]) || !stringIsInteger(argv[4]) - || !stringIsInteger(argv[5]) || !stringIsInteger(argv[6]) || !stringIsInteger(argv[7]) || !stringIsFloat(argv[8])) { - print_usage(argv[0]); - return 1; - } else { - _videoStreamPipeline = argv[1]; - _use_onevpl = std::stoi(argv[2]); - _render = std::stoi(argv[3]); - _renderPortrait = std::stoi(argv[4]); - _videoType = (MediaPipelineServiceInterface::VIDEO_TYPE) std::stoi(argv[5]); - _window_width = std::stoi(argv[6]); - _window_height = std::stoi(argv[7]); - std::cout << "_window_width: " << _window_width << std::endl; - std::cout << "_window_height: " << _window_height << std::endl; - _detection_threshold=std::stof(argv[8]); - if (_detection_threshold > 1.0 || _detection_threshold < 0.0) { - std::cout << "detection_threshold: " << _detection_threshold << ", is confidence threshold value in floating point that needs to be between 0.0 to 1.0.\n" << endl; - return 1; - } - - if (_renderPortrait) { - int tmp = _window_width; - _window_width = _window_height; - _window_height = tmp; - } - } - - gst_init(NULL, NULL); - - std::vector running_streams; - _allDecodersInitd = false; - - GstElement *pipeline; - GstElement *appsink; - ObjectDetectionInterface* objDet; - getMAPipeline(_videoStreamPipeline, &pipeline, &appsink, &objDet); - running_streams.emplace_back(run_stream, _videoStreamPipeline, pipeline, appsink, objDet); - - if (!loadOVMS()) - return -1; - - _allDecodersInitd = true; - _cvAllDecodersInitd.notify_all();; - - - for(auto& running_stream : running_streams) - running_stream.join(); - - if (_mediaService != NULL) { - delete _mediaService; - _mediaService = NULL; - } - - if (_srv) - OVMS_ServerDelete(_srv); - if (_modelsSettings) - OVMS_ModelsSettingsDelete(_modelsSettings); - if (_serverSettings) - OVMS_ServerSettingsDelete(_serverSettings); - - return 0; -} diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/Makefile b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/Makefile deleted file mode 100644 index 1765ae38..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (c) 2023 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -CV_LIBS = -L/usr/lib/x86_64-linux-gnu/ -L/usr/local/lib/x86_64-linux-gnu/ -L/ovms/lib/ -CV_INCLUDES = -I/usr/lib/include/opencv4 -CUSTOM_NODE_FLAGS = -fpic -O2 -U_FORTIFY_SOURCE -fstack-protector -fno-omit-frame-pointer -D_FORTIFY_SOURCE=1 -fno-strict-overflow -Wall -Wno-unknown-pragmas -Wno-error=sign-compare -fno-delete-null-pointer-checks -fwrapv -fstack-clash-protection -Wformat -Wformat-security - -build: - g++ -c -std=c++17 efficientnetb0_node.cpp ${CUSTOM_NODE_FLAGS} ${CV_INCLUDES} - - g++ -shared ${CUSTOM_NODE_FLAGS} -o libcustom_node_efficientnetb0-yolov5.so efficientnetb0_node.o ${CV_LIBS} ${CV_INCLUDES} -lopencv_core -lopencv_imgproc -lopencv_imgcodecs - cp libcustom_node_efficientnetb0-yolov5.so /ovms/lib/ - - g++ barcode.cpp main.cpp -I/usr/include/gstreamer-1.0/usr/lib/x86_64-linux-gnu/ -I/usr/local/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gstreamer-1.0/ -I/ovms/include $(CV_INCLUDES) $(CV_LIBS) -L/usr/lib/x86_64-linux-gnu/gstreamer-1.0 -lgstbase-1.0 -lgobject-2.0 -lglib-2.0 -lgstreamer-1.0 -lgstapp-1.0 -lopencv_imgcodecs -lopencv_imgproc -lopencv_videoio -lopencv_core -lopencv_videoio_gstreamer -lovms_shared -lopencv_highgui -lpthread -lopencv_barcode -fPIC --std=c++17 -o capi_yolov5_ensemble - diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/barcode.cpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/barcode.cpp deleted file mode 100644 index 2ad8e154..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/barcode.cpp +++ /dev/null @@ -1,70 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** - -#include -#include -#include -#include -#include - -class BarcodeProcessor -{ - -private: - cv::barcode::BarcodeDetector barcodeDetector; - cv::VideoCapture cap; - std::vector decoded_info; - std::vector decoded_type; - std::vector corners; - -public: - void decode(cv::Mat frame) - { - barcodeDetector.detectAndDecode(frame, decoded_info, decoded_type, corners); - - if (!corners.empty()) - { - for (int i = 0; i < static_cast(corners.size()); i += 4) - { - if (decoded_info[i / 4].empty()) - { - this->drawBoundingBox(frame,corners[i], corners[i + 1], corners[i + 2], corners[i + 3], cv::Scalar(255, 0, 0)); - } // Barcode decoded - else - { - this->drawBoundingBox(frame,corners[i], corners[i + 1], corners[i + 2], corners[i + 3], cv::Scalar(0, 255, 255)); - this->displayText(frame,decoded_type[i / 4] + ": " + decoded_info[i / 4], corners[i]); - } - } - } - - } - -private: - void drawBoundingBox(cv::Mat frame,const cv::Point &p1, const cv::Point &p2, const cv::Point &p3, const cv::Point &p4, const cv::Scalar &color) - { - cv::line(frame, p1, p2, color, 2); - cv::line(frame, p2, p3, color, 2); - cv::line(frame, p3, p4, color, 2); - cv::line(frame, p4, p1, color, 2); - } - - void displayText(cv::Mat frame,const std::string &text, const cv::Point &position) - { - cv::putText(frame, text, position, cv::FONT_HERSHEY_COMPLEX, 0.8, cv::Scalar(0, 0, 255)); - std::cout << text << std::endl; - } -}; \ No newline at end of file diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/buffersqueue.cpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/buffersqueue.cpp deleted file mode 100644 index d8bd45e5..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/buffersqueue.cpp +++ /dev/null @@ -1,66 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** - -#include "buffersqueue.hpp" - -#include - -namespace ovms { -namespace custom_nodes_common { -BuffersQueue::BuffersQueue(size_t singleBufferSize, int streamsLength) : - Queue(streamsLength), - singleBufferSize(singleBufferSize), - size(singleBufferSize * streamsLength), - memoryPool(std::make_unique(size)) { - for (int i = 0; i < streamsLength; ++i) { - inferRequests.push_back(memoryPool.get() + i * singleBufferSize); - } -} - -BuffersQueue::~BuffersQueue() {} - -void* BuffersQueue::getBuffer() { - // can be easily switched to async version if need arise - auto idleId = tryToGetIdleStream(); - if (idleId.has_value()) { - return getInferRequest(idleId.value()); - } - return nullptr; -} - -bool BuffersQueue::returnBuffer(void* buffer) { - if ((static_cast(buffer) < memoryPool.get()) || - ((memoryPool.get() + size - 1) < buffer) || - ((static_cast(buffer) - memoryPool.get()) % singleBufferSize != 0)) { - return false; - } - returnStream(getBufferId(buffer)); - return true; -} - -int BuffersQueue::getBufferId(void* buffer) { - return (static_cast(buffer) - memoryPool.get()) / singleBufferSize; -} - -const size_t BuffersQueue::getSize() { - return this->size; -} - -const size_t BuffersQueue::getSingleBufferSize() { - return this->singleBufferSize; -} -} // namespace custom_nodes_common -} // namespace ovms diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/buffersqueue.hpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/buffersqueue.hpp deleted file mode 100644 index 16b7a9a0..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/buffersqueue.hpp +++ /dev/null @@ -1,47 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace ovms { -namespace custom_nodes_common { - -class BuffersQueue : protected Queue { - size_t singleBufferSize; - size_t size; - std::unique_ptr memoryPool; - -public: - BuffersQueue(size_t singleBufferSize, int streamsLength); - ~BuffersQueue(); - void* getBuffer(); - bool returnBuffer(void* buffer); - const size_t getSize(); - const size_t getSingleBufferSize(); - -private: - int getBufferId(void* buffer); -}; -} // namespace custom_nodes_common -} // namespace ovms diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/custom_node_interface.h b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/custom_node_interface.h deleted file mode 100644 index 22d37f20..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/custom_node_interface.h +++ /dev/null @@ -1,78 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#pragma once - -#include -typedef enum { - UNSPECIFIED, - FP32, - FP16, - U8, - I8, - I16, - U16, - I32, - FP64, - I64 -} CustomNodeTensorPrecision; - -struct CustomNodeTensor { - const char* name; - uint8_t* data; - uint64_t dataBytes; - uint64_t* dims; - uint64_t dimsCount; - CustomNodeTensorPrecision precision; -}; - -struct CustomNodeTensorInfo { - const char* name; - uint64_t* dims; - uint64_t dimsCount; - CustomNodeTensorPrecision precision; -}; - -struct CustomNodeParam { - const char *key, *value; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Custom node library initialize enables creation of resources to be reused between predictions. - * Potential use cases include optimized temporary buffers allocation. - * Using initialize is optional and not required for custom node to work. - * CustomNodeLibraryInternalManager should be created here if initialize is used. - * On initialize failure status not equal to zero is returned and error log is printed. - */ -int initialize(void** customNodeLibraryInternalManager, const struct CustomNodeParam* params, int paramsCount); -/** - * @brief Custom node library deinitialize enables destruction of resources that were used between predictions. - * Using deinitialize is optional and not required for custom node to work. - * CustomNodeLibraryInternalManager should be destroyed here if deinitialize is used. - * On deinitialize failure only error log is printed. - */ -int deinitialize(void* customNodeLibraryInternalManager); -int execute(const struct CustomNodeTensor* inputs, int inputsCount, struct CustomNodeTensor** outputs, int* outputsCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager); -int getInputsInfo(struct CustomNodeTensorInfo** info, int* infoCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager); -int getOutputsInfo(struct CustomNodeTensorInfo** info, int* infoCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager); -int release(void* ptr, void* customNodeLibraryInternalManager); - -#ifdef __cplusplus -} -#endif diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/custom_node_library_internal_manager.cpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/custom_node_library_internal_manager.cpp deleted file mode 100644 index c4857587..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/custom_node_library_internal_manager.cpp +++ /dev/null @@ -1,78 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** - -#include "custom_node_library_internal_manager.hpp" - -#include -#include -#include -#include - -namespace ovms { -namespace custom_nodes_common { -CustomNodeLibraryInternalManager::CustomNodeLibraryInternalManager() { -} - -CustomNodeLibraryInternalManager::~CustomNodeLibraryInternalManager() { -} - -bool CustomNodeLibraryInternalManager::createBuffersQueue(const std::string& name, size_t singleBufferSize, int streamsLength) { - auto it = outputBuffers.find(name); - if (it != outputBuffers.end()) { - return false; - } - outputBuffers.emplace(name, std::make_unique(singleBufferSize, streamsLength)); - return true; -} - -bool CustomNodeLibraryInternalManager::recreateBuffersQueue(const std::string& name, size_t singleBufferSize, int streamsLength) { - auto it = outputBuffers.find(name); - if (it != outputBuffers.end()) { - if (!(it->second->getSize() == singleBufferSize && - it->second->getSingleBufferSize() == streamsLength * singleBufferSize)) { - it->second.reset(new BuffersQueue(singleBufferSize, streamsLength)); - } - return true; - } - return false; -} - -BuffersQueue* CustomNodeLibraryInternalManager::getBuffersQueue(const std::string& name) { - auto it = outputBuffers.find(name); - if (it == outputBuffers.end()) - return nullptr; - return it->second.get(); -} - -bool CustomNodeLibraryInternalManager::releaseBuffer(void* ptr) { - for (auto it = outputBuffers.begin(); it != outputBuffers.end(); ++it) { - if (it->second->returnBuffer(ptr)) { - return true; - } - } - return false; -} - -std::shared_timed_mutex& CustomNodeLibraryInternalManager::getInternalManagerLock() { - return this->internalManagerLock; -} -} // namespace custom_nodes_common -} // namespace ovms - -void cleanup(CustomNodeTensor& tensor, ovms::custom_nodes_common::CustomNodeLibraryInternalManager* internalManager) { - release(tensor.data, internalManager); - release(tensor.dims, internalManager); -} diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/custom_node_library_internal_manager.hpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/custom_node_library_internal_manager.hpp deleted file mode 100644 index c6f483c4..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/custom_node_library_internal_manager.hpp +++ /dev/null @@ -1,60 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#pragma once - -#include -#include -#include -#include - -#include "custom_node_interface.h" -#include "buffersqueue.hpp" - -namespace ovms { -namespace custom_nodes_common { - -class CustomNodeLibraryInternalManager { - std::unordered_map> outputBuffers; - std::shared_timed_mutex internalManagerLock; - -public: - CustomNodeLibraryInternalManager(); - ~CustomNodeLibraryInternalManager(); - bool createBuffersQueue(const std::string& name, size_t singleBufferSize, int streamsLength); - bool recreateBuffersQueue(const std::string& name, size_t singleBufferSize, int streamsLength); - BuffersQueue* getBuffersQueue(const std::string& name); - bool releaseBuffer(void* ptr); - std::shared_timed_mutex& getInternalManagerLock(); -}; -} // namespace custom_nodes_common -} // namespace ovms - -template -bool get_buffer(ovms::custom_nodes_common::CustomNodeLibraryInternalManager* internalManager, T** buffer, const char* buffersQueueName, uint64_t byte_size) { - auto buffersQueue = internalManager->getBuffersQueue(buffersQueueName); - if (!(buffersQueue == nullptr)) { - *buffer = static_cast(buffersQueue->getBuffer()); - } - if (*buffer == nullptr || buffersQueue == nullptr) { - *buffer = (T*)malloc(byte_size); - if (*buffer == nullptr) { - return false; - } - } - return true; -} - -void cleanup(CustomNodeTensor& tensor, ovms::custom_nodes_common::CustomNodeLibraryInternalManager* internalManager); diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/efficientnetb0_node.cpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/efficientnetb0_node.cpp deleted file mode 100644 index e97b8034..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/efficientnetb0_node.cpp +++ /dev/null @@ -1,620 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#include -#include -#include - -#include "custom_node_interface.h" -#include "opencv_utils.hpp" -#include "utils.hpp" -#include "opencv2/opencv.hpp" - -static constexpr const char* IMAGE_TENSOR_NAME = "images"; -static constexpr const char* GEOMETRY_TENSOR_NAME = "boxes"; -static constexpr const char* TEXT_IMAGES_TENSOR_NAME = "roi_images"; -static constexpr const char* COORDINATES_TENSOR_NAME = "roi_coordinates"; -static constexpr const char* CONFIDENCE_TENSOR_NAME = "confidence_levels"; - -typedef struct DetectedResult { - int frameId; - int x; - int y; - int width; - int height; - float confidence; - int classId; - char classText[1024]; -} DetectedResult; - -float boxiou_threshold = .4; -float iou_threshold = 0.4; - -static bool copy_images_into_output(struct CustomNodeTensor* output, const std::vector& boxes, const cv::Mat& originalImage, int targetImageHeight, int targetImageWidth, const std::string& targetImageLayout, bool convertToGrayScale) { - const uint64_t outputBatch = boxes.size(); - int channels = convertToGrayScale ? 1 : 3; - - uint64_t byteSize = sizeof(float) * targetImageHeight * targetImageWidth * channels * outputBatch; - - float* buffer = (float*)malloc(byteSize); - NODE_ASSERT(buffer != nullptr, "malloc has failed"); - - for (uint64_t i = 0; i < outputBatch; i++) { - cv::Size targetShape(targetImageWidth, targetImageHeight); - cv::Mat image; - - cv::Rect box = boxes[i]; - if (box.x < 0) - box.x = 0; - if (box.y < 0) - box.y = 0; - - cv::Mat cropped = originalImage(box); - - cv::resize(cropped, image, targetShape); - - if (convertToGrayScale) { - image = apply_grayscale(image); - } - - if (targetImageLayout == "NCHW") { - auto imgBuffer = reorder_to_nchw((float*)image.data, image.rows, image.cols, image.channels()); - std::memcpy(buffer + (i * channels * targetImageWidth * targetImageHeight), imgBuffer.data(), byteSize / outputBatch); - } else { - std::memcpy(buffer + (i * channels * targetImageWidth * targetImageHeight), image.data, byteSize / outputBatch); - } - } - - output->data = reinterpret_cast(buffer); - output->dataBytes = byteSize; - output->dimsCount = 5; - output->dims = (uint64_t*)malloc(output->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(output->dims != nullptr, "malloc has failed"); - output->dims[0] = outputBatch; - output->dims[1] = 1; - if (targetImageLayout == "NCHW") { - output->dims[2] = channels; - output->dims[3] = targetImageHeight; - output->dims[4] = targetImageWidth; - } else { - output->dims[2] = targetImageHeight; - output->dims[3] = targetImageWidth; - output->dims[4] = channels; - } - output->precision = FP32; - return true; -} - -static bool copy_coordinates_into_output(struct CustomNodeTensor* output, const std::vector& boxes) { - const uint64_t outputBatch = boxes.size(); - - //printf("---------->NumberOfDets by coords %li\n", outputBatch); - - uint64_t byteSize = sizeof(int32_t) * 4 * outputBatch; - - int32_t* buffer = (int32_t*)malloc(byteSize); - NODE_ASSERT(buffer != nullptr, "malloc has failed"); - - for (uint64_t i = 0; i < outputBatch; i++) { - int32_t entry[] = { - boxes[i].x, - boxes[i].y, - boxes[i].width, - boxes[i].height}; - - std::memcpy(buffer + (i * 4), entry, byteSize / outputBatch); - } - output->data = reinterpret_cast(buffer); - output->dataBytes = byteSize; - output->dimsCount = 3; - output->dims = (uint64_t*)malloc(output->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(output->dims != nullptr, "malloc has failed"); - output->dims[0] = outputBatch; - output->dims[1] = 1; - output->dims[2] = 4; - output->precision = I32; - - return true; -} - -static bool copy_scores_into_output(struct CustomNodeTensor* output, const std::vector& scores) { - const uint64_t outputBatch = scores.size(); - //printf("Number of scores------------------>%li\n", outputBatch); - uint64_t byteSize = sizeof(float) * outputBatch; - - float* buffer = (float*)malloc(byteSize); - NODE_ASSERT(buffer != nullptr, "malloc has failed"); - std::memcpy(buffer, scores.data(), byteSize); - - output->data = reinterpret_cast(buffer); - output->dataBytes = byteSize; - output->dimsCount = 3; - output->dims = (uint64_t*)malloc(output->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(output->dims != nullptr, "malloc has failed"); - output->dims[0] = outputBatch; - output->dims[1] = 1; - output->dims[2] = 1; - output->precision = FP32; - return true; -} - -int initialize(void** customNodeLibraryInternalManager, const struct CustomNodeParam* params, int paramsCount) { - return 0; -} - -int deinitialize(void* customNodeLibraryInternalManager) { - return 0; -} - -// YoloV5 PostProcessing - -// Anchors by region/output layer -const float anchors_52[6] = { - 10.0, - 13.0, - 16.0, - 30.0, - 33.0, - 23.0 -}; - -const float anchors_26[6] = { - 30.0, - 61.0, - 62.0, - 45.0, - 59.0, - 119.0 -}; - -const float anchors_13[6] = { - 116.0, - 90.0, - 156.0, - 198.0, - 373.0, - 326.0 -}; - -const std::string labels[80] = { - "person", - "bicycle", - "car", - "motorbike", - "aeroplane", - "bus", - "train", - "truck", - "boat", - "traffic light", - "fire hydrant", - "stop sign", - "parking meter", - "bench", - "bird", - "cat", - "dog", - "horse", - "sheep", - "cow", - "elephant", - "bear", - "zebra", - "giraffe", - "backpack", - "umbrella", - "handbag", - "tie", - "suitcase", - "frisbee", - "skis", - "snowboard", - "sports ball", - "kite", - "baseball bat", - "baseball glove", - "skateboard", - "surfboard", - "tennis racket", - "bottle", - "wine glass", - "cup", - "fork", - "knife", - "spoon", - "bowl", - "banana", - "apple", - "sandwich", - "orange", - "broccoli", - "carrot", - "hot dog", - "pizza", - "donut", - "cake", - "chair", - "sofa", - "pottedplant", - "bed", - "diningtable", - "toilet", - "tvmonitor", - "laptop", - "mouse", - "remote", - "keyboard", - "cell phone", - "microwave", - "oven", - "toaster", - "sink", - "refrigerator", - "book", - "clock", - "vase", - "scissors", - "teddy bear", - "hair drier", - "toothbrush" -}; - -int calculateEntryIndex(int totalCells, int lcoords, size_t lclasses, int location, int entry) { - int n = location / totalCells; - int loc = location % totalCells; - return (n * (lcoords + lclasses) + entry) * totalCells + loc; -} - -static inline float sigmoid(float x) { - return 1.f / (1.f + std::exp(-x)); -} - -double intersectionOverUnion(const DetectedResult& o1, const DetectedResult& o2) { - double overlappingWidth = std::fmin(o1.x + o1.width, o2.x + o2.width) - std::fmax(o1.x, o2.x); - double overlappingHeight = std::fmin(o1.y + o1.height, o2.y + o2.height) - std::fmax(o1.y, o2.y); - double intersectionArea = (overlappingWidth < 0 || overlappingHeight < 0) ? 0 : overlappingHeight * overlappingWidth; - double unionArea = o1.width * o1.height + o2.width * o2.height - intersectionArea; - return intersectionArea / unionArea; -} - -// IOU postproc filter -void postprocess(std::vector &detectedResults, - std::vector &rects, std::vector &scores) -{ - bool useAdvancedPostprocessing = false; - - if (useAdvancedPostprocessing) { - // Advanced postprocessing - // Checking IOU threshold conformance - // For every i-th object we're finding all objects it intersects with, and comparing confidence - // If i-th object has greater confidence than all others, we include it into result - for (const auto& obj1 : detectedResults) { - bool isGoodResult = true; - for (const auto& obj2 : detectedResults) { - if (obj1.classId == obj2.classId && obj1.confidence < obj2.confidence && - intersectionOverUnion(obj1, obj2) >= boxiou_threshold) { // if obj1 is the same as obj2, condition - // expression will evaluate to false anyway - isGoodResult = false; - break; - } - } - if (isGoodResult) { - rects.emplace_back( - obj1.x, - obj1.y, - obj1.width, - obj1.height); - scores.emplace_back(obj1.confidence); - } - } - } else { - // Classic postprocessing - std::sort(detectedResults.begin(), detectedResults.end(), [](const DetectedResult& x, const DetectedResult& y) { - return x.confidence > y.confidence; - }); - for (size_t i = 0; i < detectedResults.size(); ++i) { - if (detectedResults[i].confidence == 0) - continue; - for (size_t j = i + 1; j < detectedResults.size(); ++j) - if (intersectionOverUnion(detectedResults[i], detectedResults[j]) >= boxiou_threshold) - detectedResults[j].confidence = 0; - - rects.emplace_back( - detectedResults[i].x, - detectedResults[i].y, - detectedResults[i].width, - detectedResults[i].height); - scores.emplace_back(detectedResults[i].confidence); - } //end for - } // end if -} // end postprocess IOU filter - - -void postprocess(const float confidence_threshold, const int imageWidth, const int imageHeight, - const uint64_t* output_shape, const void* voutputData, const uint32_t dimCount, - std::vector &rects, std::vector &scores) -{ - if (!voutputData || !output_shape) { - // nothing to do - return; - } - - std::vector detectedResults; - - const int regionCoordsCount = dimCount; - const int sideH = 13; //output_shape[2]; // NCHW - const int sideW = 13; //output_shape[3]; // NCHW - const int regionNum = 3; - - const int scaleH = 416; - const int scaleW = 416; - - auto entriesNum = sideW * sideH; - const float* outData = reinterpret_cast(voutputData); - int original_im_w = imageWidth; - int original_im_h = imageHeight; - size_t classes = 80; // from yolo dataset - - auto postprocessRawData = sigmoid; //sigmoid or linear - - for (int i = 0; i < entriesNum; ++i) { - int row = i / sideW; - int col = i % sideW; - - for (int n = 0; n < regionNum; ++n) { - - int obj_index = calculateEntryIndex(entriesNum, regionCoordsCount, classes + 1 /* + confidence byte */, n * entriesNum + i,regionCoordsCount); - int box_index = calculateEntryIndex(entriesNum, regionCoordsCount, classes + 1, n * entriesNum + i, 0); - float scale = postprocessRawData(outData[obj_index]); - - if (scale >= confidence_threshold) { - float x, y,height,width; - x = static_cast((col + postprocessRawData(outData[box_index + 0 * entriesNum])) / sideW * original_im_w); - y = static_cast((row + postprocessRawData(outData[box_index + 1 * entriesNum])) / sideH * original_im_h); - height = static_cast(std::pow(2*postprocessRawData(outData[box_index + 3 * entriesNum]),2) * anchors_13[2 * n + 1] * original_im_h / scaleH ); - width = static_cast(std::pow(2*postprocessRawData(outData[box_index + 2 * entriesNum]),2) * anchors_13[2 * n] * original_im_w / scaleW ); - - DetectedResult obj; - - obj.x = std::clamp(x - width / 2, 0.f, static_cast(original_im_w)); - obj.y = std::clamp(y - height / 2, 0.f, static_cast(original_im_h)); - obj.width = std::clamp(width, 0.f, static_cast(original_im_w - obj.x)); - obj.height = std::clamp(height, 0.f, static_cast(original_im_h - obj.y)); - - for (size_t j = 0; j < classes; ++j) { - int class_index = calculateEntryIndex(entriesNum, regionCoordsCount, classes + 1, n * entriesNum + i, regionCoordsCount + 1 + j); - float prob = scale * postprocessRawData(outData[class_index]); - - if (prob >= confidence_threshold) { - obj.confidence = prob; - detectedResults.push_back(obj); - } - } - } // end else - } // end for - } // end for - - postprocess(detectedResults, rects, scores); -} -// End of Yolov5 PostProcessing - -int execute(const struct CustomNodeTensor* inputs, int inputsCount, struct CustomNodeTensor** outputs, int* outputsCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager) { - - // Parameters reading - int originalImageHeight = get_int_parameter("original_image_height", params, paramsCount, -1); - int originalImageWidth = get_int_parameter("original_image_width", params, paramsCount, -1); - NODE_ASSERT(originalImageHeight > 0, "original image height must be larger than 0"); - NODE_ASSERT(originalImageWidth > 0, "original image width must be larger than 0"); - int targetImageHeight = get_int_parameter("target_image_height", params, paramsCount, -1); - int targetImageWidth = get_int_parameter("target_image_width", params, paramsCount, -1); - NODE_ASSERT(targetImageHeight > 0, "target image height must be larger than 0"); - NODE_ASSERT(targetImageWidth > 0, "target image width must be larger than 0"); - std::string originalImageLayout = get_string_parameter("original_image_layout", params, paramsCount, "NCHW"); - NODE_ASSERT(originalImageLayout == "NCHW" || originalImageLayout == "NHWC", "original image layout must be NCHW or NHWC"); - std::string targetImageLayout = get_string_parameter("target_image_layout", params, paramsCount, "NCHW"); - NODE_ASSERT(targetImageLayout == "NCHW" || targetImageLayout == "NHWC", "target image layout must be NCHW or NHWC"); - bool convertToGrayScale = get_string_parameter("convert_to_gray_scale", params, paramsCount) == "true"; - float confidenceThreshold = get_float_parameter("confidence_threshold", params, paramsCount, -1.0); - NODE_ASSERT(confidenceThreshold >= 0 && confidenceThreshold <= 1.0, "confidence threshold must be in 0-1 range"); - uint64_t maxOutputBatch = get_int_parameter("max_output_batch", params, paramsCount, 100); - NODE_ASSERT(maxOutputBatch > 0, "max output batch must be larger than 0"); - bool debugMode = get_string_parameter("debug", params, paramsCount) == "true"; - - const CustomNodeTensor* imageTensor = nullptr; - const CustomNodeTensor* boxesTensor = nullptr; - - for (int i = 0; i < inputsCount; i++) { - if (std::strcmp(inputs[i].name, IMAGE_TENSOR_NAME) == 0) { - imageTensor = &(inputs[i]); - } else if (std::strcmp(inputs[i].name, GEOMETRY_TENSOR_NAME) == 0) { - boxesTensor = &(inputs[i]); - } else { - std::cout << "Unrecognized input: " << inputs[i].name << std::endl; - return 1; - } - } - - NODE_ASSERT(imageTensor != nullptr, "Missing input image"); - NODE_ASSERT(boxesTensor != nullptr, "Missing input boxes"); - NODE_ASSERT(imageTensor->precision == FP32, "image input is not FP32"); - NODE_ASSERT(boxesTensor->precision == FP32, "image input is not FP32"); - - NODE_ASSERT(imageTensor->dimsCount == 4, "input image shape must have 4 dimensions"); - NODE_ASSERT(imageTensor->dims[0] == 1, "input image batch must be 1"); - uint64_t _imageHeight = imageTensor->dims[originalImageLayout == "NCHW" ? 2 : 1]; - uint64_t _imageWidth = imageTensor->dims[originalImageLayout == "NCHW" ? 3 : 2]; - NODE_ASSERT(_imageHeight <= static_cast(std::numeric_limits::max()), "image height is too large"); - NODE_ASSERT(_imageWidth <= static_cast(std::numeric_limits::max()), "image width is too large"); - int imageHeight = static_cast(_imageHeight); - int imageWidth = static_cast(_imageWidth); - - if (debugMode) { - std::cout << "Processing input tensor image resolution: " << cv::Size(imageHeight, imageWidth) << "; expected resolution: " << cv::Size(originalImageHeight, originalImageWidth) << std::endl; - } - - NODE_ASSERT(imageHeight == originalImageHeight, "original image size parameter differs from original image tensor size"); - NODE_ASSERT(imageWidth == originalImageWidth, "original image size parameter differs from original image tensor size"); - - cv::Mat image; - if (originalImageLayout == "NHWC") { - image = nhwc_to_mat(imageTensor); - } else { - image = nchw_to_mat(imageTensor); - } - - NODE_ASSERT(image.cols == imageWidth, "Mat generation failed"); - NODE_ASSERT(image.rows == imageHeight, "Mat generation failed"); - - std::vector rects; - std::vector scores; - postprocess(confidenceThreshold, originalImageWidth, originalImageHeight, boxesTensor->dims, boxesTensor->data, boxesTensor->dimsCount, rects, scores); - - NODE_ASSERT(rects.size() == scores.size(), "rects and scores are not equal length"); - if (rects.size() > maxOutputBatch) { - rects.resize(maxOutputBatch); - scores.resize(maxOutputBatch); - } - - if (debugMode) - std::cout << "Total findings: " << rects.size() << std::endl; - - *outputsCount = 3; // pipeline outputs for efficientnetb0_extractor e.g. roi_images, roi_coordinates, confidence_levels - *outputs = (struct CustomNodeTensor*)malloc(*outputsCount * sizeof(CustomNodeTensor)); - - NODE_ASSERT((*outputs) != nullptr, "malloc has failed"); - CustomNodeTensor& textImagesTensor = (*outputs)[0]; - textImagesTensor.name = TEXT_IMAGES_TENSOR_NAME; - - if (!copy_images_into_output(&textImagesTensor, rects, image, targetImageHeight, targetImageWidth, targetImageLayout, convertToGrayScale)) { - free(*outputs); - return 1; - } - - CustomNodeTensor& coordinatesTensor = (*outputs)[1]; - coordinatesTensor.name = COORDINATES_TENSOR_NAME; - if (!copy_coordinates_into_output(&coordinatesTensor, rects)) { - free(*outputs); - cleanup(textImagesTensor); - return 1; - } - - - CustomNodeTensor& confidenceTensor = (*outputs)[2]; - confidenceTensor.name = CONFIDENCE_TENSOR_NAME; - if (!copy_scores_into_output(&confidenceTensor, scores)) { - free(*outputs); - cleanup(textImagesTensor); - cleanup(coordinatesTensor); - return 1; - } - - return 0; -} - -int getInputsInfo(struct CustomNodeTensorInfo** info, int* infoCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager) { - int originalImageHeight = get_int_parameter("original_image_height", params, paramsCount, -1); - int originalImageWidth = get_int_parameter("original_image_width", params, paramsCount, -1); - NODE_ASSERT(originalImageHeight > 0, "original image height must be larger than 0"); - NODE_ASSERT(originalImageWidth > 0, "original image width must be larger than 0"); - std::string originalImageLayout = get_string_parameter("original_image_layout", params, paramsCount, "NCHW"); - NODE_ASSERT(originalImageLayout == "NCHW" || originalImageLayout == "NHWC", "original image layout must be NCHW or NHWC"); - - *infoCount = 2; - *info = (struct CustomNodeTensorInfo*)malloc(*infoCount * sizeof(struct CustomNodeTensorInfo)); - NODE_ASSERT((*info) != nullptr, "malloc has failed"); - - (*info)[0].name = IMAGE_TENSOR_NAME; - (*info)[0].dimsCount = 4; - (*info)[0].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[0].dims) != nullptr, "malloc has failed"); - (*info)[0].dims[0] = 1; - if (originalImageLayout == "NCHW") { - (*info)[0].dims[1] = 3; - (*info)[0].dims[2] = originalImageHeight; - (*info)[0].dims[3] = originalImageWidth; - } else { - (*info)[0].dims[1] = originalImageHeight; - (*info)[0].dims[2] = originalImageWidth; - (*info)[0].dims[3] = 3; - } - (*info)[0].precision = FP32; - - (*info)[1].name = GEOMETRY_TENSOR_NAME; - (*info)[1].dimsCount = 4; - (*info)[1].dims = (uint64_t*)malloc((*info)[1].dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[1].dims) != nullptr, "malloc has failed"); - (*info)[1].dims[0] = 1; - (*info)[1].dims[1] = 255; - (*info)[1].dims[2] = 13; - (*info)[1].dims[3] = 13; - (*info)[1].precision = FP32; - return 0; -} - -int getOutputsInfo(struct CustomNodeTensorInfo** info, int* infoCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager) { - int targetImageHeight = get_int_parameter("target_image_height", params, paramsCount, -1); - int targetImageWidth = get_int_parameter("target_image_width", params, paramsCount, -1); - NODE_ASSERT(targetImageHeight > 0, "target image height must be larger than 0"); - NODE_ASSERT(targetImageWidth > 0, "target image width must be larger than 0"); - std::string targetImageLayout = get_string_parameter("target_image_layout", params, paramsCount, "NCHW"); - NODE_ASSERT(targetImageLayout == "NCHW" || targetImageLayout == "NHWC", "target image layout must be NCHW or NHWC"); - bool convertToGrayScale = get_string_parameter("convert_to_gray_scale", params, paramsCount) == "true"; - - *infoCount = 3; - *info = (struct CustomNodeTensorInfo*)malloc(*infoCount * sizeof(struct CustomNodeTensorInfo)); - NODE_ASSERT((*info) != nullptr, "malloc has failed"); - - (*info)[0].name = TEXT_IMAGES_TENSOR_NAME; - (*info)[0].dimsCount = 5; - (*info)[0].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[0].dims) != nullptr, "malloc has failed"); - (*info)[0].dims[0] = 0; - (*info)[0].dims[1] = 1; - if (targetImageLayout == "NCHW") { - (*info)[0].dims[2] = convertToGrayScale ? 1 : 3; - (*info)[0].dims[3] = targetImageHeight; - (*info)[0].dims[4] = targetImageWidth; - } else { - (*info)[0].dims[2] = targetImageHeight; - (*info)[0].dims[3] = targetImageWidth; - (*info)[0].dims[4] = convertToGrayScale ? 1 : 3; - } - (*info)[0].precision = FP32; - - (*info)[1].name = COORDINATES_TENSOR_NAME; - (*info)[1].dimsCount = 3; - (*info)[1].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[1].dims) != nullptr, "malloc has failed"); - (*info)[1].dims[0] = 0; - (*info)[1].dims[1] = 1; - (*info)[1].dims[2] = 4; - (*info)[1].precision = I32; - - (*info)[2].name = CONFIDENCE_TENSOR_NAME; - (*info)[2].dimsCount = 3; - (*info)[2].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[2].dims) != nullptr, "malloc has failed"); - (*info)[2].dims[0] = 0; - (*info)[2].dims[1] = 1; - (*info)[2].dims[2] = 1; - (*info)[2].precision = FP32; - - return 0; -} - -int release(void* ptr, void* customNodeLibraryInternalManager) { - free(ptr); - return 0; -} diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/main.cpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/main.cpp deleted file mode 100644 index aa83a764..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/main.cpp +++ /dev/null @@ -1,2165 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -// Utilized for GStramer hardware accelerated decode and pre-preprocessing -#include -#include -#include - -// Utilized for OpenCV based Rendering only -#include -#include -#include -#include - -// Utilized for infernece output layer post-processing -#include - -#include "ovms.h" // NOLINT - -#include "barcode.cpp" - -using namespace std; -using namespace cv; - -std::mutex _mtx; -std::mutex _infMtx; -std::mutex _drawingMtx; -std::condition_variable _cvAllDecodersInitd; -bool _allDecodersInitd = false; - -typedef struct DetectedResult { - int frameId; - int x; - int y; - int width; - int height; - float confidence; - int classId; - char classText[1024]; -} DetectedResult; - -class MediaPipelineServiceInterface { -public: - enum VIDEO_TYPE { - H265, - H264 - }; - - virtual ~MediaPipelineServiceInterface() {} - virtual const std::string getVideoDecodedPreProcessedPipeline(std::string mediaLocation, VIDEO_TYPE videoType, int video_width, int video_height, bool use_onevpl) = 0; - virtual const std::string getBroadcastPipeline() = 0; - virtual const std::string getRecordingPipeline() = 0; - - const std::string updateVideoDecodedPreProcessedPipeline(int video_width, int video_height, bool use_onevpl) - { - return getVideoDecodedPreProcessedPipeline(m_mediaLocation, m_videoType, video_width, video_height, use_onevpl); - } - -protected: - std::string m_mediaLocation; - VIDEO_TYPE m_videoType; - int m_videoWidth; - int m_videoHeight; -}; - -OVMS_Server* _srv; -OVMS_ServerSettings* _serverSettings = 0; -OVMS_ModelsSettings* _modelsSettings = 0; -int _server_grpc_port; -int _server_http_port; - -std::string _videoStreamPipeline; -MediaPipelineServiceInterface::VIDEO_TYPE _videoType = MediaPipelineServiceInterface::VIDEO_TYPE::H264; -int _detectorModel = 0; -bool _render = 0; -bool _use_onevpl = 0; -bool _renderPortrait = 0; -cv::Mat _presentationImg; -int _video_input_width = 0; // Get from media _img -int _video_input_height = 0; // Get from media _img -std::vector _vidcaps; -int _window_width = 1280; -int _window_height = 720; -float _detection_threshold = 0.5; -bool _barcode = 1; - -class GStreamerMediaPipelineService : public MediaPipelineServiceInterface { -public: - const std::string getVideoDecodedPreProcessedPipeline(std::string mediaLocation, VIDEO_TYPE videoType, int video_width, int video_height, bool use_onevpl) { - m_mediaLocation = mediaLocation; - m_videoType = videoType; - m_videoWidth = video_width; - m_videoHeight = video_height; - - if (mediaLocation.find("rtsp") != std::string::npos ) { - // video/x-raw(memory:VASurface),format=NV12 - switch (videoType) - { - case H264: - if (use_onevpl) - return "rtspsrc location=" + mediaLocation + " ! rtph264depay ! h264parse ! " + - "msdkh264dec ! msdkvpp scaling-mode=lowpower ! " + - "video/x-raw, width=" + std::to_string(video_width) + - ", height=" + std::to_string(video_height) + " ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - else - return "rtspsrc location=" + mediaLocation + " ! rtph264depay ! vaapidecodebin ! video/x-raw(memory:VASurface),format=NV12 ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - case H265: - if (use_onevpl) - return "rtspsrc location=" + mediaLocation + " ! rtph265depay ! h265parse ! " + - "msdkh265dec ! " + - "msdkvpp scaling-mode=lowpower ! " + - "video/x-raw, width=" + std::to_string(video_width) + - ", height=" + std::to_string(video_height) + " ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - else - return "rtspsrc location=" + mediaLocation + " ! rtph265depay ! vaapidecodebin ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=BGR ! appsink sync=0 drop=1"; - default: - std::cout << "Video type not supported!" << std::endl; - return ""; - } - } - else if (mediaLocation.find(".mp4") != std::string::npos ) { - switch (videoType) - { - case H264: - if (use_onevpl) - return "filesrc location=" + mediaLocation + " ! qtdemux ! h264parse ! " + - "msdkh264dec ! msdkvpp scaling-mode=lowpower ! " + - "video/x-raw, width=" + std::to_string(video_width) + ", height=" + std::to_string(video_height) + - " ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - else - return "filesrc location=" + mediaLocation + " ! qtdemux ! h264parse ! vaapidecodebin ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1 sync=0"; - case H265: - if (use_onevpl) - return "filesrc location=" + mediaLocation + " ! qtdemux ! h265parse ! " + - "msdkh265dec ! msdkvpp scaling-mode=lowpower ! " + - " video/x-raw, width=" + std::to_string(video_width) + ", height=" + std::to_string(video_height) + - " ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - else - return "filesrc location=" + mediaLocation + " ! qtdemux ! h265parse ! vaapidecodebin ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1 sync=0"; - default: - std::cout << "Video type not supported!" << std::endl; - return ""; - } - } - else { - std::cout << "Unknown media source specified " << mediaLocation << " !!" << std::endl; - return ""; - } - } - - const std::string getBroadcastPipeline() { - return "videotestsrc ! videoconvert,format=BGR ! video/x-raw ! appsink drop=1"; - } - - const std::string getRecordingPipeline() { - return "videotestsrc ! videoconvert,format=BGR ! video/x-raw ! appsink drop=1"; - } -protected: - -}; - -class ObjectDetectionInterface { -public: - const static size_t MODEL_DIM_COUNT = 4; - int64_t model_input_shape[MODEL_DIM_COUNT] = { 0 }; - - virtual ~ObjectDetectionInterface() {} - virtual const char* getModelName() = 0; - virtual const uint64_t getModelVersion() = 0; - virtual const char* getModelInputName() = 0; - virtual const size_t getModelDimCount() = 0; - virtual const std::vector getModelInputShape() = 0; - virtual const std::string getClassLabelText(int classIndex) = 0; - - static inline float sigmoid(float x) { - return 1.f / (1.f + std::exp(-x)); - } - - static inline float linear(float x) { - return x; - } - - double intersectionOverUnion(const DetectedResult& o1, const DetectedResult& o2) { - double overlappingWidth = std::fmin(o1.x + o1.width, o2.x + o2.width) - std::fmax(o1.x, o2.x); - double overlappingHeight = std::fmin(o1.y + o1.height, o2.y + o2.height) - std::fmax(o1.y, o2.y); - double intersectionArea = (overlappingWidth < 0 || overlappingHeight < 0) ? 0 : overlappingHeight * overlappingWidth; - double unionArea = o1.width * o1.height + o2.width * o2.height - intersectionArea; - return intersectionArea / unionArea; - } - - virtual void postprocess(const int64_t* output_shape, const void* voutputData, const size_t bytesize, const uint32_t dimCount, std::vector &detectedResults) - { - } - - // Yolov5Ensemble detection/classification postprocess - virtual void postprocess( - const int64_t* output_shape_conf, const void* voutputData_conf, const size_t bytesize_conf, const uint32_t dimCount_conf, - const int64_t* output_shape_boxes, const void* voutputData_boxes, const size_t bytesize_boxes, const uint32_t dimCount_boxes, - const int64_t* output_shape_classification, const void* voutputData_classification, const size_t bytesize_classification, const uint32_t dimCount_classification, - std::vector &detectedResults) - { - // derived to implement - } - - // IOU postproc filter - void postprocess(std::vector &detectedResults, std::vector &outDetectedResults) - { - - if (useAdvancedPostprocessing) { - // Advanced postprocessing - // Checking IOU threshold conformance - // For every i-th object we're finding all objects it intersects with, and comparing confidence - // If i-th object has greater confidence than all others, we include it into result - for (const auto& obj1 : detectedResults) { - bool isGoodResult = true; - for (const auto& obj2 : detectedResults) { - if (obj1.classId == obj2.classId && obj1.confidence < obj2.confidence && - intersectionOverUnion(obj1, obj2) >= boxiou_threshold) { // if obj1 is the same as obj2, condition - // expression will evaluate to false anyway - isGoodResult = false; - break; - } - } - if (isGoodResult) { - outDetectedResults.push_back(obj1); - } - } - } else { - // Classic postprocessing - std::sort(detectedResults.begin(), detectedResults.end(), [](const DetectedResult& x, const DetectedResult& y) { - return x.confidence > y.confidence; - }); - for (size_t i = 0; i < detectedResults.size(); ++i) { - if (detectedResults[i].confidence == 0) - continue; - for (size_t j = i + 1; j < detectedResults.size(); ++j) - if (intersectionOverUnion(detectedResults[i], detectedResults[j]) >= boxiou_threshold) - detectedResults[j].confidence = 0; - outDetectedResults.push_back(detectedResults[i]); - } //end for - } // end if - } // end postprocess IOU filter - - -protected: - float confidence_threshold = .9; - float boxiou_threshold = .4; - float iou_threshold = 0.4; - int classes = 80; - bool useAdvancedPostprocessing = false; - -}; - -class Yolov5Ensemble : public ObjectDetectionInterface { -public: - - Yolov5Ensemble() { - confidence_threshold = _detection_threshold; - classes = 1000; - std::vector vmodel_input_shape = getModelInputShape(); - std::copy(vmodel_input_shape.begin(), vmodel_input_shape.end(), model_input_shape); - } - - const char* getModelName() { - return MODEL_NAME; - } - - const uint64_t getModelVersion() { - return MODEL_VERSION; - } - - const char* getModelInputName() { - return INPUT_NAME; - } - - const size_t getModelDimCount() { - return MODEL_DIM_COUNT; - } - - const std::vector getModelInputShape() { - std::vector shape{1,3,416,416}; - return shape; - } - const std::string labels[1000] = { - "tench, Tinca tinca", - "goldfish, Carassius auratus", - "great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias", - "tiger shark, Galeocerdo cuvieri", - "hammerhead, hammerhead shark", - "electric ray, crampfish, numbfish, torpedo", - "stingray", - "cock", - "hen", - "ostrich, Struthio camelus", - "brambling, Fringilla montifringilla", - "goldfinch, Carduelis carduelis", - "house finch, linnet, Carpodacus mexicanus", - "junco, snowbird", - "indigo bunting, indigo finch, indigo bird, Passerina cyanea", - "robin, American robin, Turdus migratorius", - "bulbul", - "jay", - "magpie", - "chickadee", - "water ouzel, dipper", - "kite", - "bald eagle, American eagle, Haliaeetus leucocephalus", - "vulture", - "great grey owl, great gray owl, Strix nebulosa", - "European fire salamander, Salamandra salamandra", - "common newt, Triturus vulgaris", - "eft", - "spotted salamander, Ambystoma maculatum", - "axolotl, mud puppy, Ambystoma mexicanum", - "bullfrog, Rana catesbeiana", - "tree frog, tree-frog", - "tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui", - "loggerhead, loggerhead turtle, Caretta caretta", - "leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea", - "mud turtle", - "terrapin", - "box turtle, box tortoise", - "banded gecko", - "common iguana, iguana, Iguana iguana", - "American chameleon, anole, Anolis carolinensis", - "whiptail, whiptail lizard", - "agama", - "frilled lizard, Chlamydosaurus kingi", - "alligator lizard", - "Gila monster, Heloderma suspectum", - "green lizard, Lacerta viridis", - "African chameleon, Chamaeleo chamaeleon", - "Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis", - "African crocodile, Nile crocodile, Crocodylus niloticus", - "American alligator, Alligator mississipiensis", - "triceratops", - "thunder snake, worm snake, Carphophis amoenus", - "ringneck snake, ring-necked snake, ring snake", - "hognose snake, puff adder, sand viper", - "green snake, grass snake", - "king snake, kingsnake", - "garter snake, grass snake", - "water snake", - "vine snake", - "night snake, Hypsiglena torquata", - "boa constrictor, Constrictor constrictor", - "rock python, rock snake, Python sebae", - "Indian cobra, Naja naja", - "green mamba", - "sea snake", - "horned viper, cerastes, sand viper, horned asp, Cerastes cornutus", - "diamondback, diamondback rattlesnake, Crotalus adamanteus", - "sidewinder, horned rattlesnake, Crotalus cerastes", - "trilobite", - "harvestman, daddy longlegs, Phalangium opilio", - "scorpion", - "black and gold garden spider, Argiope aurantia", - "barn spider, Araneus cavaticus", - "garden spider, Aranea diademata", - "black widow, Latrodectus mactans", - "tarantula", - "wolf spider, hunting spider", - "tick", - "centipede", - "black grouse", - "ptarmigan", - "ruffed grouse, partridge, Bonasa umbellus", - "prairie chicken, prairie grouse, prairie fowl", - "peacock", - "quail", - "partridge", - "African grey, African gray, Psittacus erithacus", - "macaw", - "sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita", - "lorikeet", - "coucal", - "bee eater", - "hornbill", - "hummingbird", - "jacamar", - "toucan", - "drake", - "red-breasted merganser, Mergus serrator", - "goose", - "black swan, Cygnus atratus", - "tusker", - "echidna, spiny anteater, anteater", - "platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus", - "wallaby, brush kangaroo", - "koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus", - "wombat", - "jellyfish", - "sea anemone, anemone", - "brain coral", - "flatworm, platyhelminth", - "nematode, nematode worm, roundworm", - "conch", - "snail", - "slug", - "sea slug, nudibranch", - "chiton, coat-of-mail shell, sea cradle, polyplacophore", - "chambered nautilus, pearly nautilus, nautilus", - "Dungeness crab, Cancer magister", - "rock crab, Cancer irroratus", - "fiddler crab", - "king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica", - "American lobster, Northern lobster, Maine lobster, Homarus americanus", - "spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish", - "crayfish, crawfish, crawdad, crawdaddy", - "hermit crab", - "isopod", - "white stork, Ciconia ciconia", - "black stork, Ciconia nigra", - "spoonbill", - "flamingo", - "little blue heron, Egretta caerulea", - "American egret, great white heron, Egretta albus", - "bittern", - "crane", - "limpkin, Aramus pictus", - "European gallinule, Porphyrio porphyrio", - "American coot, marsh hen, mud hen, water hen, Fulica americana", - "bustard", - "ruddy turnstone, Arenaria interpres", - "red-backed sandpiper, dunlin, Erolia alpina", - "redshank, Tringa totanus", - "dowitcher", - "oystercatcher, oyster catcher", - "pelican", - "king penguin, Aptenodytes patagonica", - "albatross, mollymawk", - "grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus", - "killer whale, killer, orca, grampus, sea wolf, Orcinus orca", - "dugong, Dugong dugon", - "sea lion", - "Chihuahua", - "Japanese spaniel", - "Maltese dog, Maltese terrier, Maltese", - "Pekinese, Pekingese, Peke", - "Shih-Tzu", - "Blenheim spaniel", - "papillon", - "toy terrier", - "Rhodesian ridgeback", - "Afghan hound, Afghan", - "basset, basset hound", - "beagle", - "bloodhound, sleuthhound", - "bluetick", - "black-and-tan coonhound", - "Walker hound, Walker foxhound", - "English foxhound", - "redbone", - "borzoi, Russian wolfhound", - "Irish wolfhound", - "Italian greyhound", - "whippet", - "Ibizan hound, Ibizan Podenco", - "Norwegian elkhound, elkhound", - "otterhound, otter hound", - "Saluki, gazelle hound", - "Scottish deerhound, deerhound", - "Weimaraner", - "Staffordshire bullterrier, Staffordshire bull terrier", - "American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier", - "Bedlington terrier", - "Border terrier", - "Kerry blue terrier", - "Irish terrier", - "Norfolk terrier", - "Norwich terrier", - "Yorkshire terrier", - "wire-haired fox terrier", - "Lakeland terrier", - "Sealyham terrier, Sealyham", - "Airedale, Airedale terrier", - "cairn, cairn terrier", - "Australian terrier", - "Dandie Dinmont, Dandie Dinmont terrier", - "Boston bull, Boston terrier", - "miniature schnauzer", - "giant schnauzer", - "standard schnauzer", - "Scotch terrier, Scottish terrier, Scottie", - "Tibetan terrier, chrysanthemum dog", - "silky terrier, Sydney silky", - "soft-coated wheaten terrier", - "West Highland white terrier", - "Lhasa, Lhasa apso", - "flat-coated retriever", - "curly-coated retriever", - "golden retriever", - "Labrador retriever", - "Chesapeake Bay retriever", - "German short-haired pointer", - "vizsla, Hungarian pointer", - "English setter", - "Irish setter, red setter", - "Gordon setter", - "Brittany spaniel", - "clumber, clumber spaniel", - "English springer, English springer spaniel", - "Welsh springer spaniel", - "cocker spaniel, English cocker spaniel, cocker", - "Sussex spaniel", - "Irish water spaniel", - "kuvasz", - "schipperke", - "groenendael", - "malinois", - "briard", - "kelpie", - "komondor", - "Old English sheepdog, bobtail", - "Shetland sheepdog, Shetland sheep dog, Shetland", - "collie", - "Border collie", - "Bouvier des Flandres, Bouviers des Flandres", - "Rottweiler", - "German shepherd, German shepherd dog, German police dog, alsatian", - "Doberman, Doberman pinscher", - "miniature pinscher", - "Greater Swiss Mountain dog", - "Bernese mountain dog", - "Appenzeller", - "EntleBucher", - "boxer", - "bull mastiff", - "Tibetan mastiff", - "French bulldog", - "Great Dane", - "Saint Bernard, St Bernard", - "Eskimo dog, husky", - "malamute, malemute, Alaskan malamute", - "Siberian husky", - "dalmatian, coach dog, carriage dog", - "affenpinscher, monkey pinscher, monkey dog", - "basenji", - "pug, pug-dog", - "Leonberg", - "Newfoundland, Newfoundland dog", - "Great Pyrenees", - "Samoyed, Samoyede", - "Pomeranian", - "chow, chow chow", - "keeshond", - "Brabancon griffon", - "Pembroke, Pembroke Welsh corgi", - "Cardigan, Cardigan Welsh corgi", - "toy poodle", - "miniature poodle", - "standard poodle", - "Mexican hairless", - "timber wolf, grey wolf, gray wolf, Canis lupus", - "white wolf, Arctic wolf, Canis lupus tundrarum", - "red wolf, maned wolf, Canis rufus, Canis niger", - "coyote, prairie wolf, brush wolf, Canis latrans", - "dingo, warrigal, warragal, Canis dingo", - "dhole, Cuon alpinus", - "African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus", - "hyena, hyaena", - "red fox, Vulpes vulpes", - "kit fox, Vulpes macrotis", - "Arctic fox, white fox, Alopex lagopus", - "grey fox, gray fox, Urocyon cinereoargenteus", - "tabby, tabby cat", - "tiger cat", - "Persian cat", - "Siamese cat, Siamese", - "Egyptian cat", - "cougar, puma, catamount, mountain lion, painter, panther, Felis concolor", - "lynx, catamount", - "leopard, Panthera pardus", - "snow leopard, ounce, Panthera uncia", - "jaguar, panther, Panthera onca, Felis onca", - "lion, king of beasts, Panthera leo", - "tiger, Panthera tigris", - "cheetah, chetah, Acinonyx jubatus", - "brown bear, bruin, Ursus arctos", - "American black bear, black bear, Ursus americanus, Euarctos americanus", - "ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus", - "sloth bear, Melursus ursinus, Ursus ursinus", - "mongoose", - "meerkat, mierkat", - "tiger beetle", - "ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle", - "ground beetle, carabid beetle", - "long-horned beetle, longicorn, longicorn beetle", - "leaf beetle, chrysomelid", - "dung beetle", - "rhinoceros beetle", - "weevil", - "fly", - "bee", - "ant, emmet, pismire", - "grasshopper, hopper", - "cricket", - "walking stick, walkingstick, stick insect", - "cockroach, roach", - "mantis, mantid", - "cicada, cicala", - "leafhopper", - "lacewing, lacewing fly", - "dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk", - "damselfly", - "admiral", - "ringlet, ringlet butterfly", - "monarch, monarch butterfly, milkweed butterfly, Danaus plexippus", - "cabbage butterfly", - "sulphur butterfly, sulfur butterfly", - "lycaenid, lycaenid butterfly", - "starfish, sea star", - "sea urchin", - "sea cucumber, holothurian", - "wood rabbit, cottontail, cottontail rabbit", - "hare", - "Angora, Angora rabbit", - "hamster", - "porcupine, hedgehog", - "fox squirrel, eastern fox squirrel, Sciurus niger", - "marmot", - "beaver", - "guinea pig, Cavia cobaya", - "sorrel", - "zebra", - "hog, pig, grunter, squealer, Sus scrofa", - "wild boar, boar, Sus scrofa", - "warthog", - "hippopotamus, hippo, river horse, Hippopotamus amphibius", - "ox", - "water buffalo, water ox, Asiatic buffalo, Bubalus bubalis", - "bison", - "ram, tup", - "bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis", - "ibex, Capra ibex", - "hartebeest", - "impala, Aepyceros melampus", - "gazelle", - "Arabian camel, dromedary, Camelus dromedarius", - "llama", - "weasel", - "mink", - "polecat, fitch, foulmart, foumart, Mustela putorius", - "black-footed ferret, ferret, Mustela nigripes", - "otter", - "skunk, polecat, wood pussy", - "badger", - "armadillo", - "three-toed sloth, ai, Bradypus tridactylus", - "orangutan, orang, orangutang, Pongo pygmaeus", - "gorilla, Gorilla gorilla", - "chimpanzee, chimp, Pan troglodytes", - "gibbon, Hylobates lar", - "siamang, Hylobates syndactylus, Symphalangus syndactylus", - "guenon, guenon monkey", - "patas, hussar monkey, Erythrocebus patas", - "baboon", - "macaque", - "langur", - "colobus, colobus monkey", - "proboscis monkey, Nasalis larvatus", - "marmoset", - "capuchin, ringtail, Cebus capucinus", - "howler monkey, howler", - "titi, titi monkey", - "spider monkey, Ateles geoffroyi", - "squirrel monkey, Saimiri sciureus", - "Madagascar cat, ring-tailed lemur, Lemur catta", - "indri, indris, Indri indri, Indri brevicaudatus", - "Indian elephant, Elephas maximus", - "African elephant, Loxodonta africana", - "lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens", - "giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca", - "barracouta, snoek", - "eel", - "coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch", - "rock beauty, Holocanthus tricolor", - "anemone fish", - "sturgeon", - "gar, garfish, garpike, billfish, Lepisosteus osseus", - "lionfish", - "puffer, pufferfish, blowfish, globefish", - "abacus", - "abaya", - "academic gown, academic robe, judge's robe", - "accordion, piano accordion, squeeze box", - "acoustic guitar", - "aircraft carrier, carrier, flattop, attack aircraft carrier", - "airliner", - "airship, dirigible", - "altar", - "ambulance", - "amphibian, amphibious vehicle", - "analog clock", - "apiary, bee house", - "apron", - "ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin", - "assault rifle, assault gun", - "backpack, back pack, knapsack, packsack, rucksack, haversack", - "bakery, bakeshop, bakehouse", - "balance beam, beam", - "balloon", - "ballpoint, ballpoint pen, ballpen, Biro", - "Band Aid", - "banjo", - "bannister, banister, balustrade, balusters, handrail", - "barbell", - "barber chair", - "barbershop", - "barn", - "barometer", - "barrel, cask", - "barrow, garden cart, lawn cart, wheelbarrow", - "baseball", - "basketball", - "bassinet", - "bassoon", - "bathing cap, swimming cap", - "bath towel", - "bathtub, bathing tub, bath, tub", - "beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon", - "beacon, lighthouse, beacon light, pharos", - "beaker", - "bearskin, busby, shako", - "beer bottle", - "beer glass", - "bell cote, bell cot", - "bib", - "bicycle-built-for-two, tandem bicycle, tandem", - "bikini, two-piece", - "binder, ring-binder", - "binoculars, field glasses, opera glasses", - "birdhouse", - "boathouse", - "bobsled, bobsleigh, bob", - "bolo tie, bolo, bola tie, bola", - "bonnet, poke bonnet", - "bookcase", - "bookshop, bookstore, bookstall", - "bottlecap", - "bow", - "bow tie, bow-tie, bowtie", - "brass, memorial tablet, plaque", - "brassiere, bra, bandeau", - "breakwater, groin, groyne, mole, bulwark, seawall, jetty", - "breastplate, aegis, egis", - "broom", - "bucket, pail", - "buckle", - "bulletproof vest", - "bullet train, bullet", - "butcher shop, meat market", - "cab, hack, taxi, taxicab", - "caldron, cauldron", - "candle, taper, wax light", - "cannon", - "canoe", - "can opener, tin opener", - "cardigan", - "car mirror", - "carousel, carrousel, merry-go-round, roundabout, whirligig", - "carpenter's kit, tool kit", - "carton", - "car wheel", - "cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM", - "cassette", - "cassette player", - "castle", - "catamaran", - "CD player", - "cello, violoncello", - "cellular telephone, cellular phone, cellphone, cell, mobile phone", - "chain", - "chainlink fence", - "chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour", - "chain saw, chainsaw", - "chest", - "chiffonier, commode", - "chime, bell, gong", - "china cabinet, china closet", - "Christmas stocking", - "church, church building", - "cinema, movie theater, movie theatre, movie house, picture palace", - "cleaver, meat cleaver, chopper", - "cliff dwelling", - "cloak", - "clog, geta, patten, sabot", - "cocktail shaker", - "coffee mug", - "coffeepot", - "coil, spiral, volute, whorl, helix", - "combination lock", - "computer keyboard, keypad", - "confectionery, confectionary, candy store", - "container ship, containership, container vessel", - "convertible", - "corkscrew, bottle screw", - "cornet, horn, trumpet, trump", - "cowboy boot", - "cowboy hat, ten-gallon hat", - "cradle", - "crane", - "crash helmet", - "crate", - "crib, cot", - "Crock Pot", - "croquet ball", - "crutch", - "cuirass", - "dam, dike, dyke", - "desk", - "desktop computer", - "dial telephone, dial phone", - "diaper, nappy, napkin", - "digital clock", - "digital watch", - "dining table, board", - "dishrag, dishcloth", - "dishwasher, dish washer, dishwashing machine", - "disk brake, disc brake", - "dock, dockage, docking facility", - "dogsled, dog sled, dog sleigh", - "dome", - "doormat, welcome mat", - "drilling platform, offshore rig", - "drum, membranophone, tympan", - "drumstick", - "dumbbell", - "Dutch oven", - "electric fan, blower", - "electric guitar", - "electric locomotive", - "entertainment center", - "envelope", - "espresso maker", - "face powder", - "feather boa, boa", - "file, file cabinet, filing cabinet", - "fireboat", - "fire engine, fire truck", - "fire screen, fireguard", - "flagpole, flagstaff", - "flute, transverse flute", - "folding chair", - "football helmet", - "forklift", - "fountain", - "fountain pen", - "four-poster", - "freight car", - "French horn, horn", - "frying pan, frypan, skillet", - "fur coat", - "garbage truck, dustcart", - "gasmask, respirator, gas helmet", - "gas pump, gasoline pump, petrol pump, island dispenser", - "goblet", - "go-kart", - "golf ball", - "golfcart, golf cart", - "gondola", - "gong, tam-tam", - "gown", - "grand piano, grand", - "greenhouse, nursery, glasshouse", - "grille, radiator grille", - "grocery store, grocery, food market, market", - "guillotine", - "hair slide", - "hair spray", - "half track", - "hammer", - "hamper", - "hand blower, blow dryer, blow drier, hair dryer, hair drier", - "hand-held computer, hand-held microcomputer", - "handkerchief, hankie, hanky, hankey", - "hard disc, hard disk, fixed disk", - "harmonica, mouth organ, harp, mouth harp", - "harp", - "harvester, reaper", - "hatchet", - "holster", - "home theater, home theatre", - "honeycomb", - "hook, claw", - "hoopskirt, crinoline", - "horizontal bar, high bar", - "horse cart, horse-cart", - "hourglass", - "iPod", - "iron, smoothing iron", - "jack-o'-lantern", - "jean, blue jean, denim", - "jeep, landrover", - "jersey, T-shirt, tee shirt", - "jigsaw puzzle", - "jinrikisha, ricksha, rickshaw", - "joystick", - "kimono", - "knee pad", - "knot", - "lab coat, laboratory coat", - "ladle", - "lampshade, lamp shade", - "laptop, laptop computer", - "lawn mower, mower", - "lens cap, lens cover", - "letter opener, paper knife, paperknife", - "library", - "lifeboat", - "lighter, light, igniter, ignitor", - "limousine, limo", - "liner, ocean liner", - "lipstick, lip rouge", - "Loafer", - "lotion", - "loudspeaker, speaker, speaker unit, loudspeaker system, speaker system", - "loupe, jeweler's loupe", - "lumbermill, sawmill", - "magnetic compass", - "mailbag, postbag", - "mailbox, letter box", - "maillot", - "maillot, tank suit", - "manhole cover", - "maraca", - "marimba, xylophone", - "mask", - "matchstick", - "maypole", - "maze, labyrinth", - "measuring cup", - "medicine chest, medicine cabinet", - "megalith, megalithic structure", - "microphone, mike", - "microwave, microwave oven", - "military uniform", - "milk can", - "minibus", - "miniskirt, mini", - "minivan", - "missile", - "mitten", - "mixing bowl", - "mobile home, manufactured home", - "Model T", - "modem", - "monastery", - "monitor", - "moped", - "mortar", - "mortarboard", - "mosque", - "mosquito net", - "motor scooter, scooter", - "mountain bike, all-terrain bike, off-roader", - "mountain tent", - "mouse, computer mouse", - "mousetrap", - "moving van", - "muzzle", - "nail", - "neck brace", - "necklace", - "nipple", - "notebook, notebook computer", - "obelisk", - "oboe, hautboy, hautbois", - "ocarina, sweet potato", - "odometer, hodometer, mileometer, milometer", - "oil filter", - "organ, pipe organ", - "oscilloscope, scope, cathode-ray oscilloscope, CRO", - "overskirt", - "oxcart", - "oxygen mask", - "packet", - "paddle, boat paddle", - "paddlewheel, paddle wheel", - "padlock", - "paintbrush", - "pajama, pyjama, pj's, jammies", - "palace", - "panpipe, pandean pipe, syrinx", - "paper towel", - "parachute, chute", - "parallel bars, bars", - "park bench", - "parking meter", - "passenger car, coach, carriage", - "patio, terrace", - "pay-phone, pay-station", - "pedestal, plinth, footstall", - "pencil box, pencil case", - "pencil sharpener", - "perfume, essence", - "Petri dish", - "photocopier", - "pick, plectrum, plectron", - "pickelhaube", - "picket fence, paling", - "pickup, pickup truck", - "pier", - "piggy bank, penny bank", - "pill bottle", - "pillow", - "ping-pong ball", - "pinwheel", - "pirate, pirate ship", - "pitcher, ewer", - "plane, carpenter's plane, woodworking plane", - "planetarium", - "plastic bag", - "plate rack", - "plow, plough", - "plunger, plumber's helper", - "Polaroid camera, Polaroid Land camera", - "pole", - "police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria", - "poncho", - "pool table, billiard table, snooker table", - "pop bottle, soda bottle", - "pot, flowerpot", - "potter's wheel", - "power drill", - "prayer rug, prayer mat", - "printer", - "prison, prison house", - "projectile, missile", - "projector", - "puck, hockey puck", - "punching bag, punch bag, punching ball, punchball", - "purse", - "quill, quill pen", - "quilt, comforter, comfort, puff", - "racer, race car, racing car", - "racket, racquet", - "radiator", - "radio, wireless", - "radio telescope, radio reflector", - "rain barrel", - "recreational vehicle, RV, R.V.", - "reel", - "reflex camera", - "refrigerator, icebox", - "remote control, remote", - "restaurant, eating house, eating place, eatery", - "revolver, six-gun, six-shooter", - "rifle", - "rocking chair, rocker", - "rotisserie", - "rubber eraser, rubber, pencil eraser", - "rugby ball", - "rule, ruler", - "running shoe", - "safe", - "safety pin", - "saltshaker, salt shaker", - "sandal", - "sarong", - "sax, saxophone", - "scabbard", - "scale, weighing machine", - "school bus", - "schooner", - "scoreboard", - "screen, CRT screen", - "screw", - "screwdriver", - "seat belt, seatbelt", - "sewing machine", - "shield, buckler", - "shoe shop, shoe-shop, shoe store", - "shoji", - "shopping basket", - "shopping cart", - "shovel", - "shower cap", - "shower curtain", - "ski", - "ski mask", - "sleeping bag", - "slide rule, slipstick", - "sliding door", - "slot, one-armed bandit", - "snorkel", - "snowmobile", - "snowplow, snowplough", - "soap dispenser", - "soccer ball", - "sock", - "solar dish, solar collector, solar furnace", - "sombrero", - "soup bowl", - "space bar", - "space heater", - "space shuttle", - "spatula", - "speedboat", - "spider web, spider's web", - "spindle", - "sports car, sport car", - "spotlight, spot", - "stage", - "steam locomotive", - "steel arch bridge", - "steel drum", - "stethoscope", - "stole", - "stone wall", - "stopwatch, stop watch", - "stove", - "strainer", - "streetcar, tram, tramcar, trolley, trolley car", - "stretcher", - "studio couch, day bed", - "stupa, tope", - "submarine, pigboat, sub, U-boat", - "suit, suit of clothes", - "sundial", - "sunglass", - "sunglasses, dark glasses, shades", - "sunscreen, sunblock, sun blocker", - "suspension bridge", - "swab, swob, mop", - "sweatshirt", - "swimming trunks, bathing trunks", - "swing", - "switch, electric switch, electrical switch", - "syringe", - "table lamp", - "tank, army tank, armored combat vehicle, armoured combat vehicle", - "tape player", - "teapot", - "teddy, teddy bear", - "television, television system", - "tennis ball", - "thatch, thatched roof", - "theater curtain, theatre curtain", - "thimble", - "thresher, thrasher, threshing machine", - "throne", - "tile roof", - "toaster", - "tobacco shop, tobacconist shop, tobacconist", - "toilet seat", - "torch", - "totem pole", - "tow truck, tow car, wrecker", - "toyshop", - "tractor", - "trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi", - "tray", - "trench coat", - "tricycle, trike, velocipede", - "trimaran", - "tripod", - "triumphal arch", - "trolleybus, trolley coach, trackless trolley", - "trombone", - "tub, vat", - "turnstile", - "typewriter keyboard", - "umbrella", - "unicycle, monocycle", - "upright, upright piano", - "vacuum, vacuum cleaner", - "vase", - "vault", - "velvet", - "vending machine", - "vestment", - "viaduct", - "violin, fiddle", - "volleyball", - "waffle iron", - "wall clock", - "wallet, billfold, notecase, pocketbook", - "wardrobe, closet, press", - "warplane, military plane", - "washbasin, handbasin, washbowl, lavabo, wash-hand basin", - "washer, automatic washer, washing machine", - "water bottle", - "water jug", - "water tower", - "whiskey jug", - "whistle", - "wig", - "window screen", - "window shade", - "Windsor tie", - "wine bottle", - "wing", - "wok", - "wooden spoon", - "wool, woolen, woollen", - "worm fence, snake fence, snake-rail fence, Virginia fence", - "wreck", - "yawl", - "yurt", - "web site, website, internet site, site", - "comic book", - "crossword puzzle, crossword", - "street sign", - "traffic light, traffic signal, stoplight", - "book jacket, dust cover, dust jacket, dust wrapper", - "menu", - "plate", - "guacamole", - "consomme", - "hot pot, hotpot", - "trifle", - "ice cream, icecream", - "ice lolly, lolly, lollipop, popsicle", - "French loaf", - "bagel, beigel", - "pretzel", - "cheeseburger", - "hotdog, hot dog, red hot", - "mashed potato", - "head cabbage", - "broccoli", - "cauliflower", - "zucchini, courgette", - "spaghetti squash", - "acorn squash", - "butternut squash", - "cucumber, cuke", - "artichoke, globe artichoke", - "bell pepper", - "cardoon", - "mushroom", - "Granny Smith", - "strawberry", - "orange", - "lemon", - "fig", - "pineapple, ananas", - "banana", - "jackfruit, jak, jack", - "custard apple", - "pomegranate", - "hay", - "carbonara", - "chocolate sauce, chocolate syrup", - "dough", - "meat loaf, meatloaf", - "pizza, pizza pie", - "potpie", - "burrito", - "red wine", - "espresso", - "cup", - "eggnog", - "alp", - "bubble", - "cliff, drop, drop-off", - "coral reef", - "geyser", - "lakeside, lakeshore", - "promontory, headland, head, foreland", - "sandbar, sand bar", - "seashore, coast, seacoast, sea-coast", - "valley, vale", - "volcano", - "ballplayer, baseball player", - "groom, bridegroom", - "scuba diver", - "rapeseed", - "daisy", - "yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum", - "corn", - "acorn", - "hip, rose hip, rosehip", - "buckeye, horse chestnut, conker", - "coral fungus", - "agaric", - "gyromitra", - "stinkhorn, carrion fungus", - "earthstar", - "hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa", - "bolete", - "ear, spike, capitulum", - "toilet tissue, toilet paper, bathroom tissue" - }; - - const std::string getClassLabelText(int classIndex) { - return labels[classIndex]; - } - - int argmax(const float* tensor, int numberElements) { - float topConfidence = 0; - int topLabel = -1; - for (int i = 0; i < numberElements; i++) { - float confidence = tensor[i]; - if (topLabel == -1 || topConfidence < confidence) { - topLabel = i; - topConfidence = confidence; - } - } - return topLabel; - } - - void postprocess( - const int64_t* output_shape_conf, const void* voutputData_conf, const size_t bytesize_conf, const uint32_t dimCount_conf, - const int64_t* output_shape_boxes, const void* voutputData_boxes, const size_t bytesize_boxes, const uint32_t dimCount_boxes, - const int64_t* output_shape_classification, const void* voutputData_classification, const size_t bytesize_classification, const uint32_t dimCount_classification, - std::vector &detectedResults) - { - if (!voutputData_boxes || !voutputData_conf || !voutputData_classification) { - // nothing to do - return; - } - - if (dimCount_conf != 3 || dimCount_boxes != 3 || dimCount_classification != 3) - { - printf("Unknown yolov5 detection and/or efficientnet-b0 model.\n"); - return; - } - - // Output Info - // classify_output 1,1,1000 - // confidence - 1, 1, 1 - // boxes - 1,1,4 - const int numberOfDetections = output_shape_boxes[0]; - const int boxesSize = output_shape_boxes[2]; - const int* outData_boxes = reinterpret_cast(voutputData_boxes); - const float* outData_confidence = reinterpret_cast(voutputData_conf); - const float* outData_classify_labels = reinterpret_cast(voutputData_classification); - - std::vector input_shape = getModelInputShape(); - int network_h = input_shape[2]; - int network_w = input_shape[3]; - - for (int i = 0; i < numberOfDetections; i++) - { - float confidence = outData_confidence[i]; - - if (confidence > confidence_threshold ) { - int classId = argmax(outData_classify_labels, output_shape_classification[2]); - // printf("Confidence found: %f ClassID found: %i NetworkW %i NetworkH: %i BoxSize %i \n", confidence, classId, network_w, network_h, boxesSize); - - DetectedResult obj; - obj.x = std::clamp( - static_cast((outData_boxes[i * boxesSize + 0] / ((float)network_w / (float)_video_input_width))), - 0, - _video_input_width); - obj.y = std::clamp( - static_cast((outData_boxes[i * boxesSize + 1] / ((float)network_h/(float)_video_input_height))), - 0, - _video_input_height); - obj.width = std::clamp( - static_cast((outData_boxes[i * boxesSize + 2] / ((float)network_w/(float)_video_input_width) )), - 0, - _video_input_width); - obj.height = std::clamp( - static_cast((outData_boxes[i * boxesSize + 3] / ((float)network_h/(float)_video_input_height) )), - 0, - _video_input_height); - obj.confidence = confidence; - obj.classId = (int) classId; - strncpy(obj.classText, getClassLabelText(obj.classId).c_str(), sizeof(obj.classText)); - - detectedResults.push_back(obj); - } // end if confidence - } // end for - } - -private: - const char* MODEL_NAME = "detect_classify"; - const uint64_t MODEL_VERSION = 0; - const char* INPUT_NAME = "images"; -}; - - - -GStreamerMediaPipelineService* _mediaService = NULL; -std::string _user_request; - -namespace { -volatile sig_atomic_t shutdown_request = 0; -} - -bool stringIsInteger(std::string strInput) { - std::string::const_iterator it = strInput.begin(); - while (it != strInput.end() && std::isdigit(*it)) ++it; - return !strInput.empty() && it == strInput.end(); -} - -bool stringIsFloat(std::string strInput) { - std::istringstream iss(strInput); - float f; - iss >> std::noskipws >> f; // noskipws considers leading whitespace invalid - return iss.eof() && !iss.fail(); -} - -bool setActiveModel(int detectionType, ObjectDetectionInterface** objDet) -{ - if (objDet == NULL) - return false; - - - *objDet = new Yolov5Ensemble(); - return true; -} - -static void onInterrupt(int status) { - shutdown_request = 1; -} - -static void onTerminate(int status) { - shutdown_request = 1; -} - -static void onIllegal(int status) { - shutdown_request = 2; -} - -static void installSignalHandlers() { - static struct sigaction sigIntHandler; - sigIntHandler.sa_handler = onInterrupt; - sigemptyset(&sigIntHandler.sa_mask); - sigIntHandler.sa_flags = 0; - sigaction(SIGINT, &sigIntHandler, NULL); - - static struct sigaction sigTermHandler; - sigTermHandler.sa_handler = onTerminate; - sigemptyset(&sigTermHandler.sa_mask); - sigTermHandler.sa_flags = 0; - sigaction(SIGTERM, &sigTermHandler, NULL); - - static struct sigaction sigIllHandler; - sigIllHandler.sa_handler = onIllegal; - sigemptyset(&sigIllHandler.sa_mask); - sigIllHandler.sa_flags = 0; - sigaction(SIGILL, &sigIllHandler, NULL); -} - -void printInferenceResults(std::vector &results) -{ - for (auto & obj : results) { - std::cout << "Rect: [ " << obj.x << " , " << obj.y << " " << obj.width << ", " << obj.height << "] Class: " << obj.classText << "(" << obj.classId << ") Conf: " << obj.confidence << std::endl; - } -} - -void displayGUIInferenceResults(cv::Mat analytics_frame, std::vector &results, int latency, int througput) -{ - auto ttid = std::this_thread::get_id(); - std::stringstream ss; - ss << ttid; - std::string tid = ss.str(); - - for (auto & obj : results) { - const float x0 = obj.x; - const float y0 = obj.y; - const float x1 = obj.x + obj.width; - const float y1 = obj.y + obj.height; - - //printf("--------->coords: %f %f %f %f\n", x0, y0, x1, y1); - cv::rectangle( analytics_frame, - cv::Point( (int)(x0),(int)(y0) ), - cv::Point( (int)x1, (int)y1 ), - cv::Scalar(255, 0, 0), - 2, cv::LINE_8 ); - - cv::Size textsize = cv::getTextSize(obj.classText, cv::FONT_HERSHEY_PLAIN, 1, 0,0); - - cv::rectangle(analytics_frame, - cv::Point( (int)(x0),(int)(y0-20) ), - cv::Point((int)x0 + textsize.width, (int)y0 + textsize.height), - CV_RGB(0, 0, 0), - -1); - - cv::putText(analytics_frame, - obj.classText, - cv::Size((int)x0, (int)y0), - cv::FONT_HERSHEY_PLAIN, 1, CV_RGB(255, 255, 255), 1); - - } // end for - - cv::Mat presenter; - - { - std::lock_guard lock(_drawingMtx); - cv::imshow("OpenVINO Results " + tid, analytics_frame); - cv::waitKey(1); - } -} - -void saveInferenceResultsAsVideo(cv::Mat &presenter, std::vector &results) -{ - for (auto & obj : results) { - - const float scaler_w = 416.0f/_video_input_width; - const float scaler_h = 416.0f/_video_input_height; - - cv::rectangle( presenter, - cv::Point( (int)(obj.x*scaler_w),(int)(obj.y*scaler_h) ), - cv::Point( (int)((obj.x+obj.width) * scaler_w), (int)((obj.y+obj.height)*scaler_h) ), - cv::Scalar(255, 0, 0), - 4, cv::LINE_8 ); - } // end for - cv::imwrite("result.jpg", presenter); -} - -// This function is responsible for generating a GST pipeline that -// decodes and resizes the video stream based on the desired window size or -// the largest analytics frame size needed if running headless -std::string getVideoPipelineText(std::string mediaPath, ObjectDetectionInterface* objDet, ObjectDetectionInterface* textDet) -{ - - std::vector modelFrameShape = objDet->getModelInputShape(); - if (textDet) { - modelFrameShape = textDet->getModelInputShape(); - } - - int frame_width = modelFrameShape[3]; - int frame_height = modelFrameShape[2]; - - if (_render) - { - frame_width = _window_width; - frame_height = _window_height; - } - - return _mediaService->getVideoDecodedPreProcessedPipeline( - mediaPath, - _videoType, - frame_width, - frame_height, - _use_onevpl); -} - -bool createModelServer() -{ - if (_srv == NULL) - return false; - - OVMS_Status* res = OVMS_ServerStartFromConfigurationFile(_srv, _serverSettings, _modelsSettings); - - if (res) { - uint32_t code = 0; - const char* details = nullptr; - - OVMS_StatusCode(res, &code); - OVMS_StatusDetails(res, &details); - std::cerr << "ERROR: during start: code:" << code << "; details:" << details - << "; grpc_port: " << _server_grpc_port - << "; http_port: " << _server_http_port - << ";" << std::endl; - - OVMS_StatusDelete(res); - - if (_srv) - OVMS_ServerDelete(_srv); - - if (_modelsSettings) - OVMS_ModelsSettingsDelete(_modelsSettings); - - if (_serverSettings) - OVMS_ServerSettingsDelete(_serverSettings); - - return false; - } - - return true; -} - -bool loadGStreamer(GstElement** pipeline, GstElement** appsink, std::string mediaPath, ObjectDetectionInterface* _objDet) -{ - static int threadCnt = 0; - - std::string videoPipelineText = getVideoPipelineText(mediaPath, _objDet, NULL); - std::cout << "--------------------------------------------------------------" << std::endl; - std::cout << "Opening Media Pipeline: " << videoPipelineText << std::endl; - std::cout << "--------------------------------------------------------------" << std::endl; - - *pipeline = gst_parse_launch (videoPipelineText.c_str(), NULL); - if (*pipeline == NULL) { - std::cout << "ERROR: Failed to parse GST pipeline. Quitting." << std::endl; - return false; - } - - std::string appsinkName = "appsink" + std::to_string(threadCnt++); - - *appsink = gst_bin_get_by_name (GST_BIN (*pipeline), appsinkName.c_str()); - - // Check if all elements were created - if (!(*appsink)) - { - printf("ERROR: Failed to initialize GST pipeline (missing %s) Quitting.\n", appsinkName.c_str()); - return false; - } - - GstStateChangeReturn gst_res; - - // Start pipeline so it could process incoming data - gst_res = gst_element_set_state(*pipeline, GST_STATE_PLAYING); - - if (gst_res != GST_STATE_CHANGE_SUCCESS && gst_res != GST_STATE_CHANGE_ASYNC ) { - printf("ERROR: StateChange not successful. Error Code: %d\n", gst_res); - return false; - } - - return true; -} - -// OVMS C-API is a global process (singleton design) wide server so can't create many of them -bool loadOVMS() -{ - OVMS_Status* res = NULL; - - OVMS_ServerSettingsNew(&_serverSettings); - OVMS_ModelsSettingsNew(&_modelsSettings); - OVMS_ServerNew(&_srv); - OVMS_ServerSettingsSetGrpcPort(_serverSettings, _server_grpc_port); - OVMS_ServerSettingsSetRestPort(_serverSettings, _server_http_port); - OVMS_ServerSettingsSetLogLevel(_serverSettings, OVMS_LOG_ERROR); - - char * ovmsCofigJsonFilePath = std::getenv("OVMS_MODEL_CONFIG_JSON"); - std::cout << "ovmsCofigJsonFilePath: "< channels; - cv::split(src, channels); - - for (auto &img : channels) { - img = img.reshape(1, 1); - } - - // Concatenate three vectors to one - cv::hconcat( channels, dst ); -} - -void run_stream(std::string mediaPath, GstElement* pipeline, GstElement* appsink, ObjectDetectionInterface* objDet) -{ - auto ttid = std::this_thread::get_id(); - std::stringstream ss; - ss << ttid; - std::string tid = ss.str(); - - // Wait for all decoder streams to init...otherwise causes a segfault when OVMS loads - // https://stackoverflow.com/questions/48271230/using-condition-variablenotify-all-to-notify-multiple-threads - std::unique_lock lk(_mtx); - _cvAllDecodersInitd.wait(lk, [] { return _allDecodersInitd;} ); - lk.unlock(); - - printf("Starting thread: %s\n", tid.c_str()) ; - - auto initTime = std::chrono::high_resolution_clock::now(); - unsigned long numberOfFrames = 0; - long long numberOfSkipFrames = 0; - OVMS_Status* res = NULL; - - BarcodeProcessor barcode; - - while (!shutdown_request) { - auto startTime = std::chrono::high_resolution_clock::now(); - - // classify_output - const void* voutputData1; - size_t bytesize1 = 0; - OVMS_DataType datatype1 = (OVMS_DataType)42; - const int64_t* shape1{nullptr}; - size_t dimCount1 = 0; - OVMS_BufferType bufferType1 = (OVMS_BufferType)42; - uint32_t deviceId1 = 42; - const char* outputName1{nullptr}; - - // confidence_levels - const void* voutputData2; - size_t bytesize2 = 0; - OVMS_DataType datatype2 = (OVMS_DataType)42; - const int64_t* shape2{nullptr}; - size_t dimCount2 = 0; - OVMS_BufferType bufferType2 = (OVMS_BufferType)42; - uint32_t deviceId2 = 42; - const char* outputName2{nullptr}; - - // roi_coordinates - const void* voutputData3; - size_t bytesize3 = 0; - OVMS_DataType datatype3 = (OVMS_DataType)42; - const int64_t* shape3{nullptr}; - size_t dimCount3 = 0; - OVMS_BufferType bufferType3 = (OVMS_BufferType)42; - uint32_t deviceId3 = 42; - const char* outputName3{nullptr}; - - // Common across getoutput API - uint32_t outputCount = 0; - uint32_t outputId; - - GstSample *sample; - GstStructure *s; - GstBuffer *buffer; - GstMapInfo m; - - std::vector detectedResults; - std::vector detectedResultsFiltered; - - auto metricStartTime = std::chrono::high_resolution_clock::now(); - if (gst_app_sink_is_eos(GST_APP_SINK(appsink))) { - std::cout << "INFO: EOS " << std::endl; - return; - } - auto metricEndTime = std::chrono::high_resolution_clock::now(); - auto metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Get appsink latency (ms): " << metricLatencyTime << endl; - - metricStartTime = std::chrono::high_resolution_clock::now(); - sample = gst_app_sink_try_pull_sample (GST_APP_SINK(appsink), 50 * GST_SECOND); - - if (sample == nullptr) { - std::cout << "ERROR: No sample found" << std::endl; - return; - } - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Pull sample latency (ms): " << metricLatencyTime << endl; - - GstCaps *caps; - caps = gst_sample_get_caps(sample); - - if (caps == nullptr) { - std::cout << "ERROR: No caps found for sample" << std::endl; - return; - } - - s = gst_caps_get_structure(caps, 0); - gst_structure_get_int(s, "width", &_video_input_width); - gst_structure_get_int(s, "height", &_video_input_height); - - metricStartTime = std::chrono::high_resolution_clock::now(); - buffer = gst_sample_get_buffer(sample); - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Get sample buffer latency (ms): " << metricLatencyTime << endl; - - metricStartTime = std::chrono::high_resolution_clock::now(); - gst_buffer_map(buffer, &m, GST_MAP_READ); - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Copy sample buffer latency (ms): " << metricLatencyTime << endl; - - if (m.size <= 0) { - std::cout << "ERROR: Invalid buffer size" << std::endl; - return; - } - - cv::Mat analytics_frame; - cv::Mat floatImage; - std::vector inputShape; - - inputShape = objDet->getModelInputShape(); - - metricStartTime = std::chrono::high_resolution_clock::now(); - cv::Mat img(_video_input_height, _video_input_width, CV_8UC3, (void *) m.data); - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - - // When rendering is enabled then the input frame is resized to window size and not the needed model input size - if (_render) { - - if (dynamic_cast(objDet) != nullptr) - { - metricStartTime = std::chrono::high_resolution_clock::now(); - resize(img, analytics_frame, cv::Size(inputShape[2], inputShape[3]), 0, 0, cv::INTER_LINEAR); - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - metricStartTime = std::chrono::high_resolution_clock::now(); - hwc_to_chw(analytics_frame, analytics_frame); - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - } - else - { - printf("ERROR: Unknown model type\n"); - return; - } - metricStartTime = std::chrono::high_resolution_clock::now(); - analytics_frame.convertTo(floatImage, CV_32F); - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - } - else { - hwc_to_chw(img, analytics_frame); - analytics_frame.convertTo(floatImage, CV_32F); - } - - const int DATA_SIZE = floatImage.step[0] * floatImage.rows; - - OVMS_InferenceResponse* response = nullptr; - OVMS_InferenceRequest* request{nullptr}; - - // OD Inference - { - std::lock_guard lock(_infMtx); - - metricStartTime = std::chrono::high_resolution_clock::now(); - - OVMS_InferenceRequestNew(&request, _srv, objDet->getModelName(), objDet->getModelVersion()); - - OVMS_InferenceRequestAddInput( - request, - objDet->getModelInputName(), - OVMS_DATATYPE_FP32, - objDet->model_input_shape, - objDet->getModelDimCount() - ); - - // run sync request - OVMS_InferenceRequestInputSetData( - request, - objDet->getModelInputName(), - reinterpret_cast(floatImage.data), - DATA_SIZE , - OVMS_BUFFERTYPE_CPU, - 0 - ); - - res = OVMS_Inference(_srv, request, &response); - - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - - if (res != nullptr) { - uint32_t code = 0; - const char* details = 0; - OVMS_StatusCode(res, &code); - OVMS_StatusDetails(res, &details); - - OVMS_StatusDelete(res); - if (request) - OVMS_InferenceRequestDelete(request); - - metricStartTime = std::chrono::high_resolution_clock::now(); - - gst_buffer_unmap(buffer, &m); - gst_sample_unref(sample); - - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - - if (code != 176 /*ovms::StatusCode::PIPELINE_DEMULTIPLEXER_NO_RESULTS*/) - { - std::cout << "Error occured during inference. Code:" << code << std::endl; - std::cout << ", details:" << details << std::endl; - break; - } - else - continue; - } - } // end lock on inference request to server - - // Barcode detect and decode - if(_barcode == 1){ - barcode.decode(img); - } - - metricStartTime = std::chrono::high_resolution_clock::now(); - OVMS_InferenceResponseOutputCount(response, &outputCount); - outputId = 0; - - // confidence_levels - OVMS_InferenceResponseOutput(response, outputId, &outputName1, &datatype1, &shape1, &dimCount1, &voutputData1, &bytesize1, &bufferType1, &deviceId1); - - // roi_coordinates - outputId = 1; - OVMS_InferenceResponseOutput(response, outputId, &outputName2, &datatype2, &shape2, &dimCount2, &voutputData2, &bytesize2, &bufferType2, &deviceId2); - - // classify_output e.g. Classification results - outputId = 2; - OVMS_InferenceResponseOutput(response, outputId, &outputName3, &datatype3, &shape3, &dimCount3, &voutputData3, &bytesize3, &bufferType3, &deviceId3); - - objDet->postprocess( - shape1, voutputData1, bytesize1, dimCount1, - shape2, voutputData2, bytesize2, dimCount2, - shape3, voutputData3, bytesize3, dimCount3, - detectedResults); - objDet->postprocess(detectedResults, detectedResultsFiltered); - - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - - numberOfSkipFrames++; - float fps = 0; - if (numberOfSkipFrames <= 120) // allow warm up for latency/fps measurements - { - initTime = std::chrono::high_resolution_clock::now(); - numberOfFrames = 0; - - //printf("Too early...Skipping frames..\n"); - } - else - { - numberOfFrames++; - - auto endTime = std::chrono::high_resolution_clock::now(); - auto latencyTime = ((std::chrono::duration_cast(endTime-startTime)).count()); - auto runningLatencyTime = ((std::chrono::duration_cast(endTime-initTime)).count()); - if (runningLatencyTime > 0) { // skip a few to account for init - fps = (float)numberOfFrames/(float)(runningLatencyTime/1000); // convert to seconds - } - - if (_render) - displayGUIInferenceResults(img, detectedResultsFiltered, latencyTime, fps); - - static int highest_latency_frame = 0; - static int lowest_latency_frame = 9999; - static int avg_latency_frame = 0; - static int total_latency_frames = 0; - - int frame_latency = chrono::duration_cast(endTime - startTime).count(); - - if (frame_latency > highest_latency_frame) - highest_latency_frame = frame_latency; - if (frame_latency < lowest_latency_frame) - lowest_latency_frame = frame_latency; - - total_latency_frames += frame_latency; - - - - if (numberOfFrames % 30 == 0) { - avg_latency_frame = total_latency_frames / 30; - - time_t currTime = time(0); - struct tm tstruct; - char bCurrTime[80]; - tstruct = *localtime(&currTime); - // http://en.cppreference.com/w/cpp/chrono/c/strftime - strftime(bCurrTime, sizeof(bCurrTime), "%Y-%m-%d.%X", &tstruct); - - cout << detectedResultsFiltered.size() << " object(s) detected at " << bCurrTime << endl; - cout << "Avg. Pipeline Throughput FPS: " << ((isinf(fps)) ? "..." : std::to_string(fps)) << endl; - cout << "Avg. Pipeline Latency (ms): " << avg_latency_frame << endl; - cout << "Max. Pipeline Latency (ms): " << highest_latency_frame << endl; - cout << "Min. Pipeline Latency (ms): " << lowest_latency_frame << endl; - highest_latency_frame = 0; - lowest_latency_frame = 9999; - total_latency_frames = 0; - } - - } - - if (request) { - OVMS_InferenceRequestInputRemoveData(request, objDet->getModelInputName()); // doesn't help - OVMS_InferenceRequestRemoveInput(request, objDet->getModelInputName()); - OVMS_InferenceRequestDelete(request); - } - - if (response) { - OVMS_InferenceResponseDelete(response); - } - - gst_buffer_unmap(buffer, &m); - gst_sample_unref(sample); - - if (shutdown_request > 0) - break; - } // end while get frames - - std::cout << "Goodbye..." << std::endl; - - if (res != NULL) { - OVMS_StatusDelete(res); - res = NULL; - } - - if (objDet) { - delete objDet; - objDet = NULL; - } - - gst_element_set_state (pipeline, GST_STATE_NULL); - if (pipeline) - gst_object_unref(pipeline); - - if (appsink) - gst_object_unref(appsink); -} - -void print_usage(const char* programName) { - std::cout << "Usage: ./" << programName << " \n\n" - << "mediaLocation is an rtsp://127.0.0.1:8554/camera_0 url or a path to an *.mp4 file\n" - << "use_onevpl is 0 (libva - default) or 1 for onevpl\n" - << "render is 1 to launch render window or 0 (default) for headless\n" - << "video_type is 0 for AVC or 1 for HEVC\n" - << "window_width is display window width\n" - << "window_height is display window height\n" - << "detection_threshold is confidence threshold value in floating point that needs to be between 0.0 to 1.0\n"; -} - -int get_running_servers() { - const char * val = std::getenv("cid_count"); - std::cout << "val: "< 1.0 || _detection_threshold < 0.0) { - std::cout << "detection_threshold: " << _detection_threshold << ", is confidence threshold value in floating point that needs to be between 0.0 to 1.0.\n" << endl; - return 1; - } - _barcode = std::stoi(argv[9]); - std::cout << "_barcode: " << _barcode << std::endl; - - if (_renderPortrait) { - int tmp = _window_width; - _window_width = _window_height; - _window_height = tmp; - } - } - - gst_init(NULL, NULL); - - std::vector running_streams; - _allDecodersInitd = false; - - GstElement *pipeline; - GstElement *appsink; - ObjectDetectionInterface* objDet; - getMAPipeline(_videoStreamPipeline, &pipeline, &appsink, &objDet); - running_streams.emplace_back(run_stream, _videoStreamPipeline, pipeline, appsink, objDet); - - if (!loadOVMS()) - return -1; - - _allDecodersInitd = true; - _cvAllDecodersInitd.notify_all();; - - - for(auto& running_stream : running_streams) - running_stream.join(); - - if (_mediaService != NULL) { - delete _mediaService; - _mediaService = NULL; - } - - if (_srv) - OVMS_ServerDelete(_srv); - if (_modelsSettings) - OVMS_ModelsSettingsDelete(_modelsSettings); - if (_serverSettings) - OVMS_ServerSettingsDelete(_serverSettings); - - return 0; -} diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/opencv_utils.hpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/opencv_utils.hpp deleted file mode 100644 index 0e5cd7d0..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/opencv_utils.hpp +++ /dev/null @@ -1,162 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#pragma once - -#include - -#include "custom_node_interface.h" -#include "opencv2/opencv.hpp" - -template -void reorder_to_nhwc_2(const T* sourceNchwBuffer, T* destNhwcBuffer, int rows, int cols, int channels) { - for (int y = 0; y < rows; ++y) { - for (int x = 0; x < cols; ++x) { - for (int c = 0; c < channels; ++c) { - destNhwcBuffer[y * channels * cols + x * channels + c] = reinterpret_cast(sourceNchwBuffer)[c * (rows * cols) + y * cols + x]; - } - } - } -} - -template -std::vector reorder_to_nhwc(const T* nchwVector, int rows, int cols, int channels) { - std::vector nhwcVector(rows * cols * channels); - reorder_to_nhwc_2(nchwVector, nhwcVector.data(), rows, cols, channels); - return nhwcVector; -} - -template -void reorder_to_nchw_2(const T* sourceNhwcBuffer, T* destNchwBuffer, int rows, int cols, int channels) { - for (int y = 0; y < rows; ++y) { - for (int x = 0; x < cols; ++x) { - for (int c = 0; c < channels; ++c) { - destNchwBuffer[c * (rows * cols) + y * cols + x] = reinterpret_cast(sourceNhwcBuffer)[y * channels * cols + x * channels + c]; - } - } - } -} - -template -std::vector reorder_to_nchw(const T* nhwcVector, int rows, int cols, int channels) { - std::vector nchwVector(rows * cols * channels); - reorder_to_nchw_2(nhwcVector, nchwVector.data(), rows, cols, channels); - return nchwVector; -} - -const cv::Mat nhwc_to_mat(const CustomNodeTensor* input) { - uint64_t height = input->dims[1]; - uint64_t width = input->dims[2]; - return cv::Mat(height, width, CV_32FC3, input->data); -} - -const cv::Mat nchw_to_mat(const CustomNodeTensor* input) { - uint64_t channels = input->dims[1]; - uint64_t rows = input->dims[2]; - uint64_t cols = input->dims[3]; - auto nhwcVector = reorder_to_nhwc((float*)input->data, rows, cols, channels); - - cv::Mat image(rows, cols, CV_32FC3); - std::memcpy(image.data, nhwcVector.data(), nhwcVector.size() * sizeof(float)); - return image; -} - -bool crop_rotate_resize(cv::Mat originalImage, cv::Mat& targetImage, cv::Rect roi, float angle, float originalTextWidth, float originalTextHeight, cv::Size targetShape) { - try { - // Limit roi to be in range of original image. - roi.x = roi.x < 0 ? 0 : roi.x; - roi.y = roi.y < 0 ? 0 : roi.y; - roi.width = roi.width + roi.x > originalImage.size().width ? originalImage.size().width - roi.x : roi.width; - roi.height = roi.height + roi.y > originalImage.size().height ? originalImage.size().height - roi.y : roi.height; - cv::Mat cropped = originalImage(roi); - - cv::Mat rotated; - if (angle != 0.0) { - cv::Mat rotationMatrix = cv::getRotationMatrix2D(cv::Point2f(cropped.size().width / 2, cropped.size().height / 2), angle, 1.0); - cv::warpAffine(cropped, rotated, rotationMatrix, cropped.size()); - } else { - rotated = cropped; - } - cv::Mat rotatedSlicedImage; - if (angle != 0.0) { - int sliceOffset = (rotated.size().height - originalTextHeight) / 2; - rotatedSlicedImage = rotated(cv::Rect(0, sliceOffset, rotated.size().width, originalTextHeight)); - } else { - rotatedSlicedImage = rotated; - } - cv::resize(rotatedSlicedImage, targetImage, targetShape); - } catch (const cv::Exception& e) { - std::cout << e.what() << std::endl; - return false; - } - return true; -} - -cv::Mat apply_grayscale(cv::Mat image) { - cv::Mat grayscaled; - cv::cvtColor(image, grayscaled, cv::COLOR_BGR2GRAY); - return grayscaled; -} - -bool scale_image( - bool isScaleDefined, - const float scale, - const std::vector& meanValues, - const std::vector& scaleValues, - cv::Mat& image) { - if (!isScaleDefined && scaleValues.size() == 0 && meanValues.size() == 0) { - return true; - } - - size_t colorChannels = static_cast(image.channels()); - if (meanValues.size() > 0 && meanValues.size() != colorChannels) { - return false; - } - if (scaleValues.size() > 0 && scaleValues.size() != colorChannels) { - return false; - } - - std::vector channels; - if (meanValues.size() > 0 || scaleValues.size() > 0) { - cv::split(image, channels); - if (channels.size() != colorChannels) { - return false; - } - } else { - channels.emplace_back(image); - } - - for (size_t i = 0; i < meanValues.size(); i++) { - channels[i] -= meanValues[i]; - } - - if (scaleValues.size() > 0) { - for (size_t i = 0; i < channels.size(); i++) { - channels[i] /= scaleValues[i]; - } - } else if (isScaleDefined) { - for (size_t i = 0; i < channels.size(); i++) { - channels[i] /= scale; - } - } - - if (channels.size() == 1) { - image = channels[0]; - } else { - cv::merge(channels, image); - } - - return true; -} diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/queue.hpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/queue.hpp deleted file mode 100644 index b59b9348..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/queue.hpp +++ /dev/null @@ -1,136 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace ovms { - -template -class Queue { -public: - /** - * @brief Allocating idle stream for execution - */ - std::future getIdleStream() { - int value; - std::promise idleStreamPromise; - std::future idleStreamFuture = idleStreamPromise.get_future(); - std::unique_lock lk(front_mut); - if (streams[front_idx] < 0) { // we need to wait for any idle stream to be returned - std::unique_lock queueLock(queue_mutex); - promises.push(std::move(idleStreamPromise)); - } else { // we can give idle stream right away - value = streams[front_idx]; - streams[front_idx] = -1; // negative value indicate consumed vector index - front_idx = (front_idx + 1) % streams.size(); - lk.unlock(); - idleStreamPromise.set_value(value); - } - return idleStreamFuture; - } - - std::optional tryToGetIdleStream() { - int value; - std::unique_lock lk(front_mut); - if (streams[front_idx] < 0) { // we need to wait for any idle stream to be returned - return std::nullopt; - } else { // we can give idle stream right away - value = streams[front_idx]; - streams[front_idx] = -1; // negative value indicate consumed vector index - front_idx = (front_idx + 1) % streams.size(); - lk.unlock(); - return value; - } - } - - /** - * @brief Release stream after execution - */ - void returnStream(int streamID) { - std::unique_lock lk(queue_mutex); - if (promises.size()) { - std::promise promise = std::move(promises.front()); - promises.pop(); - lk.unlock(); - promise.set_value(streamID); - return; - } - std::uint32_t old_back = back_idx.load(); - while (!back_idx.compare_exchange_weak( - old_back, - (old_back + 1) % streams.size(), - std::memory_order_relaxed)) { - } - streams[old_back] = streamID; - } - - /** - * @brief Constructor with initialization - */ - Queue(int streamsLength) : - streams(streamsLength), - front_idx{0}, - back_idx{0} { - for (int i = 0; i < streamsLength; ++i) { - streams[i] = i; - } - } - - /** - * @brief Give InferRequest - */ - T& getInferRequest(int streamID) { - return inferRequests[streamID]; - } - -protected: - /** - * @brief Vector representing circular buffer for infer queue - */ - std::vector streams; - - /** - * @brief Index of the front of the idle streams list - */ - std::uint32_t front_idx; - - /** - * @brief Index of the back of the idle streams list - */ - std::atomic back_idx; - - /** - * @brief Vector representing OV streams and used for notification about completed inference operations - */ - std::mutex front_mut; - std::mutex queue_mutex; - /** - * - */ - std::vector inferRequests; - std::queue> promises; -}; -} // namespace ovms diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/utils.hpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/utils.hpp deleted file mode 100644 index d00219a2..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/utils.hpp +++ /dev/null @@ -1,145 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#pragma once - -#include -#include -#include -#include -#include - -#include "custom_node_interface.h" - -#define NODE_ASSERT(cond, msg) \ - if (!(cond)) { \ - std::cout << "[" << __LINE__ << "] Assert: " << msg << std::endl; \ - return 1; \ - } - -#define NODE_EXPECT(cond, msg) \ - if (!(cond)) { \ - std::cout << "[" << __LINE__ << "] Assert: " << msg << std::endl; \ - } - -int get_int_parameter(const std::string& name, const struct CustomNodeParam* params, int paramsCount, int defaultValue = 0) { - for (int i = 0; i < paramsCount; i++) { - if (name == params[i].key) { - try { - return std::stoi(params[i].value); - } catch (std::invalid_argument& e) { - return defaultValue; - } catch (std::out_of_range& e) { - return defaultValue; - } - } - } - return defaultValue; -} - -float get_float_parameter(const std::string& name, const struct CustomNodeParam* params, int paramsCount, float defaultValue = 0.0f) { - for (int i = 0; i < paramsCount; i++) { - if (name == params[i].key) { - try { - return std::stof(params[i].value); - } catch (std::invalid_argument& e) { - return defaultValue; - } catch (std::out_of_range& e) { - return defaultValue; - } - } - } - return defaultValue; -} - -float get_float_parameter(const std::string& name, const struct CustomNodeParam* params, int paramsCount, bool& isDefined, float defaultValue = 0.0f) { - isDefined = true; - for (int i = 0; i < paramsCount; i++) { - if (name == params[i].key) { - try { - return std::stof(params[i].value); - } catch (std::invalid_argument& e) { - isDefined = false; - return defaultValue; - } catch (std::out_of_range& e) { - isDefined = false; - return defaultValue; - } - } - } - isDefined = false; - return defaultValue; -} - -std::string get_string_parameter(const std::string& name, const struct CustomNodeParam* params, int paramsCount, const std::string& defaultValue = "") { - for (int i = 0; i < paramsCount; i++) { - if (name == params[i].key) { - return params[i].value; - } - } - return defaultValue; -} - -std::vector get_float_list_parameter(const std::string& name, const struct CustomNodeParam* params, int paramsCount) { - std::string listStr; - for (int i = 0; i < paramsCount; i++) { - if (name == params[i].key) { - listStr = params[i].value; - break; - } - } - - if (listStr.length() < 2 || listStr.front() != '[' || listStr.back() != ']') { - return {}; - } - - listStr = listStr.substr(1, listStr.size() - 2); - - std::vector result; - - std::stringstream lineStream(listStr); - std::string element; - while (std::getline(lineStream, element, ',')) { - try { - float e = std::stof(element.c_str()); - result.push_back(e); - } catch (std::invalid_argument& e) { - NODE_EXPECT(false, "error parsing list parameter"); - return {}; - } catch (std::out_of_range& e) { - NODE_EXPECT(false, "error parsing list parameter"); - return {}; - } - } - - return result; -} - -std::string floatListToString(const std::vector& values) { - std::stringstream ss; - ss << "["; - for (size_t i = 0; i < values.size(); ++i) { - if (i != 0) - ss << ","; - ss << values[i]; - } - ss << "]"; - return ss.str(); -} - -void cleanup(CustomNodeTensor& tensor) { - free(tensor.data); - free(tensor.dims); -} diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/Makefile b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/Makefile deleted file mode 100644 index 445f9ed9..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (c) 2024 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -CV_LIBS = -L/usr/lib/x86_64-linux-gnu/ -L/usr/local/lib/x86_64-linux-gnu/ -L/ovms/lib/ -CV_INCLUDES = -I/usr/include/opencv4 -I/usr/include/gstreamer-1.0 -CUSTOM_NODE_FLAGS = -fpic -O2 -U_FORTIFY_SOURCE -fstack-protector -fno-omit-frame-pointer -D_FORTIFY_SOURCE=1 -fno-strict-overflow -Wall -Wno-unknown-pragmas -Wno-error=sign-compare -fno-delete-null-pointer-checks -fwrapv -fstack-clash-protection -Wformat -Wformat-security - -build: - g++ -c -std=c++17 efficientnetb0_node.cpp ${CUSTOM_NODE_FLAGS} ${CV_INCLUDES} - - g++ -std=c++17 -shared ${CUSTOM_NODE_FLAGS} -o libcustom_node_efficientnetb0-yolov8.so efficientnetb0_node.o ${CV_LIBS} ${CV_INCLUDES} -lopencv_core -lopencv_dnn -lopencv_imgproc -lopencv_imgcodecs - cp libcustom_node_efficientnetb0-yolov8.so /ovms/lib/ - - g++ -std=c++17 main.cpp -I/usr/include/gstreamer-1.0/usr/lib/x86_64-linux-gnu/ -I/usr/local/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/ovms/include $(CV_INCLUDES) $(CV_LIBS) -L/usr/lib/x86_64-linux-gnu/gstreamer-1.0 -lgstbase-1.0 -lgobject-2.0 -lglib-2.0 -lgstreamer-1.0 -lgstapp-1.0 -lopencv_imgcodecs -lopencv_imgproc -lopencv_core -lovms_shared -lopencv_highgui -lopencv_dnn -lpthread -fPIC --std=c++17 -o capi_yolov8_ensemble - diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/buffersqueue.cpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/buffersqueue.cpp deleted file mode 100644 index d0d1f0db..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/buffersqueue.cpp +++ /dev/null @@ -1,66 +0,0 @@ -//***************************************************************************** -// Copyright 2024 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** - -#include "buffersqueue.hpp" - -#include - -namespace ovms { -namespace custom_nodes_common { -BuffersQueue::BuffersQueue(size_t singleBufferSize, int streamsLength) : - Queue(streamsLength), - singleBufferSize(singleBufferSize), - size(singleBufferSize * streamsLength), - memoryPool(std::make_unique(size)) { - for (int i = 0; i < streamsLength; ++i) { - inferRequests.push_back(memoryPool.get() + i * singleBufferSize); - } -} - -BuffersQueue::~BuffersQueue() {} - -void* BuffersQueue::getBuffer() { - // can be easily switched to async version if need arise - auto idleId = tryToGetIdleStream(); - if (idleId.has_value()) { - return getInferRequest(idleId.value()); - } - return nullptr; -} - -bool BuffersQueue::returnBuffer(void* buffer) { - if ((static_cast(buffer) < memoryPool.get()) || - ((memoryPool.get() + size - 1) < buffer) || - ((static_cast(buffer) - memoryPool.get()) % singleBufferSize != 0)) { - return false; - } - returnStream(getBufferId(buffer)); - return true; -} - -int BuffersQueue::getBufferId(void* buffer) { - return (static_cast(buffer) - memoryPool.get()) / singleBufferSize; -} - -const size_t BuffersQueue::getSize() { - return this->size; -} - -const size_t BuffersQueue::getSingleBufferSize() { - return this->singleBufferSize; -} -} // namespace custom_nodes_common -} // namespace ovms diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/buffersqueue.hpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/buffersqueue.hpp deleted file mode 100644 index e39dbf68..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/buffersqueue.hpp +++ /dev/null @@ -1,47 +0,0 @@ -//***************************************************************************** -// Copyright 2024 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace ovms { -namespace custom_nodes_common { - -class BuffersQueue : protected Queue { - size_t singleBufferSize; - size_t size; - std::unique_ptr memoryPool; - -public: - BuffersQueue(size_t singleBufferSize, int streamsLength); - ~BuffersQueue(); - void* getBuffer(); - bool returnBuffer(void* buffer); - const size_t getSize(); - const size_t getSingleBufferSize(); - -private: - int getBufferId(void* buffer); -}; -} // namespace custom_nodes_common -} // namespace ovms diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/custom_node_interface.h b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/custom_node_interface.h deleted file mode 100644 index 41ad92de..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/custom_node_interface.h +++ /dev/null @@ -1,78 +0,0 @@ -//***************************************************************************** -// Copyright 2024 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#pragma once - -#include -typedef enum { - UNSPECIFIED, - FP32, - FP16, - U8, - I8, - I16, - U16, - I32, - FP64, - I64 -} CustomNodeTensorPrecision; - -struct CustomNodeTensor { - const char* name; - uint8_t* data; - uint64_t dataBytes; - uint64_t* dims; - uint64_t dimsCount; - CustomNodeTensorPrecision precision; -}; - -struct CustomNodeTensorInfo { - const char* name; - uint64_t* dims; - uint64_t dimsCount; - CustomNodeTensorPrecision precision; -}; - -struct CustomNodeParam { - const char *key, *value; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Custom node library initialize enables creation of resources to be reused between predictions. - * Potential use cases include optimized temporary buffers allocation. - * Using initialize is optional and not required for custom node to work. - * CustomNodeLibraryInternalManager should be created here if initialize is used. - * On initialize failure status not equal to zero is returned and error log is printed. - */ -int initialize(void** customNodeLibraryInternalManager, const struct CustomNodeParam* params, int paramsCount); -/** - * @brief Custom node library deinitialize enables destruction of resources that were used between predictions. - * Using deinitialize is optional and not required for custom node to work. - * CustomNodeLibraryInternalManager should be destroyed here if deinitialize is used. - * On deinitialize failure only error log is printed. - */ -int deinitialize(void* customNodeLibraryInternalManager); -int execute(const struct CustomNodeTensor* inputs, int inputsCount, struct CustomNodeTensor** outputs, int* outputsCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager); -int getInputsInfo(struct CustomNodeTensorInfo** info, int* infoCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager); -int getOutputsInfo(struct CustomNodeTensorInfo** info, int* infoCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager); -int release(void* ptr, void* customNodeLibraryInternalManager); - -#ifdef __cplusplus -} -#endif diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/custom_node_library_internal_manager.cpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/custom_node_library_internal_manager.cpp deleted file mode 100644 index 5af18b61..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/custom_node_library_internal_manager.cpp +++ /dev/null @@ -1,78 +0,0 @@ -//***************************************************************************** -// Copyright 2024 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** - -#include "custom_node_library_internal_manager.hpp" - -#include -#include -#include -#include - -namespace ovms { -namespace custom_nodes_common { -CustomNodeLibraryInternalManager::CustomNodeLibraryInternalManager() { -} - -CustomNodeLibraryInternalManager::~CustomNodeLibraryInternalManager() { -} - -bool CustomNodeLibraryInternalManager::createBuffersQueue(const std::string& name, size_t singleBufferSize, int streamsLength) { - auto it = outputBuffers.find(name); - if (it != outputBuffers.end()) { - return false; - } - outputBuffers.emplace(name, std::make_unique(singleBufferSize, streamsLength)); - return true; -} - -bool CustomNodeLibraryInternalManager::recreateBuffersQueue(const std::string& name, size_t singleBufferSize, int streamsLength) { - auto it = outputBuffers.find(name); - if (it != outputBuffers.end()) { - if (!(it->second->getSize() == singleBufferSize && - it->second->getSingleBufferSize() == streamsLength * singleBufferSize)) { - it->second.reset(new BuffersQueue(singleBufferSize, streamsLength)); - } - return true; - } - return false; -} - -BuffersQueue* CustomNodeLibraryInternalManager::getBuffersQueue(const std::string& name) { - auto it = outputBuffers.find(name); - if (it == outputBuffers.end()) - return nullptr; - return it->second.get(); -} - -bool CustomNodeLibraryInternalManager::releaseBuffer(void* ptr) { - for (auto it = outputBuffers.begin(); it != outputBuffers.end(); ++it) { - if (it->second->returnBuffer(ptr)) { - return true; - } - } - return false; -} - -std::shared_timed_mutex& CustomNodeLibraryInternalManager::getInternalManagerLock() { - return this->internalManagerLock; -} -} // namespace custom_nodes_common -} // namespace ovms - -void cleanup(CustomNodeTensor& tensor, ovms::custom_nodes_common::CustomNodeLibraryInternalManager* internalManager) { - release(tensor.data, internalManager); - release(tensor.dims, internalManager); -} diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/custom_node_library_internal_manager.hpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/custom_node_library_internal_manager.hpp deleted file mode 100644 index 5bf1960f..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/custom_node_library_internal_manager.hpp +++ /dev/null @@ -1,60 +0,0 @@ -//***************************************************************************** -// Copyright 2024 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#pragma once - -#include -#include -#include -#include - -#include "custom_node_interface.h" -#include "buffersqueue.hpp" - -namespace ovms { -namespace custom_nodes_common { - -class CustomNodeLibraryInternalManager { - std::unordered_map> outputBuffers; - std::shared_timed_mutex internalManagerLock; - -public: - CustomNodeLibraryInternalManager(); - ~CustomNodeLibraryInternalManager(); - bool createBuffersQueue(const std::string& name, size_t singleBufferSize, int streamsLength); - bool recreateBuffersQueue(const std::string& name, size_t singleBufferSize, int streamsLength); - BuffersQueue* getBuffersQueue(const std::string& name); - bool releaseBuffer(void* ptr); - std::shared_timed_mutex& getInternalManagerLock(); -}; -} // namespace custom_nodes_common -} // namespace ovms - -template -bool get_buffer(ovms::custom_nodes_common::CustomNodeLibraryInternalManager* internalManager, T** buffer, const char* buffersQueueName, uint64_t byte_size) { - auto buffersQueue = internalManager->getBuffersQueue(buffersQueueName); - if (!(buffersQueue == nullptr)) { - *buffer = static_cast(buffersQueue->getBuffer()); - } - if (*buffer == nullptr || buffersQueue == nullptr) { - *buffer = (T*)malloc(byte_size); - if (*buffer == nullptr) { - return false; - } - } - return true; -} - -void cleanup(CustomNodeTensor& tensor, ovms::custom_nodes_common::CustomNodeLibraryInternalManager* internalManager); diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/efficientnetb0_node.cpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/efficientnetb0_node.cpp deleted file mode 100644 index ac899550..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/efficientnetb0_node.cpp +++ /dev/null @@ -1,630 +0,0 @@ -//***************************************************************************** -// Copyright 2024 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#include -#include -#include -#include - -#include "custom_node_interface.h" -#include "opencv_utils.hpp" -#include "utils.hpp" -#include "opencv2/opencv.hpp" - -bool debugMode = false; - -static constexpr const char* IMAGE_TENSOR_NAME = "images"; -static constexpr const char* GEOMETRY_TENSOR_NAME = "boxes"; -static constexpr const char* TEXT_IMAGES_TENSOR_NAME = "roi_images"; -static constexpr const char* COORDINATES_TENSOR_NAME = "roi_coordinates"; -static constexpr const char* CONFIDENCE_TENSOR_NAME = "confidence_levels"; - -typedef struct DetectedResult { - int frameId; - int x; - int y; - int width; - int height; - float confidence; - int classId; - char classText[1024]; -} DetectedResult; - -float boxiou_threshold = 0.3; -float iou_threshold = 0.3; - -static bool copy_images_into_output(struct CustomNodeTensor* output, const std::vector& boxes, const cv::Mat& originalImage, int targetImageHeight, int targetImageWidth, const std::string& targetImageLayout, bool convertToGrayScale) { - const uint64_t outputBatch = boxes.size(); - int channels = convertToGrayScale ? 1 : 3; - - uint64_t byteSize = sizeof(float) * targetImageHeight * targetImageWidth * channels * outputBatch; - float* buffer = (float*)malloc(byteSize); - - NODE_ASSERT(buffer != nullptr, "malloc has failed"); - - for (uint64_t i = 0; i < outputBatch; i++) { - cv::Size targetShape(targetImageWidth, targetImageHeight); - cv::Mat image; - - cv::Rect box = boxes[i]; - if (box.x < 0) - box.x = 0; - if (box.y < 0) - box.y = 0; - - // std::string imgname = "/tmp/results/classifyimage" + std::to_string(i) + ".jpg"; - // cv::imwrite(imgname.c_str(), originalImage); - - cv::Mat cropped = originalImage(box); - cv::resize(cropped, image, targetShape); - - // std::string imgname = "/tmp/results/classifyimage" + std::to_string(i) + ".jpg"; - // cv::Mat tmp2; - // image.convertTo(tmp2, CV_8UC3); - // cv::imwrite(imgname.c_str(), tmp2); - - if (convertToGrayScale) { - image = apply_grayscale(image); - } - - if (targetImageLayout == "NCHW") { - auto imgBuffer = reorder_to_nchw((float*)image.data, image.rows, image.cols, image.channels()); - std::memcpy(buffer + (i * channels * targetImageWidth * targetImageHeight), imgBuffer.data(), byteSize / outputBatch); - } else { - std::memcpy(buffer + (i * channels * targetImageWidth * targetImageHeight), image.data, byteSize / outputBatch); - } - } - - output->data = reinterpret_cast(buffer); - output->dataBytes = byteSize; - output->dimsCount = 5; - output->dims = (uint64_t*)malloc(output->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(output->dims != nullptr, "malloc has failed"); - output->dims[0] = outputBatch; - output->dims[1] = 1; - if (targetImageLayout == "NCHW") { - output->dims[2] = channels; - output->dims[3] = targetImageHeight; - output->dims[4] = targetImageWidth; - } else { - output->dims[2] = targetImageHeight; - output->dims[3] = targetImageWidth; - output->dims[4] = channels; - } - output->precision = FP32; - return true; -} - -static bool copy_coordinates_into_output(struct CustomNodeTensor* output, const std::vector& boxes) { - const uint64_t outputBatch = boxes.size(); - - //printf("---------->NumberOfDets by coords %li\n", outputBatch); - - uint64_t byteSize = sizeof(int32_t) * 4 * outputBatch; - - int32_t* buffer = (int32_t*)malloc(byteSize); - NODE_ASSERT(buffer != nullptr, "malloc has failed"); - - for (uint64_t i = 0; i < outputBatch; i++) { - int32_t entry[] = { - boxes[i].x, - boxes[i].y, - boxes[i].width, - boxes[i].height}; - - std::memcpy(buffer + (i * 4), entry, byteSize / outputBatch); - } - output->data = reinterpret_cast(buffer); - output->dataBytes = byteSize; - output->dimsCount = 3; - output->dims = (uint64_t*)malloc(output->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(output->dims != nullptr, "malloc has failed"); - output->dims[0] = outputBatch; - output->dims[1] = 1; - output->dims[2] = 4; - output->precision = I32; - - return true; -} - -static bool copy_scores_into_output(struct CustomNodeTensor* output, const std::vector& scores) { - const uint64_t outputBatch = scores.size(); - //printf("Number of scores------------------>%li\n", outputBatch); - uint64_t byteSize = sizeof(float) * outputBatch; - - float* buffer = (float*)malloc(byteSize); - NODE_ASSERT(buffer != nullptr, "malloc has failed"); - std::memcpy(buffer, scores.data(), byteSize); - - output->data = reinterpret_cast(buffer); - output->dataBytes = byteSize; - output->dimsCount = 3; - output->dims = (uint64_t*)malloc(output->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(output->dims != nullptr, "malloc has failed"); - output->dims[0] = outputBatch; - output->dims[1] = 1; - output->dims[2] = 1; - output->precision = FP32; - return true; -} - -int initialize(void** customNodeLibraryInternalManager, const struct CustomNodeParam* params, int paramsCount) { - return 0; -} - -int deinitialize(void* customNodeLibraryInternalManager) { - return 0; -} - -// YoloV8 PostProcessing - -const std::string labels[80] = { - "person", - "bicycle", - "car", - "motorbike", - "aeroplane", - "bus", - "train", - "truck", - "boat", - "traffic light", - "fire hydrant", - "stop sign", - "parking meter", - "bench", - "bird", - "cat", - "dog", - "horse", - "sheep", - "cow", - "elephant", - "bear", - "zebra", - "giraffe", - "backpack", - "umbrella", - "handbag", - "tie", - "suitcase", - "frisbee", - "skis", - "snowboard", - "sports ball", - "kite", - "baseball bat", - "baseball glove", - "skateboard", - "surfboard", - "tennis racket", - "bottle", - "wine glass", - "cup", - "fork", - "knife", - "spoon", - "bowl", - "banana", - "apple", - "sandwich", - "orange", - "broccoli", - "carrot", - "hot dog", - "pizza", - "donut", - "cake", - "chair", - "sofa", - "pottedplant", - "bed", - "diningtable", - "toilet", - "tvmonitor", - "laptop", - "mouse", - "remote", - "keyboard", - "cell phone", - "microwave", - "oven", - "toaster", - "sink", - "refrigerator", - "book", - "clock", - "vase", - "scissors", - "teddy bear", - "hair drier", - "toothbrush" -}; - -std::vector nms(const std::vector& res, const float thresh, bool includeBoundaries=false, size_t keep_top_k=0) { - if (keep_top_k == 0) { - keep_top_k = 10; //res.size(); - } - std::vector areas(res.size()); - for (size_t i = 0; i < res.size(); ++i) { - areas[i] = (float) (res[i].width - res[i].x + includeBoundaries) * (res[i].height - res[i].y + includeBoundaries); - } - std::vector order(res.size()); - std::iota(order.begin(), order.end(), 0); - std::sort(order.begin(), order.end(), [&res](int o1, int o2) { return res[o1].confidence > res[o2].confidence; }); - - size_t ordersNum = 0; - for (; ordersNum < order.size() && res[order[ordersNum]].confidence >= 0 && ordersNum < keep_top_k; ordersNum++); - - std::vector keep; - bool shouldContinue = true; - for (size_t i = 0; shouldContinue && i < ordersNum; ++i) { - int idx1 = order[i]; - if (idx1 >= 0) { - keep.push_back(idx1); - shouldContinue = false; - for (size_t j = i + 1; j < ordersNum; ++j) { - int idx2 = order[j]; - if (idx2 >= 0) { - shouldContinue = true; - float overlappingWidth = std::fminf(res[idx1].width, res[idx2].width) - std::fmaxf(res[idx1].x, res[idx2].x); - float overlappingHeight = std::fminf(res[idx1].height, res[idx2].height) - std::fmaxf(res[idx1].y, res[idx2].y); - float intersection = overlappingWidth > 0 && overlappingHeight > 0 ? overlappingWidth * overlappingHeight : 0; - float union_area = areas[idx1] + areas[idx2] - intersection; - if (0.0f == union_area || intersection / union_area > thresh) { - order[j] = -1; - } - } - } - } - } - return keep; -} - -std::vector multiclass_nms(const std::vector& res, const float iou_threshold, bool includeBoundaries, size_t maxNum) { - std::vector boxes_copy; - boxes_copy.reserve(res.size()); - - float max_coord = 0.f; - for (const auto& box : res) { - max_coord = std::max(max_coord, std::max((float)box.width, (float)box.height)); - } - for (auto& box : res) { - float offset = box.classId * max_coord; - DetectedResult tmp; - tmp.x = box.x + offset; - tmp.y = box.y + offset; - tmp.width = box.width + offset; - tmp.height = box.height + offset; - tmp.classId = box.classId; - tmp.confidence = box.confidence; - boxes_copy.emplace_back(tmp); - } - - return nms(boxes_copy, iou_threshold, includeBoundaries, maxNum); -} - - -void postprocess(const float confidence_threshold, const int imageWidth, const int imageHeight, - const uint64_t* output_shape, const void* voutputData, const uint32_t dimCount, - std::vector &rects, std::vector &scores) -{ - if (!voutputData || !output_shape) { - // nothing to do - return; - } - - /* - https://github.com/openvinotoolkit/openvino_notebooks/blob/main/notebooks/230-yolov8-optimization/230-yolov8-object-detection.ipynb - detection box has the [x, y, h, w, class_no_1, ..., class_no_80] format, where: - (x, y) - raw coordinates of box center - h, w - raw height and width of the box - class_no_1, ..., class_no_80 - probability distribution over the classes. - */ - - std::vector detectedResults; - size_t num_proposals = output_shape[2]; - std::vector boxes_with_class; - std::vector confidences; - const float* const detections = (float*)(voutputData); - for (size_t i = 0; i < num_proposals; ++i) { - float confidence = 0.0f; - size_t max_id = 0; - constexpr size_t LABELS_START = 4; - // get max confidence level in the 80 classes for this detection - for (size_t j = LABELS_START; j < output_shape[1]; ++j) { - if (detections[j * num_proposals + i] > confidence) { - confidence = detections[j * num_proposals + i]; - max_id = j; - } - } - // add the detection if the max confi. meets the threshold - if (confidence > confidence_threshold) { - DetectedResult obj; - obj.x = detections[0 * num_proposals + i] - detections[2 * num_proposals + i] / 2.0f; - obj.y = detections[1 * num_proposals + i] - detections[3 * num_proposals + i] / 2.0f; - obj.width = detections[0 * num_proposals + i] + detections[2 * num_proposals + i] / 2.0f; - obj.height = detections[1 * num_proposals + i] + detections[3 * num_proposals + i] / 2.0f; - obj.classId = max_id - LABELS_START; - obj.confidence = confidence; - - boxes_with_class.emplace_back(obj); - confidences.push_back(confidence); - } - } - - constexpr bool includeBoundaries = false; - constexpr size_t keep_top_k = 30000; - std::vector keep; - bool agnostic_nms = true; - - if (agnostic_nms) { - keep = nms(boxes_with_class, boxiou_threshold, includeBoundaries, keep_top_k); - } else { - keep = multiclass_nms(boxes_with_class, boxiou_threshold, includeBoundaries, keep_top_k); - } - - int padLeft = 15, padTop = 0; // adjust padding for optimal efficientnet inference - float floatInputImgWidth = float(imageWidth), - floatInputImgHeight = float(imageHeight), - netInputWidth = floatInputImgWidth, - netInputHeight = floatInputImgHeight, - invertedScaleX = floatInputImgWidth / netInputWidth, - invertedScaleY = floatInputImgHeight / netInputHeight; - - for (size_t idx : keep) { - int x1 = std::clamp( - round((boxes_with_class[idx].x - padLeft) * invertedScaleX), - 0.f, - floatInputImgWidth); - int y1 = std::clamp( - round((boxes_with_class[idx].y - padTop) * invertedScaleY), - 0.f, - floatInputImgHeight); - int x2 = std::clamp( - round((boxes_with_class[idx].width + padLeft) * invertedScaleX) - x1, - 0.f, - floatInputImgWidth - x1); - int y2 = std::clamp( - round((boxes_with_class[idx].height + padTop) * invertedScaleY) - y1, - 0.f, - floatInputImgHeight-y1); - - rects.emplace_back(x1, y1, x2, y2); - scores.emplace_back(confidences[idx]); - } -} -// End of Yolov8 PostProcessing - -int execute(const struct CustomNodeTensor* inputs, int inputsCount, struct CustomNodeTensor** outputs, int* outputsCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager) { - - // Parameters reading - int originalImageHeight = get_int_parameter("original_image_height", params, paramsCount, -1); - int originalImageWidth = get_int_parameter("original_image_width", params, paramsCount, -1); - NODE_ASSERT(originalImageHeight > 0, "original image height must be larger than 0"); - NODE_ASSERT(originalImageWidth > 0, "original image width must be larger than 0"); - int targetImageHeight = get_int_parameter("target_image_height", params, paramsCount, -1); - int targetImageWidth = get_int_parameter("target_image_width", params, paramsCount, -1); - NODE_ASSERT(targetImageHeight > 0, "target image height must be larger than 0"); - NODE_ASSERT(targetImageWidth > 0, "target image width must be larger than 0"); - std::string originalImageLayout = get_string_parameter("original_image_layout", params, paramsCount, "NCHW"); - NODE_ASSERT(originalImageLayout == "NCHW" || originalImageLayout == "NHWC", "original image layout must be NCHW or NHWC"); - std::string targetImageLayout = get_string_parameter("target_image_layout", params, paramsCount, "NCHW"); - NODE_ASSERT(targetImageLayout == "NCHW" || targetImageLayout == "NHWC", "target image layout must be NCHW or NHWC"); - bool convertToGrayScale = get_string_parameter("convert_to_gray_scale", params, paramsCount) == "true"; - float confidenceThreshold = get_float_parameter("confidence_threshold", params, paramsCount, -1.0); - NODE_ASSERT(confidenceThreshold >= 0 && confidenceThreshold <= 1.0, "confidence threshold must be in 0-1 range"); - uint64_t maxOutputBatch = get_int_parameter("max_output_batch", params, paramsCount, 100); - NODE_ASSERT(maxOutputBatch > 0, "max output batch must be larger than 0"); - debugMode = get_string_parameter("debug", params, paramsCount) == "true"; - - const CustomNodeTensor* imageTensor = nullptr; - const CustomNodeTensor* boxesTensor = nullptr; - - for (int i = 0; i < inputsCount; i++) { - if (std::strcmp(inputs[i].name, IMAGE_TENSOR_NAME) == 0) { - imageTensor = &(inputs[i]); - } else if (std::strcmp(inputs[i].name, GEOMETRY_TENSOR_NAME) == 0) { - boxesTensor = &(inputs[i]); - } else { - std::cout << "Unrecognized input: " << inputs[i].name << std::endl; - return 1; - } - } - - NODE_ASSERT(imageTensor != nullptr, "Missing input image"); - NODE_ASSERT(boxesTensor != nullptr, "Missing input boxes"); - NODE_ASSERT(imageTensor->precision == FP32, "image input is not FP32"); - NODE_ASSERT(boxesTensor->precision == FP32, "boxes input is not FP32"); - - NODE_ASSERT(imageTensor->dimsCount == 4, "input image shape must have 4 dimensions"); - NODE_ASSERT(imageTensor->dims[0] == 1, "input image batch must be 1"); - uint64_t _imageHeight = imageTensor->dims[originalImageLayout == "NCHW" ? 2 : 1]; - uint64_t _imageWidth = imageTensor->dims[originalImageLayout == "NCHW" ? 3 : 2]; - NODE_ASSERT(_imageHeight <= static_cast(std::numeric_limits::max()), "image height is too large"); - NODE_ASSERT(_imageWidth <= static_cast(std::numeric_limits::max()), "image width is too large"); - int imageHeight = static_cast(_imageHeight); - int imageWidth = static_cast(_imageWidth); - - if (debugMode) { - std::cout << "Processing input tensor image resolution: " << cv::Size(imageHeight, imageWidth) << "; expected resolution: " << cv::Size(originalImageHeight, originalImageWidth) << std::endl; - } - - NODE_ASSERT(imageHeight == originalImageHeight, "original image size parameter differs from original image tensor size"); - NODE_ASSERT(imageWidth == originalImageWidth, "original image size parameter differs from original image tensor size"); - - cv::Mat image; - if (originalImageLayout == "NHWC") { - image = nhwc_to_mat(imageTensor); - } else { - image = nchw_to_mat(imageTensor); - } - - NODE_ASSERT(image.cols == imageWidth, "Mat generation failed"); - NODE_ASSERT(image.rows == imageHeight, "Mat generation failed"); - - - std::vector rects; - std::vector scores; - postprocess(confidenceThreshold, originalImageWidth, originalImageHeight, boxesTensor->dims, boxesTensor->data, boxesTensor->dimsCount, rects, scores); - - NODE_ASSERT(rects.size() == scores.size(), "rects and scores are not equal length"); - if (rects.size() > maxOutputBatch) { - rects.resize(maxOutputBatch); - scores.resize(maxOutputBatch); - } - - if (debugMode) - std::cout << "Total findings: " << rects.size() << std::endl; - - *outputsCount = 3; // pipeline outputs for efficientnetb0_extractor e.g. roi_images, roi_coordinates, confidence_levels - *outputs = (struct CustomNodeTensor*)malloc(*outputsCount * sizeof(CustomNodeTensor)); - - NODE_ASSERT((*outputs) != nullptr, "malloc has failed"); - CustomNodeTensor& textImagesTensor = (*outputs)[0]; - textImagesTensor.name = TEXT_IMAGES_TENSOR_NAME; - - if (!copy_images_into_output(&textImagesTensor, rects, image, targetImageHeight, targetImageWidth, targetImageLayout, convertToGrayScale)) { - free(*outputs); - return 1; - } - - CustomNodeTensor& coordinatesTensor = (*outputs)[1]; - coordinatesTensor.name = COORDINATES_TENSOR_NAME; - if (!copy_coordinates_into_output(&coordinatesTensor, rects)) { - free(*outputs); - cleanup(textImagesTensor); - return 1; - } - - - CustomNodeTensor& confidenceTensor = (*outputs)[2]; - confidenceTensor.name = CONFIDENCE_TENSOR_NAME; - if (!copy_scores_into_output(&confidenceTensor, scores)) { - free(*outputs); - cleanup(textImagesTensor); - cleanup(coordinatesTensor); - return 1; - } - - return 0; -} - -int getInputsInfo(struct CustomNodeTensorInfo** info, int* infoCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager) { - int originalImageHeight = get_int_parameter("original_image_height", params, paramsCount, -1); - int originalImageWidth = get_int_parameter("original_image_width", params, paramsCount, -1); - NODE_ASSERT(originalImageHeight > 0, "original image height must be larger than 0"); - NODE_ASSERT(originalImageWidth > 0, "original image width must be larger than 0"); - std::string originalImageLayout = get_string_parameter("original_image_layout", params, paramsCount, "NCHW"); - NODE_ASSERT(originalImageLayout == "NCHW" || originalImageLayout == "NHWC", "original image layout must be NCHW or NHWC"); - - *infoCount = 2; - *info = (struct CustomNodeTensorInfo*)malloc(*infoCount * sizeof(struct CustomNodeTensorInfo)); - NODE_ASSERT((*info) != nullptr, "malloc has failed"); - - (*info)[0].name = IMAGE_TENSOR_NAME; - (*info)[0].dimsCount = 4; - (*info)[0].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[0].dims) != nullptr, "malloc has failed"); - (*info)[0].dims[0] = 1; - if (originalImageLayout == "NCHW") { - (*info)[0].dims[1] = 3; - (*info)[0].dims[2] = originalImageHeight; - (*info)[0].dims[3] = originalImageWidth; - } else { - (*info)[0].dims[1] = originalImageHeight; - (*info)[0].dims[2] = originalImageWidth; - (*info)[0].dims[3] = 3; - } - (*info)[0].precision = FP32; - - (*info)[1].name = GEOMETRY_TENSOR_NAME; - (*info)[1].dimsCount = 3; - (*info)[1].dims = (uint64_t*)malloc((*info)[1].dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[1].dims) != nullptr, "malloc has failed"); - // 416x416 - (*info)[1].dims[0] = 1; - (*info)[1].dims[1] = 84; - (*info)[1].dims[2] = 3549; - - // 512x512 - // (*info)[1].dims[0] = 1; - // (*info)[1].dims[1] = 84; - // (*info)[1].dims[2] = 5376; - - //640x640 - // (*info)[1].dims[0] = 1; - // (*info)[1].dims[1] = 84; - // (*info)[1].dims[2] = 8400; - - (*info)[1].precision = FP32; - return 0; -} - -int getOutputsInfo(struct CustomNodeTensorInfo** info, int* infoCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager) { - int targetImageHeight = get_int_parameter("target_image_height", params, paramsCount, -1); - int targetImageWidth = get_int_parameter("target_image_width", params, paramsCount, -1); - NODE_ASSERT(targetImageHeight > 0, "target image height must be larger than 0"); - NODE_ASSERT(targetImageWidth > 0, "target image width must be larger than 0"); - std::string targetImageLayout = get_string_parameter("target_image_layout", params, paramsCount, "NCHW"); - NODE_ASSERT(targetImageLayout == "NCHW" || targetImageLayout == "NHWC", "target image layout must be NCHW or NHWC"); - bool convertToGrayScale = get_string_parameter("convert_to_gray_scale", params, paramsCount) == "true"; - - *infoCount = 3; - *info = (struct CustomNodeTensorInfo*)malloc(*infoCount * sizeof(struct CustomNodeTensorInfo)); - NODE_ASSERT((*info) != nullptr, "malloc has failed"); - - (*info)[0].name = TEXT_IMAGES_TENSOR_NAME; - (*info)[0].dimsCount = 5; - (*info)[0].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[0].dims) != nullptr, "malloc has failed"); - (*info)[0].dims[0] = 0; - (*info)[0].dims[1] = 1; - if (targetImageLayout == "NCHW") { - (*info)[0].dims[2] = convertToGrayScale ? 1 : 3; - (*info)[0].dims[3] = targetImageHeight; - (*info)[0].dims[4] = targetImageWidth; - } else { - (*info)[0].dims[2] = targetImageHeight; - (*info)[0].dims[3] = targetImageWidth; - (*info)[0].dims[4] = convertToGrayScale ? 1 : 3; - } - (*info)[0].precision = FP32; - - (*info)[1].name = COORDINATES_TENSOR_NAME; - (*info)[1].dimsCount = 3; - (*info)[1].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[1].dims) != nullptr, "malloc has failed"); - (*info)[1].dims[0] = 0; - (*info)[1].dims[1] = 1; - (*info)[1].dims[2] = 4; - (*info)[1].precision = I32; - - (*info)[2].name = CONFIDENCE_TENSOR_NAME; - (*info)[2].dimsCount = 3; - (*info)[2].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[2].dims) != nullptr, "malloc has failed"); - (*info)[2].dims[0] = 0; - (*info)[2].dims[1] = 1; - (*info)[2].dims[2] = 1; - (*info)[2].precision = FP32; - - return 0; -} - -int release(void* ptr, void* customNodeLibraryInternalManager) { - free(ptr); - return 0; -} diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/efficientnetb0_node_debug.cpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/efficientnetb0_node_debug.cpp deleted file mode 100644 index d41c3620..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/efficientnetb0_node_debug.cpp +++ /dev/null @@ -1,728 +0,0 @@ -//***************************************************************************** -// Copyright 2024 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#include -#include -#include -#include - -#include "custom_node_interface.h" -#include "opencv_utils.hpp" -#include "utils.hpp" -#include "opencv2/opencv.hpp" - -bool debugMode = false; - -static constexpr const char* IMAGE_TENSOR_NAME = "images"; -static constexpr const char* GEOMETRY_TENSOR_NAME = "boxes"; -static constexpr const char* TEXT_IMAGES_TENSOR_NAME = "roi_images"; -static constexpr const char* COORDINATES_TENSOR_NAME = "roi_coordinates"; -static constexpr const char* CONFIDENCE_TENSOR_NAME = "confidence_levels"; - -typedef struct DetectedResult { - int frameId; - int x; - int y; - int width; - int height; - float confidence; - int classId; - char classText[1024]; -} DetectedResult; - -float boxiou_threshold = 0.3; -float iou_threshold = 0.3; - -static bool copy_images_into_output(struct CustomNodeTensor* output, const std::vector& boxes, const cv::Mat& originalImage, int targetImageHeight, int targetImageWidth, const std::string& targetImageLayout, bool convertToGrayScale) { - const uint64_t outputBatch = boxes.size(); - int channels = convertToGrayScale ? 1 : 3; - - uint64_t byteSize = sizeof(float) * targetImageHeight * targetImageWidth * channels * outputBatch; - float* buffer = (float*)malloc(byteSize); - - NODE_ASSERT(buffer != nullptr, "malloc has failed"); - - for (uint64_t i = 0; i < outputBatch; i++) { - cv::Size targetShape(targetImageWidth, targetImageHeight); - cv::Mat image; - - cv::Rect box = boxes[i]; - if (box.x < 0) - box.x = 0; - if (box.y < 0) - box.y = 0; - - // std::string imgname = "/tmp/results/classifyimage" + std::to_string(i) + ".jpg"; - // cv::imwrite(imgname.c_str(), originalImage); - - cv::Mat tmp; - originalImage.convertTo(tmp, CV_32F, 255.0f); - cv::Mat cropped = tmp(box); - cv::resize(cropped, image, targetShape); - - // std::string imgname = "/tmp/results/classifyimage" + std::to_string(i) + ".jpg"; - // cv::Mat tmp2; - // image.convertTo(tmp2, CV_8UC3); - // cv::imwrite(imgname.c_str(), tmp2); - - if (convertToGrayScale) { - image = apply_grayscale(image); - } - - if (targetImageLayout == "NCHW") { - auto imgBuffer = reorder_to_nchw((float*)image.data, image.rows, image.cols, image.channels()); - std::memcpy(buffer + (i * channels * targetImageWidth * targetImageHeight), imgBuffer.data(), byteSize / outputBatch); - } else { - std::memcpy(buffer + (i * channels * targetImageWidth * targetImageHeight), image.data, byteSize / outputBatch); - } - } - - output->data = reinterpret_cast(buffer); - output->dataBytes = byteSize; - output->dimsCount = 5; - output->dims = (uint64_t*)malloc(output->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(output->dims != nullptr, "malloc has failed"); - output->dims[0] = outputBatch; - output->dims[1] = 1; - if (targetImageLayout == "NCHW") { - output->dims[2] = channels; - output->dims[3] = targetImageHeight; - output->dims[4] = targetImageWidth; - } else { - output->dims[2] = targetImageHeight; - output->dims[3] = targetImageWidth; - output->dims[4] = channels; - } - output->precision = FP32; - return true; -} - -static bool copy_coordinates_into_output(struct CustomNodeTensor* output, const std::vector& boxes) { - const uint64_t outputBatch = boxes.size(); - - //printf("---------->NumberOfDets by coords %li\n", outputBatch); - - uint64_t byteSize = sizeof(int32_t) * 4 * outputBatch; - - int32_t* buffer = (int32_t*)malloc(byteSize); - NODE_ASSERT(buffer != nullptr, "malloc has failed"); - - for (uint64_t i = 0; i < outputBatch; i++) { - int32_t entry[] = { - boxes[i].x, - boxes[i].y, - boxes[i].width, - boxes[i].height}; - - std::memcpy(buffer + (i * 4), entry, byteSize / outputBatch); - } - output->data = reinterpret_cast(buffer); - output->dataBytes = byteSize; - output->dimsCount = 3; - output->dims = (uint64_t*)malloc(output->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(output->dims != nullptr, "malloc has failed"); - output->dims[0] = outputBatch; - output->dims[1] = 1; - output->dims[2] = 4; - output->precision = I32; - - return true; -} - -static bool copy_scores_into_output(struct CustomNodeTensor* output, const std::vector& scores) { - const uint64_t outputBatch = scores.size(); - //printf("Number of scores------------------>%li\n", outputBatch); - uint64_t byteSize = sizeof(float) * outputBatch; - - float* buffer = (float*)malloc(byteSize); - NODE_ASSERT(buffer != nullptr, "malloc has failed"); - std::memcpy(buffer, scores.data(), byteSize); - - output->data = reinterpret_cast(buffer); - output->dataBytes = byteSize; - output->dimsCount = 3; - output->dims = (uint64_t*)malloc(output->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(output->dims != nullptr, "malloc has failed"); - output->dims[0] = outputBatch; - output->dims[1] = 1; - output->dims[2] = 1; - output->precision = FP32; - return true; -} - -int initialize(void** customNodeLibraryInternalManager, const struct CustomNodeParam* params, int paramsCount) { - return 0; -} - -int deinitialize(void* customNodeLibraryInternalManager) { - return 0; -} - -// YoloV8 PostProcessing - -const std::string labels[80] = { - "person", - "bicycle", - "car", - "motorbike", - "aeroplane", - "bus", - "train", - "truck", - "boat", - "traffic light", - "fire hydrant", - "stop sign", - "parking meter", - "bench", - "bird", - "cat", - "dog", - "horse", - "sheep", - "cow", - "elephant", - "bear", - "zebra", - "giraffe", - "backpack", - "umbrella", - "handbag", - "tie", - "suitcase", - "frisbee", - "skis", - "snowboard", - "sports ball", - "kite", - "baseball bat", - "baseball glove", - "skateboard", - "surfboard", - "tennis racket", - "bottle", - "wine glass", - "cup", - "fork", - "knife", - "spoon", - "bowl", - "banana", - "apple", - "sandwich", - "orange", - "broccoli", - "carrot", - "hot dog", - "pizza", - "donut", - "cake", - "chair", - "sofa", - "pottedplant", - "bed", - "diningtable", - "toilet", - "tvmonitor", - "laptop", - "mouse", - "remote", - "keyboard", - "cell phone", - "microwave", - "oven", - "toaster", - "sink", - "refrigerator", - "book", - "clock", - "vase", - "scissors", - "teddy bear", - "hair drier", - "toothbrush" -}; - -int calculateEntryIndex(int totalCells, int lcoords, size_t lclasses, int location, int entry) { - int n = location / totalCells; - int loc = location % totalCells; - return (n * (lcoords + lclasses) + entry) * totalCells + loc; -} - -static inline float sigmoid(float x) { - return 1.f / (1.f + std::exp(-x)); -} - -double intersectionOverUnion(const DetectedResult& o1, const DetectedResult& o2) { - double overlappingWidth = std::fmin(o1.x + o1.width, o2.x + o2.width) - std::fmax(o1.x, o2.x); - double overlappingHeight = std::fmin(o1.y + o1.height, o2.y + o2.height) - std::fmax(o1.y, o2.y); - double intersectionArea = (overlappingWidth < 0 || overlappingHeight < 0) ? 0 : overlappingHeight * overlappingWidth; - double unionArea = o1.width * o1.height + o2.width * o2.height - intersectionArea; - return intersectionArea / unionArea; -} - -// IOU postproc filter -void postprocess(std::vector &detectedResults, - std::vector &rects, std::vector &scores) -{ - bool useAdvancedPostprocessing = false; - - if (useAdvancedPostprocessing) { - // Advanced postprocessing - // Checking IOU threshold conformance - // For every i-th object we're finding all objects it intersects with, and comparing confidence - // If i-th object has greater confidence than all others, we include it into result - for (const auto& obj1 : detectedResults) { - bool isGoodResult = true; - for (const auto& obj2 : detectedResults) { - if (obj1.classId == obj2.classId && obj1.confidence < obj2.confidence && - intersectionOverUnion(obj1, obj2) >= boxiou_threshold) { // if obj1 is the same as obj2, condition - // expression will evaluate to false anyway - isGoodResult = false; - break; - } - } - if (isGoodResult) { - //outDetectedResults.push_back(obj1); - rects.emplace_back( - obj1.x, - obj1.y, - obj1.width, - obj1.height); - scores.emplace_back(obj1.confidence); - } - } - } else { - // Classic postprocessing - printf("Checking %i boxes for IOU\n", detectedResults.size()); - std::sort(detectedResults.begin(), detectedResults.end(), [](const DetectedResult& x, const DetectedResult& y) { - return x.confidence > y.confidence; - }); - for (size_t i = 0; i < detectedResults.size(); ++i) { - if (detectedResults[i].confidence == 0) - continue; - - for (size_t j = i + 1; j < detectedResults.size(); ++j) - { - float iou = intersectionOverUnion(detectedResults[i], detectedResults[j]); - - if (iou >= boxiou_threshold) - detectedResults[j].confidence = 0; - // else - // printf("\tiou saving: %f", iou); - } - - if (detectedResults[i].confidence > 0) - { - //outDetectedResults.push_back(detectedResults[i]); - rects.emplace_back( - detectedResults[i].x, - detectedResults[i].y, - detectedResults[i].width, - detectedResults[i].height); - scores.emplace_back(detectedResults[i].confidence); - } - } //end for - } // end if -} // end postprocess IOU filter - - -std::vector nms(const std::vector& res, const float thresh, bool includeBoundaries=false, size_t keep_top_k=0) { - if (keep_top_k == 0) { - keep_top_k = 10; //res.size(); - } - std::vector areas(res.size()); - for (size_t i = 0; i < res.size(); ++i) { - areas[i] = (float) (res[i].width - res[i].x + includeBoundaries) * (res[i].height - res[i].y + includeBoundaries); - } - std::vector order(res.size()); - std::iota(order.begin(), order.end(), 0); - std::sort(order.begin(), order.end(), [&res](int o1, int o2) { return res[o1].confidence > res[o2].confidence; }); - - size_t ordersNum = 0; - for (; ordersNum < order.size() && res[order[ordersNum]].confidence >= 0 && ordersNum < keep_top_k; ordersNum++); - - std::vector keep; - bool shouldContinue = true; - for (size_t i = 0; shouldContinue && i < ordersNum; ++i) { - int idx1 = order[i]; - if (idx1 >= 0) { - keep.push_back(idx1); - shouldContinue = false; - for (size_t j = i + 1; j < ordersNum; ++j) { - int idx2 = order[j]; - if (idx2 >= 0) { - shouldContinue = true; - float overlappingWidth = std::fminf(res[idx1].width, res[idx2].width) - std::fmaxf(res[idx1].x, res[idx2].x); - float overlappingHeight = std::fminf(res[idx1].height, res[idx2].height) - std::fmaxf(res[idx1].y, res[idx2].y); - float intersection = overlappingWidth > 0 && overlappingHeight > 0 ? overlappingWidth * overlappingHeight : 0; - float union_area = areas[idx1] + areas[idx2] - intersection; - if (0.0f == union_area || intersection / union_area > thresh) { - order[j] = -1; - } - } - } - } - } - return keep; -} - -std::vector multiclass_nms(const std::vector& res, const float iou_threshold, bool includeBoundaries, size_t maxNum) { - std::vector boxes_copy; - boxes_copy.reserve(res.size()); - - float max_coord = 0.f; - for (const auto& box : res) { - max_coord = std::max(max_coord, std::max((float)box.width, (float)box.height)); - } - for (auto& box : res) { - float offset = box.classId * max_coord; - DetectedResult tmp; - tmp.x = box.x + offset; - tmp.y = box.y + offset; - tmp.width = box.width + offset; - tmp.height = box.height + offset; - tmp.classId = box.classId; - tmp.confidence = box.confidence; - boxes_copy.emplace_back(tmp); - } - - return nms(boxes_copy, iou_threshold, includeBoundaries, maxNum); -} - - -void postprocess(const float confidence_threshold, const int imageWidth, const int imageHeight, - const uint64_t* output_shape, const void* voutputData, const uint32_t dimCount, - std::vector &rects, std::vector &scores) -{ - if (!voutputData || !output_shape) { - // nothing to do - return; - } - - /* - https://github.com/openvinotoolkit/openvino_notebooks/blob/main/notebooks/230-yolov8-optimization/230-yolov8-object-detection.ipynb - detection box has the [x, y, h, w, class_no_1, ..., class_no_80] format, where: - (x, y) - raw coordinates of box center - h, w - raw height and width of the box - class_no_1, ..., class_no_80 - probability distribution over the classes. - */ - - std::vector detectedResults; - size_t num_proposals = output_shape[2]; - std::vector boxes_with_class; - std::vector confidences; - const float* const detections = (float*)(voutputData); - for (size_t i = 0; i < num_proposals; ++i) { - float confidence = 0.0f; - size_t max_id = 0; - constexpr size_t LABELS_START = 4; - // get max confidence level in the 80 classes for this detection - for (size_t j = LABELS_START; j < output_shape[1]; ++j) { - if (detections[j * num_proposals + i] > confidence) { - confidence = detections[j * num_proposals + i]; - max_id = j; - } - } - // add the detection if the max confi. meets the threshold - if (confidence > confidence_threshold) { - DetectedResult obj; - obj.x = detections[0 * num_proposals + i] - detections[2 * num_proposals + i] / 2.0f; - obj.y = detections[1 * num_proposals + i] - detections[3 * num_proposals + i] / 2.0f; - obj.width = detections[0 * num_proposals + i] + detections[2 * num_proposals + i] / 2.0f; - obj.height = detections[1 * num_proposals + i] + detections[3 * num_proposals + i] / 2.0f; - obj.classId = max_id - LABELS_START; - obj.confidence = confidence; - - // if (obj.classId != 39 && obj.classId != 0) - // printf("Found: %i conf: %f\n", obj.classId, obj.confidence); - - boxes_with_class.emplace_back(obj); - confidences.push_back(confidence); - } - } - - constexpr bool includeBoundaries = false; - constexpr size_t keep_top_k = 30000; - std::vector keep; - bool agnostic_nms = true; - - if (agnostic_nms) { - keep = nms(boxes_with_class, boxiou_threshold, includeBoundaries, keep_top_k); - } else { - keep = multiclass_nms(boxes_with_class, boxiou_threshold, includeBoundaries, keep_top_k); - } - - int padLeft = 15, padTop = 0; // adjust padding for optimal efficientnet inference - float floatInputImgWidth = float(imageWidth), - floatInputImgHeight = float(imageHeight), - netInputWidth = floatInputImgWidth, - netInputHeight = floatInputImgHeight, - invertedScaleX = floatInputImgWidth / netInputWidth, - invertedScaleY = floatInputImgHeight / netInputHeight; - - for (size_t idx : keep) { - int x1 = std::clamp( - round((boxes_with_class[idx].x - padLeft) * invertedScaleX), - 0.f, - floatInputImgWidth); - int y1 = std::clamp( - round((boxes_with_class[idx].y - padTop) * invertedScaleY), - 0.f, - floatInputImgHeight); - int x2 = std::clamp( - round((boxes_with_class[idx].width + padLeft) * invertedScaleX) - x1, - 0.f, - floatInputImgWidth - x1); - int y2 = std::clamp( - round((boxes_with_class[idx].height + padTop) * invertedScaleY) - y1, - 0.f, - floatInputImgHeight-y1); - - // if (boxes_with_class[idx].classId != 39 && boxes_with_class[idx].classId != 0) - //printf("Keeping: %i conf: %f %i,%i,%i,%i/%i\n", boxes_with_class[idx].classId, boxes_with_class[idx].confidence, x1, y1, x2,y2,y3); - - //printf("Adding detection %i conf:%f/%f %ix%ix%ix%i\n",boxes_with_class[idx].classId, boxes_with_class[idx].confidence, confidences[idx], x1, y1, x2, y2); - rects.emplace_back(x1, y1, x2, y2); - scores.emplace_back(confidences[idx]); - - //desc.classId = static_cast(boxes_with_class[idx].classId); - //desc.label = getLabelName(desc.labelID); - //detectedResults.push_back(desc); - } - -} -// End of Yolov8 PostProcessing - -int execute(const struct CustomNodeTensor* inputs, int inputsCount, struct CustomNodeTensor** outputs, int* outputsCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager) { - - // Parameters reading - int originalImageHeight = get_int_parameter("original_image_height", params, paramsCount, -1); - int originalImageWidth = get_int_parameter("original_image_width", params, paramsCount, -1); - NODE_ASSERT(originalImageHeight > 0, "original image height must be larger than 0"); - NODE_ASSERT(originalImageWidth > 0, "original image width must be larger than 0"); - int targetImageHeight = get_int_parameter("target_image_height", params, paramsCount, -1); - int targetImageWidth = get_int_parameter("target_image_width", params, paramsCount, -1); - NODE_ASSERT(targetImageHeight > 0, "target image height must be larger than 0"); - NODE_ASSERT(targetImageWidth > 0, "target image width must be larger than 0"); - std::string originalImageLayout = get_string_parameter("original_image_layout", params, paramsCount, "NCHW"); - NODE_ASSERT(originalImageLayout == "NCHW" || originalImageLayout == "NHWC", "original image layout must be NCHW or NHWC"); - std::string targetImageLayout = get_string_parameter("target_image_layout", params, paramsCount, "NCHW"); - NODE_ASSERT(targetImageLayout == "NCHW" || targetImageLayout == "NHWC", "target image layout must be NCHW or NHWC"); - bool convertToGrayScale = get_string_parameter("convert_to_gray_scale", params, paramsCount) == "true"; - float confidenceThreshold = get_float_parameter("confidence_threshold", params, paramsCount, -1.0); - NODE_ASSERT(confidenceThreshold >= 0 && confidenceThreshold <= 1.0, "confidence threshold must be in 0-1 range"); - uint64_t maxOutputBatch = get_int_parameter("max_output_batch", params, paramsCount, 100); - NODE_ASSERT(maxOutputBatch > 0, "max output batch must be larger than 0"); - debugMode = get_string_parameter("debug", params, paramsCount) == "true"; - - const CustomNodeTensor* imageTensor = nullptr; - const CustomNodeTensor* boxesTensor = nullptr; - - for (int i = 0; i < inputsCount; i++) { - if (std::strcmp(inputs[i].name, IMAGE_TENSOR_NAME) == 0) { - imageTensor = &(inputs[i]); - } else if (std::strcmp(inputs[i].name, GEOMETRY_TENSOR_NAME) == 0) { - boxesTensor = &(inputs[i]); - } else { - std::cout << "Unrecognized input: " << inputs[i].name << std::endl; - return 1; - } - } - - NODE_ASSERT(imageTensor != nullptr, "Missing input image"); - NODE_ASSERT(boxesTensor != nullptr, "Missing input boxes"); - NODE_ASSERT(imageTensor->precision == FP32, "-------------->>>>>>>image input is not FP32"); - NODE_ASSERT(boxesTensor->precision == FP32, "image input is not FP32"); - - NODE_ASSERT(imageTensor->dimsCount == 4, "input image shape must have 4 dimensions"); - NODE_ASSERT(imageTensor->dims[0] == 1, "input image batch must be 1"); - uint64_t _imageHeight = imageTensor->dims[originalImageLayout == "NCHW" ? 2 : 1]; - uint64_t _imageWidth = imageTensor->dims[originalImageLayout == "NCHW" ? 3 : 2]; - NODE_ASSERT(_imageHeight <= static_cast(std::numeric_limits::max()), "image height is too large"); - NODE_ASSERT(_imageWidth <= static_cast(std::numeric_limits::max()), "image width is too large"); - int imageHeight = static_cast(_imageHeight); - int imageWidth = static_cast(_imageWidth); - - if (debugMode) { - std::cout << "Processing input tensor image resolution: " << cv::Size(imageHeight, imageWidth) << "; expected resolution: " << cv::Size(originalImageHeight, originalImageWidth) << std::endl; - } - - NODE_ASSERT(imageHeight == originalImageHeight, "original image size parameter differs from original image tensor size"); - NODE_ASSERT(imageWidth == originalImageWidth, "original image size parameter differs from original image tensor size"); - - cv::Mat image; - if (originalImageLayout == "NHWC") { - image = nhwc_to_mat(imageTensor); - } else { - image = nchw_to_mat(imageTensor); - } - - NODE_ASSERT(image.cols == imageWidth, "Mat generation failed"); - NODE_ASSERT(image.rows == imageHeight, "Mat generation failed"); - -// TODO: - std::vector rects; - std::vector scores; - postprocess(confidenceThreshold, originalImageWidth, originalImageHeight, boxesTensor->dims, boxesTensor->data, boxesTensor->dimsCount, rects, scores); - - NODE_ASSERT(rects.size() == scores.size(), "rects and scores are not equal length"); - if (rects.size() > maxOutputBatch) { - rects.resize(maxOutputBatch); - scores.resize(maxOutputBatch); - } - - if (debugMode) - std::cout << "Total findings: " << rects.size() << std::endl; - - *outputsCount = 3; // pipeline outputs for efficientnetb0_extractor e.g. roi_images, roi_coordinates, confidence_levels - *outputs = (struct CustomNodeTensor*)malloc(*outputsCount * sizeof(CustomNodeTensor)); - - NODE_ASSERT((*outputs) != nullptr, "malloc has failed"); - CustomNodeTensor& textImagesTensor = (*outputs)[0]; - textImagesTensor.name = TEXT_IMAGES_TENSOR_NAME; - - if (!copy_images_into_output(&textImagesTensor, rects, image, targetImageHeight, targetImageWidth, targetImageLayout, convertToGrayScale)) { - free(*outputs); - return 1; - } - - CustomNodeTensor& coordinatesTensor = (*outputs)[1]; - coordinatesTensor.name = COORDINATES_TENSOR_NAME; - if (!copy_coordinates_into_output(&coordinatesTensor, rects)) { - free(*outputs); - cleanup(textImagesTensor); - return 1; - } - - - CustomNodeTensor& confidenceTensor = (*outputs)[2]; - confidenceTensor.name = CONFIDENCE_TENSOR_NAME; - if (!copy_scores_into_output(&confidenceTensor, scores)) { - free(*outputs); - cleanup(textImagesTensor); - cleanup(coordinatesTensor); - return 1; - } - - //printf("finished execute\n"); - return 0; -} - -int getInputsInfo(struct CustomNodeTensorInfo** info, int* infoCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager) { - int originalImageHeight = get_int_parameter("original_image_height", params, paramsCount, -1); - int originalImageWidth = get_int_parameter("original_image_width", params, paramsCount, -1); - NODE_ASSERT(originalImageHeight > 0, "original image height must be larger than 0"); - NODE_ASSERT(originalImageWidth > 0, "original image width must be larger than 0"); - std::string originalImageLayout = get_string_parameter("original_image_layout", params, paramsCount, "NCHW"); - NODE_ASSERT(originalImageLayout == "NCHW" || originalImageLayout == "NHWC", "original image layout must be NCHW or NHWC"); - - *infoCount = 2; - *info = (struct CustomNodeTensorInfo*)malloc(*infoCount * sizeof(struct CustomNodeTensorInfo)); - NODE_ASSERT((*info) != nullptr, "malloc has failed"); - - (*info)[0].name = IMAGE_TENSOR_NAME; - (*info)[0].dimsCount = 4; - (*info)[0].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[0].dims) != nullptr, "malloc has failed"); - (*info)[0].dims[0] = 1; - if (originalImageLayout == "NCHW") { - (*info)[0].dims[1] = 3; - (*info)[0].dims[2] = originalImageHeight; - (*info)[0].dims[3] = originalImageWidth; - } else { - (*info)[0].dims[1] = originalImageHeight; - (*info)[0].dims[2] = originalImageWidth; - (*info)[0].dims[3] = 3; - } - (*info)[0].precision = FP32; - - (*info)[1].name = GEOMETRY_TENSOR_NAME; - (*info)[1].dimsCount = 3; - (*info)[1].dims = (uint64_t*)malloc((*info)[1].dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[1].dims) != nullptr, "malloc has failed"); - // 416x416 - (*info)[1].dims[0] = 1; - (*info)[1].dims[1] = 84; - (*info)[1].dims[2] = 3549; - - // 512x512 - // (*info)[1].dims[0] = 1; - // (*info)[1].dims[1] = 84; - // (*info)[1].dims[2] = 5376; - //640x640 - // (*info)[1].dims[0] = 1; - // (*info)[1].dims[1] = 84; - // (*info)[1].dims[2] = 8400; - - (*info)[1].precision = FP32; - return 0; -} - -int getOutputsInfo(struct CustomNodeTensorInfo** info, int* infoCount, const struct CustomNodeParam* params, int paramsCount, void* customNodeLibraryInternalManager) { - int targetImageHeight = get_int_parameter("target_image_height", params, paramsCount, -1); - int targetImageWidth = get_int_parameter("target_image_width", params, paramsCount, -1); - NODE_ASSERT(targetImageHeight > 0, "target image height must be larger than 0"); - NODE_ASSERT(targetImageWidth > 0, "target image width must be larger than 0"); - std::string targetImageLayout = get_string_parameter("target_image_layout", params, paramsCount, "NCHW"); - NODE_ASSERT(targetImageLayout == "NCHW" || targetImageLayout == "NHWC", "target image layout must be NCHW or NHWC"); - bool convertToGrayScale = get_string_parameter("convert_to_gray_scale", params, paramsCount) == "true"; - - *infoCount = 3; - *info = (struct CustomNodeTensorInfo*)malloc(*infoCount * sizeof(struct CustomNodeTensorInfo)); - NODE_ASSERT((*info) != nullptr, "malloc has failed"); - - (*info)[0].name = TEXT_IMAGES_TENSOR_NAME; - (*info)[0].dimsCount = 5; - (*info)[0].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[0].dims) != nullptr, "malloc has failed"); - (*info)[0].dims[0] = 0; - (*info)[0].dims[1] = 1; - if (targetImageLayout == "NCHW") { - (*info)[0].dims[2] = convertToGrayScale ? 1 : 3; - (*info)[0].dims[3] = targetImageHeight; - (*info)[0].dims[4] = targetImageWidth; - } else { - (*info)[0].dims[2] = targetImageHeight; - (*info)[0].dims[3] = targetImageWidth; - (*info)[0].dims[4] = convertToGrayScale ? 1 : 3; - } - (*info)[0].precision = FP32; - - (*info)[1].name = COORDINATES_TENSOR_NAME; - (*info)[1].dimsCount = 3; - (*info)[1].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[1].dims) != nullptr, "malloc has failed"); - (*info)[1].dims[0] = 0; - (*info)[1].dims[1] = 1; - (*info)[1].dims[2] = 4; - (*info)[1].precision = I32; - - (*info)[2].name = CONFIDENCE_TENSOR_NAME; - (*info)[2].dimsCount = 3; - (*info)[2].dims = (uint64_t*)malloc((*info)->dimsCount * sizeof(uint64_t)); - NODE_ASSERT(((*info)[2].dims) != nullptr, "malloc has failed"); - (*info)[2].dims[0] = 0; - (*info)[2].dims[1] = 1; - (*info)[2].dims[2] = 1; - (*info)[2].precision = FP32; - - return 0; -} - -int release(void* ptr, void* customNodeLibraryInternalManager) { - free(ptr); - return 0; -} diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/main.cpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/main.cpp deleted file mode 100644 index 846d78b2..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/main.cpp +++ /dev/null @@ -1,2138 +0,0 @@ -//***************************************************************************** -// Copyright 2024 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -// Utilized for GStramer hardware accelerated decode and pre-preprocessing -#include -#include -#include - -// Utilized for OpenCV based Rendering only -#include -#include -#include -#include - -// Utilized for infernece output layer post-processing -#include - -#include "ovms.h" // NOLINT - -using namespace std; -using namespace cv; - -std::mutex _mtx; -std::mutex _infMtx; -std::mutex _drawingMtx; -std::condition_variable _cvAllDecodersInitd; -bool _allDecodersInitd = false; - -typedef struct DetectedResult { - int frameId; - int x; - int y; - int width; - int height; - float confidence; - int classId; - char classText[1024]; -} DetectedResult; - -class MediaPipelineServiceInterface { -public: - enum VIDEO_TYPE { - H265, - H264 - }; - - virtual ~MediaPipelineServiceInterface() {} - virtual const std::string getVideoDecodedPreProcessedPipeline(std::string mediaLocation, VIDEO_TYPE videoType, int video_width, int video_height, bool use_onevpl) = 0; - - const std::string updateVideoDecodedPreProcessedPipeline(int video_width, int video_height, bool use_onevpl) - { - return getVideoDecodedPreProcessedPipeline(m_mediaLocation, m_videoType, video_width, video_height, use_onevpl); - } - -protected: - std::string m_mediaLocation; - VIDEO_TYPE m_videoType; - int m_videoWidth; - int m_videoHeight; -}; - -OVMS_Server* _srv; -OVMS_ServerSettings* _serverSettings = 0; -OVMS_ModelsSettings* _modelsSettings = 0; -int _server_grpc_port; -int _server_http_port; - -std::string _videoStreamPipeline; -std::string _videoStreamPipeline2; -MediaPipelineServiceInterface::VIDEO_TYPE _videoType = MediaPipelineServiceInterface::VIDEO_TYPE::H264; -MediaPipelineServiceInterface::VIDEO_TYPE _videoType2 = MediaPipelineServiceInterface::VIDEO_TYPE::H264; -int _detectorModel = 0; -bool _render = 0; -bool _use_onevpl = 0; -bool _renderPortrait = 0; -cv::Mat _presentationImg; -int _video_input_width = 0; // Get from media _img -int _video_input_height = 0; // Get from media _img -std::vector _vidcaps; -int _window_width = 1280; -int _window_height = 720; -float _detection_threshold = 0.5; - -class GStreamerMediaPipelineService : public MediaPipelineServiceInterface { -public: - const std::string getVideoDecodedPreProcessedPipeline(std::string mediaLocation, VIDEO_TYPE videoType, int video_width, int video_height, bool use_onevpl) { - m_mediaLocation = mediaLocation; - m_videoType = videoType; - m_videoWidth = video_width; - m_videoHeight = video_height; - - if (mediaLocation.find("rtsp") != std::string::npos ) { - switch (videoType) - { - case H264: - if (use_onevpl) - return "rtspsrc location=" + mediaLocation + " ! rtph264depay ! h264parse ! " + - "msdkh264dec ! msdkvpp scaling-mode=lowpower ! " + - "video/x-raw, width=" + std::to_string(video_width) + - ", height=" + std::to_string(video_height) + " ! videoconvert ! video/x-raw,format=RGB ! queue ! appsink drop=1 sync=0"; - else - return "rtspsrc location=" + mediaLocation + " ! rtph264depay ! h264parse ! vah264dec ! video/x-raw(memory:VAMemory),format=NV12 " + - " ! vapostproc ! " + - " video/x-raw, width=" + std::to_string(video_width) + - ", height=" + std::to_string(video_height) + - " ! videoconvert ! video/x-raw,format=RGB ! queue ! appsink drop=1 sync=0"; - case H265: - if (use_onevpl) - return "rtspsrc location=" + mediaLocation + " ! rtph265depay ! h265parse ! " + - "msdkh265dec ! " + - "msdkvpp scaling-mode=lowpower ! " + - "video/x-raw, width=" + std::to_string(video_width) + - ", height=" + std::to_string(video_height) + " ! videoconvert ! video/x-raw,format=RGB ! queue ! appsink drop=1 sync=0"; - else - return "rtspsrc location=" + mediaLocation + " ! rtph265depay ! h265parse ! vah265dec ! video/x-raw(memory:VAMemory),format=NV12 " + - " ! vapostproc ! " + - " video/x-raw, width=" + std::to_string(video_width) + - ", height=" + std::to_string(video_height) + - " ! videoconvert ! video/x-raw,format=RGB ! queue ! appsink drop=1 sync=0"; - default: - std::cout << "Video type not supported!" << videoType << std::endl; - return ""; - } - } - else if (mediaLocation.find(".mp4") != std::string::npos ) { - switch (videoType) - { - case H264: - if (use_onevpl) - return "filesrc location=" + mediaLocation + " ! qtdemux ! h264parse ! " + - "msdkh264dec ! msdkvpp scaling-mode=lowpower ! " + - "video/x-raw, width=" + std::to_string(video_width) + ", height=" + std::to_string(video_height) + - " ! videoconvert ! video/x-raw,format=RGB ! queue ! appsink drop=1 sync=0"; - else - return "filesrc location=" + mediaLocation + " ! qtdemux ! h264parse ! vaapidecodebin ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=RGB ! appsink drop=1 sync=0"; - case H265: - if (use_onevpl) - return "filesrc location=" + mediaLocation + " ! qtdemux ! h265parse ! " + - "msdkh265dec ! msdkvpp scaling-mode=lowpower ! " + - " video/x-raw, width=" + std::to_string(video_width) + ", height=" + std::to_string(video_height) + - " ! videoconvert ! video/x-raw,format=RGB ! queue ! appsink drop=1 sync=0"; - else - return "filesrc location=" + mediaLocation + " ! qtdemux ! h265parse ! vaapidecodebin ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=RGB ! appsink drop=1 sync=0"; - default: - std::cout << "Video type not supported!" << videoType << std::endl; - return ""; - } - } - else { - std::cout << "Unknown media source specified " << mediaLocation << " !!" << std::endl; - return ""; - } - } -protected: - -}; - -class ObjectDetectionInterface { -public: - const static size_t MODEL_DIM_COUNT = 4; - int64_t model_input_shape[MODEL_DIM_COUNT] = { 0 }; - - virtual ~ObjectDetectionInterface() {} - virtual const char* getModelName() = 0; - virtual const uint64_t getModelVersion() = 0; - virtual const char* getModelInputName() = 0; - virtual const size_t getModelDimCount() = 0; - virtual const std::vector getModelInputShape() = 0; - virtual const std::string getClassLabelText(int classIndex) = 0; - - double intersectionOverUnion(const DetectedResult& o1, const DetectedResult& o2) { - double overlappingWidth = std::fmin(o1.x + o1.width, o2.x + o2.width) - std::fmax(o1.x, o2.x); - double overlappingHeight = std::fmin(o1.y + o1.height, o2.y + o2.height) - std::fmax(o1.y, o2.y); - double intersectionArea = (overlappingWidth < 0 || overlappingHeight < 0) ? 0 : overlappingHeight * overlappingWidth; - double unionArea = o1.width * o1.height + o2.width * o2.height - intersectionArea; - return intersectionArea / unionArea; - } - - virtual void postprocess(const int64_t* output_shape, const void* voutputData, const size_t bytesize, const uint32_t dimCount, std::vector &detectedResults) - { - // do nothing - } - - // Yolov8Ensemble detection/classification postprocess - virtual void postprocess( - const int64_t* output_shape_conf, const void* voutputData_conf, const size_t bytesize_conf, const uint32_t dimCount_conf, - const int64_t* output_shape_boxes, const void* voutputData_boxes, const size_t bytesize_boxes, const uint32_t dimCount_boxes, - const int64_t* output_shape_classification, const void* voutputData_classification, const size_t bytesize_classification, const uint32_t dimCount_classification, - std::vector &detectedResults) - { - // derived to implement - } - -protected: - float confidence_threshold = .9; - float boxiou_threshold = .4; - float iou_threshold = 0.4; - int classes = 80; - bool useAdvancedPostprocessing = false; - -}; - -class Yolov8Ensemble : public ObjectDetectionInterface { -public: - - Yolov8Ensemble() { - confidence_threshold = _detection_threshold; - // end of pipeline is efficientnet results - classes = 1000; - std::vector vmodel_input_shape = getModelInputShape(); - std::copy(vmodel_input_shape.begin(), vmodel_input_shape.end(), model_input_shape); - } - - const char* getModelName() { - return MODEL_NAME; - } - - const uint64_t getModelVersion() { - return MODEL_VERSION; - } - - const char* getModelInputName() { - return INPUT_NAME; - } - - const size_t getModelDimCount() { - return MODEL_DIM_COUNT; - } - - const std::vector getModelInputShape() { - std::vector shape{1, 3, 416, 416}; - return shape; - } - const std::string labels[1000] = { - "tench, Tinca tinca", - "goldfish, Carassius auratus", - "great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias", - "tiger shark, Galeocerdo cuvieri", - "hammerhead, hammerhead shark", - "electric ray, crampfish, numbfish, torpedo", - "stingray", - "cock", - "hen", - "ostrich, Struthio camelus", - "brambling, Fringilla montifringilla", - "goldfinch, Carduelis carduelis", - "house finch, linnet, Carpodacus mexicanus", - "junco, snowbird", - "indigo bunting, indigo finch, indigo bird, Passerina cyanea", - "robin, American robin, Turdus migratorius", - "bulbul", - "jay", - "magpie", - "chickadee", - "water ouzel, dipper", - "kite", - "bald eagle, American eagle, Haliaeetus leucocephalus", - "vulture", - "great grey owl, great gray owl, Strix nebulosa", - "European fire salamander, Salamandra salamandra", - "common newt, Triturus vulgaris", - "eft", - "spotted salamander, Ambystoma maculatum", - "axolotl, mud puppy, Ambystoma mexicanum", - "bullfrog, Rana catesbeiana", - "tree frog, tree-frog", - "tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui", - "loggerhead, loggerhead turtle, Caretta caretta", - "leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea", - "mud turtle", - "terrapin", - "box turtle, box tortoise", - "banded gecko", - "common iguana, iguana, Iguana iguana", - "American chameleon, anole, Anolis carolinensis", - "whiptail, whiptail lizard", - "agama", - "frilled lizard, Chlamydosaurus kingi", - "alligator lizard", - "Gila monster, Heloderma suspectum", - "green lizard, Lacerta viridis", - "African chameleon, Chamaeleo chamaeleon", - "Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis", - "African crocodile, Nile crocodile, Crocodylus niloticus", - "American alligator, Alligator mississipiensis", - "triceratops", - "thunder snake, worm snake, Carphophis amoenus", - "ringneck snake, ring-necked snake, ring snake", - "hognose snake, puff adder, sand viper", - "green snake, grass snake", - "king snake, kingsnake", - "garter snake, grass snake", - "water snake", - "vine snake", - "night snake, Hypsiglena torquata", - "boa constrictor, Constrictor constrictor", - "rock python, rock snake, Python sebae", - "Indian cobra, Naja naja", - "green mamba", - "sea snake", - "horned viper, cerastes, sand viper, horned asp, Cerastes cornutus", - "diamondback, diamondback rattlesnake, Crotalus adamanteus", - "sidewinder, horned rattlesnake, Crotalus cerastes", - "trilobite", - "harvestman, daddy longlegs, Phalangium opilio", - "scorpion", - "black and gold garden spider, Argiope aurantia", - "barn spider, Araneus cavaticus", - "garden spider, Aranea diademata", - "black widow, Latrodectus mactans", - "tarantula", - "wolf spider, hunting spider", - "tick", - "centipede", - "black grouse", - "ptarmigan", - "ruffed grouse, partridge, Bonasa umbellus", - "prairie chicken, prairie grouse, prairie fowl", - "peacock", - "quail", - "partridge", - "African grey, African gray, Psittacus erithacus", - "macaw", - "sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita", - "lorikeet", - "coucal", - "bee eater", - "hornbill", - "hummingbird", - "jacamar", - "toucan", - "drake", - "red-breasted merganser, Mergus serrator", - "goose", - "black swan, Cygnus atratus", - "tusker", - "echidna, spiny anteater, anteater", - "platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus", - "wallaby, brush kangaroo", - "koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus", - "wombat", - "jellyfish", - "sea anemone, anemone", - "brain coral", - "flatworm, platyhelminth", - "nematode, nematode worm, roundworm", - "conch", - "snail", - "slug", - "sea slug, nudibranch", - "chiton, coat-of-mail shell, sea cradle, polyplacophore", - "chambered nautilus, pearly nautilus, nautilus", - "Dungeness crab, Cancer magister", - "rock crab, Cancer irroratus", - "fiddler crab", - "king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica", - "American lobster, Northern lobster, Maine lobster, Homarus americanus", - "spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish", - "crayfish, crawfish, crawdad, crawdaddy", - "hermit crab", - "isopod", - "white stork, Ciconia ciconia", - "black stork, Ciconia nigra", - "spoonbill", - "flamingo", - "little blue heron, Egretta caerulea", - "American egret, great white heron, Egretta albus", - "bittern", - "crane", - "limpkin, Aramus pictus", - "European gallinule, Porphyrio porphyrio", - "American coot, marsh hen, mud hen, water hen, Fulica americana", - "bustard", - "ruddy turnstone, Arenaria interpres", - "red-backed sandpiper, dunlin, Erolia alpina", - "redshank, Tringa totanus", - "dowitcher", - "oystercatcher, oyster catcher", - "pelican", - "king penguin, Aptenodytes patagonica", - "albatross, mollymawk", - "grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus", - "killer whale, killer, orca, grampus, sea wolf, Orcinus orca", - "dugong, Dugong dugon", - "sea lion", - "Chihuahua", - "Japanese spaniel", - "Maltese dog, Maltese terrier, Maltese", - "Pekinese, Pekingese, Peke", - "Shih-Tzu", - "Blenheim spaniel", - "papillon", - "toy terrier", - "Rhodesian ridgeback", - "Afghan hound, Afghan", - "basset, basset hound", - "beagle", - "bloodhound, sleuthhound", - "bluetick", - "black-and-tan coonhound", - "Walker hound, Walker foxhound", - "English foxhound", - "redbone", - "borzoi, Russian wolfhound", - "Irish wolfhound", - "Italian greyhound", - "whippet", - "Ibizan hound, Ibizan Podenco", - "Norwegian elkhound, elkhound", - "otterhound, otter hound", - "Saluki, gazelle hound", - "Scottish deerhound, deerhound", - "Weimaraner", - "Staffordshire bullterrier, Staffordshire bull terrier", - "American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier", - "Bedlington terrier", - "Border terrier", - "Kerry blue terrier", - "Irish terrier", - "Norfolk terrier", - "Norwich terrier", - "Yorkshire terrier", - "wire-haired fox terrier", - "Lakeland terrier", - "Sealyham terrier, Sealyham", - "Airedale, Airedale terrier", - "cairn, cairn terrier", - "Australian terrier", - "Dandie Dinmont, Dandie Dinmont terrier", - "Boston bull, Boston terrier", - "miniature schnauzer", - "giant schnauzer", - "standard schnauzer", - "Scotch terrier, Scottish terrier, Scottie", - "Tibetan terrier, chrysanthemum dog", - "silky terrier, Sydney silky", - "soft-coated wheaten terrier", - "West Highland white terrier", - "Lhasa, Lhasa apso", - "flat-coated retriever", - "curly-coated retriever", - "golden retriever", - "Labrador retriever", - "Chesapeake Bay retriever", - "German short-haired pointer", - "vizsla, Hungarian pointer", - "English setter", - "Irish setter, red setter", - "Gordon setter", - "Brittany spaniel", - "clumber, clumber spaniel", - "English springer, English springer spaniel", - "Welsh springer spaniel", - "cocker spaniel, English cocker spaniel, cocker", - "Sussex spaniel", - "Irish water spaniel", - "kuvasz", - "schipperke", - "groenendael", - "malinois", - "briard", - "kelpie", - "komondor", - "Old English sheepdog, bobtail", - "Shetland sheepdog, Shetland sheep dog, Shetland", - "collie", - "Border collie", - "Bouvier des Flandres, Bouviers des Flandres", - "Rottweiler", - "German shepherd, German shepherd dog, German police dog, alsatian", - "Doberman, Doberman pinscher", - "miniature pinscher", - "Greater Swiss Mountain dog", - "Bernese mountain dog", - "Appenzeller", - "EntleBucher", - "boxer", - "bull mastiff", - "Tibetan mastiff", - "French bulldog", - "Great Dane", - "Saint Bernard, St Bernard", - "Eskimo dog, husky", - "malamute, malemute, Alaskan malamute", - "Siberian husky", - "dalmatian, coach dog, carriage dog", - "affenpinscher, monkey pinscher, monkey dog", - "basenji", - "pug, pug-dog", - "Leonberg", - "Newfoundland, Newfoundland dog", - "Great Pyrenees", - "Samoyed, Samoyede", - "Pomeranian", - "chow, chow chow", - "keeshond", - "Brabancon griffon", - "Pembroke, Pembroke Welsh corgi", - "Cardigan, Cardigan Welsh corgi", - "toy poodle", - "miniature poodle", - "standard poodle", - "Mexican hairless", - "timber wolf, grey wolf, gray wolf, Canis lupus", - "white wolf, Arctic wolf, Canis lupus tundrarum", - "red wolf, maned wolf, Canis rufus, Canis niger", - "coyote, prairie wolf, brush wolf, Canis latrans", - "dingo, warrigal, warragal, Canis dingo", - "dhole, Cuon alpinus", - "African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus", - "hyena, hyaena", - "red fox, Vulpes vulpes", - "kit fox, Vulpes macrotis", - "Arctic fox, white fox, Alopex lagopus", - "grey fox, gray fox, Urocyon cinereoargenteus", - "tabby, tabby cat", - "tiger cat", - "Persian cat", - "Siamese cat, Siamese", - "Egyptian cat", - "cougar, puma, catamount, mountain lion, painter, panther, Felis concolor", - "lynx, catamount", - "leopard, Panthera pardus", - "snow leopard, ounce, Panthera uncia", - "jaguar, panther, Panthera onca, Felis onca", - "lion, king of beasts, Panthera leo", - "tiger, Panthera tigris", - "cheetah, chetah, Acinonyx jubatus", - "brown bear, bruin, Ursus arctos", - "American black bear, black bear, Ursus americanus, Euarctos americanus", - "ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus", - "sloth bear, Melursus ursinus, Ursus ursinus", - "mongoose", - "meerkat, mierkat", - "tiger beetle", - "ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle", - "ground beetle, carabid beetle", - "long-horned beetle, longicorn, longicorn beetle", - "leaf beetle, chrysomelid", - "dung beetle", - "rhinoceros beetle", - "weevil", - "fly", - "bee", - "ant, emmet, pismire", - "grasshopper, hopper", - "cricket", - "walking stick, walkingstick, stick insect", - "cockroach, roach", - "mantis, mantid", - "cicada, cicala", - "leafhopper", - "lacewing, lacewing fly", - "dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk", - "damselfly", - "admiral", - "ringlet, ringlet butterfly", - "monarch, monarch butterfly, milkweed butterfly, Danaus plexippus", - "cabbage butterfly", - "sulphur butterfly, sulfur butterfly", - "lycaenid, lycaenid butterfly", - "starfish, sea star", - "sea urchin", - "sea cucumber, holothurian", - "wood rabbit, cottontail, cottontail rabbit", - "hare", - "Angora, Angora rabbit", - "hamster", - "porcupine, hedgehog", - "fox squirrel, eastern fox squirrel, Sciurus niger", - "marmot", - "beaver", - "guinea pig, Cavia cobaya", - "sorrel", - "zebra", - "hog, pig, grunter, squealer, Sus scrofa", - "wild boar, boar, Sus scrofa", - "warthog", - "hippopotamus, hippo, river horse, Hippopotamus amphibius", - "ox", - "water buffalo, water ox, Asiatic buffalo, Bubalus bubalis", - "bison", - "ram, tup", - "bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis", - "ibex, Capra ibex", - "hartebeest", - "impala, Aepyceros melampus", - "gazelle", - "Arabian camel, dromedary, Camelus dromedarius", - "llama", - "weasel", - "mink", - "polecat, fitch, foulmart, foumart, Mustela putorius", - "black-footed ferret, ferret, Mustela nigripes", - "otter", - "skunk, polecat, wood pussy", - "badger", - "armadillo", - "three-toed sloth, ai, Bradypus tridactylus", - "orangutan, orang, orangutang, Pongo pygmaeus", - "gorilla, Gorilla gorilla", - "chimpanzee, chimp, Pan troglodytes", - "gibbon, Hylobates lar", - "siamang, Hylobates syndactylus, Symphalangus syndactylus", - "guenon, guenon monkey", - "patas, hussar monkey, Erythrocebus patas", - "baboon", - "macaque", - "langur", - "colobus, colobus monkey", - "proboscis monkey, Nasalis larvatus", - "marmoset", - "capuchin, ringtail, Cebus capucinus", - "howler monkey, howler", - "titi, titi monkey", - "spider monkey, Ateles geoffroyi", - "squirrel monkey, Saimiri sciureus", - "Madagascar cat, ring-tailed lemur, Lemur catta", - "indri, indris, Indri indri, Indri brevicaudatus", - "Indian elephant, Elephas maximus", - "African elephant, Loxodonta africana", - "lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens", - "giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca", - "barracouta, snoek", - "eel", - "coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch", - "rock beauty, Holocanthus tricolor", - "anemone fish", - "sturgeon", - "gar, garfish, garpike, billfish, Lepisosteus osseus", - "lionfish", - "puffer, pufferfish, blowfish, globefish", - "abacus", - "abaya", - "academic gown, academic robe, judge's robe", - "accordion, piano accordion, squeeze box", - "acoustic guitar", - "aircraft carrier, carrier, flattop, attack aircraft carrier", - "airliner", - "airship, dirigible", - "altar", - "ambulance", - "amphibian, amphibious vehicle", - "analog clock", - "apiary, bee house", - "apron", - "ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin", - "assault rifle, assault gun", - "backpack, back pack, knapsack, packsack, rucksack, haversack", - "bakery, bakeshop, bakehouse", - "balance beam, beam", - "balloon", - "ballpoint, ballpoint pen, ballpen, Biro", - "Band Aid", - "banjo", - "bannister, banister, balustrade, balusters, handrail", - "barbell", - "barber chair", - "barbershop", - "barn", - "barometer", - "barrel, cask", - "barrow, garden cart, lawn cart, wheelbarrow", - "baseball", - "basketball", - "bassinet", - "bassoon", - "bathing cap, swimming cap", - "bath towel", - "bathtub, bathing tub, bath, tub", - "beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon", - "beacon, lighthouse, beacon light, pharos", - "beaker", - "bearskin, busby, shako", - "beer bottle", - "beer glass", - "bell cote, bell cot", - "bib", - "bicycle-built-for-two, tandem bicycle, tandem", - "bikini, two-piece", - "binder, ring-binder", - "binoculars, field glasses, opera glasses", - "birdhouse", - "boathouse", - "bobsled, bobsleigh, bob", - "bolo tie, bolo, bola tie, bola", - "bonnet, poke bonnet", - "bookcase", - "bookshop, bookstore, bookstall", - "bottlecap", - "bow", - "bow tie, bow-tie, bowtie", - "brass, memorial tablet, plaque", - "brassiere, bra, bandeau", - "breakwater, groin, groyne, mole, bulwark, seawall, jetty", - "breastplate, aegis, egis", - "broom", - "bucket, pail", - "buckle", - "bulletproof vest", - "bullet train, bullet", - "butcher shop, meat market", - "cab, hack, taxi, taxicab", - "caldron, cauldron", - "candle, taper, wax light", - "cannon", - "canoe", - "can opener, tin opener", - "cardigan", - "car mirror", - "carousel, carrousel, merry-go-round, roundabout, whirligig", - "carpenter's kit, tool kit", - "carton", - "car wheel", - "cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM", - "cassette", - "cassette player", - "castle", - "catamaran", - "CD player", - "cello, violoncello", - "cellular telephone, cellular phone, cellphone, cell, mobile phone", - "chain", - "chainlink fence", - "chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour", - "chain saw, chainsaw", - "chest", - "chiffonier, commode", - "chime, bell, gong", - "china cabinet, china closet", - "Christmas stocking", - "church, church building", - "cinema, movie theater, movie theatre, movie house, picture palace", - "cleaver, meat cleaver, chopper", - "cliff dwelling", - "cloak", - "clog, geta, patten, sabot", - "cocktail shaker", - "coffee mug", - "coffeepot", - "coil, spiral, volute, whorl, helix", - "combination lock", - "computer keyboard, keypad", - "confectionery, confectionary, candy store", - "container ship, containership, container vessel", - "convertible", - "corkscrew, bottle screw", - "cornet, horn, trumpet, trump", - "cowboy boot", - "cowboy hat, ten-gallon hat", - "cradle", - "crane", - "crash helmet", - "crate", - "crib, cot", - "Crock Pot", - "croquet ball", - "crutch", - "cuirass", - "dam, dike, dyke", - "desk", - "desktop computer", - "dial telephone, dial phone", - "diaper, nappy, napkin", - "digital clock", - "digital watch", - "dining table, board", - "dishrag, dishcloth", - "dishwasher, dish washer, dishwashing machine", - "disk brake, disc brake", - "dock, dockage, docking facility", - "dogsled, dog sled, dog sleigh", - "dome", - "doormat, welcome mat", - "drilling platform, offshore rig", - "drum, membranophone, tympan", - "drumstick", - "dumbbell", - "Dutch oven", - "electric fan, blower", - "electric guitar", - "electric locomotive", - "entertainment center", - "envelope", - "espresso maker", - "face powder", - "feather boa, boa", - "file, file cabinet, filing cabinet", - "fireboat", - "fire engine, fire truck", - "fire screen, fireguard", - "flagpole, flagstaff", - "flute, transverse flute", - "folding chair", - "football helmet", - "forklift", - "fountain", - "fountain pen", - "four-poster", - "freight car", - "French horn, horn", - "frying pan, frypan, skillet", - "fur coat", - "garbage truck, dustcart", - "gasmask, respirator, gas helmet", - "gas pump, gasoline pump, petrol pump, island dispenser", - "goblet", - "go-kart", - "golf ball", - "golfcart, golf cart", - "gondola", - "gong, tam-tam", - "gown", - "grand piano, grand", - "greenhouse, nursery, glasshouse", - "grille, radiator grille", - "grocery store, grocery, food market, market", - "guillotine", - "hair slide", - "hair spray", - "half track", - "hammer", - "hamper", - "hand blower, blow dryer, blow drier, hair dryer, hair drier", - "hand-held computer, hand-held microcomputer", - "handkerchief, hankie, hanky, hankey", - "hard disc, hard disk, fixed disk", - "harmonica, mouth organ, harp, mouth harp", - "harp", - "harvester, reaper", - "hatchet", - "holster", - "home theater, home theatre", - "honeycomb", - "hook, claw", - "hoopskirt, crinoline", - "horizontal bar, high bar", - "horse cart, horse-cart", - "hourglass", - "iPod", - "iron, smoothing iron", - "jack-o'-lantern", - "jean, blue jean, denim", - "jeep, landrover", - "jersey, T-shirt, tee shirt", - "jigsaw puzzle", - "jinrikisha, ricksha, rickshaw", - "joystick", - "kimono", - "knee pad", - "knot", - "lab coat, laboratory coat", - "ladle", - "lampshade, lamp shade", - "laptop, laptop computer", - "lawn mower, mower", - "lens cap, lens cover", - "letter opener, paper knife, paperknife", - "library", - "lifeboat", - "lighter, light, igniter, ignitor", - "limousine, limo", - "liner, ocean liner", - "lipstick, lip rouge", - "Loafer", - "lotion", - "loudspeaker, speaker, speaker unit, loudspeaker system, speaker system", - "loupe, jeweler's loupe", - "lumbermill, sawmill", - "magnetic compass", - "mailbag, postbag", - "mailbox, letter box", - "maillot", - "maillot, tank suit", - "manhole cover", - "maraca", - "marimba, xylophone", - "mask", - "matchstick", - "maypole", - "maze, labyrinth", - "measuring cup", - "medicine chest, medicine cabinet", - "megalith, megalithic structure", - "microphone, mike", - "microwave, microwave oven", - "military uniform", - "milk can", - "minibus", - "miniskirt, mini", - "minivan", - "missile", - "mitten", - "mixing bowl", - "mobile home, manufactured home", - "Model T", - "modem", - "monastery", - "monitor", - "moped", - "mortar", - "mortarboard", - "mosque", - "mosquito net", - "motor scooter, scooter", - "mountain bike, all-terrain bike, off-roader", - "mountain tent", - "mouse, computer mouse", - "mousetrap", - "moving van", - "muzzle", - "nail", - "neck brace", - "necklace", - "nipple", - "notebook, notebook computer", - "obelisk", - "oboe, hautboy, hautbois", - "ocarina, sweet potato", - "odometer, hodometer, mileometer, milometer", - "oil filter", - "organ, pipe organ", - "oscilloscope, scope, cathode-ray oscilloscope, CRO", - "overskirt", - "oxcart", - "oxygen mask", - "packet", - "paddle, boat paddle", - "paddlewheel, paddle wheel", - "padlock", - "paintbrush", - "pajama, pyjama, pj's, jammies", - "palace", - "panpipe, pandean pipe, syrinx", - "paper towel", - "parachute, chute", - "parallel bars, bars", - "park bench", - "parking meter", - "passenger car, coach, carriage", - "patio, terrace", - "pay-phone, pay-station", - "pedestal, plinth, footstall", - "pencil box, pencil case", - "pencil sharpener", - "perfume, essence", - "Petri dish", - "photocopier", - "pick, plectrum, plectron", - "pickelhaube", - "picket fence, paling", - "pickup, pickup truck", - "pier", - "piggy bank, penny bank", - "pill bottle", - "pillow", - "ping-pong ball", - "pinwheel", - "pirate, pirate ship", - "pitcher, ewer", - "plane, carpenter's plane, woodworking plane", - "planetarium", - "plastic bag", - "plate rack", - "plow, plough", - "plunger, plumber's helper", - "Polaroid camera, Polaroid Land camera", - "pole", - "police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria", - "poncho", - "pool table, billiard table, snooker table", - "pop bottle, soda bottle", - "pot, flowerpot", - "potter's wheel", - "power drill", - "prayer rug, prayer mat", - "printer", - "prison, prison house", - "projectile, missile", - "projector", - "puck, hockey puck", - "punching bag, punch bag, punching ball, punchball", - "purse", - "quill, quill pen", - "quilt, comforter, comfort, puff", - "racer, race car, racing car", - "racket, racquet", - "radiator", - "radio, wireless", - "radio telescope, radio reflector", - "rain barrel", - "recreational vehicle, RV, R.V.", - "reel", - "reflex camera", - "refrigerator, icebox", - "remote control, remote", - "restaurant, eating house, eating place, eatery", - "revolver, six-gun, six-shooter", - "rifle", - "rocking chair, rocker", - "rotisserie", - "rubber eraser, rubber, pencil eraser", - "rugby ball", - "rule, ruler", - "running shoe", - "safe", - "safety pin", - "saltshaker, salt shaker", - "sandal", - "sarong", - "sax, saxophone", - "scabbard", - "scale, weighing machine", - "school bus", - "schooner", - "scoreboard", - "screen, CRT screen", - "screw", - "screwdriver", - "seat belt, seatbelt", - "sewing machine", - "shield, buckler", - "shoe shop, shoe-shop, shoe store", - "shoji", - "shopping basket", - "shopping cart", - "shovel", - "shower cap", - "shower curtain", - "ski", - "ski mask", - "sleeping bag", - "slide rule, slipstick", - "sliding door", - "slot, one-armed bandit", - "snorkel", - "snowmobile", - "snowplow, snowplough", - "soap dispenser", - "soccer ball", - "sock", - "solar dish, solar collector, solar furnace", - "sombrero", - "soup bowl", - "space bar", - "space heater", - "space shuttle", - "spatula", - "speedboat", - "spider web, spider's web", - "spindle", - "sports car, sport car", - "spotlight, spot", - "stage", - "steam locomotive", - "steel arch bridge", - "steel drum", - "stethoscope", - "stole", - "stone wall", - "stopwatch, stop watch", - "stove", - "strainer", - "streetcar, tram, tramcar, trolley, trolley car", - "stretcher", - "studio couch, day bed", - "stupa, tope", - "submarine, pigboat, sub, U-boat", - "suit, suit of clothes", - "sundial", - "sunglass", - "sunglasses, dark glasses, shades", - "sunscreen, sunblock, sun blocker", - "suspension bridge", - "swab, swob, mop", - "sweatshirt", - "swimming trunks, bathing trunks", - "swing", - "switch, electric switch, electrical switch", - "syringe", - "table lamp", - "tank, army tank, armored combat vehicle, armoured combat vehicle", - "tape player", - "teapot", - "teddy, teddy bear", - "television, television system", - "tennis ball", - "thatch, thatched roof", - "theater curtain, theatre curtain", - "thimble", - "thresher, thrasher, threshing machine", - "throne", - "tile roof", - "toaster", - "tobacco shop, tobacconist shop, tobacconist", - "toilet seat", - "torch", - "totem pole", - "tow truck, tow car, wrecker", - "toyshop", - "tractor", - "trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi", - "tray", - "trench coat", - "tricycle, trike, velocipede", - "trimaran", - "tripod", - "triumphal arch", - "trolleybus, trolley coach, trackless trolley", - "trombone", - "tub, vat", - "turnstile", - "typewriter keyboard", - "umbrella", - "unicycle, monocycle", - "upright, upright piano", - "vacuum, vacuum cleaner", - "vase", - "vault", - "velvet", - "vending machine", - "vestment", - "viaduct", - "violin, fiddle", - "volleyball", - "waffle iron", - "wall clock", - "wallet, billfold, notecase, pocketbook", - "wardrobe, closet, press", - "warplane, military plane", - "washbasin, handbasin, washbowl, lavabo, wash-hand basin", - "washer, automatic washer, washing machine", - "water bottle", - "water jug", - "water tower", - "whiskey jug", - "whistle", - "wig", - "window screen", - "window shade", - "Windsor tie", - "wine bottle", - "wing", - "wok", - "wooden spoon", - "wool, woolen, woollen", - "worm fence, snake fence, snake-rail fence, Virginia fence", - "wreck", - "yawl", - "yurt", - "web site, website, internet site, site", - "comic book", - "crossword puzzle, crossword", - "street sign", - "traffic light, traffic signal, stoplight", - "book jacket, dust cover, dust jacket, dust wrapper", - "menu", - "plate", - "guacamole", - "consomme", - "hot pot, hotpot", - "trifle", - "ice cream, icecream", - "ice lolly, lolly, lollipop, popsicle", - "French loaf", - "bagel, beigel", - "pretzel", - "cheeseburger", - "hotdog, hot dog, red hot", - "mashed potato", - "head cabbage", - "broccoli", - "cauliflower", - "zucchini, courgette", - "spaghetti squash", - "acorn squash", - "butternut squash", - "cucumber, cuke", - "artichoke, globe artichoke", - "bell pepper", - "cardoon", - "mushroom", - "Granny Smith", - "strawberry", - "orange", - "lemon", - "fig", - "pineapple, ananas", - "banana", - "jackfruit, jak, jack", - "custard apple", - "pomegranate", - "hay", - "carbonara", - "chocolate sauce, chocolate syrup", - "dough", - "meat loaf, meatloaf", - "pizza, pizza pie", - "potpie", - "burrito", - "red wine", - "espresso", - "cup", - "eggnog", - "alp", - "bubble", - "cliff, drop, drop-off", - "coral reef", - "geyser", - "lakeside, lakeshore", - "promontory, headland, head, foreland", - "sandbar, sand bar", - "seashore, coast, seacoast, sea-coast", - "valley, vale", - "volcano", - "ballplayer, baseball player", - "groom, bridegroom", - "scuba diver", - "rapeseed", - "daisy", - "yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum", - "corn", - "acorn", - "hip, rose hip, rosehip", - "buckeye, horse chestnut, conker", - "coral fungus", - "agaric", - "gyromitra", - "stinkhorn, carrion fungus", - "earthstar", - "hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa", - "bolete", - "ear, spike, capitulum", - "toilet tissue, toilet paper, bathroom tissue" - }; - - const std::string getClassLabelText(int classIndex) { - return labels[classIndex]; - } - - int argmax(const float* tensor, int numberElements) { - float topConfidence = 0; - int topLabel = -1; - for (int i = 0; i < numberElements; i++) { - float confidence = tensor[i]; - if (topLabel == -1 || topConfidence < confidence) { - topLabel = i; - topConfidence = confidence; - } - } - return topLabel; - } - - void postprocess( - const int64_t* output_shape_conf, const void* voutputData_conf, const size_t bytesize_conf, const uint32_t dimCount_conf, - const int64_t* output_shape_boxes, const void* voutputData_boxes, const size_t bytesize_boxes, const uint32_t dimCount_boxes, - const int64_t* output_shape_classification, const void* voutputData_classification, const size_t bytesize_classification, const uint32_t dimCount_classification, - std::vector &detectedResults) - { - if (!voutputData_boxes || !voutputData_conf || !voutputData_classification) { - // nothing to do - return; - } - - if (dimCount_conf != 3 || dimCount_boxes != 3 || dimCount_classification != 3) - { - printf("Unknown yolov8 detection and/or efficientnet-b0 model.\n"); - return; - } - - // Output Info - // classify_output 1,1,1000 - // confidence - 1, 1, 1 - // boxes - 1,1,4 - const int numberOfDetections = output_shape_boxes[0]; - const int boxesSize = output_shape_boxes[2]; - const int* outData_boxes = reinterpret_cast(voutputData_boxes); - const float* outData_confidence = reinterpret_cast(voutputData_conf); - const float* outData_classify_labels = reinterpret_cast(voutputData_classification); - - std::vector input_shape = getModelInputShape(); - int network_h = input_shape[2]; - int network_w = input_shape[3]; - - for (int i = 0; i < numberOfDetections; i++) - { - float confidence = outData_confidence[i]; - - //printf("Confidence found: %f ClassID found: %i NetworkW %i NetworkH: %i BoxSize %i \n", confidence, classId, network_w, network_h, boxesSize); - - if (confidence > confidence_threshold ) { - int classId = argmax(outData_classify_labels, output_shape_classification[2]); - //printf("numberofTensors %li classId %i\n", output_shape_classification[2], classId); - DetectedResult obj; - obj.x = std::clamp( - static_cast((outData_boxes[i * boxesSize + 0] / ((float)network_w / (float)_video_input_width))), - 0, - _video_input_width); - obj.y = std::clamp( - static_cast((outData_boxes[i * boxesSize + 1] / ((float)network_h/(float)_video_input_height))), - 0, - _video_input_height); - obj.width = std::clamp( - static_cast((outData_boxes[i * boxesSize + 2] / ((float)network_w/(float)_video_input_width) )), - 0, - _video_input_width); - obj.height = std::clamp( - static_cast((outData_boxes[i * boxesSize + 3] / ((float)network_h/(float)_video_input_height) )), - 0, - _video_input_height); - obj.confidence = confidence; - obj.classId = (int) classId; - strncpy(obj.classText, getClassLabelText(obj.classId).c_str(), sizeof(obj.classText)); - - // printf("Actual found: %f %s...%i,%i,%i,%i vs. %i,%i,%i,%i...%ix%i \n", - // confidence, - // obj.classText, - // obj.x, - // obj.y, - // obj.width, - // obj.height, - // outData_boxes[i * boxesSize + 0], - // outData_boxes[i * boxesSize + 1], - // outData_boxes[i * boxesSize + 2], - // outData_boxes[i * boxesSize + 3], - // _video_input_width, - // _video_input_height); - - detectedResults.push_back(obj); - } // end if confidence - } // end for - } - -private: - // yolov8 - ?x3x416x416 NCHW - const char* MODEL_NAME = "detect_classify"; - const uint64_t MODEL_VERSION = 0; - const char* INPUT_NAME = "images"; -}; - -GStreamerMediaPipelineService* _mediaService = NULL; -std::string _user_request; - -namespace { -volatile sig_atomic_t shutdown_request = 0; -} - -bool stringIsInteger(std::string strInput) { - std::string::const_iterator it = strInput.begin(); - while (it != strInput.end() && std::isdigit(*it)) ++it; - return !strInput.empty() && it == strInput.end(); -} - -bool stringIsFloat(std::string strInput) { - std::istringstream iss(strInput); - float f; - iss >> std::noskipws >> f; // noskipws considers leading whitespace invalid - return iss.eof() && !iss.fail(); -} - -bool setActiveModel(int detectionType, ObjectDetectionInterface** objDet) -{ - if (objDet == NULL) - return false; - - *objDet = new Yolov8Ensemble(); - return true; -} - -static void onInterrupt(int status) { - shutdown_request = 1; -} - -static void onTerminate(int status) { - shutdown_request = 1; -} - -static void onIllegal(int status) { - shutdown_request = 2; -} - -static void installSignalHandlers() { - static struct sigaction sigIntHandler; - sigIntHandler.sa_handler = onInterrupt; - sigemptyset(&sigIntHandler.sa_mask); - sigIntHandler.sa_flags = 0; - sigaction(SIGINT, &sigIntHandler, NULL); - - static struct sigaction sigTermHandler; - sigTermHandler.sa_handler = onTerminate; - sigemptyset(&sigTermHandler.sa_mask); - sigTermHandler.sa_flags = 0; - sigaction(SIGTERM, &sigTermHandler, NULL); - - static struct sigaction sigIllHandler; - sigIllHandler.sa_handler = onIllegal; - sigemptyset(&sigIllHandler.sa_mask); - sigIllHandler.sa_flags = 0; - sigaction(SIGILL, &sigIllHandler, NULL); -} - -void printInferenceResults(std::vector &results) -{ - for (auto & obj : results) { - std::cout << "Rect: [ " << obj.x << " , " << obj.y << " " << obj.width << ", " << obj.height << "] Class: " << obj.classText << "(" << obj.classId << ") Conf: " << obj.confidence << std::endl; - } -} - -// TODO: Multiple references state that imshow can't be used in any other thread than main! -void displayGUIInferenceResults(cv::Mat analytics_frame, std::vector &results, int latency, int througput) -{ - auto ttid = std::this_thread::get_id(); - std::stringstream ss; - ss << ttid; - std::string tid = ss.str(); - - for (auto & obj : results) { - const float x0 = obj.x; - const float y0 = obj.y; - const float x1 = obj.x + obj.width; - const float y1 = obj.y + obj.height; - - //printf("--------->coords: %f %f %f %f\n", x0, y0, x1, y1); - cv::rectangle( analytics_frame, - cv::Point( (int)(x0),(int)(y0) ), - cv::Point( (int)x1, (int)y1 ), - cv::Scalar(255, 0, 0), - 2, cv::LINE_8 ); - - cv::Size textsize = cv::getTextSize(obj.classText, cv::FONT_HERSHEY_PLAIN, 1, 0,0); - - cv::rectangle(analytics_frame, - cv::Point( (int)(x0),(int)(y0-20) ), - cv::Point((int)x0 + textsize.width, (int)y0 + textsize.height), - CV_RGB(0, 0, 0), - -1); - - std::string putText = obj.classText; - putText += " " + std::to_string(obj.confidence); - cv::putText(analytics_frame, - obj.classText, - cv::Size((int)x0, (int)y0), - cv::FONT_HERSHEY_PLAIN, 1, CV_RGB(255, 255, 255), 1); - - } // end for - - cv::Mat presenter; - { - std::lock_guard lock(_drawingMtx); - cv::cvtColor(analytics_frame, analytics_frame, cv::COLOR_BGR2RGB); - cv::imshow("OpenVINO Results " + tid, analytics_frame); - cv::waitKey(1); - } -} - - -// This function is responsible for generating a GST pipeline that -// decodes and resizes the video stream based on the desired window size or -// the largest analytics frame size needed if running headless -std::string getVideoPipelineText(std::string mediaPath, ObjectDetectionInterface* objDet, ObjectDetectionInterface* textDet) -{ - - std::vector modelFrameShape = objDet->getModelInputShape(); - if (textDet) { - modelFrameShape = textDet->getModelInputShape(); - } - - int frame_width = modelFrameShape[3]; - int frame_height = modelFrameShape[2]; - - if (_render) - { - frame_width = _window_width; - frame_height = _window_height; - } - - return _mediaService->getVideoDecodedPreProcessedPipeline( - mediaPath, - _videoType, - frame_width, - frame_height, - _use_onevpl); -} - -bool createModelServer() -{ - if (_srv == NULL) - return false; - - OVMS_Status* res = OVMS_ServerStartFromConfigurationFile(_srv, _serverSettings, _modelsSettings); - - if (res) { - uint32_t code = 0; - const char* details = nullptr; - - OVMS_StatusCode(res, &code); - OVMS_StatusDetails(res, &details); - std::cerr << "ERROR: during start: code:" << code << "; details:" << details - << "; grpc_port: " << _server_grpc_port - << "; http_port: " << _server_http_port - << ";" << std::endl; - - OVMS_StatusDelete(res); - - if (_srv) - OVMS_ServerDelete(_srv); - - if (_modelsSettings) - OVMS_ModelsSettingsDelete(_modelsSettings); - - if (_serverSettings) - OVMS_ServerSettingsDelete(_serverSettings); - - return false; - } - - return true; -} - -bool loadGStreamer(GstElement** pipeline, GstElement** appsink, std::string mediaPath, ObjectDetectionInterface* _objDet) -{ - static int threadCnt = 0; - - std::string videoPipelineText = getVideoPipelineText(mediaPath, _objDet, NULL); - std::cout << "--------------------------------------------------------------" << std::endl; - std::cout << "Opening Media Pipeline: " << videoPipelineText << std::endl; - std::cout << "--------------------------------------------------------------" << std::endl; - - *pipeline = gst_parse_launch (videoPipelineText.c_str(), NULL); - if (*pipeline == NULL) { - std::cout << "ERROR: Failed to parse GST pipeline. Quitting." << std::endl; - return false; - } - - std::string appsinkName = "appsink" + std::to_string(threadCnt++); - - *appsink = gst_bin_get_by_name (GST_BIN (*pipeline), appsinkName.c_str()); - - // Check if all elements were created - if (!(*appsink)) - { - printf("ERROR: Failed to initialize GST pipeline (missing %s) Quitting.\n", appsinkName.c_str()); - return false; - } - - GstStateChangeReturn gst_res; - - // Start pipeline so it could process incoming data - gst_res = gst_element_set_state(*pipeline, GST_STATE_PLAYING); - - if (gst_res != GST_STATE_CHANGE_SUCCESS && gst_res != GST_STATE_CHANGE_ASYNC ) { - printf("ERROR: StateChange not successful. Error Code: %d\n", gst_res); - return false; - } - - return true; -} - -// OVMS C-API is a global process (singleton design) wide server so can't create many of them -bool loadOVMS() -{ - OVMS_Status* res = NULL; - - OVMS_ServerSettingsNew(&_serverSettings); - OVMS_ModelsSettingsNew(&_modelsSettings); - OVMS_ServerNew(&_srv); - OVMS_ServerSettingsSetGrpcPort(_serverSettings, _server_grpc_port); - OVMS_ServerSettingsSetRestPort(_serverSettings, _server_http_port); - OVMS_ServerSettingsSetLogLevel(_serverSettings, OVMS_LOG_INFO); - - char * ovmsCofigJsonFilePath = std::getenv("OVMS_MODEL_CONFIG_JSON"); - std::cout << "ovmsCofigJsonFilePath: "< channels; - cv::split(src, channels); - - for (auto &img : channels) { - img = img.reshape(1, 1); - } - - // Concatenate three vectors to one - cv::hconcat( channels, dst ); - -} - -void run_stream(std::string mediaPath, GstElement* pipeline, GstElement* appsink, ObjectDetectionInterface* objDet) -{ - auto ttid = std::this_thread::get_id(); - std::stringstream ss; - ss << ttid; - std::string tid = ss.str(); - - // Wait for all decoder streams to init...otherwise causes a segfault when OVMS loads - // https://stackoverflow.com/questions/48271230/using-condition-variablenotify-all-to-notify-multiple-threads - std::unique_lock lk(_mtx); - _cvAllDecodersInitd.wait(lk, [] { return _allDecodersInitd;} ); - lk.unlock(); - - printf("Starting thread: %s\n", tid.c_str()) ; - - auto initTime = std::chrono::high_resolution_clock::now(); - unsigned long numberOfFrames = 0; - long long numberOfSkipFrames = 0; - int highest_latency_frame = 0; - int lowest_latency_frame = 9999; - int avg_latency_frame = 0; - int total_latency_frames = 0; - OVMS_Status* res = NULL; - - while (!shutdown_request) { - auto startTime = std::chrono::high_resolution_clock::now(); - - // classify_output - const void* voutputData1; - size_t bytesize1 = 0; - OVMS_DataType datatype1 = (OVMS_DataType)42; - const int64_t* shape1{nullptr}; - size_t dimCount1 = 0; - OVMS_BufferType bufferType1 = (OVMS_BufferType)42; - uint32_t deviceId1 = 42; - const char* outputName1{nullptr}; - - // confidence_levels - const void* voutputData2; - size_t bytesize2 = 0; - OVMS_DataType datatype2 = (OVMS_DataType)42; - const int64_t* shape2{nullptr}; - size_t dimCount2 = 0; - OVMS_BufferType bufferType2 = (OVMS_BufferType)42; - uint32_t deviceId2 = 42; - const char* outputName2{nullptr}; - - // roi_coordinates - const void* voutputData3; - size_t bytesize3 = 0; - OVMS_DataType datatype3 = (OVMS_DataType)42; - const int64_t* shape3{nullptr}; - size_t dimCount3 = 0; - OVMS_BufferType bufferType3 = (OVMS_BufferType)42; - uint32_t deviceId3 = 42; - const char* outputName3{nullptr}; - - // Common across getoutput API - uint32_t outputCount = 0; - uint32_t outputId; - - GstSample *sample; - GstStructure *s; - GstBuffer *buffer; - GstMapInfo m; - - std::vector detectedResults; - - auto metricStartTime = std::chrono::high_resolution_clock::now(); - if (gst_app_sink_is_eos(GST_APP_SINK(appsink))) { - std::cout << "INFO: EOS " << std::endl; - return; - } - auto metricEndTime = std::chrono::high_resolution_clock::now(); - auto metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Get appsink latency (ms): " << metricLatencyTime << endl; - - metricStartTime = std::chrono::high_resolution_clock::now(); - sample = gst_app_sink_try_pull_sample (GST_APP_SINK(appsink), 5 * GST_SECOND); - - if (sample == nullptr) { - std::cout << "ERROR: No sample found" << std::endl; - return; - } - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Pull sample latency (ms): " << metricLatencyTime << endl; - - GstCaps *caps; - caps = gst_sample_get_caps(sample); - - if (caps == nullptr) { - std::cout << "ERROR: No caps found for sample" << std::endl; - return; - } - - s = gst_caps_get_structure(caps, 0); - gst_structure_get_int(s, "width", &_video_input_width); - gst_structure_get_int(s, "height", &_video_input_height); - - metricStartTime = std::chrono::high_resolution_clock::now(); - buffer = gst_sample_get_buffer(sample); - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Get sample buffer latency (ms): " << metricLatencyTime << endl; - - metricStartTime = std::chrono::high_resolution_clock::now(); - gst_buffer_map(buffer, &m, GST_MAP_READ); - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Copy sample buffer latency (ms): " << metricLatencyTime << endl; - - if (m.size <= 0) { - std::cout << "ERROR: Invalid buffer size" << std::endl; - return; - } - - cv::Mat analytics_frame; - cv::Mat floatImage; - std::vector inputShape; - - inputShape = objDet->getModelInputShape(); - - metricStartTime = std::chrono::high_resolution_clock::now(); - cv::Mat img(_video_input_height, _video_input_width, CV_8UC3, (void *) m.data); - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Copy decoded frame to mat latency (ms): " << metricLatencyTime << endl; - - // When rendering is enabled then the input frame is resized to window size and not the needed model input size - if (_render) { - - if (dynamic_cast(objDet) != nullptr) - { - metricStartTime = std::chrono::high_resolution_clock::now(); - resize(img, analytics_frame, cv::Size(inputShape[2], inputShape[3]), 0, 0, cv::INTER_AREA /*cv::INTER_LINEAR*/); - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Resize decoded frame latency (ms): " << metricLatencyTime << endl; - } - else - { - printf("ERROR: Unknown model type\n"); - return; - } - metricStartTime = std::chrono::high_resolution_clock::now(); - analytics_frame.convertTo(analytics_frame, CV_32F); - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "DataType transform decoded frame latency (ms): " << metricLatencyTime << endl; - - metricStartTime = std::chrono::high_resolution_clock::now(); - hwc_to_chw(analytics_frame, floatImage); - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Layout transform decoded frame latency (ms): " << metricLatencyTime << endl; - } - else { - img.convertTo(analytics_frame, CV_32F); - hwc_to_chw(analytics_frame, floatImage); - } - - const int DATA_SIZE = floatImage.step[0] * floatImage.rows; - - OVMS_InferenceResponse* response = nullptr; - OVMS_InferenceRequest* request{nullptr}; - - // OD Inference - { - //std::lock_guard lock(_infMtx); - - metricStartTime = std::chrono::high_resolution_clock::now(); - - OVMS_InferenceRequestNew(&request, _srv, objDet->getModelName(), objDet->getModelVersion()); - - OVMS_InferenceRequestAddInput( - request, - objDet->getModelInputName(), - OVMS_DATATYPE_FP32, - objDet->model_input_shape, - objDet->getModelDimCount() - ); - - // run sync request - OVMS_InferenceRequestInputSetData( - request, - objDet->getModelInputName(), - reinterpret_cast(floatImage.data), - DATA_SIZE , - OVMS_BUFFERTYPE_CPU, - 0 - ); - - res = OVMS_Inference(_srv, request, &response); - - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - // std::cout << "Inference latency (ms): " << metricLatencyTime << std::endl; - - if (res != nullptr) { - //std::cout << "OVMS_Inference failed " << std::endl; - uint32_t code = 0; - const char* details = 0; - OVMS_StatusCode(res, &code); - OVMS_StatusDetails(res, &details); - - OVMS_StatusDelete(res); - if (request) - OVMS_InferenceRequestDelete(request); - - metricStartTime = std::chrono::high_resolution_clock::now(); - - gst_buffer_unmap(buffer, &m); - gst_sample_unref(sample); - - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Decoded frame release latency (ms): " << metricLatencyTime << endl; - - if (code != 177 /*OVMS_Status::PIPELINE_DEMULTIPLEXER_NO_RESULTS */) - { - std::cout << "Error occured during inference. Code:" << code << std::endl; - //std::cout << "Details: " << details << std::endl; - break; - } - else - continue; - } - } // end lock on inference request to server - - metricStartTime = std::chrono::high_resolution_clock::now(); - OVMS_InferenceResponseOutputCount(response, &outputCount); - outputId = 0; - - // anchor free yolov8 results - OVMS_InferenceResponseOutput(response, outputId, &outputName1, &datatype1, &shape1, &dimCount1, &voutputData1, &bytesize1, &bufferType1, &deviceId1); - // std::cout << "------------>" << tid << " : " << "DeviceID " << deviceId1 - // << ", OutputName " << outputName1 - // << ", DimCount " << dimCount1 - // << ", shape " << shape1[0] << " " << shape1[1] << " " << shape1[2] - // << ", byteSize " << bytesize1 - // << ", OutputCount " << outputCount << std::endl; - - // roi_coordinates - outputId = 1; - OVMS_InferenceResponseOutput(response, outputId, &outputName2, &datatype2, &shape2, &dimCount2, &voutputData2, &bytesize2, &bufferType2, &deviceId2); - // std::cout << "------------>" << tid << " : " << "DeviceID " << deviceId1 - // << ", OutputName " << outputName2 - // << ", DimCount " << dimCount2 - // << ", shape " << shape2[0] << " " << shape2[1] << " " << shape2[2] - // << ", byteSize " << bytesize2 - // << ", OutputCount " << outputCount << std::endl; - - // classify_output e.g. Classification results - outputId = 2; - OVMS_InferenceResponseOutput(response, outputId, &outputName3, &datatype3, &shape3, &dimCount3, &voutputData3, &bytesize3, &bufferType3, &deviceId3); - // std::cout << "------------>" << tid << " : " << "DeviceID " << deviceId1 - // << ", OutputName " << outputName3 - // << ", DimCount " << dimCount3 - // << ", shape " << shape3[0] << " " << shape3[1] << " " << shape3[2] - // << ", byteSize " << bytesize3 - // << ", OutputCount " << outputCount << std::endl; - - // roi_images dims == 5 batch, 1, c, h, w - - objDet->postprocess( - shape1, voutputData1, bytesize1, dimCount1, - shape2, voutputData2, bytesize2, dimCount2, - shape3, voutputData3, bytesize3, dimCount3, - detectedResults); - //objDet->postprocess(detectedResults, detectedResultsFiltered); - - metricEndTime = std::chrono::high_resolution_clock::now(); - metricLatencyTime = ((std::chrono::duration_cast(metricEndTime-metricStartTime)).count()); - //cout << "Post-processing latency (ms): " << metricLatencyTime << endl; - - numberOfSkipFrames++; - float fps = 0; - int skip_frames = 120; - if (numberOfSkipFrames <= skip_frames) // allow warm up for latency/fps measurements - { - initTime = std::chrono::high_resolution_clock::now(); - //printf("Too early...Skipping frames..\n"); - } - else - { - numberOfFrames++; - - auto endTime = std::chrono::high_resolution_clock::now(); - auto latencyTime = ((std::chrono::duration_cast(endTime-startTime)).count()); - auto runningLatencyTime = ((std::chrono::duration_cast(endTime-initTime)).count()); - if (runningLatencyTime > 0) { // skip a few to account for init - fps = (float)numberOfFrames/(float)(runningLatencyTime/1000); // convert to seconds - } - - if (_render) - displayGUIInferenceResults(img, detectedResults, latencyTime, fps); - - int frame_latency = chrono::duration_cast(endTime - startTime).count(); - - if (frame_latency > highest_latency_frame) - highest_latency_frame = frame_latency; - if (frame_latency < lowest_latency_frame) - lowest_latency_frame = frame_latency; - - total_latency_frames += frame_latency; - - if (numberOfFrames % 30 == 0) { - avg_latency_frame = total_latency_frames / 30; - - time_t currTime = time(0); - struct tm tstruct; - char bCurrTime[80]; - tstruct = *localtime(&currTime); - - strftime(bCurrTime, sizeof(bCurrTime), "%Y-%m-%d.%X", &tstruct); - - cout << detectedResults.size() << " object(s) detected at " << bCurrTime << endl; - cout << "Avg. Pipeline Throughput FPS: " << ((isinf(fps)) ? "..." : std::to_string(fps)) << endl; - cout << "Avg. Pipeline Latency (ms): " << avg_latency_frame << endl; - cout << "Max. Pipeline Latency (ms): " << highest_latency_frame << endl; - cout << "Min. Pipeline Latency (ms): " << lowest_latency_frame << endl; - highest_latency_frame = 0; - lowest_latency_frame = 9999; - total_latency_frames = 0; - } - } - - if (request) { - OVMS_InferenceRequestInputRemoveData(request, objDet->getModelInputName()); // doesn't help - OVMS_InferenceRequestRemoveInput(request, objDet->getModelInputName()); - OVMS_InferenceRequestDelete(request); - } - - if (response) { - OVMS_InferenceResponseDelete(response); - } - - gst_buffer_unmap(buffer, &m); - gst_sample_unref(sample); - - // DEBUG: TODO - //shutdown_request = 1; - - if (shutdown_request > 0) - break; - } // end while get frames - - std::cout << "Goodbye..." << std::endl; - - if (res != NULL) { - OVMS_StatusDelete(res); - res = NULL; - } - - if (objDet) { - delete objDet; - objDet = NULL; - } - - gst_element_set_state (pipeline, GST_STATE_NULL); - if (pipeline) - gst_object_unref(pipeline); - - if (appsink) - gst_object_unref(appsink); -} - -void print_usage(const char* programName) { - std::cout << "Usage: " << programName << " \n\n" - << "\tmedia 1 location: an rtsp://127.0.0.1:8554/camera_0 url or a path to a *.mp4 file\n" - << "\tuse_onevpl: 0 (libva) or 1 for oneVPL\n" - << "\trender mode: 0 for headless or 1 to launch a render window \n" - << "\trender portrait mode: 0 for headless or 1 to launch a render window \n" - << "\tvideo_type for media 1: 0 for HEVC or 1 for AVC\n" - << "\twindow_width is display window width\n" - << "\twindow_height is display window height\n" - << "\tdetection_threshold is confidence threshold value in floating point that needs to be between 0.0 to 1.0\n"; -} - -int get_running_model_servers() { - const char * val = std::getenv("cid_count"); - std::cout << "val: "< 1.0 || _detection_threshold < 0.0) { - std::cout << "detection_threshold: " << _detection_threshold << ", is confidence threshold value in floating point that needs to be between 0.0 to 1.0.\n" << endl; - return 1; - } - - // Swap width/height to enable portrait mode - if (_renderPortrait) { - int tmp = _window_width; - _window_width = _window_height; - _window_height = tmp; - } - } - - // Use GST pipelines for media HWA decode and pre-procesing - _mediaService = new GStreamerMediaPipelineService(); - - // get valid server port numbers - int running_servers = get_running_model_servers(); - _server_grpc_port = 9178 + running_servers; - _server_http_port = 11338 + running_servers; - - gst_init(NULL, NULL); - - std::vector running_streams; - _allDecodersInitd = false; - - GstElement *pipeline; - GstElement *appsink; - ObjectDetectionInterface* objDet; - getMAPipeline(_videoStreamPipeline, &pipeline, &appsink, &objDet); - running_streams.emplace_back(run_stream, _videoStreamPipeline, pipeline, appsink, objDet); - - GstElement *pipeline2; - GstElement *appsink2; - ObjectDetectionInterface* objDet2; - if (!_videoStreamPipeline2.empty()) - { - std::cout << "in the 2nd inputsrc..." << std::endl; - - getMAPipeline(_videoStreamPipeline2, &pipeline2, &appsink2, &objDet2); - running_streams.emplace_back(run_stream, _videoStreamPipeline2, pipeline2, appsink2, objDet2); - } - - if (!loadOVMS()) - return -1; - - // give some time for OVMS server being ready - sleep(10); - - _allDecodersInitd = true; - _cvAllDecodersInitd.notify_all();; - - for(auto& running_stream : running_streams) - running_stream.join(); - - if (_mediaService != NULL) { - delete _mediaService; - _mediaService = NULL; - } - - if (_srv) - OVMS_ServerDelete(_srv); - if (_modelsSettings) - OVMS_ModelsSettingsDelete(_modelsSettings); - if (_serverSettings) - OVMS_ServerSettingsDelete(_serverSettings); - - return 0; -} diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/opencv_utils.hpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/opencv_utils.hpp deleted file mode 100644 index 059bac79..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/opencv_utils.hpp +++ /dev/null @@ -1,163 +0,0 @@ -//***************************************************************************** -// Copyright 2024 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#pragma once - -#include - -#include "custom_node_interface.h" -#include "opencv2/opencv.hpp" - -template -void reorder_to_nhwc_2(const T* sourceNchwBuffer, T* destNhwcBuffer, int rows, int cols, int channels) { - for (int y = 0; y < rows; ++y) { - for (int x = 0; x < cols; ++x) { - for (int c = 0; c < channels; ++c) { - destNhwcBuffer[y * channels * cols + x * channels + c] = reinterpret_cast(sourceNchwBuffer)[c * (rows * cols) + y * cols + x]; - } - } - } -} - -template -std::vector reorder_to_nhwc(const T* nchwVector, int rows, int cols, int channels) { - std::vector nhwcVector(rows * cols * channels); - reorder_to_nhwc_2(nchwVector, nhwcVector.data(), rows, cols, channels); - return nhwcVector; -} - -template -void reorder_to_nchw_2(const T* sourceNhwcBuffer, T* destNchwBuffer, int rows, int cols, int channels) { - for (int y = 0; y < rows; ++y) { - for (int x = 0; x < cols; ++x) { - for (int c = 0; c < channels; ++c) { - destNchwBuffer[c * (rows * cols) + y * cols + x] = reinterpret_cast(sourceNhwcBuffer)[y * channels * cols + x * channels + c]; - } - } - } -} - -template -std::vector reorder_to_nchw(const T* nhwcVector, int rows, int cols, int channels) { - std::vector nchwVector(rows * cols * channels); - reorder_to_nchw_2(nhwcVector, nchwVector.data(), rows, cols, channels); - return nchwVector; -} - -const cv::Mat nhwc_to_mat(const CustomNodeTensor* input) { - uint64_t height = input->dims[1]; - uint64_t width = input->dims[2]; - return cv::Mat(height, width, CV_32FC3, input->data); -} - -const cv::Mat nchw_to_mat(const CustomNodeTensor* input) { - uint64_t channels = input->dims[1]; - uint64_t rows = input->dims[2]; - uint64_t cols = input->dims[3]; - auto nhwcVector = reorder_to_nhwc((float*)input->data, rows, cols, channels); - - cv::Mat image(rows, cols, CV_32FC3); - std::memcpy(image.data, nhwcVector.data(), nhwcVector.size() * sizeof(float)); - return image; -} - -bool crop_rotate_resize(cv::Mat originalImage, cv::Mat& targetImage, cv::Rect roi, float angle, float originalTextWidth, float originalTextHeight, cv::Size targetShape) { - try { - // Limit roi to be in range of original image. - // Face detection detections may go beyond original image. - roi.x = roi.x < 0 ? 0 : roi.x; - roi.y = roi.y < 0 ? 0 : roi.y; - roi.width = roi.width + roi.x > originalImage.size().width ? originalImage.size().width - roi.x : roi.width; - roi.height = roi.height + roi.y > originalImage.size().height ? originalImage.size().height - roi.y : roi.height; - cv::Mat cropped = originalImage(roi); - - cv::Mat rotated; - if (angle != 0.0) { - cv::Mat rotationMatrix = cv::getRotationMatrix2D(cv::Point2f(cropped.size().width / 2, cropped.size().height / 2), angle, 1.0); - cv::warpAffine(cropped, rotated, rotationMatrix, cropped.size()); - } else { - rotated = cropped; - } - cv::Mat rotatedSlicedImage; - if (angle != 0.0) { - int sliceOffset = (rotated.size().height - originalTextHeight) / 2; - rotatedSlicedImage = rotated(cv::Rect(0, sliceOffset, rotated.size().width, originalTextHeight)); - } else { - rotatedSlicedImage = rotated; - } - cv::resize(rotatedSlicedImage, targetImage, targetShape); - } catch (const cv::Exception& e) { - std::cout << e.what() << std::endl; - return false; - } - return true; -} - -cv::Mat apply_grayscale(cv::Mat image) { - cv::Mat grayscaled; - cv::cvtColor(image, grayscaled, cv::COLOR_BGR2GRAY); - return grayscaled; -} - -bool scale_image( - bool isScaleDefined, - const float scale, - const std::vector& meanValues, - const std::vector& scaleValues, - cv::Mat& image) { - if (!isScaleDefined && scaleValues.size() == 0 && meanValues.size() == 0) { - return true; - } - - size_t colorChannels = static_cast(image.channels()); - if (meanValues.size() > 0 && meanValues.size() != colorChannels) { - return false; - } - if (scaleValues.size() > 0 && scaleValues.size() != colorChannels) { - return false; - } - - std::vector channels; - if (meanValues.size() > 0 || scaleValues.size() > 0) { - cv::split(image, channels); - if (channels.size() != colorChannels) { - return false; - } - } else { - channels.emplace_back(image); - } - - for (size_t i = 0; i < meanValues.size(); i++) { - channels[i] -= meanValues[i]; - } - - if (scaleValues.size() > 0) { - for (size_t i = 0; i < channels.size(); i++) { - channels[i] /= scaleValues[i]; - } - } else if (isScaleDefined) { - for (size_t i = 0; i < channels.size(); i++) { - channels[i] /= scale; - } - } - - if (channels.size() == 1) { - image = channels[0]; - } else { - cv::merge(channels, image); - } - - return true; -} diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/queue.hpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/queue.hpp deleted file mode 100644 index 73e3daa2..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/queue.hpp +++ /dev/null @@ -1,139 +0,0 @@ -//***************************************************************************** -// Copyright 2024 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// #include "profiler.hpp" - -namespace ovms { - -template -class Queue { -public: - /** - * @brief Allocating idle stream for execution - */ - std::future getIdleStream() { - // OVMS_PROFILE_FUNCTION(); - int value; - std::promise idleStreamPromise; - std::future idleStreamFuture = idleStreamPromise.get_future(); - std::unique_lock lk(front_mut); - if (streams[front_idx] < 0) { // we need to wait for any idle stream to be returned - std::unique_lock queueLock(queue_mutex); - promises.push(std::move(idleStreamPromise)); - } else { // we can give idle stream right away - value = streams[front_idx]; - streams[front_idx] = -1; // negative value indicate consumed vector index - front_idx = (front_idx + 1) % streams.size(); - lk.unlock(); - idleStreamPromise.set_value(value); - } - return idleStreamFuture; - } - - std::optional tryToGetIdleStream() { - // OVMS_PROFILE_FUNCTION(); - int value; - std::unique_lock lk(front_mut); - if (streams[front_idx] < 0) { // we need to wait for any idle stream to be returned - return std::nullopt; - } else { // we can give idle stream right away - value = streams[front_idx]; - streams[front_idx] = -1; // negative value indicate consumed vector index - front_idx = (front_idx + 1) % streams.size(); - lk.unlock(); - return value; - } - } - - /** - * @brief Release stream after execution - */ - void returnStream(int streamID) { - // OVMS_PROFILE_FUNCTION(); - std::unique_lock lk(queue_mutex); - if (promises.size()) { - std::promise promise = std::move(promises.front()); - promises.pop(); - lk.unlock(); - promise.set_value(streamID); - return; - } - std::uint32_t old_back = back_idx.load(); - while (!back_idx.compare_exchange_weak( - old_back, - (old_back + 1) % streams.size(), - std::memory_order_relaxed)) { - } - streams[old_back] = streamID; - } - - /** - * @brief Constructor with initialization - */ - Queue(int streamsLength) : - streams(streamsLength), - front_idx{0}, - back_idx{0} { - for (int i = 0; i < streamsLength; ++i) { - streams[i] = i; - } - } - - /** - * @brief Give InferRequest - */ - T& getInferRequest(int streamID) { - return inferRequests[streamID]; - } - -protected: - /** - * @brief Vector representing circular buffer for infer queue - */ - std::vector streams; - - /** - * @brief Index of the front of the idle streams list - */ - std::uint32_t front_idx; - - /** - * @brief Index of the back of the idle streams list - */ - std::atomic back_idx; - - /** - * @brief Vector representing OV streams and used for notification about completed inference operations - */ - std::mutex front_mut; - std::mutex queue_mutex; - - std::vector inferRequests; - std::queue> promises; -}; -} // namespace ovms diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/utils.hpp b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/utils.hpp deleted file mode 100644 index e866ed83..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/utils.hpp +++ /dev/null @@ -1,145 +0,0 @@ -//***************************************************************************** -// Copyright 2024 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#pragma once - -#include -#include -#include -#include -#include - -#include "custom_node_interface.h" - -#define NODE_ASSERT(cond, msg) \ - if (!(cond)) { \ - std::cout << "[" << __LINE__ << "] Assert: " << msg << std::endl; \ - return 1; \ - } - -#define NODE_EXPECT(cond, msg) \ - if (!(cond)) { \ - std::cout << "[" << __LINE__ << "] Assert: " << msg << std::endl; \ - } - -int get_int_parameter(const std::string& name, const struct CustomNodeParam* params, int paramsCount, int defaultValue = 0) { - for (int i = 0; i < paramsCount; i++) { - if (name == params[i].key) { - try { - return std::stoi(params[i].value); - } catch (std::invalid_argument& e) { - return defaultValue; - } catch (std::out_of_range& e) { - return defaultValue; - } - } - } - return defaultValue; -} - -float get_float_parameter(const std::string& name, const struct CustomNodeParam* params, int paramsCount, float defaultValue = 0.0f) { - for (int i = 0; i < paramsCount; i++) { - if (name == params[i].key) { - try { - return std::stof(params[i].value); - } catch (std::invalid_argument& e) { - return defaultValue; - } catch (std::out_of_range& e) { - return defaultValue; - } - } - } - return defaultValue; -} - -float get_float_parameter(const std::string& name, const struct CustomNodeParam* params, int paramsCount, bool& isDefined, float defaultValue = 0.0f) { - isDefined = true; - for (int i = 0; i < paramsCount; i++) { - if (name == params[i].key) { - try { - return std::stof(params[i].value); - } catch (std::invalid_argument& e) { - isDefined = false; - return defaultValue; - } catch (std::out_of_range& e) { - isDefined = false; - return defaultValue; - } - } - } - isDefined = false; - return defaultValue; -} - -std::string get_string_parameter(const std::string& name, const struct CustomNodeParam* params, int paramsCount, const std::string& defaultValue = "") { - for (int i = 0; i < paramsCount; i++) { - if (name == params[i].key) { - return params[i].value; - } - } - return defaultValue; -} - -std::vector get_float_list_parameter(const std::string& name, const struct CustomNodeParam* params, int paramsCount) { - std::string listStr; - for (int i = 0; i < paramsCount; i++) { - if (name == params[i].key) { - listStr = params[i].value; - break; - } - } - - if (listStr.length() < 2 || listStr.front() != '[' || listStr.back() != ']') { - return {}; - } - - listStr = listStr.substr(1, listStr.size() - 2); - - std::vector result; - - std::stringstream lineStream(listStr); - std::string element; - while (std::getline(lineStream, element, ',')) { - try { - float e = std::stof(element.c_str()); - result.push_back(e); - } catch (std::invalid_argument& e) { - NODE_EXPECT(false, "error parsing list parameter"); - return {}; - } catch (std::out_of_range& e) { - NODE_EXPECT(false, "error parsing list parameter"); - return {}; - } - } - - return result; -} - -std::string floatListToString(const std::vector& values) { - std::stringstream ss; - ss << "["; - for (size_t i = 0; i < values.size(); ++i) { - if (i != 0) - ss << ","; - ss << values[i]; - } - ss << "]"; - return ss.str(); -} - -void cleanup(CustomNodeTensor& tensor) { - free(tensor.data); - free(tensor.dims); -} diff --git a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/yolo_efficientnet.sh b/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/yolo_efficientnet.sh deleted file mode 100755 index 1d9eab40..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/capi_yolov8_ensemble/yolo_efficientnet.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2024 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -cid_count=0 - - - -# User configured parameters -if [ -z "$INPUT_TYPE" ] -then - echo "INPUT_TYPE is required" - exit 1 - #INPUT_TYPE="FILE_H264" - #INPUT_TYPE="RTSP_H265" -fi - -if [ -z "$INPUTSRC" ] -then - echo "INPUTSRC is required" - exit 1 - #INPUTSRC="sample-video.mp4" - #INPUTSRC="rtsp://127.0.0.1:8554/camera_0" -fi - -CODEC_TYPE=0 -if [ "$INPUT_TYPE" == "FILE_H264" ] || [ "$INPUT_TYPE" == "RTSP_H264" ] -then - CODEC_TYPE=1 -elif [ "$INPUT_TYPE" == "FILE_H265" ] || [ "$INPUT_TYPE" == "RTSP_H265" ] -then - CODEC_TYPE=0 -fi - -if [ -z "$USE_VPL" ] -then - USE_VPL=0 -fi - -if [ -z "$RENDER_MODE" ] -then - RENDER_MODE=0 -fi - -if [ -z "$RENDER_PORTRAIT_MODE" ] -then - RENDER_PORTRAIT_MODE=0 -fi - -# DEBUGGING prints: -env -ls -al /tmp/ - -# Direct console output -if [ "$DC" != 1 ] -then - cid_count=0 /app/gst-ovms/pipelines/yolov8_ensemble/capi_yolov8_ensemble $INPUTSRC $USE_VPL $RENDER_MODE $RENDER_PORTRAIT_MODE $CODEC_TYPE $WINDOW_WIDTH $WINDOW_HEIGHT $DETECTION_THRESHOLD 2>&1 | tee >/tmp/results/r$cid_count.jsonl >(stdbuf -oL sed -n -e 's/^.*FPS: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid_count.log) -else - cid_count=0 /app/gst-ovms/pipelines/yolov8_ensemble/capi_yolov8_ensemble $INPUTSRC $USE_VPL $RENDER_MODE $RENDER_PORTRAIT_MODE $CODEC_TYPE $WINDOW_WIDTH $WINDOW_HEIGHT $DETECTION_THRESHOLD -fi \ No newline at end of file diff --git a/configs/opencv-ovms/gst_capi/pipelines/face_detection/Makefile b/configs/opencv-ovms/gst_capi/pipelines/face_detection/Makefile deleted file mode 100644 index bf7c8408..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/face_detection/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (c) 2023 Intel Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -.PHONY: build - -CV_LIBS = -L/usr/lib/x86_64-linux-gnu/ -L/usr/local/lib/x86_64-linux-gnu/ -L/ovms/lib/ -CV_INCLUDES = -I/usr/lib/include/opencv4 - -build: - g++ main.cpp -I/usr/include/gstreamer-1.0/usr/lib/x86_64-linux-gnu/ -I/usr/local/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gstreamer-1.0/ -I/ovms/include $(CV_INCLUDES) $(CV_LIBS) -L/usr/lib/x86_64-linux-gnu/gstreamer-1.0 -lgstbase-1.0 -lgobject-2.0 -lglib-2.0 -lgstreamer-1.0 -lgstapp-1.0 -lopencv_imgcodecs -lopencv_imgproc -lopencv_videoio -lopencv_core -lopencv_videoio_gstreamer -lovms_shared -lopencv_highgui -lpthread -fPIC --std=c++17 -o face_detection - diff --git a/configs/opencv-ovms/gst_capi/pipelines/face_detection/main.cpp b/configs/opencv-ovms/gst_capi/pipelines/face_detection/main.cpp deleted file mode 100644 index d12368b0..00000000 --- a/configs/opencv-ovms/gst_capi/pipelines/face_detection/main.cpp +++ /dev/null @@ -1,1009 +0,0 @@ -//***************************************************************************** -// Copyright 2023 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//***************************************************************************** -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -// Utilized for GStramer hardware accelerated decode and pre-preprocessing -#include -#include -#include - -// Utilized for OpenCV based Rendering only -#include -#include -#include -#include - -// Utilized for infernece output layer post-processing -#include - -#include "ovms.h" // NOLINT - -using namespace std; -using namespace cv; - -std::mutex _mtx; -std::mutex _infMtx; -std::mutex _drawingMtx; -std::condition_variable _cvAllDecodersInitd; -bool _allDecodersInitd = false; - -typedef struct DetectedResult { - int frameId; - int x; - int y; - int width; - int height; - float confidence; - int classId; - char classText[1024]; -} DetectedResult; - -class MediaPipelineServiceInterface { -public: - enum VIDEO_TYPE { - H265, - H264 - }; - - virtual ~MediaPipelineServiceInterface() {} - virtual const std::string getVideoDecodedPreProcessedPipeline(std::string mediaLocation, VIDEO_TYPE videoType, int video_width, int video_height, bool use_onevpl) = 0; - virtual const std::string getBroadcastPipeline() = 0; - virtual const std::string getRecordingPipeline() = 0; - - const std::string updateVideoDecodedPreProcessedPipeline(int video_width, int video_height, bool use_onevpl) - { - return getVideoDecodedPreProcessedPipeline(m_mediaLocation, m_videoType, video_width, video_height, use_onevpl); - } - -protected: - std::string m_mediaLocation; - VIDEO_TYPE m_videoType; - int m_videoWidth; - int m_videoHeight; -}; - -OVMS_Server* _srv; -OVMS_ServerSettings* _serverSettings = 0; -OVMS_ModelsSettings* _modelsSettings = 0; -int _server_grpc_port; -int _server_http_port; - -std::string _videoStreamPipeline; -MediaPipelineServiceInterface::VIDEO_TYPE _videoType = MediaPipelineServiceInterface::VIDEO_TYPE::H264; -int _detectorModel = 0; -bool _render = 0; -bool _use_onevpl = 0; -bool _renderPortrait = 0; -cv::Mat _presentationImg; -int _video_input_width = 0; // Get from media _img -int _video_input_height = 0; // Get from media _img -std::vector _vidcaps; -int _window_width = 1920; -int _window_height = 1080; -float _detection_threshold = 0.5; - -class GStreamerMediaPipelineService : public MediaPipelineServiceInterface { -public: - const std::string getVideoDecodedPreProcessedPipeline(std::string mediaLocation, VIDEO_TYPE videoType, int video_width, int video_height, bool use_onevpl) { - m_mediaLocation = mediaLocation; - m_videoType = videoType; - m_videoWidth = video_width; - m_videoHeight = video_height; - - if (mediaLocation.find("rtsp") != std::string::npos ) { - // video/x-raw(memory:VASurface),format=NV12 - switch (videoType) - { - case H264: - if (use_onevpl) - return "rtspsrc location=" + mediaLocation + " ! rtph264depay ! h264parse ! " + - "msdkh264dec ! msdkvpp scaling-mode=lowpower ! " + - "video/x-raw, width=" + std::to_string(video_width) + - ", height=" + std::to_string(video_height) + " ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - else - return "rtspsrc location=" + mediaLocation + " ! rtph264depay ! vaapidecodebin ! video/x-raw(memory:VASurface),format=NV12 ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - case H265: - if (use_onevpl) - return "rtspsrc location=" + mediaLocation + " ! rtph265depay ! h265parse ! " + - "msdkh265dec ! " + - "msdkvpp scaling-mode=lowpower ! " + - "video/x-raw, width=" + std::to_string(video_width) + - ", height=" + std::to_string(video_height) + " ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - else - return "rtspsrc location=" + mediaLocation + " ! rtph265depay ! vaapidecodebin ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=BGR ! appsink sync=0 drop=1"; - default: - std::cout << "Video type not supported!" << std::endl; - return ""; - } - } - else if (mediaLocation.find(".mp4") != std::string::npos ) { - switch (videoType) - { - case H264: - if (use_onevpl) - return "filesrc location=" + mediaLocation + " ! qtdemux ! h264parse ! " + - "msdkh264dec ! msdkvpp scaling-mode=lowpower ! " + - "video/x-raw, width=" + std::to_string(video_width) + ", height=" + std::to_string(video_height) + - " ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - else - return "filesrc location=" + mediaLocation + " ! qtdemux ! h264parse ! vaapidecodebin ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1"; - case H265: - if (use_onevpl) - return "filesrc location=" + mediaLocation + " ! qtdemux ! h265parse ! " + - "msdkh265dec ! msdkvpp scaling-mode=lowpower ! " + - " video/x-raw, width=" + std::to_string(video_width) + ", height=" + std::to_string(video_height) + - " ! videoconvert ! video/x-raw,format=BGR ! queue ! appsink drop=1 sync=0"; - else - return "filesrc location=" + mediaLocation + " ! qtdemux ! h265parse ! vaapidecodebin ! vaapipostproc" + - " width=" + std::to_string(video_width) + - " height=" + std::to_string(video_height) + - " scale-method=fast ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1"; - default: - std::cout << "Video type not supported!" << std::endl; - return ""; - } - } - else { - std::cout << "Unknown media source specified " << mediaLocation << " !!" << std::endl; - return ""; - } - } - - const std::string getBroadcastPipeline() { - // TODO: Not implemented - return "videotestsrc ! videoconvert,format=BGR ! video/x-raw ! appsink drop=1"; - } - - const std::string getRecordingPipeline() { - // TODO: Not implemented - return "videotestsrc ! videoconvert,format=BGR ! video/x-raw ! appsink drop=1"; - } -protected: - -}; - -class ObjectDetectionInterface { -public: - const static size_t MODEL_DIM_COUNT = 4; - int64_t model_input_shape[MODEL_DIM_COUNT] = { 0 }; - - virtual ~ObjectDetectionInterface() {} - virtual const char* getModelName() = 0; - virtual const uint64_t getModelVersion() = 0; - virtual const char* getModelInputName() = 0; - virtual const size_t getModelDimCount() = 0; - virtual const std::vector getModelInputShape() = 0; - virtual const std::string getClassLabelText(int classIndex) = 0; - virtual void postprocess(const int64_t* output_shape, const void* voutputData, const size_t bytesize, const uint32_t dimCount, std::vector &detectedResults) = 0; - - static inline float sigmoid(float x) { - return 1.f / (1.f + std::exp(-x)); - } - - static inline float linear(float x) { - return x; - } - - double intersectionOverUnion(const DetectedResult& o1, const DetectedResult& o2) { - double overlappingWidth = std::fmin(o1.x + o1.width, o2.x + o2.width) - std::fmax(o1.x, o2.x); - double overlappingHeight = std::fmin(o1.y + o1.height, o2.y + o2.height) - std::fmax(o1.y, o2.y); - double intersectionArea = (overlappingWidth < 0 || overlappingHeight < 0) ? 0 : overlappingHeight * overlappingWidth; - double unionArea = o1.width * o1.height + o2.width * o2.height - intersectionArea; - return intersectionArea / unionArea; - } - - void postprocess(std::vector &detectedResults, std::vector &outDetectedResults) - { - - if (useAdvancedPostprocessing) { - // Advanced postprocessing - // Checking IOU threshold conformance - // For every i-th object we're finding all objects it intersects with, and comparing confidence - // If i-th object has greater confidence than all others, we include it into result - for (const auto& obj1 : detectedResults) { - bool isGoodResult = true; - for (const auto& obj2 : detectedResults) { - if (obj1.classId == obj2.classId && obj1.confidence < obj2.confidence && - intersectionOverUnion(obj1, obj2) >= boxiou_threshold) { // if obj1 is the same as obj2, condition - // expression will evaluate to false anyway - isGoodResult = false; - break; - } - } - if (isGoodResult) { - outDetectedResults.push_back(obj1); - } - } - } else { - // Classic postprocessing - std::sort(detectedResults.begin(), detectedResults.end(), [](const DetectedResult& x, const DetectedResult& y) { - return x.confidence > y.confidence; - }); - for (size_t i = 0; i < detectedResults.size(); ++i) { - if (detectedResults[i].confidence == 0) - continue; - for (size_t j = i + 1; j < detectedResults.size(); ++j) - if (intersectionOverUnion(detectedResults[i], detectedResults[j]) >= boxiou_threshold) - detectedResults[j].confidence = 0; - outDetectedResults.push_back(detectedResults[i]); - } //end for - } // end if - } // end postprocess filter - - -protected: - float confidence_threshold = .9; - float boxiou_threshold = .4; - float iou_threshold = 0.4; - int classes = 80; - bool useAdvancedPostprocessing = false; - -}; - -class FaceDetection0005 : public ObjectDetectionInterface { -public: - - FaceDetection0005() { - confidence_threshold = _detection_threshold; - classes = 1; - std::vector vmodel_input_shape = getModelInputShape(); - std::copy(vmodel_input_shape.begin(), vmodel_input_shape.end(), model_input_shape); - } - - const char* getModelName() { - return MODEL_NAME; - } - - const uint64_t getModelVersion() { - return MODEL_VERSION; - } - - const char* getModelInputName() { - return INPUT_NAME; - } - - const size_t getModelDimCount() { - return MODEL_DIM_COUNT; - } - - const std::vector getModelInputShape() { - std::vector shape{1, 3, 800, 800}; - return shape; - } - - const std::string getClassLabelText(int classIndex) { - return (classIndex == 1 ? "Face" : "Unknown"); - } - - /* - * Reference: FaceDetection - * TODO: Move a shared lib. - */ - void postprocess(const int64_t* output_shape, const void* voutputData, const size_t bytesize, const uint32_t dimCount, std::vector &detectedResults) - { - if (!voutputData || !output_shape) { - // nothing to do - return; - } - // Input Info - // input.1 - 1,3,H,W - - // Output Info - // data - 1, 1, 200, 7 - // [image_id, label, conf, x_min, y_min, x_max, y_max], - const int numberOfDetections = output_shape[2]; - const int objectSize = output_shape[3]; - const float* outData = reinterpret_cast(voutputData); - std::vector input_shape = getModelInputShape(); - int network_h = input_shape[2]; - int network_w = input_shape[3]; - - for (int i = 0; i < numberOfDetections; i++) - { - float image_id = outData[i * objectSize + 0]; - if (image_id < 0) - break; - - float confidence = outData[i * objectSize + 2]; - - if (confidence > confidence_threshold ) { - DetectedResult obj; - obj.x = std::clamp(static_cast(outData[i * objectSize + 3] * _video_input_width), 0, _video_input_width); - obj.y = std::clamp(static_cast(outData[i * objectSize + 4] * _video_input_height), 0, _video_input_height); - obj.width = std::clamp(static_cast(outData[i * objectSize + 5] * _video_input_width - obj.x), 0, _video_input_width); - obj.height = std::clamp(static_cast(outData[i * objectSize + 6] * _video_input_height - obj.y), 0, _video_input_height); - obj.confidence = confidence; - obj.classId = outData[i * objectSize + 1]; - strncpy(obj.classText, getClassLabelText(obj.classId).c_str(), sizeof(obj.classText)); - - - if (obj.classId != 1) - printf("SHOULDN'T OCCUR:---------found: %s\n", obj.classText); - detectedResults.push_back(obj); - } // end if confidence - } // end for - } // End of FaceDetect Post-Processing - - -private: - /* Model Serving Info for https://github.com/openvinotoolkit/open_model_zoo/tree/master/models/intel/face-detection-retail-0005 */ - // FaceDet - 1x3x300x300 NCHW - const char* MODEL_NAME = "face-detection-retail-0005"; - const uint64_t MODEL_VERSION = 0; - const char* INPUT_NAME = "input.1"; -}; - -GStreamerMediaPipelineService* _mediaService = NULL; -std::string _user_request; - -namespace { -volatile sig_atomic_t shutdown_request = 0; -} - -bool stringIsInteger(std::string strInput) { - std::string::const_iterator it = strInput.begin(); - while (it != strInput.end() && std::isdigit(*it)) ++it; - return !strInput.empty() && it == strInput.end(); -} - -bool stringIsFloat(std::string strInput) { - std::istringstream iss(strInput); - float f; - iss >> std::noskipws >> f; // noskipws considers leading whitespace invalid - return iss.eof() && !iss.fail(); -} - -bool setActiveModel(int detectionType, ObjectDetectionInterface** objDet) -{ - if (objDet == NULL) - return false; - *objDet = new FaceDetection0005(); - return true; -} - -static void onInterrupt(int status) { - shutdown_request = 1; -} - -static void onTerminate(int status) { - shutdown_request = 1; -} - -static void onIllegal(int status) { - shutdown_request = 2; -} - -static void installSignalHandlers() { - static struct sigaction sigIntHandler; - sigIntHandler.sa_handler = onInterrupt; - sigemptyset(&sigIntHandler.sa_mask); - sigIntHandler.sa_flags = 0; - sigaction(SIGINT, &sigIntHandler, NULL); - - static struct sigaction sigTermHandler; - sigTermHandler.sa_handler = onTerminate; - sigemptyset(&sigTermHandler.sa_mask); - sigTermHandler.sa_flags = 0; - sigaction(SIGTERM, &sigTermHandler, NULL); - - static struct sigaction sigIllHandler; - sigIllHandler.sa_handler = onIllegal; - sigemptyset(&sigIllHandler.sa_mask); - sigIllHandler.sa_flags = 0; - sigaction(SIGILL, &sigIllHandler, NULL); -} - -void printInferenceResults(std::vector &results) -{ - for (auto & obj : results) { - std::cout << "Rect: [ " << obj.x << " , " << obj.y << " " << obj.width << ", " << obj.height << "] Class: " << obj.classText << "(" << obj.classId << ") Conf: " << obj.confidence << std::endl; - } -} - -// TODO: Multiple references state that imshow can't be used in any other thread than main! -void displayGUIInferenceResults(cv::Mat analytics_frame, std::vector &results, int latency, int througput) -{ - auto ttid = std::this_thread::get_id(); - std::stringstream ss; - ss << ttid; - std::string tid = ss.str(); - - for (auto & obj : results) { - const float x0 = obj.x; - const float y0 = obj.y; - const float x1 = obj.x + obj.width; - const float y1 = obj.y + obj.height; - - cv::rectangle( analytics_frame, - cv::Point( (int)(x0),(int)(y0) ), - cv::Point( (int)x1, (int)y1 ), - cv::Scalar(255, 0, 0), - 2, cv::LINE_8 ); - } // end for - - //latency - // std::string fps_msg = (througput == 0) ? "..." : std::to_string(througput) + "fps"; - // std::string latency_msg = (latency == 0) ? "..." : std::to_string(latency) + "ms"; - // std::string roiCount_msg = std::to_string(results.size()); - // std::string message = "E2E Pipeline Performance: " + latency_msg + " and " + fps_msg + " with ROIs#" + roiCount_msg; - // cv::putText(analytics_frame, message.c_str(), cv::Size(0, 20), cv::FONT_HERSHEY_PLAIN, 1, (255, 0, 0), 1, cv::LINE_4); - // cv::putText(analytics_frame, tid, cv::Size(0, 40), cv::FONT_HERSHEY_PLAIN, 1, (255, 0, 0), 1, cv::LINE_4); - - cv::Mat presenter; - - { - std::lock_guard lock(_drawingMtx); - cv::imshow("OpenVINO Results " + tid, analytics_frame); - cv::waitKey(1); - } -} - -void saveInferenceResultsAsVideo(cv::Mat &presenter, std::vector &results) -{ - for (auto & obj : results) { - - const float scaler_w = 416.0f/_video_input_width; - const float scaler_h = 416.0f/_video_input_height; - - cv::rectangle( presenter, - cv::Point( (int)(obj.x*scaler_w),(int)(obj.y*scaler_h) ), - cv::Point( (int)((obj.x+obj.width) * scaler_w), (int)((obj.y+obj.height)*scaler_h) ), - cv::Scalar(255, 0, 0), - 4, cv::LINE_8 ); - } // end for - cv::imwrite("result.jpg", presenter); -} - -// This function is responsible for generating a GST pipeline that -// decodes and resizes the video stream based on the desired window size or -// the largest analytics frame size needed if running headless -std::string getVideoPipelineText(std::string mediaPath, ObjectDetectionInterface* objDet, ObjectDetectionInterface* textDet) -{ - - std::vector modelFrameShape = objDet->getModelInputShape(); - if (textDet) { - modelFrameShape = textDet->getModelInputShape(); - } - - int frame_width = _window_width; - int frame_height = _window_height; - - return _mediaService->getVideoDecodedPreProcessedPipeline( - mediaPath, - _videoType, - frame_width, - frame_height, - _use_onevpl); -} - -bool createModelServer() -{ - if (_srv == NULL) - return false; - - OVMS_Status* res = OVMS_ServerStartFromConfigurationFile(_srv, _serverSettings, _modelsSettings); - - if (res) { - uint32_t code = 0; - const char* details = nullptr; - - OVMS_StatusCode(res, &code); - OVMS_StatusDetails(res, &details); - std::cerr << "ERROR: during start: code:" << code << "; details:" << details - << "; grpc_port: " << _server_grpc_port - << "; http_port: " << _server_http_port - << ";" << std::endl; - - OVMS_StatusDelete(res); - - if (_srv) - OVMS_ServerDelete(_srv); - - if (_modelsSettings) - OVMS_ModelsSettingsDelete(_modelsSettings); - - if (_serverSettings) - OVMS_ServerSettingsDelete(_serverSettings); - - return false; - } - - return true; -} - -bool loadGStreamer(GstElement** pipeline, GstElement** appsink, std::string mediaPath, ObjectDetectionInterface* _objDet) -{ - static int threadCnt = 0; - - std::string videoPipelineText = getVideoPipelineText(mediaPath, _objDet, NULL); - std::cout << "--------------------------------------------------------------" << std::endl; - std::cout << "Opening Media Pipeline: " << videoPipelineText << std::endl; - std::cout << "--------------------------------------------------------------" << std::endl; - - *pipeline = gst_parse_launch (videoPipelineText.c_str(), NULL); - if (*pipeline == NULL) { - std::cout << "ERROR: Failed to parse GST pipeline. Quitting." << std::endl; - return false; - } - - std::string appsinkName = "appsink" + std::to_string(threadCnt++); - - *appsink = gst_bin_get_by_name (GST_BIN (*pipeline), appsinkName.c_str()); - - // Check if all elements were created - if (!(*appsink)) - { - printf("ERROR: Failed to initialize GST pipeline (missing %s) Quitting.\n", appsinkName.c_str()); - return false; - } - - GstStateChangeReturn gst_res; - - // Start pipeline so it could process incoming data - gst_res = gst_element_set_state(*pipeline, GST_STATE_PLAYING); - - if (gst_res != GST_STATE_CHANGE_SUCCESS && gst_res != GST_STATE_CHANGE_ASYNC ) { - printf("ERROR: StateChange not successful. Error Code: %d\n", gst_res); - return false; - } - - return true; -} - -// OVMS C-API is a global process (singleton design) wide server so can't create many of them -bool loadOVMS() -{ - OVMS_Status* res = NULL; - - OVMS_ServerSettingsNew(&_serverSettings); - OVMS_ModelsSettingsNew(&_modelsSettings); - OVMS_ServerNew(&_srv); - OVMS_ServerSettingsSetGrpcPort(_serverSettings, _server_grpc_port); - OVMS_ServerSettingsSetRestPort(_serverSettings, _server_http_port); - OVMS_ServerSettingsSetLogLevel(_serverSettings, OVMS_LOG_ERROR); - - char * ovmsCofigJsonFilePath = std::getenv("OVMS_MODEL_CONFIG_JSON"); - std::cout << "ovmsCofigJsonFilePath: "< channels; - cv::split(src, channels); - - for (auto &img : channels) { - img = img.reshape(1, 1); - } - - // Concatenate three vectors to one - cv::hconcat( channels, dst ); -} - -void run_stream(std::string mediaPath, GstElement* pipeline, GstElement* appsink, ObjectDetectionInterface* objDet) -{ - auto ttid = std::this_thread::get_id(); - std::stringstream ss; - ss << ttid; - std::string tid = ss.str(); - - // Wait for all decoder streams to init...otherwise causes a segfault when OVMS loads - // https://stackoverflow.com/questions/48271230/using-condition-variablenotify-all-to-notify-multiple-threads - std::unique_lock lk(_mtx); - _cvAllDecodersInitd.wait(lk, [] { return _allDecodersInitd;} ); - lk.unlock(); - - printf("Starting thread: %s\n", tid.c_str()) ; - - auto initTime = std::chrono::high_resolution_clock::now(); - unsigned long numberOfFrames = 0; - long long numberOfSkipFrames = 0; - OVMS_Status* res = NULL; - - while (!shutdown_request) { - auto startTime = std::chrono::high_resolution_clock::now(); - - const void* voutputData1; - size_t bytesize1 = 0; - uint32_t outputCount = 0; - uint32_t outputId; - OVMS_DataType datatype1 = (OVMS_DataType)42; - const int64_t* shape1{nullptr}; - size_t dimCount1 = 0; - OVMS_BufferType bufferType1 = (OVMS_BufferType)42; - uint32_t deviceId1 = 42; - const char* outputName1{nullptr}; - - GstSample *sample; - GstStructure *s; - GstBuffer *buffer; - GstMapInfo m; - - std::vector detectedResults; - std::vector detectedResultsFiltered; - - if (gst_app_sink_is_eos(GST_APP_SINK(appsink))) { - std::cout << "INFO: EOS " << std::endl; - return; - } - - sample = gst_app_sink_try_pull_sample (GST_APP_SINK(appsink), 5 * GST_SECOND); - - if (sample == nullptr) { - std::cout << "ERROR: No sample found" << std::endl; - return; - } - - GstCaps *caps; - caps = gst_sample_get_caps(sample); - - if (caps == nullptr) { - std::cout << "ERROR: No caps found for sample" << std::endl; - return; - } - - s = gst_caps_get_structure(caps, 0); - gst_structure_get_int(s, "width", &_video_input_width); - gst_structure_get_int(s, "height", &_video_input_height); - - buffer = gst_sample_get_buffer(sample); - gst_buffer_map(buffer, &m, GST_MAP_READ); - - if (m.size <= 0) { - std::cout << "ERROR: Invalid buffer size" << std::endl; - return; - } - - cv::Mat analytics_frame; - cv::Mat floatImage; - std::vector inputShape; - - inputShape = objDet->getModelInputShape(); - - cv::Mat img(_video_input_height, _video_input_width, CV_8UC3, (void *) m.data); - - if (dynamic_cast(objDet) != nullptr) - { - resize(img, analytics_frame, cv::Size(inputShape[2], inputShape[3]), 0, 0, cv::INTER_LINEAR); - hwc_to_chw(analytics_frame, analytics_frame); - } - else - { - printf("ERROR: Unknown model type\n"); - return; - } - analytics_frame.convertTo(floatImage, CV_32F); - - const int DATA_SIZE = floatImage.step[0] * floatImage.rows; - - OVMS_InferenceResponse* response = nullptr; - OVMS_InferenceRequest* request{nullptr}; - - // OD Inference - { - std::lock_guard lock(_infMtx); - - OVMS_InferenceRequestNew(&request, _srv, objDet->getModelName(), objDet->getModelVersion()); - - OVMS_InferenceRequestAddInput( - request, - objDet->getModelInputName(), - OVMS_DATATYPE_FP32, - objDet->model_input_shape, - objDet->getModelDimCount() - ); - - // run sync request - OVMS_InferenceRequestInputSetData( - request, - objDet->getModelInputName(), - reinterpret_cast(floatImage.data), - DATA_SIZE , - OVMS_BUFFERTYPE_CPU, - 0 - ); - - res = OVMS_Inference(_srv, request, &response); - - if (res != nullptr) { - std::cout << "OVMS_Inference failed " << std::endl; - uint32_t code = 0; - const char* details = 0; - OVMS_StatusCode(res, &code); - OVMS_StatusDetails(res, &details); - std::cout << "Error occured during inference. Code:" << code - << ", details:" << details << std::endl; - - OVMS_StatusDelete(res); - if (request) - OVMS_InferenceRequestDelete(request); - break; - } - } // end lock on inference request to server - - OVMS_InferenceResponseOutputCount(response, &outputCount); - outputId = outputCount - 1; - - OVMS_InferenceResponseOutput(response, outputId, &outputName1, &datatype1, &shape1, &dimCount1, &voutputData1, &bytesize1, &bufferType1, &deviceId1); - - objDet->postprocess(shape1, voutputData1, bytesize1, dimCount1, detectedResults); - objDet->postprocess(detectedResults, detectedResultsFiltered); - - numberOfSkipFrames++; - float fps = 0; - if (numberOfSkipFrames <= 120) // allow warm up for latency/fps measurements - { - initTime = std::chrono::high_resolution_clock::now(); - numberOfFrames = 0; - - //printf("Too early...Skipping frames..\n"); - } - else - { - numberOfFrames++; - - auto endTime = std::chrono::high_resolution_clock::now(); - auto latencyTime = ((std::chrono::duration_cast(endTime-startTime)).count()); - auto runningLatencyTime = ((std::chrono::duration_cast(endTime-initTime)).count()); - if (runningLatencyTime > 0) { // skip a few to account for init - fps = (float)numberOfFrames/(float)(runningLatencyTime/1000); // convert to seconds - } - - if (_render) - displayGUIInferenceResults(img, detectedResultsFiltered, latencyTime, fps); - - static int highest_latency_frame = 0; - static int lowest_latency_frame = 9999; - static int avg_latency_frame = 0; - static int total_latency_frames = 0; - - int frame_latency = chrono::duration_cast(endTime - startTime).count(); - - if (frame_latency > highest_latency_frame) - highest_latency_frame = frame_latency; - if (frame_latency < lowest_latency_frame) - lowest_latency_frame = frame_latency; - - total_latency_frames += frame_latency; - if (numberOfFrames % 30 == 0) { - avg_latency_frame = total_latency_frames / 30; - - time_t currTime = time(0); - struct tm tstruct; - char bCurrTime[80]; - tstruct = *localtime(&currTime); - // http://en.cppreference.com/w/cpp/chrono/c/strftime - strftime(bCurrTime, sizeof(bCurrTime), "%Y-%m-%d.%X", &tstruct); - - cout << detectedResultsFiltered.size() << " object(s) detected at " << bCurrTime << endl; - cout << "Avg. Pipeline Throughput FPS: " << ((isinf(fps)) ? "..." : std::to_string(fps)) << endl; - cout << "Avg. Pipeline Latency (ms): " << avg_latency_frame << endl; - cout << "Max. Pipeline Latency (ms): " << highest_latency_frame << endl; - cout << "Min. Pipeline Latency (ms): " << lowest_latency_frame << endl; - highest_latency_frame = 0; - lowest_latency_frame = 9999; - total_latency_frames = 0; - } - - } - - if (request) { - OVMS_InferenceRequestInputRemoveData(request, objDet->getModelInputName()); // doesn't help - OVMS_InferenceRequestRemoveInput(request, objDet->getModelInputName()); - OVMS_InferenceRequestDelete(request); - } - - if (response) { - OVMS_InferenceResponseDelete(response); - } - - gst_buffer_unmap(buffer, &m); - gst_sample_unref(sample); - - if (shutdown_request > 0) - break; - } // end while get frames - - std::cout << "Goodbye..." << std::endl; - - if (res != NULL) { - OVMS_StatusDelete(res); - res = NULL; - } - - if (objDet) { - delete objDet; - objDet = NULL; - } - - gst_element_set_state (pipeline, GST_STATE_NULL); - if (pipeline) - gst_object_unref(pipeline); - - if (appsink) - gst_object_unref(appsink); -} - -void print_usage(const char* programName) { - std::cout << "Usage: ./" << programName << " \n\n" - << "mediaLocation is an rtsp://127.0.0.1:8554/camera_0 url or a path to an *.mp4 file\n" - << "use_onevpl is 0 (libva - default) or 1 for onevpl\n" - << "render is 1 to launch render window or 0 (default) for headless\n" - << "render portrait is 1 for render swap the size of window width and height\n" - << "video_type is 0 for AVC or 1 for HEVC\n" - << "window_width is display window width\n" - << "window_height is display window height\n" - << "detection_threshold is confidence threshold value in floating point that needs to be between 0.0 to 1.0\n"; - -} - -int get_running_servers() { - char buffer[128]; - string cmd = "echo $cid_count"; - std::string result = ""; - FILE* pipe = popen(cmd.c_str(), "r"); - - if (!pipe) - throw std::runtime_error("popen() failed!"); - - try - { - while (fgets(buffer, sizeof buffer, pipe) != NULL) - { - result += buffer; - } - } - catch (...) - { - pclose(pipe); - throw; - } - pclose(pipe); - return std::stoi(result.c_str()); -} - -int main(int argc, char** argv) { - std::cout << std::setprecision(2) << std::fixed; - - // Use GST pipelines for media HWA decode and pre-procesing - _mediaService = new GStreamerMediaPipelineService(); - - // get valid server port numbers - int running_servers = get_running_servers(); - _server_grpc_port = 9178 + running_servers; - _server_http_port = 11338 + running_servers; - - _videoStreamPipeline = "people-detection.mp4"; - - if (argc < 9) { - print_usage(argv[0]); - return 1; - } - - if (!stringIsInteger(argv[2]) || !stringIsInteger(argv[3]) || !stringIsInteger(argv[4]) - || !stringIsInteger(argv[5]) || !stringIsInteger(argv[6]) || !stringIsInteger(argv[7]) || !stringIsFloat(argv[8])) { - print_usage(argv[0]); - return 1; - } else { - _videoStreamPipeline = argv[1]; - _use_onevpl = std::stoi(argv[2]); - _render = std::stoi(argv[3]); - _renderPortrait = std::stoi(argv[4]); - _videoType = (MediaPipelineServiceInterface::VIDEO_TYPE) std::stoi(argv[5]); - _window_width = std::stoi(argv[6]); - _window_height = std::stoi(argv[7]); - std::cout << "_window_width: " << _window_width << std::endl; - std::cout << "_window_height: " << _window_height << std::endl; - _detection_threshold=std::stof(argv[8]); - if (_detection_threshold > 1.0 || _detection_threshold < 0.0) { - std::cout << "detection_threshold: " << _detection_threshold << ", is confidence threshold value in floating point that needs to be between 0.0 to 1.0.\n" << endl; - return 1; - } - - if (_renderPortrait) { - int tmp = _window_width; - _window_width = _window_height; - _window_height = tmp; - } - } - - gst_init(NULL, NULL); - - std::vector running_streams; - _allDecodersInitd = false; - - GstElement *pipeline; - GstElement *appsink; - ObjectDetectionInterface* objDet; - getMAPipeline(_videoStreamPipeline, &pipeline, &appsink, &objDet); - running_streams.emplace_back(run_stream, _videoStreamPipeline, pipeline, appsink, objDet); - - if (!loadOVMS()) - return -1; - - _allDecodersInitd = true; - _cvAllDecodersInitd.notify_all();; - - - for(auto& running_stream : running_streams) - running_stream.join(); - - if (_mediaService != NULL) { - delete _mediaService; - _mediaService = NULL; - } - - if (_srv) - OVMS_ServerDelete(_srv); - if (_modelsSettings) - OVMS_ModelsSettingsDelete(_modelsSettings); - if (_serverSettings) - OVMS_ServerSettingsDelete(_serverSettings); - - return 0; -} diff --git a/configs/opencv-ovms/gst_capi/run_gst_capi.sh b/configs/opencv-ovms/gst_capi/run_gst_capi.sh deleted file mode 100755 index 3214f467..00000000 --- a/configs/opencv-ovms/gst_capi/run_gst_capi.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -# Default values -cid_count="${cid_count:=0}" -INPUTSRC="${INPUTSRC:=}" -RENDER_PORTRAIT_MODE="${RENDER_PORTRAIT_MODE:=0}" -GST_VAAPI_DRM_DEVICE="${GST_VAAPI_DRM_DEVICE:=/dev/dri/renderD128}" -USE_ONEVPL="${USE_ONEVPL:=0}" -RENDER_MODE="${RENDER_MODE:=0}" -TARGET_GPU_DEVICE="${TARGET_GPU_DEVICE:=--privileged}" -WINDOW_WIDTH="${WINDOW_WIDTH:=1920}" -WINDOW_HEIGHT="${WINDOW_HEIGHT:=1080}" -DETECTION_THRESHOLD="${DETECTION_THRESHOLD:=0.5}" -BARCODE="${BARCODE:=1}" -OCR_DEVICE="${OCR_DEVICE:=}" - -update_media_device_engine() { - # Use discrete GPU if it exists, otherwise use iGPU or CPU - if [ "$PLATFORM" != "cpu" ] - then - if [ "$HAS_ARC" == "1" ] || [ "$HAS_FLEX_140" == "1" ] || [ "$HAS_FLEX_170" == "1" ] - then - GST_VAAPI_DRM_DEVICE=/dev/dri/renderD129 - fi - fi -} - -# This updates the media GPU engine utilized based on the request PLATFOR by user -# The default state of all libva (*NIX) media decode/encode/etc is GPU.0 instance -update_media_device_engine - -chmod +x $PIPELINE_EXEC_PATH -bash_cmd="./launch-pipeline.sh $PIPELINE_EXEC_PATH $INPUTSRC $USE_ONEVPL $RENDER_MODE $RENDER_PORTRAIT_MODE $WINDOW_WIDTH $WINDOW_HEIGHT $DETECTION_THRESHOLD $BARCODE" - -echo "BashCmd: $bash_cmd with media on $GST_VAAPI_DRM_DEVICE with USE_ONEVPL=$USE_ONEVPL" - -cl_cache_dir="/home/intel/gst-ovms/.cl-cache" \ -DISPLAY="$DISPLAY" \ -RESULT_DIR="/tmp/result" \ -LOG_LEVEL="$LOG_LEVEL" \ -GST_DEBUG="$GST_DEBUG" \ -cid_count="$cid_count" \ -INPUTSRC="$INPUTSRC" \ -RUN_MODE="$RUN_MODE" \ -RENDER_MODE="$RENDER_MODE" \ -TARGET_GPU_DEVICE="$TARGET_GPU_DEVICE" \ -GST_VAAPI_DRM_DEVICE="$GST_VAAPI_DRM_DEVICE" \ -PIPELINE_EXEC_PATH="$PIPELINE_EXEC_PATH" \ -RENDER_PORTRAIT_MODE="$RENDER_PORTRAIT_MODE" \ -USE_ONEVPL="$USE_ONEVPL" \ -DETECTION_THRESHOLD="$DETECTION_THRESHOLD" \ -BARCODE="$BARCODE" \ -OCR_DEVICE="$OCR_DEVICE" \ -$bash_cmd \ -2>&1 | tee >/tmp/results/r$cid_count.jsonl >(stdbuf -oL sed -n -e 's/^.*FPS: //p' | stdbuf -oL cut -d , -f 1 > /tmp/results/pipeline$cid_count.log) \ No newline at end of file diff --git a/configs/opencv-ovms/images/inputimages.txt b/configs/opencv-ovms/images/inputimages.txt deleted file mode 100644 index 1db814e6..00000000 --- a/configs/opencv-ovms/images/inputimages.txt +++ /dev/null @@ -1 +0,0 @@ -/images/sample-bottle.jpg NWHC diff --git a/configs/opencv-ovms/images/readme.txt b/configs/opencv-ovms/images/readme.txt deleted file mode 100644 index fea4d10b..00000000 --- a/configs/opencv-ovms/images/readme.txt +++ /dev/null @@ -1 +0,0 @@ -Put image file here diff --git a/configs/opencv-ovms/models/2022/config_template.json b/configs/opencv-ovms/models/2022/config_template.json deleted file mode 100644 index 9f07160d..00000000 --- a/configs/opencv-ovms/models/2022/config_template.json +++ /dev/null @@ -1,247 +0,0 @@ -{ - "model_config_list": [ - { - "config": { - "name": "bit_64", - "base_path": "/models/BiT_M_R50x1_10C_50e_IR/FP16-INT8", - "nireq": 1, - "batch_size": "1", - "shape": "(1,64,64,3)", - "layout": "NHWC:NHWC", - "plugin_config": { - "PERFORMANCE_HINT": "LATENCY" - }, - "target_device": "{target_device}" - }, - "latest": { - "num_versions": 1 - } - }, - { - "config": { - "name": "instance-segmentation-security-1040", - "base_path": "/models/instance-segmentation-security-1040/FP16-INT8", - "nireq": 1, - "batch_size": "1", - "shape": "(1,608,608,3)", - "layout": "NHWC:NCHW", - "plugin_config": { - "PERFORMANCE_HINT": "LATENCY" - }, - "target_device": "{target_device}" - }, - "latest": { - "num_versions": 1 - } - }, - { - "config": { - "name": "yolov5s", - "base_path": "/models/yolov5s/FP16-INT8", - "layout": "NHWC:NCHW", - "shape": "(1,416,416,3)", - "nireq": 1, - "batch_size": "1", - "plugin_config": { - "PERFORMANCE_HINT": "LATENCY" - }, - "target_device": "{target_device}" - } - }, - { - "config": { - "name": "ssd_mobilenet_v1_coco", - "base_path": "/models/ssd_mobilenet_v1_coco/FP32", - "nireq": 1, - "batch_size": "1", - "plugin_config": { - "PERFORMANCE_HINT": "LATENCY" - }, - "target_device": "{target_device}" - }, - "latest": { - "num_versions": 1 - } - }, - {"config": { - "name": "face-detection-retail-0005", - "base_path": "face-detection-retail-0005/FP16-INT8", - "shape": "(1,3,800,800)", - "nireq": 2, - "batch_size":"1", - "plugin_config": {"PERFORMANCE_HINT": "LATENCY"}, - "target_device": "{target_device}"}, - "latest": { "num_versions": 2 } - }, - { - "config": { - "name": "yolov5", - "base_path": "/models/yolov5s/FP16-INT8", - "shape": "(1,3,416,416)", - "nireq": 2, - "batch_size": "1", - "plugin_config": { - "PERFORMANCE_HINT": "LATENCY" - }, - "target_device": "{target_device}" - }, - "latest": { - "num_versions": 2 - } - }, - { "config": { - "name": "yolov8", - "base_path": "/models/yolov8/FP32-INT8", - "shape": "(1,3,416,416)", - "layout": "NCHW:NCHW", - "nireq": 3, - "batch_size": "1", - "plugin_config": { "PERFORMANCE_HINT": "LATENCY" }, - "target_device": "{target_device}" - }, - "latest": { "num_versions": 2 } - }, - { - "config": { - "name": "efficientnetb0_FP32INT8", - "base_path": "/models/efficientnet-b0/FP32-INT8", - "shape": "(1,3,224,224)", - "nireq": 2, - "batch_size": "1", - "plugin_config": { - "PERFORMANCE_HINT": "LATENCY" - }, - "target_device": "{target_device}" - }, - "latest": { - "num_versions": 2 - } - } -], -"custom_node_library_config_list": [ - { - "name": "efficientnetb0_extractor", - "base_path": "/ovms/lib/libcustom_node_efficientnetb0-yolov5.so" - } -], -"pipeline_config_list": [ - { - "name": "detect_classify", - "inputs": [ - "images" - ], - "nodes": [ - { - "name": "detection_node", - "model_name": "yolov5", - "type": "DL model", - "inputs": [ - { - "images": { - "node_name": "request", - "data_item": "images" - } - } - ], - "outputs": [ - { - "data_item": "442", - "alias": "boxes" - } - ] - }, - { - "name": "extract_node", - "library_name": "efficientnetb0_extractor", - "type": "custom", - "demultiply_count": 0, - "params": { - "original_image_width": "416", - "original_image_height": "416", - "original_image_layout": "NCHW", - "target_image_width": "224", - "target_image_height": "224", - "target_image_layout": "NCHW", - "convert_to_gray_scale": "false", - "confidence_threshold": "0.7", - "max_output_batch": "100", - "debug": "false" - }, - "inputs": [ - { - "images": { - "node_name": "request", - "data_item": "images" - } - }, - { - "boxes": { - "node_name": "detection_node", - "data_item": "boxes" - } - } - ], - "outputs": [ - { - "data_item": "roi_images", - "alias": "roi_images" - }, - { - "data_item": "roi_coordinates", - "alias": "roi_coordinates" - }, - { - "data_item": "confidence_levels", - "alias": "confidence_levels" - } - ] - }, - { - "name": "classification_node", - "model_name": "efficientnetb0_FP32INT8", - "type": "DL model", - "inputs": [ - { - "sub": { - "node_name": "extract_node", - "data_item": "roi_images" - } - } - ], - "outputs": [ - { - "data_item": "efficientnet-b0/model/head/dense/BiasAdd/Add", - "alias": "classify_output" - } - ] - } - ], - "outputs": [ - { - "roi_images": { - "node_name": "extract_node", - "data_item": "roi_images" - } - }, - { - "roi_coordinates": { - "node_name": "extract_node", - "data_item": "roi_coordinates" - } - }, - { - "confidence_levels": { - "node_name": "extract_node", - "data_item": "confidence_levels" - } - }, - { - "classify_output": { - "node_name": "classification_node", - "data_item": "classify_output" - } - } - ] - } - ] -} \ No newline at end of file diff --git a/configs/opencv-ovms/scripts/docker-launcher.sh b/configs/opencv-ovms/scripts/docker-launcher.sh deleted file mode 100755 index 44830b89..00000000 --- a/configs/opencv-ovms/scripts/docker-launcher.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2024 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -error() { - printf '%s\n' "$1" >&2 - exit 1 -} - -cid_count="${cid_count:=0}" -DEVICE="${DEVICE:=CPU}" - -echo "VOLUMES is: $VOLUMES" -echo "DOCKER image is: $DOCKER_IMAGE" -echo "RUN_PATH: $RUN_PATH" -echo "CONTAINER_NAME: $CONTAINER_NAME" -echo "DOCKER_CMD: $DOCKER_CMD" -echo "DOT_ENV_FILE: $DOT_ENV_FILE" - -# Set RENDER_MODE=1 for demo purposes only -# RUN_MODE="-itd" -# if [ "$RENDER_MODE" == 1 ] -# then -# RUN_MODE="-it -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix" -# fi - -echo "DEVICE is: $DEVICE" - -# Set GPU device based on target device set -if [ "$DEVICE" == "CPU" ]; then - echo "Using CPU" - TARGET_GPU_DEVICE="--privileged" -elif [ "$DEVICE" == "MULTI:GPU,CPU" ]; then - # Set container to privilieged to have access to multiple devices - TARGET_GPU_DEVICE="--privileged" -elif grep -q "GPU" <<< "$DEVICE"; then - # Get device id if GPU.X is set - arrgpu=(${DEVICE//./ }) - TARGET_GPU_NUMBER=${arrgpu[1]} - # If GPU is not specified set to privileged so pipline has access to all GPUs - if [ -z "$TARGET_GPU_NUMBER" ]; then - TARGET_GPU_DEVICE="--privileged" - else - # If GPU is speicified only mount that GPU - TARGET_GPU_ID=$((128+$TARGET_GPU_NUMBER)) - TARGET_GPU_DEVICE="--device=/dev/dri/renderD"$TARGET_GPU_ID - fi -else - error 'ERROR: "--device" requires an argument CPU|GPU|MULTI' -fi - -if [ "$CPU_ONLY" == "1" ] -then - echo "CPU_ONLY mode is on, limit access to only CPU" - TARGET_GPU_DEVICE="" -fi - -# Mount the USB if using a usb camera -TARGET_USB_DEVICE="" -if [[ "$INPUTSRC" == *"/dev/vid"* ]] -then - TARGET_USB_DEVICE="--device=$INPUTSRC" -fi - -containerNameInstance="$CONTAINER_NAME$cid_count" - -# interpret any nested environment variables inside the VOLUMES if any -volFullExpand=$(eval echo "$VOLUMES") -echo "DEBUG: volFullExpand $volFullExpand" -DOCKER_CMD="${DOCKER_CMD:="/bin/bash"}" - -echo -echo -echo "DEBUG===================================== " -cat $DOT_ENV_FILE -echo -echo - -# volFullExpand is docker volume command and meant to be words splitting -# shellcheck disable=2086 -if [ "$NO_BASH_C" == 1 ] -then - docker run --network host --user root --ipc=host \ - --name "$containerNameInstance" \ - --env-file "$DOT_ENV_FILE" \ - -e CONTAINER_NAME="$containerNameInstance" \ - $TARGET_USB_DEVICE \ - $TARGET_GPU_DEVICE \ - $volFullExpand \ - "$DOCKER_IMAGE" \ - '$DOCKER_CMD' -else - docker run --network host --user root --ipc=host \ - --name "$containerNameInstance" \ - --env-file "$DOT_ENV_FILE" \ - -e CONTAINER_NAME="$containerNameInstance" \ - $TARGET_USB_DEVICE \ - $TARGET_GPU_DEVICE \ - $volFullExpand \ - "$DOCKER_IMAGE" \ - bash -c '$DOCKER_CMD' -fi diff --git a/configs/opencv-ovms/scripts/docker_compose_generic_entrypoint.sh b/configs/opencv-ovms/scripts/docker_compose_generic_entrypoint.sh deleted file mode 100755 index 010cd7a3..00000000 --- a/configs/opencv-ovms/scripts/docker_compose_generic_entrypoint.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -echo "Waiting for OVMS server to be ready...." -sleep 10 -echo "Done Waiting...." - -echo "ENTRYPOINT_SCRIPT: " -echo "$ENTRYPOINT_SCRIPT" -source "$ENTRYPOINT_SCRIPT" diff --git a/configs/opencv-ovms/scripts/gen_ovms_model_config_json.sh b/configs/opencv-ovms/scripts/gen_ovms_model_config_json.sh deleted file mode 100755 index 13ac9446..00000000 --- a/configs/opencv-ovms/scripts/gen_ovms_model_config_json.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -DEVICE="$DEVICE" \ -./profile-launcher --genOVMSModelConfig ./configs/opencv-ovms/models/2022 \ No newline at end of file diff --git a/configs/opencv-ovms/scripts/get_server_grpc_port.sh b/configs/opencv-ovms/scripts/get_server_grpc_port.sh deleted file mode 100755 index 3391f45a..00000000 --- a/configs/opencv-ovms/scripts/get_server_grpc_port.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -docker inspect "$SERVER_CONTAINER_INSTANCE" | docker run -i --rm -v ./:/app ghcr.io/jqlang/jq -r '.[].Args[3]' diff --git a/configs/opencv-ovms/scripts/image_download.sh b/configs/opencv-ovms/scripts/image_download.sh deleted file mode 100755 index 6c99192e..00000000 --- a/configs/opencv-ovms/scripts/image_download.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -if [ ! -f configs/opencv-ovms/images/sample-bottle.jpg ]; then - echo "Downloading sample image" - curl "https://images.pexels.com/photos/4389678/pexels-photo-4389678.jpeg?cs=srgb&dl=pexels-karolina-grabowska-4389678.jpg&fm=jpg&w=1280&h=1920&_gl=1*1lus06a*_ga*NjU2OTUyNjU3LjE2Njc1OTYyNjI.*_ga_8JE65Q40S6*MTY3OTYxNTI3NC4xNy4xLjE2Nzk2MTY4NjkuMC4wLjA." --output configs/opencv-ovms/images/sample-bottle.jpg -fi - diff --git a/configs/opencv-ovms/scripts/run_test.sh b/configs/opencv-ovms/scripts/run_test.sh deleted file mode 100755 index 54a5ba9c..00000000 --- a/configs/opencv-ovms/scripts/run_test.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -GRPC_PORT="${GRPC_PORT:=9000}" - -echo "running test with GRPC_PORT=$GRPC_PORT" -echo "this is just a testing profile example script" -echo -echo "DETECTION_THRESHOLD: $DETECTION_THRESHOLD" -echo \ No newline at end of file diff --git a/configs/opencv-ovms/scripts/start_ovms_server.sh b/configs/opencv-ovms/scripts/start_ovms_server.sh deleted file mode 100755 index 40df2b35..00000000 --- a/configs/opencv-ovms/scripts/start_ovms_server.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -cid_count="${cid_count:=0}" -GRPC_PORT="${GRPC_PORT:=9000}" - -srvContainerNameInstance="$SERVER_CONTAINER_NAME$cid_count" - -echo "$OVMS_SERVER_START_UP_MSG" -docker run --network host -d $cameras $TARGET_USB_DEVICE $TARGET_GPU_DEVICE --user root --ipc=host --name $srvContainerNameInstance \ --e cl_cache_dir=$server_cl_cache_dir \ --v $cl_cache_dir:$server_cl_cache_dir \ --v `pwd`/configs/opencv-ovms/models/2022:/models \ -$OVMS_SERVER_IMAGE_TAG --config_path $OVMS_MODEL_CONFIG_JSON --port $GRPC_PORT diff --git a/create-symbolic-link.sh b/create-symbolic-link.sh deleted file mode 100755 index db02d1f0..00000000 --- a/create-symbolic-link.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -TARGET_LINK="$1" -SOURCE_LINK="$2" - -if [ -e "$SOURCE_LINK" ]; -then - echo "symbolic link $SOURCE_LINK existing, remove it..." - sudo unlink "$SOURCE_LINK" -fi - -ln -s "$TARGET_LINK" "$SOURCE_LINK" diff --git a/detection.gif b/detection.gif deleted file mode 100644 index df66f472b2f25307c95aa0a0664aad375da9700c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1241443 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%0AoO$zdq2%z^qn>pBCvV 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 z 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
-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 {tpNPwdy25^`e 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
    so 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�W7HP3xA5g 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≯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
    intel-retail/automated-self-checkout @@ -193,35 +193,16 @@ - - -
  1. - - - - Getting Started - - -
  2. - - - - +
  3. + - - - -
  4. - - - Developer Tools + Getting Started - -
  5. - + + @@ -230,12 +211,12 @@
  6. - + - FAQs + Advanced Settings
  7. @@ -246,17 +227,16 @@ +
  8. + + + - -
  9. - - - Release Notes + Performance - -
  10. - + + @@ -302,7 +282,7 @@
    - +
    intel-retail/automated-self-checkout @@ -338,109 +318,12 @@ - - - - - - - -
  11. - - - - - - - - - - -
  12. - - - - - - - - - - - - - - - - -
  13. - - - - - - - - - - -
  14. - - - - - - - - - -
  15. - - - - - FAQs - - - - -
  16. - - - - - - - - - - - - - - - - -
  17. - - - - - - - - - - -
  18. - - @@ -1350,7 +434,7 @@

    404 - Not found

    - + diff --git a/docs/LICENSE.html b/docs/LICENSE.html deleted file mode 100644 index 191a387b..00000000 --- a/docs/LICENSE.html +++ /dev/null @@ -1,1574 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - LICENSE - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    LICENSE

    - -
                                 Apache License
    -                       Version 2.0, January 2004
    -                    http://www.apache.org/licenses/
    -
    -

    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

    -
      -
    1. Definitions.
    2. -
    -

    "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document.

    -

    "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License.

    -

    "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity.

    -

    "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License.

    -

    "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files.

    -

    "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types.

    -

    "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below).

    -

    "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof.

    -

    "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution."

    -

    "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work.

    -
      -
    1. -

      Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form.

      -
    2. -
    3. -

      Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed.

      -
    4. -
    5. -

      Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions:

      -
    6. -
    -

    (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and

    -

    (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and

    -

    (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and

    -

    (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License.

    -

    You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License.

    -
      -
    1. -

      Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions.

      -
    2. -
    3. -

      Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file.

      -
    4. -
    5. -

      Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License.

      -
    6. -
    7. -

      Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages.

      -
    8. -
    9. -

      Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability.

      -
    10. -
    -

    END OF TERMS AND CONDITIONS

    -

    APPENDIX: How to apply the Apache License to your work.

    -
      To apply the Apache License to your work, attach the following
    -  boilerplate notice, with the fields enclosed by brackets "[]"
    -  replaced with your own identifying information. (Don't include
    -  the brackets!)  The text should be enclosed in the appropriate
    -  comment syntax for the file format. We also recommend that a
    -  file or class name and description of purpose be included on the
    -  same "printed page" as the copyright notice for easier
    -  identification within third-party archives.
    -
    -

    Copyright 2023 Intel Corporation

    -

    Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at

    -
       http://www.apache.org/licenses/LICENSE-2.0
    -
    -

    Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License.

    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/OVMS/capiPipelineRun.html b/docs/OVMS/capiPipelineRun.html deleted file mode 100644 index 28f7cfc4..00000000 --- a/docs/OVMS/capiPipelineRun.html +++ /dev/null @@ -1,1669 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - C-API Face Detection Pipeline - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    OpenVINO OVMS C-API Pipeline Run

    -

    OpenVINO Model Server has many ways to run inferencing pipeline: -TensorFlow Serving gRPC API, KServe gRPC API, TensorFlow Serving REST API, KServe REST API and OVMS C API through OpenVINO model server (OVMS). Here is a demonstration for using OVMS C API method to run face detection inferencing pipeline with steps below:

    -
      -
    1. Add new section to model configuration file for model server
    2. -
    3. Add pipeline specific files
    4. -
    5. Add environment variable file dependency
    6. -
    7. Add a profile launcher pipeline configuration file
    8. -
    9. Build and run
    10. -
    -

    Add New Section To Model Config File for Model Server

    -

    Here is the template config file location: configs/opencv-ovms/models/2022/config_template.json, edit the file and append the following face detection model configuration section to the template -

    ,
    -{"config": {
    -      "name": "face-detection-retail-0005",
    -      "base_path": "face-detection-retail-0005/FP16-INT8",
    -      "shape": "(1,3,800,800)",
    -      "nireq": 2,
    -      "batch_size":"1",
    -      "plugin_config": {"PERFORMANCE_HINT": "LATENCY"},
    -      "target_device": "{target_device}"},
    -      "latest": { "num_versions": 2 }
    -    }
    -

    -
    -

    Note

    -

    shape is optional and takes precedence over batch_size, please remove this attribute if you don't know the value for the model.

    -
    -
    -

    Note

    -

    Please leave target_device value as it is, as the value {target_device} will be recognized and replaced by script run.

    -
    -

    You can find the parameter description in the ovms docs.

    -

    Add pipeline specific files

    -

    Here is the list of files we added in directory of configs/opencv-ovms/gst_capi/pipelines/face_detection/:

    -
      -
    1. main.cpp - this is all the work about pre-processing before sending to OVMS for inferencing and post-processing for displaying.
    2. -
    3. Makefile - to help building the pre-processing and post-processing binary.
    4. -
    -

    Add Environment Variable File

    -

    You can add multiple environment variable files to configs/opencv-ovms/envs/ directory for your pipeline. For face detection pipeline run, we have added configs/opencv-ovms/envs/capi_face_detection.env environment variable file. Below is a list of explanation for all environment variables and current default values we set for face detection pipeline run, this list can be extended for any future modification.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    EV NameFace Detection Default ValueDescription
    RENDER_PORTRAIT_MODE1rendering in portrait mode, value: 0 or 1
    GST_DEBUG1running GStreamer in debug mode, value: 0 or 1
    USE_ONEVPL1using OneVPL CPU & GPU Support, value: 0 or 1
    PIPELINE_EXEC_PATHpipelines/face_detection/face_detectionpipeline execution path inside container
    GST_VAAPI_DRM_DEVICE/dev/dri/renderD128GStreamer VAAPI DRM device input
    TARGET_GPU_DEVICE--privilegedallow using GPU devices if any
    LOG_LEVEL0GST_DEBUG log level to be set when running gst pipeline
    RENDER_MODE1option to display the input source video stream with the inferencing results, value: 0 or 1
    cl_cache_dir/home/intel/gst-ovms/.cl-cachecache directory in container
    WINDOW_WIDTH1920display window width
    WINDOW_HEIGHT1080display window height
    DETECTION_THRESHOLD0.9detection threshold value in floating point that needs to be between 0.0 to 1.0
    -
    -

    Note

    -

    Details of the face detection pipeline environment variable file can be viewed in configs/opencv-ovms/envs/capi_face_detection.env.

    -
    -

    Add A Profile Launcher Configuration File

    -

    The details about Profile Launcher configuration can be found here, and the details of capi face detection profile launcher configuration can be viewed in configs/opencv-ovms/cmd_client/res/capi_face_detection/configuration.yaml.

    -

    Build and Run

    -

    Here are the quick start steps to build and run OVMS C API face detection pipeline profile:

    -
      -
    1. -

      Build gst-capi ovms with profile-launcher:

      -
      make build-capi_face_detection
      -
      -
    2. -
    3. -

      Download sample video files:

      -
      cd benchmark-scripts/ && ./download_sample_videos.sh && cd ..
      -
      -
    4. -
    5. -

      Start simulator camera:

      -
      make run-camera-simulator
      -
      -
    6. -
    7. -

      To start face detection pipeline:

      -
      PIPELINE_PROFILE="capi_face_detection" RENDER_MODE=1 sudo -E ./run.sh --platform core --inputsrc rtsp://127.0.0. 1:8554/camera_0
      -
      -
      -

      Note

      -

      The pipeline run will automatically download the OpenVINO model files listed in configs/opencv-ovms/models/2022/config_template.json

      -
      -
    8. -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/OVMS/capiYolov5EnsemblePipelineRun.html b/docs/OVMS/capiYolov5EnsemblePipelineRun.html deleted file mode 100644 index 07743b92..00000000 --- a/docs/OVMS/capiYolov5EnsemblePipelineRun.html +++ /dev/null @@ -1,1498 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - OpenVINO OVMS C-API Yolov5 Ensemble Pipeline Run - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    OpenVINO OVMS C-API Yolov5 Ensemble Pipeline Run

    -

    OpenVINO Model Server has many ways to run inferencing pipeline: -TensorFlow Serving gRPC API, KServe gRPC API, TensorFlow Serving REST API, KServe REST API and OVMS C API through OpenVINO model server (OVMS). Here we are demonstrating for using OVMS C API method to run inferencing pipeline yolov5s ensemble models in following steps:

    -
      -
    1. Add new section to model configuration file for model server
    2. -
    3. Add pipeline specific files
    4. -
    5. Add environment variable file dependency
    6. -
    7. Add a profile launcher pipeline configuration file
    8. -
    9. Build and run
    10. -
    11. Clean up
    12. -
    -

    Add New Section To Model Config File for Model Server

    -

    The model template configuration file has been updated with model configs of yolov5, efficientnetb0_FP32INT8 and custom configurations, please view configs/opencv-ovms/models/2022/config_template.json for detail.

    -
    -

    Note

    -

    New model yolov5 is similar to yolov5s configuration except the layout difference.

    -
    -

    Add pipeline specific files

    -

    The pre-processing and post-processing work files are added in directory of configs/opencv-ovms/gst_capi/pipelines/capi_yolov5_ensemble/, please view directory for details.

    -

    Add Environment Variable File

    -

    You can add multiple environment variable files to configs/opencv-ovms/envs/ directory for your pipeline, we've added capi_yolov5_ensemble.env for yolov5 ensemble pipeline run. Below is a list of explanation for all environment variables and current default values we set, this list can be extended for any future modification.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    EV NameDefault ValueDescription
    RENDER_PORTRAIT_MODE1rendering in portrait mode, value: 0 or 1
    GST_DEBUG1running GStreamer in debug mode, value: 0 or 1
    USE_ONEVPL1using OneVPL CPU & GPU Support, value: 0 or 1
    PIPELINE_EXEC_PATHpipelines/capi_yolov5_ensemble/capi_yolov5_ensemblepipeline execution path inside container
    GST_VAAPI_DRM_DEVICE/dev/dri/renderD128GStreamer VAAPI DRM device input
    TARGET_GPU_DEVICE--privilegedallow using GPU devices if any
    LOG_LEVEL0GST_DEBUG log level to be set when running gst pipeline
    RENDER_MODE1option to display the input source video stream with the inferencing results, value: 0 or 1
    cl_cache_dir/home/intel/gst-ovms/.cl-cachecache directory in container
    WINDOW_WIDTH1920display window width
    WINDOW_HEIGHT1080display window height
    DETECTION_THRESHOLD0.7detection threshold value in floating point that needs to be between 0.0 to 1.0
    BARCODE1For capi_yolov5_ensemble pipeline, you can enable barcode detection. value: 0 or 1
    -

    details of yolov5s pipeline environment variable file can be viewed in configs/opencv-ovms/envs/capi_yolov5_ensemble.env.

    -

    Add A Profile Launcher Configuration File

    -

    The details about Profile Launcher configuration can be found here, details for yolov5 pipeline profile launcher configuration can be viewed in configs/opencv-ovms/cmd_client/res/capi_yolov5_ensemble/configuration.yaml

    -

    Build and Run

    -

    Here are the quick start steps to build and run capi yolov5 pipeline profile :

    -
      -
    1. Build docker image with profile-launcher: make build-capi_yolov5_ensemble
    2. -
    3. Download sample video files: cd benchmark-scripts/ && ./download_sample_videos.sh && cd ..
    4. -
    5. Start simulator camera: make run-camera-simulator
    6. -
    7. To start the pipeline run: PIPELINE_PROFILE="capi_yolov5_ensemble" RENDER_MODE=1 sudo -E ./run.sh --platform core --inputsrc rtsp://127.0.0.1:8554/camera_0
    8. -
    -
    -

    Note

    -

    The pipeline will automatically download the OpenVINO model files listed in configs/opencv-ovms/models/2022/config_template.json

    -
    -

    Clean Up

    -

    To stop existing container: make clean-capi_yolov5_ensemble -To stop all running containers including camera simulator and remove all log files: make clean-all

    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/OVMS/capiYolov5PipelineRun.html b/docs/OVMS/capiYolov5PipelineRun.html deleted file mode 100644 index 392949de..00000000 --- a/docs/OVMS/capiYolov5PipelineRun.html +++ /dev/null @@ -1,1513 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - OpenVINO OVMS C-API Yolov5 Pipeline Run - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    OpenVINO OVMS C-API Yolov5 Pipeline Run

    -

    OpenVINO Model Server has many ways to run inferencing pipeline: -TensorFlow Serving gRPC API, KServe gRPC API, TensorFlow Serving REST API, KServe REST API and OVMS C API through OpenVINO model server (OVMS). Here we are demonstrating for using OVMS C API method to run inferencing pipeline yolov5s model in following steps:

    -
      -
    1. Add new section to model configuration file for model server
    2. -
    3. Add pipeline specific files
    4. -
    5. Add environment variable file dependency
    6. -
    7. Add a profile launcher pipeline configuration file
    8. -
    9. Build and run
    10. -
    -

    Add New Section To Model Config File for Model Server

    -

    Here is the template config file location: configs/opencv-ovms/models/2022/config_template.json, edit the file and append the new model's configuration into the template, such as yolov5 model as shown below: -

        {
    -      "config": {
    -        "name": "yolov5s",
    -        "base_path": "/models/yolov5s/FP16-INT8",
    -        "layout": "NHWC:NCHW",
    -        "shape": "(1,416,416,3)",
    -        "nireq": 1,
    -        "batch_size": "1",
    -        "plugin_config": {
    -          "PERFORMANCE_HINT": "LATENCY"
    -        },
    -        "target_device": "{target_device}"
    -      }
    -    }
    -

    -
    -

    Note

    -

    shape is optional and takes precedence over batch_size, please remove this attribute if you don't know the value for the model.

    -
    -
    -

    Note

    -

    Please leave target_device value as it is, as the value {target_device} will be recognized and replaced by script run.

    -
    -

    You can find the parameter description in the ovms docs.

    -

    Add pipeline specific files

    -

    Here is the list of files we added in directory of configs/opencv-ovms/gst_capi/pipelines/capi_yolov5/:

    -
      -
    1. main.cpp - this is all the work about pre-processing before sending to OVMS for inferencing and post-processing for displaying.
    2. -
    3. Makefile - to help building the pre-processing and post-processing binary.
    4. -
    -

    Add Environment Variable File

    -

    You can add multiple environment variable files to configs/opencv-ovms/envs/ directory for your pipeline, we've added capi_yolov5.env for yolov5 pipeline run. Below is a list of explanation for all environment variables and current default values we set, this list can be extended for any future modification.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    EV NameDefault ValueDescription
    RENDER_PORTRAIT_MODE1rendering in portrait mode, value: 0 or 1
    GST_DEBUG1running GStreamer in debug mode, value: 0 or 1
    USE_ONEVPL1using OneVPL CPU & GPU Support, value: 0 or 1
    PIPELINE_EXEC_PATHpipelines/capi_yolov5/capi_yolov5pipeline execution path inside container
    GST_VAAPI_DRM_DEVICE/dev/dri/renderD128GStreamer VAAPI DRM device input
    TARGET_GPU_DEVICE--privilegedallow using GPU devices if any
    LOG_LEVEL0GST_DEBUG log level to be set when running gst pipeline
    RENDER_MODE1option to display the input source video stream with the inferencing results, value: 0 or 1
    cl_cache_dir/home/intel/gst-ovms/.cl-cachecache directory in container
    WINDOW_WIDTH1920display window width
    WINDOW_HEIGHT1080display window height
    DETECTION_THRESHOLD0.7detection threshold value in floating point that needs to be between 0.0 to 1.0
    -

    details of yolov5s pipeline environment variable file can be viewed in configs/opencv-ovms/envs/capi_yolov5.env.

    -

    Add A Profile Launcher Configuration File

    -

    The details about Profile Launcher configuration can be found here, details for yolov5 pipeline profile launcher configuration can be viewed in configs/opencv-ovms/cmd_client/res/capi_yolov5/configuration.yaml

    -

    Build and Run

    -

    Here are the quick start steps to build and run capi yolov5 pipeline profile :

    -
      -
    1. Build docker image with profile-launcher: make build-capi_yolov5
    2. -
    3. Download sample video files: cd benchmark-scripts/ && ./download_sample_videos.sh && cd ..
    4. -
    5. Start simulator camera: make run-camera-simulator
    6. -
    7. To start the pipeline run: PIPELINE_PROFILE="capi_yolov5" RENDER_MODE=1 sudo -E ./run.sh --platform core --inputsrc rtsp://127.0.0.1:8554/camera_1
    8. -
    -
    -

    Note

    -

    The pipeline will automatically download the OpenVINO model files listed in configs/opencv-ovms/models/2022/config_template.json

    -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/OVMS/pipelineDockerCompose.html b/docs/OVMS/pipelineDockerCompose.html deleted file mode 100644 index c87b0deb..00000000 --- a/docs/OVMS/pipelineDockerCompose.html +++ /dev/null @@ -1,1525 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - Run Pipelines with Docker-Compose for Developer Toolbox - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    Docker-Compose for Developer Toolbox

    -

    Pipelines can be run using docker-compose files. Changes are custom made inside the docker-compose.yml file for integration with the Developer Toolbox.

    -
    -

    Note

    -

    To utilize all the features offered by Automated Self-Checkout, run the pipelines as illustrated in the section Run Pipelines.

    -
    -

    Steps to Run Pipelines

    -
      -
    1. -

      Before running, complete the prerequisites for setting Up the Pipelines. - !!! Note - Ensure Docker Compose v2 is installed in order to run the pipelines via this feature.

      -
    2. -
    3. -

      Customize the docker-compose.yml to add the number of camera simulators required and the number of different type of pipelines that need to be run

      -
      -

      Note

      -

      Follow all the instructions in docker-compose.yml for customizations.

      -
      -
    4. -
    5. -

      Run the pipelines

      -
      make run-pipelines
      -
      -
    6. -
    7. -

      All the containers i.e camera simulators, OVMS server and pipelines should start without any errors in portainer as shown below in Figure 1

      -

      -Figure 1: Pipelines Running Successfully -
      Figure 1: Pipelines Running Successfully
      -

      -
    8. -
    9. -

      Stop the pipelines

      -
      make down-pipelines
      -
      -
    10. -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/OVMS/pipelinerun.html b/docs/OVMS/pipelinerun.html deleted file mode 100644 index 63ef07b7..00000000 --- a/docs/OVMS/pipelinerun.html +++ /dev/null @@ -1,1565 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - Custom Run Pipelines - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    Customized Run Pipeline

    -

    Overview

    -

    When the pipeline is run, the run.sh script starts the service and performs inferencing on the selected input media. The output of running the pipeline provides the inference results for each frame based on the media source such as text, barcode, and so on, as well as the frames per second (FPS). Pipeline run provides many options in media type, system process platform type, and additional optional parameters. These options give you the opportunity to compare what system process platform is better for your need.

    -

    Start Pipeline

    -

    You can run the pipeline script, run.sh with a given pipeline profile via the environment variable PIPELINE_PROFILE, and the following additional input parameters:

    -
      -
    1. Media type -
    2. -
    3. Platform
        -
      • core
      • -
      • dgpu.0
      • -
      • dgpu.1
      • -
      • xeon
      • -
      -
    4. -
    5. Environment Variables
    6. -
    -

    Run the command based on your requirement. Once choices are selected for #1-3 above, to start the pipeline run, use the commands from the Examples section below.

    -

    Examples using different input source types

    -

    In the following examples, environment variables are used to select the desired PIPELINE_PROFILE and RENDER_MODE. This table uses run.sh to run the object_detection pipeline profile:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Input source TypeInput Source ParameterCommand
    Simulated camerartsp://127.0.0.1:8554/camera_XPIPELINE_PROFILE="object_detection" RENDER_MODE=1 sudo -E ./run.sh --platform core|xeon|dgpu.x --inputsrc rtsp://127.0.0.1:8554/camera_1
    RealSense camera<serial_number> --realsense_enabledPIPELINE_PROFILE="object_detection" RENDER_MODE=1 sudo -E ./run.sh --platform core|xeon|dgpu.x --inputsrc --realsense_enabled
    USB camera/dev/video0PIPELINE_PROFILE="object_detection" RENDER_MODE=1 sudo -E ./run.sh --platform core|xeon|dgpu.x --inputsrc /dev/video0
    Video filefile:my_video_file.mp4PIPELINE_PROFILE="object_detection" RENDER_MODE=1 sudo -E ./run.sh --platform core|xeon|dgpu.x --inputsrc file:my_video_file.mp4
    -
    -

    Note

    -

    The value of x in dgpu.x can be 0, 1, 2, and so on depending on the number of discrete GPUs in the system.

    -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/OVMS/pipelinesetup.html b/docs/OVMS/pipelinesetup.html deleted file mode 100644 index ff048e71..00000000 --- a/docs/OVMS/pipelinesetup.html +++ /dev/null @@ -1,1555 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - Setup Pipelines - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    Set up Pipeline

    -
      -
    1. -

      Clone the repository

      -
      git clone  https://github.com/intel-retail/automated-self-checkout.git && cd ./automated-self-checkout
      -
      -
    2. -
    3. -

      Build the profile launcher binary executable

      -
      make build-profile-launcher
      -
      -

      Each profile is an unique pipeline use case. We provide some profile examples, and the configuration examples of profiles are located here. Go here to find out the detail descriptions for the configuration of profile used by profile launcher.

      -
    4. -
    5. -

      Build the benchmark Docker images

      -
      cd benchmark-scripts
      -make build-all
      -
      -cd ..
      -
      -
      -

      Note

      -

      A successfully built benchmark Docker images should contain the following Docker images from docker images benchmark --format 'table{{.Repository}}\t{{.Tag}}' command:

      -
        -
      • benchmark:dev
      • -
      • benchmark:xpu
      • -
      • benchmark:igt
      • -
      -
      -
      -

      Note

      -

      After successfully built benchmark Docker images, please remember to change the directory back to the project base directory from the current benchmark-scripts directory (i.e. cd ..) for the following steps.

      -
      -
    6. -
    7. -

      Download the models manually (Optional)

      -
      -

      Note

      -

      The model downloader script is automatically called as part of run.sh.

      -
      -
      ./download_models/getModels.sh
      -
      -
      -

      Warning

      -

      Depending on your internet connection, this might take some time.

      -
      -
    8. -
    9. -

      (Optional) Download the video file manually. This video is used as the input source to give to the pipeline.

      -
      -

      Note

      -

      The sample image downloader script is automatically called as part of run.sh.

      -
      -
      ./configs/opencv-ovms/scripts/image_download.sh
      -
      -
      -

      Warning

      -

      Depending on your internet connection, this might take some time.

      -
      -
    10. -
    11. -

      (optional) Download the bit model manually

      -

      a. Here is the command to build the container for bit model downloading:

      -
      docker build -f Dockerfile.bitModel -t bit_model_downloader:dev .
      -
      -

      b. Here is the script to run the container that downloads the bit models:

      -
      docker run bit_model_downloader:dev
      -
      -
    12. -
    13. -

      Build the reference design images. This table shows the commands for the OpenVINO (OVMS) model Server and profile-launcher build command:

      - - - - - - - - - - - - - - - - - - - - -
      TargetDocker Build CommandCheck Success
      OVMS Server
      make build-ovms-server
      docker images command output contains Docker image openvino/model_server:2023.1-gpu
      OVMS Profile Launcher
      make build-profile-launcher
      ls -al ./profile-launcher command to show the binary executable
      -
      -

      Note

      -

      Build command may take a while, depending on your internet connection and machine specifications.

      -
      -
      -

      Note

      -

      If the build command succeeds, you will see all the built Docker images files as indicated in the Check Success column. If the build fails, check the console output for errors.

      -
      -
      -

      Proxy

      -

      If docker build system requires a proxy network, just set your proxy env standard way on your terminal as below and make build:

      -
      export HTTP_PROXY="http://your-proxy-url.com:port"
      -export HTTPS_PROXY="https://your-proxy-url.com:port"
      -make build-ovms-server
      -make build-profile-launcher
      -
      -
      -
    14. -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/OVMS/profileLauncherConfigs.html b/docs/OVMS/profileLauncherConfigs.html deleted file mode 100644 index 8c2f1753..00000000 --- a/docs/OVMS/profileLauncherConfigs.html +++ /dev/null @@ -1,1504 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - Profile Configuration - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    Profile Configuration

    -

    For the profile launcher, each profile has its own configuration for different pipelines. The configuration of each profile is done through a yaml configuration file, configuration.yaml. One example of configuration.yaml is shown here for classification profile:

    -
    OvmsSingleContainer: false
    -OvmsServer:
    -  ServerDockerScript: start_ovms_server.sh
    -  ServerDockerImage: openvino/model_server:2023.1-gpu
    -  ServerContainerName: ovms-server
    -  ServerConfig: "/models/config.json"
    -  StartupMessage: Starting OVMS server
    -  InitWaitTime: 10s
    -  EnvironmentVariableFiles:
    -    - ovms_server.env
    -  # StartUpPolicy:
    -  # when there is an error on launching ovms server startup, choose one of these values for the behavior of profile-launcher: 
    -  #   remove-and-restart: it will remove the existing container with the same container name if any and then restart the container
    -  #   exit: it will exit the profile-launcher and 
    -  #   ignore: it will ignore the error and continue (this is the default value if not given or none of the above)
    -  StartUpPolicy: ignore    
    -OvmsClient:
    -  DockerLauncher:
    -    Script: docker-launcher.sh
    -    DockerImage: python-demo:dev
    -    ContainerName: classification
    -    Volumes:
    -      - "$RUN_PATH/results:/tmp/results"
    -      - ~/.Xauthority:/home/dlstreamer/.Xauthority
    -      - /tmp/.X11-unix
    -  PipelineScript: ./classification/python/entrypoint.sh
    -  PipelineInputArgs: "" # space delimited like we run the script in command and take those input arguments
    -  EnvironmentVariableFiles:
    -    - classification.env
    -
    -

    The description of each configuration element is explained below:

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Configuration ElementDescription
    OvmsSingleContainerThis boolean flag indicates whether this profile is running as a single OpenVino Model Server (OVMS) container or not, e.g. the C-API pipeline use case will use this as true.
    It can indicate the distributed architecture of OVMS client-server when this flag is false.
    OvmsServerThis is configuration section for OpenVino Model Server in the case of client-server architecture.
    OvmsServer/ServerDockerScriptThe infra-structure shell script to start an instance of OVMS server.
    OvmsServer/ServerDockerImageThe Docker image tag name for OpenVino Model Server.
    OvmsServer/ServerContainerNameThe Docker container base name for OpenVino Model Server.
    OvmsServer/ServerConfigThe model config.json file name path for OpenVino Model Server.
    OvmsServer/StartupMessageThe starting message shown in the console or log when OpenVino Model Server instance is launched.
    OvmsServer/InitWaitTimeThe waiting time duration (like 5s, 5m, .. etc) after OpenVino Model Server is launched to allow some settling time before launching the pipeline from the client.
    OvmsServer/EnvironmentVariableFilesThe list of environment variable files applied for starting OpenVino Model Server Docker instance.
    OvmsServer/StartUpPolicyThis configuration controls the behavior of OpenVino Model Server Docker instance when there is error occurred during launching.
    Use one of these values:
    remove-and-restart: it will remove the existing container with the same container name if any and then restart the container
    exit: it will exit the profile-launcher
    ignore: it will ignore the error and continue (this is the default value if not given or none of the above).
    OvmsClientThis is configuration section for the OVMS client running pipelines in the case of client-server architecture.
    The C-API pipeline use case should also use this section to configure.
    OvmsClient/DockerLauncherThis is configuration section for the generic Docker launcher to run pipelines for a given profile.
    OvmsClient/DockerLauncher/ScriptThe generic Docker launcher script file name.
    OvmsClient/DockerLauncher/DockerImageThe Docker image tag name for the pipeline profile.
    OvmsClient/DockerLauncher/ContainerNameThe Docker container base name for the running pipeline profile.
    OvmsClient/DockerLauncher/VolumesThe Docker container volume mounts for the running pipeline profile.
    OvmsClient/PipelineScriptThe file name path for the pipeline profile to launch. The file path here is in the perspective of the running container. i.e. the path inside the running container.
    OvmsClient/PipelineInputArgsAny input arguments or parameters for the above pipeline script to take. Like any command line argument, they are space-delimited if multiple arguments.
    OvmsClient/EnvironmentVariableFilesThe list of environment variable files applied for the running pipeline profile Docker instance.
    -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/OVMS/quick_pipelinerun.html b/docs/OVMS/quick_pipelinerun.html deleted file mode 100644 index bb72fa12..00000000 --- a/docs/OVMS/quick_pipelinerun.html +++ /dev/null @@ -1,1697 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - Quick Start Run Pipeline - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    Quick Start Guide to Run Pipeline

    -

    Prerequisites

    -

    Before running, set up the pipeline.

    -

    Running OVMS with the camera simulator

    -

    Start the Camera Simulator

    -
      -
    1. -

      Download the video files to the sample-media directory: -

      cd benchmark-scripts;
      -./download_sample_videos.sh;
      -cd ..;
      -

      -
      -

      Example - Specify Resolution and Framerate

      -

      This example downloads a sample video for 1080p@15fps. -

      cd benchmark-scripts;
      -./download_sample_videos.sh 1920 1080 15;
      -cd ..;
      -

      -
      -
      -

      Note

      -

      Only AVC encoded files are supported.

      -
      -
    2. -
    3. -

      After the video files are downloaded to the sample-media folder, start the camera simulator: -

      make run-camera-simulator
      -

      -
    4. -
    5. -

      Wait for few seconds, and then check if the camera-simulator containers are running: -

      docker ps --format 'table{{.Image}}\t{{.Status}}\t{{.Names}}'
      -

      -
      -

      Success

      -

      Your output is as follows:

      - - - - - - - - - - - - - - - - - - - - -
      IMAGESTATUSNAMES
      openvino/ubuntu20_data_runtime:2021.4.2Up 11 secondscamera-simulator0
      aler9/rtsp-simple-serverUp 13 secondscamera-simulator
      -
      -

      Note

      -

      There could be multiple containers with the image "openvino/ubuntu20_data_runtime:2021.4.2", depending on the number of sample-media video files provided.

      -
      -
      -
      -

      Failure

      -

      If all the Docker* containers are not visible, then review the console output for errors. Sometimes dependencies fail to resolve. Address obvious issues and retry.

      -
      -
    6. -
    -

    Run Instance Segmentation

    -

    There are several pipeline profiles to chose from. Use the make list-profiles to see the different pipeline options. In this example, the instance_segmentation pipeline profile will be used.

    -
      -
    1. -

      Use the following command to run instance segmentation using OVMS on core.

      -
      PIPELINE_PROFILE="instance_segmentation" RENDER_MODE=1 sudo -E ./run.sh --platform core --inputsrc rtsp://127.0.0.1:8554/camera_0
      -
      -
    2. -
    3. -

      Check the status of the pipeline.

      -
      docker ps --format 'table{{.Image}}\t{{.Status}}\t{{.Names}}' -a
      -
      -
      -

      Success

      -

      Here is a sample output:

      - - - - - - - - - - - - - - - -
      IMAGESTATUSNAMES
      openvino/model_server-gpu:latestUp 59 secondsovms-server0
      -
      -
      -

      Failure

      -

      If you do not see above Docker container(s), review the console output for errors. Sometimes dependencies fail to resolve and must be run again. Address obvious issues and try again repeating the above steps. Here are couple debugging tips:

      -
        -
      1. -

        check the docker logs using following command to see if there is an issue with the container

        -
        docker logs <containerName>
        -
        -
      2. -
      3. -

        check ovms log in automated-self-checkout/results/r0.jsonl

        -
      4. -
      -
      -
    4. -
    5. -

      Check the output in the results directory.

      -
      -

      Example - results/r0.jsonl sample

      -

      The output in results/r0.jsonl file lists average processing time in milliseconds and average number of frames per second. This file is intended for scripts to parse. -

      Processing time: 53.17 ms; fps: 18.81
      -Processing time: 47.98 ms; fps: 20.84
      -Processing time: 48.35 ms; fps: 20.68
      -Processing time: 46.88 ms; fps: 21.33
      -Processing time: 47.56 ms; fps: 21.03
      -Processing time: 49.66 ms; fps: 20.14
      -Processing time: 52.49 ms; fps: 19.05
      -Processing time: 52.27 ms; fps: 19.13
      -Processing time: 50.86 ms; fps: 19.66
      -Processing time: 58.19 ms; fps: 17.18
      -Processing time: 58.28 ms; fps: 17.16
      -Processing time: 52.17 ms; fps: 19.17
      -Processing time: 50.89 ms; fps: 19.65
      -Processing time: 49.58 ms; fps: 20.17
      -Processing time: 51.14 ms; fps: 19.55
      -

      -
      -
      -

      Example - results/pipeline0.log sample

      -

      The output in results/pipeline0.log lists average number of frames per second. Below is a snap shot of the output: -

      18.81
      -20.84
      -20.68
      -21.33
      -21.03
      -20.14
      -19.05
      -19.13
      -19.66
      -17.18
      -17.16
      -19.17
      -19.65
      -20.17
      -19.55
      -

      -
      -
      -

      Note

      -

      The automated-self-checkout/results/ directory is volume mounted to the pipeline container.

      -
      -
    6. -
    -

    Stop running the pipelines

    -
      -
    1. To stop the instance segmentation container and clean up, run -
      make clean-all
      -
    2. -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/OVMS/quick_stream_density.html b/docs/OVMS/quick_stream_density.html deleted file mode 100644 index 4ec4a96b..00000000 --- a/docs/OVMS/quick_stream_density.html +++ /dev/null @@ -1,1679 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - Stream Density Quick Start Guide - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    Quick Start Guide to Run Pipeline Stream Density

    -

    In this section, we show the steps to run the stream density for a chosen pipeline profile. By definition, the objective of the stream density is -to bench-mark the maximum number of multiple running pipelines at the same time while still maintaining the goal-setting target frames-per-second (FPS).

    -

    Prerequisites

    -

    Before running, set up the pipeline if not already done.

    -

    Stop All Other Running Pipelines

    -

    To make sure we have a good stream density benchmarking, it is recommended to stop all other running pipelines before running the stream density. -To stop all running pipelines and clean up, run -

    make clean-all
    -

    -

    Build Benchmark Docker Images

    -

    For running stream density, the benchmark scripts are utilized. To set up the benchmarking, we need to build the benchmark Docker images first.

    -
      -
    1. -

      Build the benchmark Docker* images - Benchmark scripts are containerized inside Docker. These scripts are dependent on the platform.

      -
      -
      -
      -
      cd ./benchmark-scripts
      -make build-benchmark
      -make build-igt
      -
      -
      -

      Success

      -

      Run docker images to ensure that both the benchmark:dev and benchmark:igt images were built.

      -
      -
      -
      -
      cd ./benchmark-scripts
      -make build-benchmark
      -make build-xpu
      -
      -
      -

      Success

      -

      Run docker images to ensure that both the benchmark:dev and benchmark:xpu images were built.

      -
      -
      -
      -
      -
    2. -
    -
    -

    Warning

    -

    Build command may take a while, depending on your internet connection and machine specifications.

    -
    -

    Start the Camera Simulator

    -

    We will use the camera simulator as the input source to show the stream density. Please refer to the section of Start the Camera Simulator in Quick Start Guide to Run Pipeline on how to start the camera simulator.

    -

    Run Objection Detection Pipeline Stream Density

    -

    There are several pipeline profiles to choose from for running pipeline stream density. Use the make list-profiles to see the different pipeline options. In this example, the object_detection pipeline profile will be used for running stream density.

    -
      -
    1. -

      To run the stream density, the benchmark shell script, benchmark.sh, is used. The script is in the <project_base_dir>/benchmark-scripts directory. Use the following command to run objection detection pipeline profile using OVMS on core.

      -
      cd ./benchmark-scripts
      -PIPELINE_PROFILE="object_detection" RENDER_MODE=0 sudo -E ./benchmark.sh --stream_density 15.0 --logdir object_detection/data --duration 120 --init_duration 40 --platform core --inputsrc rtsp://127.0.0.1:8554/camera_1
      -
      -
      -

      Note

      -

      Description of some key benchmarking input parameters is given as below:

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Parameter NameExample ValueDescription
      --stream_density15.0The value 15.0 after the --stream_density is the target FPS that we want to achieve for running maximum number of object detection pipelines while the averaged of all pipelines from the output FPS still maintaining that target FPS value.
      --logdirobject_detection/datathe output directory of benchmarking resource details
      --duration120the time duration, in number of seconds, the benchmarking will run
      --init_duration40the time duration, in number of seconds, to wait for system initialization before the benchmarking metrics or data collection begins
      -
      -
      -

      Note

      -

      For stream density run, it is recommended to turn off the display to conserve the system resources hence setting RENDER_MODE=0

      -
      -
      -

      Note

      -

      This takes a while for the whole stream density benchmarking process depending on your system resources like CPU, memory, ... etc.

      -
      -
      -

      Note

      -

      The benchmark.sh script automatically cleans all running Docker containers after it is done.

      -
      -

      If the hardware supports, then one can also run the benchmarking on different devices like CPU or GPU. This can be done through the environment variable DEVICE. The following is an example to run the object_detection profile using GPU:

      -
      PIPELINE_PROFILE="object_detection" RENDER_MODE=0 DEVICE="GPU" sudo -E ./benchmark.sh --stream_density 14.95 --logdir object_detection/data --duration 120 --init_duration 40 --platform dgpu.0 --inputsrc rtsp://127.0.0.1:8554/camera_1
      -
      -
      -

      Note

      -

      The performance of running object detection benchmarking should be better while running on GPU using model precision FP32. If supported, then you can change the model precision by going to the folder configs/opencv-ovms/models/2022 from the root of project folder and editing the base_path for that particular model in the config_template.json file. For example, you can change the the base_path of FP32 to FP16 assuming the precision FP16 of the model is available:

      -
          ...
      -    "config": {
      -    "name": "ssd_mobilenet_v1_coco",
      -    "base_path": "/models/ssd_mobilenet_v1_coco/FP32",
      -    ...
      -    }
      -
      -

      The directory structure of models with both precisions should look like the followings:

      -
      ssd_mobilenet_v1_coco
      -├── FP32
      -|   └── 1
      -|       ├── ssd_mobilenet_v1_coco.bin
      -|       └── ssd_mobilenet_v1_coco.xml
      -├── FP16
      -|   └── 1
      -|       ├── ssd_mobilenet_v1_coco.bin
      -|       └── ssd_mobilenet_v1_coco.xml
      -
      -
      -
    2. -
    3. -

      Check the output in the base results directory.

      -

      After the stream density is done, the results of stream density can be seen on the base directory of the results directory:

      -
      cat ../results/stream_density.log
      -
      -
      -

      Example - results/stream_density.log sample

      -

      The output in results/stream_density.log file gives the detailed information of stream density results: -

         ......
      -   FPS for pipeline0: 15.1225
      -   FPS for pipeline1: 15.19
      -   FPS for pipeline2: 15.18
      -   Total FPS throughput: 45.4925
      -   Total FPS per stream: 15.1642
      -   Max stream density achieved for target FPS 15.0 is 3
      -   Finished stream density benchmarking
      -   stream_density done!
      -

      -
      -
    4. -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/OVMS/runObjectDetectionPipelineWithNewModel.html b/docs/OVMS/runObjectDetectionPipelineWithNewModel.html deleted file mode 100644 index 2b03a99d..00000000 --- a/docs/OVMS/runObjectDetectionPipelineWithNewModel.html +++ /dev/null @@ -1,1653 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - Object Detection Pipeline - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    Run Object Detection Pipeline with New Model

    -

    OpenVINO Model Server has many ways to run inferencing pipeline: -TensorFlow Serving gRPC API, KServe gRPC API, TensorFlow Serving REST API, KServe REST API and OVMS C API through OpenVINO model server (OVMS). For running object detection pipeline, it is based on KServe gRPC API method, default model used is ssd_mobilenet_v1_coco. You can use different model to run object detection. Here are the steps:

    -
      -
    1. Add new section to config file for model server
    2. -
    3. Download new model
    4. -
    5. Update environment variables of detection pipeline for new model
    6. -
    7. Build and Run
    8. -
    -

    Add New Section to Config File for Model Server

    -

    Here is the config file location: configs/opencv-ovms/models/2022/config_template.json, edit the file and append the following configuration section template -

    ,
    -{
    -      "config": {
    -        "name": "ssd_mobilenet_v1_coco",
    -        "base_path": "/models/ssd_mobilenet_v1_coco/FP32",
    -        "nireq": 1,
    -        "batch_size": "1",
    -        "plugin_config": {
    -          "PERFORMANCE_HINT": "LATENCY"
    -        },
    -        "target_device": "{target_device}"
    -      },
    -      "latest": {
    -        "num_versions": 1
    -      }
    -    }
    -

    -
    -

    Note

    -

    Please leave target_device value as it is, as the value {target_device} will be recognized and replaced by script run.

    -
    -

    You can find the parameter description in the ovms docs.

    -

    Download New Model

    -

    The pipeline run script automatically download the model files if it is part of open model zoo supported list; otherwise, please add your model files manually to configs/opencv-ovms/models/2022/. When you add your model manually, make sure to follow the model file structure as //1/modelfiles, for example:

    -
    ssd_mobilenet_v1_coco
    -├── FP32
    -   └── 1
    -       ├── ssd_mobilenet_v1_coco.bin
    -       └── ssd_mobilenet_v1_coco.xml
    -
    -

    Update Environment Variables

    -

    You can update the object detection environment variables in file: configs/opencv-ovms/envs/object_detection.env, here is default value and explanation for each environment variable:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    EV NameDefault ValueDescription
    DETECTION_MODEL_NAMEssd_mobilenet_v1_cocomodel name for object detection
    DETECTION_LABEL_FILEcoco_91cl_bkgr.txtlabel file name to use on object detection for model
    DETECTION_ARCHITECTURE_TYPEssdarchitecture type for object detection model
    DETECTION_OUTPUT_RESOLUTION1920x1080output resolution for object detection result
    DETECTION_THRESHOLD0.50threshold for object detection in floating point that needs to be between 0.0 to 1.0
    MQTTenable MQTT notification of result, value: empty
    RENDER_MODE1display the input source video stream with the inferencing results, value: 0
    -

    Build and Run Pipeline

    -
      -
    1. -

      Build the python app and profile-launcher:

      -
       make build-python-apps
      -
      -
    2. -
    3. -

      Download sample video files:

      -
      cd benchmark-scripts/ && ./download_sample_videos.sh && cd ..
      -
      -
    4. -
    5. -

      Start simulator camera if not started:

      -
      make run-camera-simulator
      -
      -
    6. -
    7. -

      (Optional) Run MQTT broker:

      -
      docker run --network host --rm -d -it -p 1883:1883 -p 9001:9001 eclipse-mosquitto
      -
      -
    8. -
    9. -

      Start the object detection pipeline:

      -
      PIPELINE_PROFILE="object_detection" RENDER_MODE=1 MQTT=127.0.0.1:1883 sudo -E ./run.sh --platform core --inputsrc rtsp://127.0.0.1:8554/camera_0
      -
      -
      -

      Note

      -

      Remove the MQTT environment variable if not using it.

      -
      -
    10. -
    11. -

      If using MQTT, use the same container name as the MQTT topic to subscribe to the inference metadata. Use the command docker ps to know the container name.

      -
    12. -
    13. -

      Use one of the following commands for stopping and cleaning up:

      -
        -
      1. -

        To stop and clean up the client side containers, run:

        -
        make clean-profile-launcher
        -
        -
      2. -
      3. -

        To stop and clean up everything, run:

        -
        make clean-all
        -
        -
      4. -
      -
    14. -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/OVMS/supportingDifferentLanguage.html b/docs/OVMS/supportingDifferentLanguage.html deleted file mode 100644 index 44bddfc8..00000000 --- a/docs/OVMS/supportingDifferentLanguage.html +++ /dev/null @@ -1,1516 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - Supporting Different Languages - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    Supporting Different Languages

    -

    For running OVMS as inferencing engine through grpc, these are the supported languages:

    -
      -
    1. python
    2. -
    3. golang
    4. -
    -

    Sample Commands using the Camera Simulator

    - - - - - - - - - - - - - - - - - -
    Input source TypeCommand
    PythonPIPELINE_PROFILE="grpc_python" sudo -E ./run.sh --platform core --inputsrc rtsp://127.0.0.1:8554/camera_1
    GolangPIPELINE_PROFILE="grpc_go" sudo -E ./run.sh --platform core --inputsrc rtsp://127.0.0.1:8554/camera_1
    -
    -

    Note

    -

    Above example scripts are based on camera simulator for rtsp input source, before running them, please run the camera simulator. If you used a different input source, fill in the appropriate value for --inputsrc.

    -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/OVMS/supportingDifferentModel.html b/docs/OVMS/supportingDifferentModel.html deleted file mode 100644 index 278f4f08..00000000 --- a/docs/OVMS/supportingDifferentModel.html +++ /dev/null @@ -1,1524 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - Supporting Different Models - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    Supporting Different Models

    -

    For running OVMS as inferencing engine through grpc, we are supporting different models for your need.

    -

    Models Supported In Python

    -

    Here is the list of inferencing models we are currently supporting in python:

    -
      -
    1. instance-segmentation-security-1040
    2. -
    3. bit_64
    4. -
    -

    You can switch between them by editing the configuration file configs/opencv-ovms/cmd_client/res/grpc_python/configuration.yaml, uncomment # PipelineInputArgs: "--model_name instance-segmentation-security-1040" for supporting instance-segmentation-security-1040 and comment out rest; or you can uncomment # PipelineInputArgs: "--model_name bit_64" for supporting bit_64 and comment out rest.

    -

    Here is the configuration.yaml content, default to use instance-segmentation-security-1040 model -

    OvmsClient:
    -  PipelineScript: run_grpc_python.sh
    -  PipelineInputArgs: "--model_name instance-segmentation-security-1040" # space delimited like we run the script in command and take those input arguments
    -  # PipelineInputArgs: "--model_name bit_64" # space delimited like we run the script in command and take those input arguments
    -  # PipelineInputArgs: "--model_name yolov5s" # space delimited like we run the script in command and take those input arguments
    -

    -

    Download Models

    -

    You can download models by editing download_models/models.lst file, you can add new models(from https://github.com/openvinotoolkit/open_model_zoo/blob/master/demos/object_detection_demo/python/models.lst) to it or uncomment from existing list in this file, saved the file once editing is done. Then you can download the list using following steps:

    -
      -
    1. cd download_models
    2. -
    3. make build
    4. -
    5. make run
    6. -
    -

    after above steps, the downloaded models can be found in configs/opencv-ovms/models/2022 directory.

    -
    -

    Note

    -

    Model files in configs/opencv-ovms/models/2022 directory will be replaced with new downloads if previously existed.

    -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/faq.html b/docs/faq.html deleted file mode 100644 index 68cc9f25..00000000 --- a/docs/faq.html +++ /dev/null @@ -1,1549 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - FAQs - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    Frequently Asked Questions

    -

    What are the platform requirements?

    -

    For optimal hardware, refer to the platform guide.

    -

    What are the software prerequisites?

    -

    At a minimum, you will need Docker* 23.0 or later. For more details, refer to the hardware setup.

    -

    How do I download the models?

    -

    The models are downloaded automatically when the benchmark script benchmark.sh is run. For more details on downloading models, refer to Pipeline Setup.

    -

    How do I simulate RTSP cameras?

    -

    You can use the camera simulator script camera-simulator.sh to run simulated RTSP camera streams. For more details on the script, refer to Run Camera Simulator page.

    -

    How do I download video files for benchmarking?

    -

    You can download your own media file or use the the provided download_sample_videos.sh script to download an existing media file. For more details, refer to Benchmark Pipeline.

    -

    How do I run different types of pipelines?

    -

    For details on running different types of pipelines, refer to Quick Start Guide.

    -

    Where are the pipeline container logs located ?

    -

    Pipeline container logs are redirected to a text file at automated-self-checkout/results. For every new pipeline a new log file pipeline##.log (eg.: pipeline0.log, pipeline1.log, ... etc.) is created.

    -
    -

    Note

    -

    As pipeline container logs are redirected to separate text files, docker logs displayed using portainer or command docker logs <**CONTAINER**> will be empty.

    -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/hardwaresetup.html b/docs/hardwaresetup.html deleted file mode 100644 index 0c938fe1..00000000 --- a/docs/hardwaresetup.html +++ /dev/null @@ -1,1548 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - System Setup - Intel® Automated Self-Checkout Reference Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - - - - - - - -
    - - - - - - - -
    - -
    - - - - -
    -
    - - - -
    -
    -
    - - - - - - - - - -
    -
    -
    - - - - -
    -
    - - - - - - - -

    System Setup

    -

    Prerequisites

    -

    To build the Intel® Automated Self-Checkout Reference Package, you need:

    - -

    Click the links for corresponding set up instructions.

    -

    Hardware Dependent Installation

    -
    -
    -
    -
      -
    1. -

      Download Ubuntu 22.04 and follow these installation steps.

      -
    2. -
    3. -

      Install Docker* Engine

      -
      -

      Note

      -

      To avoid typing sudo when running the Docker command, follow these steps.

      -
      -
    4. -
    5. -

      [Optional] Install Docker Compose v2, if using the docker compose feature

      -
    6. -
    7. -

      Install Git

      -
    8. -
    9. -

      Set up the pipeline

      -
    10. -
    -
    -
    -
      -
    1. -

      Download Ubuntu 22.04 and follow these installation steps.

      -
    2. -
    3. -

      Install Docker Engine

      -
    4. -
    5. -

      [Optional] Install Docker Compose v2, if using the docker compose feature

      -
    6. -
    7. -

      Install Git

      -
    8. -
    9. -

      Set up the pipeline

      -
    10. -
    -
    -
    -
    - - - - - - - - - - - - - -
    -
    - - - -
    - - - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/images/dashboard.png b/docs/images/dashboard.png deleted file mode 100644 index edd0b40b4c16d07d60a59ad35f11384e88bc7963..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111670 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

    3yTIzUGl#8*K;lwN zpT+`QU_J1c%+dRn1Fk=&6!1bU+WSom({|LM^Nt|GpwJ_5wE^5B`%86kR52 zN`Kx{PS*&=21jI4FhKgSVd*n=tl}X*4Un|4-|phf|DzZ@LIUi9T_5cX_;Hl9+!gEw zuzM}+j0~0nN9YdMJFr}RQE?(OS-k7CcVSo~yV`5LdD3{(6Qw704kAsUI_6$M;SlgO zu!6lVpN$Ph-!zU7lMGL(yKzuA3sZcjp$`mOjbx{(-b)#Z7{|x`WOhY;ib{w;1=F>4 z)7i2%{rnRwE6X=S5L0tr^*1{%tp8bdv6*mC zv;o;k%-V?huN^s(KR2Wb5SdQWoB&o++Y*1_FpE{)c3(W3?hn=eYo33-qNPU+-^f>-GdKKi^7V!m?}HFzuF~< zpjp_{yxkEuEDvjXOa8OM5+=6C@O$vhS(fYJs#&v)J0U>Jx=jf-6`9+6Xus)XwgiIyRQY=bij%y%OjsH=hI(RK9`H7@Kp`#ln$7m z?y0R49ZWZ}E;x2p*qh$zyHmL3knt^1+bk?{xMz7SP%e^iq}&=`r#oRisVq$nOPpjw zbN3#bSGg?XoE=T@R%{I}JcOmi6`C@Zvf$`}MY|UX%w9+U<)|=Inm7!uhP>{KK&DeB z@)FooF>K@tj;8DEPi6&Ngn}%4RS%{`RXBP6NFJ_1pJoVW9rlf zMWHEu3$jAhRNFupcKvzjp6pwqE2EJ+GO$bt(Ae1jTgN^K>Vegm@l;wYFSj{$vv;2A zn#Ou1Kjp4XyodUCO8b;pl@q}7`$m%%1_!)_GS7X{FQWRV`cQwNG-k3s#8_X7&p;nV*1#rZPg*;@=AW4^$dHouJ1PsSNldHIe{x9 z%9g;cE*_!Z+a#i&j9Un^SufHfkTH+FU~GG?HLk1&B-y_j^k-?d;Yf$|>-`7pH{Uk0({fSA8#5e{DT zFC-S{`)O0PmFPs|nAX-i+4K`7e6bEiCm)@RQZH#A`Ah`gni5oa=<(=Zphf%J6eG{lKyeak0de?D|(d8QkiDlyS+!gvc66>|pAbqtKc zg%QluW1TG4m7+Nso5MX-;tP}AvWi7HAyY^T{scdBoytZ zdp;_0!L%6EyTrrwqX`Tab5{%nHb|6oXO37CVCddS#)ToRYq zPCB^_mOJhWVEW!nuEh_Wro0eGGZBls6QnfQRvQ|ddth8ls(A}Xx=weDo&W>$UpHYL zhfML~8&DlDsH!Rit__z^XGJ%8ZqhgQ=Y@`fo!!;h(ZMuQRe#;ML+p@m>z+B7+uw?c zN!j*7)mw(CKqv3;p7#6)6Isa4D2`dtz4PaIZ&cHtdD%TrYHFVRZ}o@ldRKDmP5bmr zWYSc76)An2)hvzL*sFXa~y>fR@@LEfRqQOc$$_lQTv-6S5B?74a0 z`zPApoTU=Im?XATiNg+mqWfUC9=$r4s zr|5}DkQ=sOem>19s)y_G_kHnKV74`s;mNOjXVpLi?@WYxMP;A5)8;r-y=4UhF; z#&|wuxjoGr;o*+mV&lXz#%4mzCTm+55`1WM0dXn4cSlggom95kRm{i{l^Cn_pTu48+fU881&BU7ldCNtm6POv&ww(P#D71E zDzJKHFB3wME2uJ)!sEpNO8yxfh(G%@ezaAYeC5K#>*ARyq%{5gs1v&hO-d1gtS`+3 z>tJn%=Mn6TD++O5rV9Ru_)aEyL>n9-D<}B;0!I5obO>lY|NMz`wChiFYkw~H{&u&o zE8$<}7EE2tF1Neu^6Vqp4TI!q@3v3s;?sr+${$|1dX!%p4|VVrgPn0$lkLBTY_~Z1 zEgWb?ijot3<{3!T%ARxE(NMEx;)<`TqPKJ^lbjw1ZL!o|^o?pyVEcvimu~A|3y2T5T`j6d@t@{q^w7Ci$Pb#?aBx25l-KC~jfn1d zz1zH!4;Shp2N(6euL4JZnF|>CGAF8>yqKl!D9Tdqj|ze$D`z)$=`vK@k-g)?lMz5K z=a}LdYrUC|lPhZ2H@sJJuN?s>!vyXOA4w8aT+avQwt6~FhkV`#>xMw| zGm*POKbkH1SEhY+LEb9{V9I6rMc6$$-H zoOm&F*3^u9E-Y05mkwp;%$sfHq5*E}6FBR7r zZ|#6kiM96R%U9%z)u!!hGo&HU=!a6SY6AnnCT^6mo;BI-CtLli(E6&S79S4v@T`L0 z);FwvL+D#iLbugsTQXV!OvbZ)=G5#b)==uIvGqsHj2uZDt4qwvgZ!wmd|`P<)g4;M`C3e3H^6N-_KFb3H3v6Ipo z!K*jHiw`MnIj-tqOVfe#4XSK^!s)+O=-gSpctpQc7if{59#&SCWLU>+@~kxi)a=>y zdeRX32d{`iRkf{_w_@+>uWotXS)zOV;`Pa93#_lTt}0WM_so%cmryumvg>|(tk+*w zp;?A6ln9=DU(NF}s$r^A*5A{id%V^bS3h*Tp379Hn1$8{@=woTkjB zzs`V02ao)PPPSu0Y!w2na)~}agz^ytizbmd-pSH#Xi*Eiv9K1YlWYQJOm%Ir*yaKu zFS8(HBSNrAbIr|(dz!gPFb^%Yl&^kGjt|SXE0?V0Bxod}^x{*>4(S!&uq-me;dQys zy?DwE)+MhjEu|-$xp2;;-Y~&qz2-16_A^1gp54duGSNQWWf-ZXp@ivG$Z!5VY_TC4 zyK3*j5ehJN!8GEe{Bmu~kOP?B8o;`J_Tu)fAuKBXjjBTw>==9at3@#?H(iIj{)nGU zZ*X|&#sqR`OL`46bKBuDvVEBBN{FSopE=LUsK9<`K6t|0gdTVr;p06w$lBwoh z6)1}8$lTdupc&ulq;xG8cFVKZH3~_6qYJrH6(=8kB7|gl*}K*Vg(YgO^LM z_bJHE&Z2AhneJy8`IUXMk2S~7@kV^wo-U84gSdA`gUw8>pMuk-+zs)8cJ9XC01A|9Vv4S5Y+F z@wJS9J@ZfxdD!A&R6{R#bXG*SqU9`$a#h3wq`w9|<)cf3s5j=~DWnAVDwQW6UOqei zn~CMF{^@O>#XM`$;#O&m+=@%w;j;UCb?nwyE!X_sp zf5c}!n>U%!l`*ES|7IvgHLdF@5mMw;7W7=qexX~nI`vx;^(KAhD(*RbNx<1~20b-1 z94}sAov8{8Y&Y^rGT5Y7*4|7ISy&Kro9_lT(rL85BJ`=fhRN@pZWm1Kg_Z~@g?MK& z8G!`Mw4#oM|7LxO++mX zs0$*WzDB=$uOAs|q*%fio6@YX`c4fUDg&y+9X`^?1&m>pTUGswN7=zaQ9PivMMuuQ zm?PD7MY_%luK5s(6ZN!UxV0r^rVc-@+};8=TfER?$#Xyty)-`Dg5Do?E>0vvq8c4G zoWA2ZfIn8?w1PTC6SeiJc}}|av6)Rx9VvUm2Ztinc~y-Z^fx9}CwE`e;!sLD$OMKb zrsc@LjRruWK0GX8bb+@0BSGYnD%Qti!gd1gVt^gX9k(^6h`_?j4^+rebGHTAC*6(! zrJBu&yNS}XTEEUy>Xf>Gk^b@v~9br3b!0g452AH+p$*@Q!75yhSt-d;h^yjIG z`FP7GIb{46efnf+{&G2>o_Dp(U?8$sa3pF@_xC@eD)x5l z0R&hcpR<%3t8Ewxi7+<649``{*A3I4$i$`8g~qLGo7*_`#%gDd{-d^$^SamhBPZ^; z{qDlyz41a3Te%w?x66mR`z4zF75{_THe_|i0HbN8`T9e3T6AKueyPZPCv+9hLsfUs z^U$oQI5VmKi8#p$phdW<`F(EzF~h3PKy`iUW}Itj^{<+vSc4HRH2v8I^n1z7w(bEPBYoYHZQOJ!|62<%?YW$Z*K)m&Bfw$xbXj7A zxdt2(*t)*uS05wDT(0c;=Z7HwL+old+sTlD76JqGmlJ_a=rpv6rbwRzQ)n6zX!A$XjAH9op^-5uK2KP?}+;R2ZIYLYK|p-1;DY;cr~{ zb*J9rb#xAg1l`WomTmgb>F;d!Y*kQxza-nIHPIU>rbnH)YOfPyuU1wlv)*59LA_z3 zsA_B|M8qC9_{Pc@Mn?&sDJ(SWd{vP00Z+cyfqFb@P}SOAxHGp5gKSzs(~DQ2-t`U5 zgrzs7(2B=lUj;Lo&^%f4`LnHbW{S(cbZk3O8~EEP?-dRwm_K7>W^Mf+<*kpnyVfUO z1O#L?8mCA(?r2H(Ag!)PczjppU5GgQ8D|XI?HKDZ4cN&ip(@(7$tlmMe_1~9Za&TF z2v+m0%PlC3wK)3Y)wve28BimNdq68H3#V#0iFf{)< z18FO#O&50;`EG%b0Qn9f!Ah_*J-URjqo)oJ96Z_DDl{<}+pnkEA=*743(#S!>CH$8 z)ctjBlgOXb7N~@W@wDsH_mU|(dYxsNaxv!YF`!$#0`R{mnJ}a&XW%$P#+6$rcRQI& z?;H<%7X4XA<`%reGlBM z`E%o32h`$CVO4d$40FtZB}Q1hi+x$*qrjtiu2y!m@#oEhElwe);DaRYD#7I3Bdp2U zjx^Q8d0YB#5u3XPyL$qPNn{sW1i_nAco?)KdMASGM+ZzwbE*^+j9+?taiq5?3_1Qe zIk!#D0_+U4T>5QQAnL+nk|bvy4Q-=OXVDpI0ftkk_fc z3sRhE_81w0B5Kg0+h&g#W))?}YQD+?3pK_(&Lt_LG}QEYbs)7MaeDmJvUKkzNU){h z8~dAy<~zLLkHGq6AGGXnt3z$;Z(KA>4$^1T4T>5LoD9$DNi&RJ!HcJVrc(*e{aQ~@ zMgdu2Xdd5{@D=)FtG2Ca>AC&FA~xDE(BGL4_TL-aeo!N8K(;lZA=CdVraECu?pKiC ziL;Z4618Y<>SyJ^v|< zDf?WP)wGrtJBuXMJkPph!nV9B%NL1OW0VVsWW&QwYvM=Ys3%b z%Byx~tW{mE)QZzlf(Hw1pr=6K&#PPrvh}av_o8l)WG;vzOV2B70<;}>{#(tLd=pk$ zlTZP*zVx%n+jJY_ozuu~=7_`Xr_wOq)z-UB$K$(pC$v=tx+X3R>F#`8BYiH9XeBXpY-1S=R_~g<{UezIA!=}kX}01&q!RGXKM#-d-Y_KOKu0NH$Z-jwSn+5 z(#oQ33dSiLACV>AGyjM%Z^iMoolTNicighbOKym>G`*VLid*?@Q@v0&!7e&#b3ALH zyM9iCPU^WZ)kU;4rfgFWZzhiy#BrNFQEA%Zn23TR-MbIWD1m3BoJ&ka&c)Vc9AXHM zccj($G_kc;L{2#xP?DTfyZv!1*U?pBVxk$~m7oSO?TC&4v*Ho&9o8KJffO3q^H6d+ zFmB7t7eR)wQu}s>254k z{%kB&m{5Vjcw63zMlj>+uqrdC2 z2JThGp=7B5OPS=w=7TiSvs$130%Mj5c4m9psP5Yf%5QbeocY&_x1_{J{+hx%=*dLI z`nq{A1xGw;#Iv|1hd_kWu|4(tq2B%@yhgpjOwe@ti1rHawy+w&WqNY# z(!Zb{Iv<&`?xSl;Y%v${8ZB;Fz<_>>y#MTGy7>d?aOBLUWmocYaKY_*1G^`e&kj5S(_g2L7Y-= zS!T+94mVlAuvQJtY)8AX@h>Mu)@bL5F9810y16=gb0=jjT*2>?0=YqzyTc^j|M7qP zCfa0~mwBJU)qh;@=y7!bEQevO{EHW-*T$xDMBP(YllDdT+^vtdIkRRo4M27Fwm`?W ztQ_dsQ|0_i6taEYuDO$YG|A^K7|Z%^P=GomL;x?M)@?d9$OTzn_K8wY<%Km`h~d;} zNMdWx*sAGXb8mU{hW8j7E%sAV&4Sm2jDiV*C-ys%+fQh*$O{_~Pmge4w3# zm2vbU44;!cevK?pR+P989mRlLm09C6D>~(O(Do^g?n+&rt&|b)(49LkF-9Fav-=&fiE-t^~=u8|i7cKr{ zG2}p@2_%6V9hf}%LR_wqo;$X0EQw*7uqu}ERO)Koos9fjW!n>CB@3a*NXVxD@s2cG!3 z-{C^vn3E|6TQ#ngxjf5#Yk?r6v7qG#cT{(j-DiDYDR=izT3_-%^-f^Pr&52fEP>IS zmga3;`Q}_L$X?#<_y-;u=ND&jnXhQdhdjC6U4w38Yy~g|b#pzWP}%tt<8!Dtm$QX( z$hi~6#t058QWuNsS}r4C2MCWnMmn-Kms`cKrFX`&T6{-bbnxpqW3=dwYOBVQ@}`B~ z-tG;zw4bB0l(pkqcGKQaQcWJO=8gAl0Z^4T<&lwz)3$d#Tv$)aNN2ywuQCn?w zG<*4jO2>bbwJbaqxMtIU67M!@E(NnRxjk+%S7rk@?krVPc(gWj$$e_%8y%D_6zN*V zOXr);MS2kh1=1tEe(^@lmI?FZV?V?K(0hd>BMk2HHb&$?DFm6fIZEEmrGC;oB_MC- zfWIS*?4u0cdBMaK)AhXZCsJBuwRtGSs56TH^x)HQNa{{iEuJo6t=sBoI0%zMl~Drv^^Aqw0&Tbi}H8VXus$3KhG~W zLhv4M?^>J+j?QROLJO$5;9+}=Az2_SA$HP&HGO!s1wc^PzExgduVgTyv+6nWl5p6f z<$#~f57iFK*noohQLUs~in~l3TRIgGY(L}LN_}AQw)?RW$nM@Szki@M z6VW8th@i@%up(+8C&B;CM4-rk`D$qc6xrCQpo);f5^o_?=m7B$3vw@ghE>#E+}+Q8 z8M0FDP1LD@rm6-%(TFfbnArGclOf*7oNBLW_?wBq4+DZ^;{I0^&#!R^??d~FOC`%9 zXQwI)1iUlqdQPKEjBJE>8)bxgUC5TfqtN1w>1}RFqoX2Mw*n&8-_lG^Ri*Xz#kD>R%aw0GZL1uo zTTaXhrZgH9Hbmgh=w_R~cAn>^&c{>~`T~g_d385Z=@j!HWtV4Pg?@a{E#rYz9tKXn z%(bR*pRqZ3d<5jO?W@7)-}UI9|I9beWCGy<#fe1pMfKDH$S9GMU2DnY{+97ciA}3K zObAfr^N;{d8@N!Cj3Vmhr;jVwgG?%G9W!cUr-DDj*N7xbO$w8$xMJMHqGFRw+M@j7 z-XW{a&YG7X#cGNUw+)?zfw%SbjAz#6#o86>>=3_+aYW-+$KZIxRG^XM)c4MQ?tO3! zF-}&kvXw|g7grn8>ZK?_Cn_$N`ZlO`|h?f4zxpYToBXr@T!vAT#)mf>njN?{yTf62th>j;8*>kBY?G zhVP4${Wr%tz~Af?NuC>lvugtAWf;Y_%I|E8!oDm{@zy~-DvK9ta#uY(|XzmN3YEOMvxZ+HwWM+*R6O+xj8 zBMNr-X9_gAy&jRna*>~0Q2AAt0&}0pH3+Rb{luT+sWUVQhpNA?MpYy$J?sb9g!9LX zg_eBr;0XHW!FF)*M;m(Is7YfT=9rgmHz=l#U=`SNkIHCTnj}q+XOYJ5kj#|Bpuvtp z6$vzSZ$WvX#lxH*Fp}I_>HXH?J}beA>@v%1?VP22TKhp^s0BZ5UwvidIi2M>IosEC zqX!bk{z8)y+xx6Rf1z0WddVM#slqN69QzO5KPO8x+re4hGDy$#c!7SB{Xh8W@=$De zgTk_cwEN<$!`9G7m`s>Uj$Qn+=c?&zK!cGb|5HI5bb6R1`Cd`}!;N^jIC*~rn8e+)0R&f&?)TM+lGe54fArJo2_uo<`8G0 z3jN+toHC6IhArO5^{L;)YcdCtS#p35$EydEZbEO3=$esBv2JtowZ8^oZ3f%9oLL%M z`-efLq8F8foYTj@%<4}@lHceOSx1b;UV3u~N(U{cq95-hzY0VhjNH*bH*@+w&bA%E z4{7eTnT=>4QL`EHR&xFBv}QMCPpLA0XZpPk+}Yx6hGIwdu6Cr`lf&~PTU~IhElV`W z0WDUjU7~a^WvfhhH`#gQ$&>HPZp_$&-|*_y)srAwRwR{y=uuAV)P8~dBoUe|s7V`; znh@_MN+vxwhHfZC7clpoBx#9aFFnjXiq&&vDCkCrtk*^ju{$UIev^iYmfB}E8lx$p zb9bEJ*^D^nKo6_6`Qv#li9WLebda#UCCZ=F%HP-F)*Y34+B=UH?0lJ(_95e^FMXxK zZtM=gKFvL;z@z$Lx$(mbv9!d0@;dsM-vJ+ieHH8W^INCI6?U)UH7tcHjGEFDCT(KW zSi7xO+0+B~no~n7gg%6#-PTcl9}A3$(Vh2Dr)ebh+~Ty&Mc1Lab@wC@;k86eS zZ~Mtm>6mRy_Wyy~>%8zQci!^9;PGTS!1G!&@!j(dBbQl8u1PI1XkWbvx~)7DUFn-% zK@>r|LYq0{6gwEJLRJ1@nwsYO78>Q8$oeW_7+Cy!OL_AT7&R?a2(uZo^w;@4jGXQ+ zH%LR^?^)cihXB^iXjbBoL48*cG6P&%v38HWVBqh6Gr+l;_WX9`*Y+^W>Gq|=$9YF% z1)InoWBVVx=?SmUH?75bd4TYk;@< zt6nJA?qi6Wj?9+}$C8;2PW=8h39bxI=K4;O@bparZ_8 zH16&We`l<<_FDVw|6HBBefN#3(W8rEe$`d8-erF37VigkfP_bvIpIK zn&$;xx^T0?D$zWZdpmT|viMfor-ipWD>}xtcLhU~@RlRM} zE!w2X=MQ;`&U%%t%zG9qEl8NR-&pp_B*|rwvLKa_mWNV`tk@shL#RpNidenw4aEt% zx`x7DGT-hUzTs=TuPh7VcFiWUZ^y4oBn}&3xBp67SQv&fUPBhwV1xd6gt=s zspL3J-X9LcPlYb9Ozmdh;tlQdl=8;CSgbz$mTu!(LFJkuW{aA-EMzNC(9UJ3RI!;# zrnRdd!H1HIy~yzp%44u5iaD-Sp|=OgK5OvMGu^6Efxd&?L@O90MaT(jg=!!GsG25t zOH1l4KBhN6~4*YEt6<@?J zKlcWE|9rhXj@_(S1O&|$W?bM0WE04Qcc8fNb##rA$(?k`gh%}9uiYM*#mh=nSR%~M zRWe>+F-G&%;mnQNA8u*ee+Wm>sr4tDWpApsgC$fRo~~0?Jwmcbo=@EGZwd>OO%+T* z+f=Hi!yHwvk~1~;=Kn&uKO@iev>|^Cu{m>NI>`VTE&_dggcq;~5#ZfWjO+(Qc9njM zziG96hsA{{L2B1=aym9onQy548-rEsx=|UW-drgR6kcqLn=EbtRzGUL+vcpoNWwtJ z>IsaOvSb+aE6Y-I7j4L#vH^m0>nxR$Ul*#7Zi{p$Wc(^YstT?S!g zxvMDOv)XZ!ORssG&;8uP%bupBq@;2AofTI)A}H>QeH6cE^aE9$*|va+kWp`^uZaiQ z2|}KHISrSjJqWxg)E{2hZc!0b_q5>?t(3J(Cm`;v`!4$^yMJ`1TU!D?!EX2}ZQ^yL z`LEIM8hD}cndh`s#dv^%%kA`BeQeMldtgzsibNQ0WfKy6tE~4=(gwXek6ILwX4j|Z z5ii_LU-0YN*47tGOHZF3Uki87me&AYjE$3Yy-N>rHp~V5TjpThQ*ur#;U2U_)(%Hy zJ{8Ykz|d#5?N9Mc<)(TcyZq*|I6w11eQ!6oXgO@OLv(NX2>;1Hos&B2!@Y+Z*L9Qn z5>YWR{n`o|LZlIRFmLzeQ5RYE7Um*)cq1&8gOOex@XPm@W_J4GA9Ub9M|xZIXc!pL|sxG64y! z3k38U&dmTb3;4|xo!>10r$^iAChob`Kh7iF^2z*1xP^-RCF+1CGhx^a&Gn~xfXzyF zD>~e1caJcEyHw7LC)?+ zN{H4zui1P`95%kT>l8Mx5HW0^!>$kAqO49g#MLqoML{<+-;fxeGZAkZ24>ZKx$A%m z<$~#w?v7l#Wi21~jGU_K{(@Zppg+&Q#6!KLUu(Zps|j#)`3dlE%CjBxB6-B+;2A<| zqUyLF6n^Q<3RP(cqO3a&A}Bz^h+M!KKZ2dQ|LVsHz~Ci_?}Fwkp;t>liF*Nz%&$2S zV;~Z1$>G{b%SBop>+5$d3oN#$rgJyt(lWk9zMQ20o|;$6Th$+H-9h#@r^2%TAo^Tg z^Ti_iRZ6kW(064+TQ^VhBW~BLMUdp>uieKv<13OCKE9y0!y672cwfl-8wFAlmK+-Y zJ(kbQsZ%}oRl}Q_Hy>d^&+LhKpNm^*-l=N~{=NR1?-7FP5?}~LG=WsHJpq<0u0j&l z=m0NvkP+cd%s0T<*g20`!!_vG8EF_9?cL)7dzsA}sYNrb2Yz-RyDhl^nSb-e30Wt4 zfSjC_*4t!0o;N?Cu-?ma$ZHo7qJx{aug7cqxCj~1p3-m9c*`r}rX^uQ_BP?$*BAA< zsZOhFFY}vY+U~fz2p!wr274Ww>!TCQ1X7|wZK27&;1zFw`ADl*eC36? zxVRLL&xuXTpxItLzH#LBl@T|<<9Y1&w(2XI6EM2cO<7$VkSU#CXy$eh`Xb!&AqPns zkL@$#yB^UOQl`94C7et=gFu0l0I>Hguefc@n@H1P zW~8BJQbpnOa-{a66wh(;*s0a0Y*LzHI+G{m?RpLcp=tc)}6y_jA^_3Uzcs(O1t)QnsiJitOdBMJG)9UStpi6)NX zbu!+n0Ndk?gUJe`X%(%EcZbboH>Bn=yHyAIoHQ@i)e@VueI{{kEN!Y~l zT^PY70`lsCTu9QG#cU0!F^Knzzt+R`nELI-qPF+m!iGcI@BMN5_<5%eEL?QPV#u?M6+q@OveQSf+ z_r>OiYRO$$eI+GGypLSwinbU58xvv27Bj`){S=fT3n@xQH?;~r^4S9fVDB4NqzcvI z8f$!TmiT;u`X4WtRNMs?QKWG7`%eVX#N%W29?yfq7dmTnU9efwXRIHk_Q%$#cCqW%`L{vDXW$!%2Uo zfEFch$!@dHBAbkMwVQ9&zC7ORSWG6aUkj}nwSH_f(GQvUGfwdm_SJa`h9=?CH?vG( zeEZ99B#nK`OU)&Z-uj~vdYI?MSxYMQKR$yk2QKI8Z;1B623+UItLvK=3KzOyg)nRG zAYnoQF=Q(^`+VTFda6F)6U7Qjvqy@ANxQ3nzA=`>(l~kUw)W^bV+14berxM*(<$Tl zrWsqh$HPXzmut5$A4jfqSiy+);)MFww>mZ`^=EFmVkaMjB;aR7fJGnw@JE?zLBiOg zgY?azN5v0EHoo8ppdFDvHT3N^umeKd68IE`^Fg)_%qIepiYoR7(C|lD_#mxO8+$(X zlydDhBTR5~r=H4G?L9;#4}b(5F15=(a;1o>ozMDxf#}qwbJ}tBKIj4VRxf^dE6jtN z2uOOCC#_#7KpJGd-r_P#16SN2vbqtJx#Pv2medtiM$)m-RY$&Gzk+Lwju4J$*;B-{ zU2D$kgcfY^Mi8tjbCS%wNAPiC9zsR2gU`471&_3z5yzM(j7PhT```m-p~bKoR?WE< zxqdnD>V|!S(h_hAC%GGh!8g!KBkTYlJ|}%z|XvM zKDNCn&z3^Bp|q3xBi5p$r&;U?Xz`uh>A8VzcH2m^f)0`o$GhFKfoqQ z2PUXbSbZV5zHMPiLprI+~D^9#wzcaq+ z=bfrC7yCrsvLU*P^!4)qsfk-*mb4zRh9YNZu6TXpxpmJ7S8RDq^rtbZ9}v#0T`?eB zUyG3Pp-WzRJodT+!o6z6fcADf%^1CvOzSIp>y|aLgfUx6^(i!SkS~6=vQ8V+!P8XT z?+yLwZtamdfpg`i={%lUY^mVWhDx0zo#COs?yN>Y9+~JBz*lOQ^|>&dfVAF zs3mmW*~DFj9tQWdMx(u>9&^hWk3Xv`v7O6fiaz+3eS076Dm8oQa@;+P*eMuX<}H)f zcp#ZQg?ukab*sa2Vjw$0HhOO>5RkPm@_5sZ*S_&7M9rsDX2NB2$W<4Q&DYnbV9{%v z8z*{SqNt(5e6|vyN>)d~oU2%@z^0}9#Dl`U!JA%7XetqRRd;wjzs*jW@}){F^5pq5 zV_IY3;ZL|D1)8zbC6O7(edOM(A6JDo_$4*g%jFa6Ezy)DqUKPbpRV~zE+;V%)%am9 zl(6!ez~N9Fyd9;g69(xInQ%2cDhxCluX(#<4awkI(Ko&5SFF9*E&KM$mp>8W(87_ZRhN)SI-IurHiMNmc1oD22l(){4J0s7KazAfahyBsn#3XQ z>yZMpTe(7AUyt`^LZEN-bD+Dq`H-f2y>C=kCf#~5cwM6ec7+t|@X%|@@MC+6Z%)Ui z>nGV5Eg)||Xbn-kO)0ysj2ojgsZGd?|Df%R^%QhP;}Z>!!t~YIgFJKryi41F+4@Uh zrN|o!F)^OkG4);LnmmuCq0;F}pyYRiV8icPUg6Eg{8;rdk|+=NbU{y7nB6I81S*1i zaQLhEt~`Nn{DA5;Wk0D0T(TGhvL31nW)9lTZ98P zFK6mfK5fHoouF}JT$VEZsF0#OXu+Ok8%^9rKEUS*H*3){Xf$zpK?k&zNGnr(xgzbY zBDXzJkX?O{pLXed_mdj$dDam^dPO9dWvMWqTvUDRXxs7!QO)Oq7(vPD0552cbQYO` zcsYbOM0tVt7bbBC1BL8w`;(E5EB9A+v$nZ_o8#4;WUPuoPnICt0Hv8O1a{+djR$8> ze<5TM7F_KCZ+pofZ@!F~Jftc5IM7eLymEdzDL|@^4$C>rQn@&&N{Q3JJLyzs=Kka% zsj64=ZOX~&ZB3B1)m)llgGUnJ^$cF;D5|VOy^ug||3wvb zU>EKXg+J> zws`DG!OnxB8_2CK-q`K@?f1=@9YJJ2g z-xH^?Jfq=c5KH8OV$WhxXZqmS5ziyOs6xe7-_Q0yOC%Ec?Q_N}0cAyYpKV_WpSAW) zeHOBD6i!N&fIoRsGFf|6~!w1!=M*cuT1^5?R0&*Fr@|lnye!&aGKgw(;R=z zE2No$H_9LNvC(L#hNnBOHWjK^N$PutaPgw6VX&q5ouZ-E+?&9L>Sgdocj@ki6PL@o zHdK`I8;6UYZc59IU>ZM%;Z>;|1ECfIY$}l^OZfgS!38Az_-L^GwJG5cvoIU>Kud>2aO%mkl}|OmX?=UlmWzx zHB9+i@P}7|qtAQXbdj1}4Vg0p8v#^$(@`Jwm2YgJ<%AeAJ_Ea_oVX8hc$6Jy8JH7 zs~b~8-%tk_A=h(R8U|u=JLwWeZqqFZ5e$)UQ<}vb{>WCP?Eq`@Nu0pQAn9i{8r#0| z1$L;#-|I=CXpoM;$tk20RGMVSY<7V=h3C$?YW(`8;RxzQK6m4DD`r)}CFV`ZPyc(MI^n{Bx$DsC8n?OzoJqXjhHA z;9Cj>2d=#QYZyY`G-vZb5a$o+{_SV4+e;7sH11Aa7!J%-i<11p9iM47R*Rg=O1Zpn zH13tM@HD*{*BSaE-mgUhW>?qu^E`0g4@6uuqCyK8)=cj__)Cq3k)-wMv>m((KJ2gFzvk z#hK{NgSF1O!Jo<;m=@j(?hJ787JsTw?0crmW2VwCR36|V-IM6Aox0ke^e?PvWp{^= zmBT*Uw_PI42YuKe%g1QF)m96fUq3!=sJ0qVXj8xb6u*1&`FH(4MA!KR4r@87xI2{w z*AJw4+V{*tnXU2Z;@R}2FOrlG-W`$a*BKUqwy+?EJ<%K{Kz1%#@OO(VHZHsSglPGF zvAFc%s?XO_y$mWw~e`=ehfh86ckh(OCMJNdkH(S4d(vfj)1`hpt#eC#)@>P#8( zTmEKdJ?r1-IBozx8)4dWsf*>|UQTugj2o3kxQi~vECd6zAI?HE{l|xsvKWUam3(bp zx<3fMS{;f~@Wb^D2Um`bD84GaO-ClC0RLqs{(m?LC02>P8k*TmsWDv|yEpU*04f3P zh;5g0nIlfUG~+TS*UdiZIlMR8Zrm-N08ET*%ukY>mOP6GRs7#8Y_1kk8Rnx99`y6f z`Y=649+TyDY+1-=Gs58UoZ+G~lH}T0cf$+Q*c=HyVhM^xMHc+u0Gw*2{R~;DpJWs# z7|{JO^up4@rRVRqxuv-W9{U!Vv z%}wDsy{I`cDEgY(NrpOjxPJdbVBT9-?8A>+dcp8xR%`h`y7*Jp938&(X?$_W9|{#4 zC4IpYk|sDuq{>(+4?_Xz+~NJ~4=BIy^8-j+=N6Wc^feGM>K%$+2Wa05E{beLM`hUE zVTfuc^oUPwsueLa3u_i`i3H_}O2AJUe(W`)YvLy8jtmogKUt!)*pLK{3ONJe_$<(R z>R1X4j2w?0Ejv7L0f)mh$5>Y< zUCvheLG-xYtd_J#+Sl~h2+_I5loHN-2y{Z%bbDh_sW<*W?T69Y6xFslA?|Go0SoQX9ikOH66=_<+_i&EIbmUT>J7Q#ltuf`Vc}8F_!Fsd^Xt;p7LOix-8n{!BLD3Q?;%Z?HZ{AlT&R2KQ>i!hegAHMePg6WK{!V& z{~5>r?A%C+-K})56AOFbg27G5XF0Xjv)aMYa5>L*tML?9yFs~FvnK$_5Nh!Iw%&R! zV>n-v(QQ~NFV$TmwF=7Qo*z}dz*lkBAaG2B*(P~;47AtWemOaJhsjQ}&tS|kcQysE z#&G6(G{#z2`z9GG+~>j82S&Al3n+;BcYIpf26iyAEn76dFMS7thw5E=p@K{`hweqP zh$|FS-R7P8D%Z#=fX$9bcv$&@@e|LzcC>|=?2h(e2-GGk!5$N4BYLdN)*$5W zT(?0cLvXnRYs)%;2ux^*9k$KTls*3ZOyffEb-wioV|(73_}@#3GdCl()*nw6trSXj z2V}TMHu~m5Z*{E~Fk`!a@MS?0&&q~fA9buzZoTc_e323AN3X-Je&|%SrQB)J8;A5sSGGhnip19*Y4DGuI^*7hUjze*g6S{9Aq# zuH1TA@dDYJf#If0-9H_5QRT}ktnW|_@8`XxBIP^BCT{--!o%_3vhn&7!t|jbJX&3r zm!p{Du$ST}s94j16!xVap#@NC@Wy83q$T7c$f)WVqL8BTZMGwmxqmJ>6N4P+vT3Ni zJd?U+f4b?&TxLRcvFL~SvF|t!D`@Nh8`AJ=>%Et%hHI(LR1XK5-u>SOaG0=e+v1E0 zdd~moYaDi2Pkmwkm|B@PjcQsbeWLcQ2=BYogb+Wy?#pknDcU_%RQ8|VJ8$)@FfV{@ zT8Y=2_8_+2!qhX@-?S`kSt1_lR#(lU=UCd&;LeZLbd!SWL(efMEr>a9r%I^2maUPF zNbj1K418xK>)|1AXnAS2;SD=?AZVn^jJyncl0cJ&~N+H`1p1O0IEL z$u&QTv;t28$k zZ_a&Fldl<^%$#YCpzzAp(GO1g2%V^rs2NLnE?%BBmHOHCh2x0o@tPDeoOVi_qhnFs=te-twp3<(L=w-=@ zfa(@uk7Wu3o9r_NuDhPC&k>K%F7?zU~87WKt7DHbq2XZNZLt z$MIU2lB}e@-12B-RotH7r7=l09OG+COhQCgKYS(tS3GiGmQnjhh`Zq^*xLJ<8%^F^ ztaStMt;IB)8HmzcI?iw+hJ!YKG!mM49z@9}sG9X0o;|>o)X#qYs&uk{J^D%>xbodh zhyGr9mKIL#cW!Qy<}SS=g)AGG8>YJ90 z`C;*wo7u;U+biSq5mgHh-Sy6HTI$4A@M!TY^R=3?)KIOFeQnqAAFYgy&Q|7zwUt9x zV^PZXSay5@ET(tm+vz;X=vhCE0HUV+)DV1?nDeYY71XL{5*jWQ*Ew*>eL%UDv$yFq zkyV6(nNY0Sd%8AbDD8!-DyT{<%?y+1VJlNGIXRKVj$12bVG+aphVIeW(f<0Ha*d?? z8lKP7iHo|%h|uCZ5Ri($rSc1$<$Jg>bnqs1wdBOx z+YMFP(Yk^gV3x++GILw$?iNd&qaj)5{Ye!;ZVr0lS#_!U`ZIlHTPz}vEfR|F#a(&P zlQ!Id_V1ZW!?HJ3yI^t_awP1FzN9Va3&$CbiYC5?;419hGvo$yla<@|_AInQK@hd^ zC!VN2{AbN8C%Y#bzaxDQI67Y5W^>8}0xW=C+wn$NbFs)+H=u$t z8X1w~4vXIhgvHCRc?R`?^63cNm(!gx++Jt{q-ux|NjhBgFBLE`Gd=}(%~s0EQ2trU zoQZeX`d(Fi4wm+^e%dbjv9XeT-};Et2oOj|TRSd<{W3>lmRrs({o6F{LxUwmuwz6pSR|FFeq${vFO~)dHXR7ys#f1&shX};DN2r& z$l*jbWs@{~Vc{jVfN59sna`IMY4dHRznmJ#$RLtv@Xh6M|ISbmSHv@21JG6ADF*)>o=wh9$!hFlxr#mIeWk zU8z}dB%7(RxdwX4?Vl#OH}ic|$~#Rn`?_dn`_#{0yMoW%7gPM3o`M!Oj<6$nci2^x z3}Z-b0|MhS0|L3rjD;4lx>!g%fS9lSg5wZqYvMb7IaBIvr5)_@^1GzOn*1msl?xTw z2X7{UB2d3vzBSFWI^Uk_PoiynGHbs54e9lUv^YcA#81m@W^Rjp>U;LL1VS%wPJ+HG z0ug{%WpEMj2SLBv9wDv=a%p{+v#%Q=qzdsSDg8f~z;9RpMX_V%o!;y!g23T#51`NlP#HnyLnkI7cV6^)c~Bl~OD>kYA<>CC+? zx-R1N0PocW4e$_YKESRRO;4Jn{UkG3Cd>|&D-l{ffi=<14S)fFlhH$Sa{U~;+L;`k zOt-B?vU()F5&BWZm}K=hbk|zWu7ytrRJCiZlyV24V#S#p6`!-^|N6MHxMi3FH0B;Z zirPv4Mz1zD92V*%P|Fc4i1TG?-8#>Ki#1s#LhZsI2Oc-8s_f!A`rXa8h53$`&kIGC z@GSi)dZm@&%gwi!@!2nRj#p>ATF)7stQAepD9*sisI&Gd2Dw@zF$zkiEI^WYtw7yc z3Os)StA#o|E`!17&_-V3M*+8{9FdBJz3Pb}3W1UE{WRI+!{sE&Uuxc@BvBEjN9#J% zs)>7p8W6tH-M)UN+btuN3cNM1AT??555_RVfRo+kpl^eXmxBep`pE@Sy=d!TVghfgF5CO zE4cd7>nEc;i(mSk;!~UrA^D)nSiV^KXA{6fBA^{Y0u&Vh$QQ-heeY_36U=6-@w9y} z0j@CLF}Y!Uh&#>_+?&erhe8vKT=3Xsi~iw>qw%0>XPME&)8pS3OPod81I|83dQ#ug z;AV)(=M@b12!%094&LugCTcx`41LUr?$Z+MdsZ)Pq?FOIer0KQRRbV9$$MTLnT*l$ zu6x+T;kgt!#_E<&*PNH4%sCUUPs%y;If?GIUmTk!y>0br%h*8WapgJ z9k@oLmO)QZ6i!&tBHUflSGVX+g^W#)FQI-m7jarg`xS0!=W5T$$mNW!8%j;y<1TVO za>9Ez99~?xF(uM(s%_IkUiT1<%oH}#Lzio-EW}P@`MlJ33+yY>0=`3-4Fh8ps;_Z(B=?aSy^E_S3QzU*SUk11n$?Xc?)J7PO6{kB1? zbsSG_=XTGj?@(!@B~mLO(oEc1UFf-(^s6T(RXn2d`sMUw4t4vJYwcRZvCiP{pM>p+ z&HB%xV-Vev0%jnP@s&kpm1v}%b3l@_M58Wm@%I&Ow5sJd(TOD}|KJ-aq>DWV$GnyO zj$&t2x%}A+aaZf6AifICdH*PlGvi$Un2c#6ob~*ZjPNsw@#zakm1L));6Mv4W@_^b z*1j2XDu5fa?TQAKUr>!Dt$XexH#&NT4R*D6Mwk`U#lGl+h=|C0M9qE#-RHBz2N;>c zTMEe{3j0nkpOxxhQc)zKI-@B`EuIF0tz61T?-?{K?Ti&cdpEjvSAh9sCJD(>3jZrQ z)0Wm?%xj2Pom%{A4gJ_j;g=TZl?pwUU;`JQN(5XP{7!->gT8~sp9aFJ%N1G5c~a=U zUINI@T0}9#p%qcZo}`N2;Y!M_h``JlbNd1R>zf=W6R%Z*lt%H(GaU*|Pi+z#jVS#; zO>44UEDn9+nX$7@?jD951G1h6bEUl#3ho=o>fAF2L>{enAChcv-LE3Nrl&5yxab!O zA4I~gDN=`W@=itSVUITvp}N_*LH2YLscm3Tt~~15gkL@5I+cBnNH!EUjYiTu`F>aR zC9LM{y{a_L*2^Iu8AHdg8oxZiJ zL<6Wa1ZUP^zIq7!6smj^9eJvp*~W)aslVDKqI8%t&KTGi`5=Rvcd5d~n= z*#D&1`n20nE^eDyhQ50Jo5k~y*1tic#?8r4a{iBOsdJ1s7zy>vZfFC!RmN*IqazIm zRMBzbVtk_?`E%AnY2YOZ{|IO-c)1fnl3V2t21lPFZf{=4o1eTmuIk;_zG8LeCy`L$t*zG1+@1oG#nH+I z6V;A#du?4kT~W&2JidLg5VAg=NC~0)n3N*3cQ5+~u4OtuaNjF@)3yp!3h-^URNqmj zFZupzX0@>^xiE=y;qWu4V}|{ne`(}fL_JWZHFJh1o@aGJERst8Z_5 z=6mz0^xGoP7aLep;V%)6?vaL=x2*S@KJ^O9XFk;k?OO1TKZKdM3} zz?*ulr~&;h1ubX^rOzpByqP6kqV5}l$S0@|EV;hyXvFl4m^sJ?)OuOD*qq}297)^_Rf9y)Ix?ij(PphW14d9jW0j$m0p=$)LWauqZd7Hp`5w@ zh_3P-o`er(8_)I!3`mWRX2_fcc8p4L86B?t9A^ee0fmXzzSMopW_Nu7$lgyhe#SdK z_bn!kU-dy^7Ngez6&MJQkBPI`ED*M_SrBmIdP@#WSJGmGBy54{p^&iT1I>H;A+nnt zIu$69KTXmx({fc;?qu*q7gpJ=q-}AoM3P1Sm#e5Rd^Yby&*k*pRboq-_k>zPTT(U%)Ku4qpRJs*(Bab+ zb#$O^&iW+FF0=_sYKv%CKyLV1o(XV`5W_i$dqhg)i7+W3;?8;20%I23w%`ESp0`=@ z9&Jcf*eI^*%CS%$%od7C&i2ao+Wn+;^B5TO0GC5Qag*rD>Y+yBvTfA!9 zzdA5exti31=$^v?xRBJ;;oZ7{DWDdT``oYV9}{=QF}`028Lm*p zmQ;PqtF&VQx{m-I4>ZXFn>MkSvxo%4&!8gv#|?%fI^kaSOzpMix;2{>)VX`x!s&yU zHThOD=IZ0kb!T+qPHveHJ>iSia;V7uSV*tJp1AEw0K%V8ULMYTZCRtiLz*nT`GBqO zRm;)UwFw;CbWR2hvcl97i4X5DMK5ol;e)#Onh;|u()*86;G=k5u()jGBDo~{v^UK+7_WfI2Tp0E6BOX7kNSvcp^kTLU3K4f3u*=Lxq@}=$T@wPDbV@O3@g+GR4?&gL`hgv5mG!| z884;ZqdA{dGIzm1mF}n4#sJEJr1HJHlb9A&^ zBrW`ubGDZ!XXj8Ujq7yA5kor3+7N=9cxo=++rCwVLvgYm`;Jbk1jN3Py*hGjfzJyS z_TM60_GyslWreCy{2)z(?D4_;OTlYf)M^<{Ms~veI6ZMLdZg!CkhS4u%Z77|#>nS^ ziH}9>7Y(VuDermnnk2BL_bd;P`nQTU^!4`S9%}H@vL;w1-m&IS{z9{C2NBz&9oHJwW(@AEi z>Cu1t$nF2|Hu~S&(vvy<^zA#5WwOoa;Oe{X6aLJo^zq!1j4`P#YkBer<|DIzzW4l@jQ=sa zy`0d9>?J-MeYv+*5OOW5bI@k!s7~K&Q}MB6-H-=tSK=o99APd3SNbptC8KLSf_o=w zL>{Fl8Zoj`WXzqZj!T=T7v?{@0iVZ4Pl#)7R0ww2BdE%pI((V~-WfM!0mfefN1*zA zYVdo7(e0kO7q7|TSN&~v2D0Q&+^tJcef~t_w9mc6^3nCX=Ed`_N{zXjGSOB`rpEuK z&(B^~h4HTgOw_rZlEuX-ja+-Es{{Ttcn79&!rD2E2R8BE6lAv|7hx;eJ6H_AxfN*W zCE0yq)PgrW4_c|E`bwM2Cd+Z|^x4^Za~4^ zVD6665O0;>STaI#O(0v8s3;-CUTDCYe7U1rd9DAvTxt<<$=AIpW7XL4a8 zc1_+dpOCS>Y-c#6)u@tR|KCeP?vt|{AFNnV@Cl=v{hLqh?CI@5^p$R?KHus2L+h

    &#PGSc{ooUM0AucOq)hlLR_A=tykunb=(~( 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 KpUXO@geCx58ow|A diff --git a/docs/images/vision-data-flow.jpg b/docs/images/vision-data-flow.jpg deleted file mode 100644 index 735d0e576a56dea284b1c8c5c3f904694a6de612..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49146 zcmdSB2UJtd`ZpRxQ0cuF=^dm?RVe{N4+*^pgcgbrnu1`VcL|{v1ri`M=_QCt@4Z*0 zNiR}WL~q{rJI8bW>z@C2%Ubul>l^mkd-lvT&oi?#GyC_H&F|UYp8-@Lpbii~KtKR^ zi2nopUI3^A2(MlH>%gb$_=D&s5z+PQL?kzE5Z@#tAtNItAtfcJprInCpr#-trDC9> zrlq5&rzfLiWMZIWqM@Uw`-=$yA->IZqFY2nx9G@8$?5(dr{5m|)HeyZt``y#a09MU z6A)4p{O$y>0|)@u2=Uz|0Q@r%5nsP?lYsErEqt{r6#zg)2q3&pNkd9>{U$LX06=gJ zKLldx8#G+BbdnEl(lap1${9nTruGQG>Io)pDQOvbH6Py>$P`p+P21Qw57<9BAC0M< zTv_9VIlm0oFmX8I6VP-FD{TLIi~p{=Qv|S}122gc--Ew8^3Pu2uY^Pd*RB)az*kCB z1Fqro_y=$e{~Z6O!FPk2hE~e>Ivtm!^aHTH50To7Jn}pN( z%~LF=tFOKK-Xvuz&pzwJV5T1SzMNOEaCtd8)uH>}!K$NQ+N0)5IEA(5nK(Mw0{IaS zkW`DaMwhaL8`_uZe|S6$Ci7X$>?77z|HF;KLog)k#W6Z0|HYnU55k3)nTvcVg0j{~ z6_Qk^P?diUztNw39(kkcf4Rt89{Bz^KJ=ja`Okr99mtMoryW~3V975ak99qJ)li{h z)baLd_#yMvsCO7qyYR61gJflEtkc2cdPg9mDVrAa#lDdSmA;#y@NJu?Gnc~G6nC+jxwmRXgW8(Voe_jM+l=lBWiR9Xf_|sQqrS_<{fvjhL zt&qQ`t2?g>=go1Jw0;h!PTcr_kR>Ir(-aS>J@;f4>8+{qILUwkgVeHlXzjae3bc|9r@s(rHm8s5~s?Ec3s;9P!!MCPlW8 zuOwA6Ocla*HB zWc&OozaS+0{niJxW3b35XPt~;ZQv5)X}s>o9T?jqSP|c#`kZHbhDf|ZX!c0h z=u59#!?I7wVSX1EsTfSKPXNisFs@1{PH<9gP{^rhkll_tnQO@wjQm+mzUtkiDYIWl#g``1QtbZz`+XT zHJQtXD3vesCc9oLI_Y$2;}+mSWJL`3yi4u1Hex?`j+|5btI4LMH#u(S47zILPDo?H z8lct`S9V3$NY%~rN)jtnN+~yn8uE^%amP-l_N6qB3PRaKN=l{Wj^wsk?g#4^{Qhz+ z`Xy@dz~c3;jERam4GU>7vXHyY|1q&5bMqa-Yq{Rwo$;I`Vhn}je#625TxrWk$I}V* zkH@S0aNv2!cPH93wzr@39$gItF1O@+wdDExpZVrm?+r`lhRN$$_Yz#cy7JH}D?;w~ zfV@gEa1{NJn*{UOtyWKu%l5!-DTmJhKrdqg>$Aq-_CyI5x!(Y3nG7p8Y_d*Cps zTh(#vH=tPJ{XM4dNe}4C<6JQh0ffP<79Ie=!@o|7q+-tjHy$`u0RRkE0047U%`5=W z6_NH4aIJj+Pb&9UDN8N6h-&1@n^O*f=2wZ$Dn>Iwp^|(Lwv-Khx!4gu@+&WPIc(oL zLm=bo06=Nyg~D?H*=q1}071+F06;9z1OPDQeFgv={&NwbWD0JF+Np3_c#ztQRjMSba77+RAr?4ZKG?4(aGIy-rE34P^F8Hx1`kaHfX_ROiVKse5 zZsugF8T7(i<@Ty6|2t67^@OE%!Qqm@1pSieMp;j(ZtSLgLf2D^r*pXe$;*Er1qLS#)>b= z3Z>GNw^~G4gNznSb}iCMq3u!HNXz2#9Kj}CCC!*il3Ii?YoJYl80fmz1fQf(-31rl z2KqQ*ap;2Fjc1|M67ABi^^slOb&`d<#Hx`fNiW4V6CG0@l^Y__8-LYZ1StsVOvZR} zY?NwfSm^Ae-HjOE6-s_&QH)5PZBfba;76H`jTrAHhth)s^K()aa;V*%?ygSLm>MKX zlo8Lxs1@5ZTvjr3&!4#*u~v<6IBB|8i=)(|{96I+ z2C450xpWN3_4pdId{}zw`n>Mi=#int?_1L823!?1`BYk!7IjF`xj93D{^BqdhuMK> zovL%v@R(!pWswkzTz>Y`B(PV+bfu2$`go~`5cojoa79}_MtIU^Lx5MufYQvFc(G>B z--@1O!_w)2KYYn;dMQ%`!Eed!shE)8&^rRXC7SF6GF>WiP+cC267&O}B@Kwprc*%l zfB6jYT2(g%&1dzr;k;eE?&@+mG72*gfkTlnAX>L!I zGm&w;P9MdR{TziOmpJq(n%{{~xs^|_BQ$)2MC;^`-11B_I=j?qIyx4D(MQfsRZm2K zH0}web`>-7R}LYPJ62xRY;$qsjWjU0mqJtFw6sbQCM$`lkD)EGU}wWojS(6Y1#0wc z=?<=UahWhr*J{8q7wCyP;&wl5Gr-&%>ycsOf4Sm`uAM%98 zM&8<#(>qRBy6V>E9AaaIxh73sZS=5F-uwxg#+a+3xTHpEgpxTq zGdbhZHLuGTn59y%AU;KJ8IU*r3KtfSNma#&>B_RuIBSFk$GI5AJ$JH}dl&Z*K%M}o zwp=cL_FjUjGLHW3PT=M0*PHIH{FstVvp4r#U0*vN;v}}2mitd{?32^(EnR3{@z5M8 zq91ezXi&W3ZKddFhTYkj4axFIXZ5dVfke=Pq>P!pnK_oCk}+=e11dwT>e(9a;ZUWX zR8QqWb2A7oK8nu^2Ge2;@J0b!V|jo#;|IUSr(HA){v5TchuiM>T%2k-9L(e9v$kY5 znHS_Nu%8BGoPLYi#Wkf2Dm*w@ZhoOV!wZ5m*GoI| zNq&#bT8Gu8B)ykU&YCWmcd6^Gu~1(3yo7foX+|MBP&>lLW&X_4xo+JtLcGcvz_Bz# z^XRxJXN1VDF}{GjfLhdUk@&t>vyddCF-GY4?&0lMY17&vttH%TqDjOWnx*E{pOeM! zHh?T?#bQM*Q;lQNuQSEJY3#T#Ig^`H^WBPj#zDGZpi~ft_{88JtZUStA6m<@2qiMO zvo3=1c2v5J-YGfD47pxU6W}>~)3YUry^nq-)w*=NR7{Akng6vOf*bi{-q{_wEm+;D zVf*dd3D0kUd6XYr?Y$ooso68WzX9);WY203;cG2ZDhOnguzZrs0&3b8X{6<%1GiZ|phGjM4|LS6`cc=}%TOss5(Iq0iHCUO~&g3S!o~-k-lF z5}Z_6#J=_)I}ns6$u)`uIT)A=&`Jq6WP|2YL^yQsHEC_*;rhn(|Y> zk_9iYz9+UbIay2_1Ob*a==B~2`}%tIml6EDt66+k_bq;?` zf!*b8ijG>b6fPcU*r97qDb`6>1pW*tF@)>ry;R0@4>s_a&7$KVan6(ix#dHUg3zV0 ziR9_dQl~zvIIw3Ywg+PnU?q_p#9OI2>4{El93Kx8%aHoa(!Gc^hSLvB?jFC*L=-O4 zWIReWFr#N~NGU4`e`K;49Vf7<>pE9q*{CKKW&c-^K7nE5AzFM*|gHNyFL* zoQrw2&4YTd8;G}jBN$$N|zWauYr8c1ZVW>XsXLPO7Bku1W0A+lqCm3 zo+R)1@lOpY?m-@yeh^;F!1nN14Ig|-`2<875@R>5#$XLMu~3&%I-R{a`j!HxP)EJiN=gysh*sF0o_65GwUe}9(`)45 z?b!I-*#$7wTGn9`1}PigCj`Fv?O4t7f zS~k|lz$T{{*45a!#llZnx}l$1gk|BdGu@)1NsW@Bl*p#;-4vR6TNzmNV2oy-GJ}*_ zo5h=s#ud%b3hNfk^dfNX^ks?81BHarH7FcGiZ;+iRl*&N&(m2mw*TK+@+5493wEh4`YQL>}qov$N6K$o*;12I6V)=F( zURa!S!$w6>p%cZK+;UM_cl7@O{vUF?hMW!5|G=aFb;jA(}GI%zOUhzIZ@SvqGp z+%rDVRex8!BLw?(mu~wNUn8yyHJEAazuOX$|ZTI@a@3F_V&^;oIbUS0nt*+U&ib~%J5=m-KZpfZumTJ z?XG`py`>Fxx-isyNIjRYzM@{+t?^cOpJk~y5jDr-$F&JB$tcOAt6Izl3L)Yb#a#53 z>@;lR^sN*%r%|NXaA6VHvzw7kqnc_bkAN~V>TgD0zbOCCb+P-XZYSkE+q@@AmYUN$ zEp(22=7(hW(`yNYYSTmfLco`}Q^7u2A<07PDgJDOngp#<`Q zWexUWn|4vy0%Zywz1Py8hXi60i^iEP{>7QCi@_-7HluVY?DK+QroY^)8 zPAqOnmm#F7ay-Rv&so;fRZJ+%*cRtW@$e>7yuet=%&UO%ReAmSVW%~j1{E7k#euwV z`CLa8wDnVg_9s-SHnf&g3FnX6o}{EI;8IGXR5eUKY4h;nQry}nZ7JQ*6BTwb^kV{w8nw_9Yls5V($CP`v|7{EipbP%ccP_{cS1qRAQ>T#1&M=L=Z?|`(I6KS zL3F>B+ev3=TNK$hvZ_>0Y7XMQxI$r3n2uU*1;|;K0_dMPHFs=f{L_Q*(I6HRdV#uUhNUU) z#qxTYQh5udDrU}fjkmPQazw|M>8z9w5az5(AipeXquo^bh1jVOh{f32J1-gz|JE)b z`eA&6n>ZVXzo9EKs-O%^j?rsy9Lsc0&};i>FJd7ql$?po^0l%d5zV7Z;St^Y_@jNS zzLh+4h|YqR0_G14** zl-E855O?2y=Q?rKxJ>8sc&wQ0(__R}Ra&mHH}AfZEBX6%+*=}EJ?Al4vbi&I@u1`5 zuG0<1d}_xW8Bg2loisKb`rO--6km*cmkL1!})D3Ji~m@U5MLgy`gA(VJrQR7tai&n3R3UrWH&wl|K;IK3{p* z+JjoyJz~uZ^qi~FqR=&C8X?$xt`o7MouK33F&bpiOs!R*YZHbrh1bby7*9E?mx1!4 zKSg+C%fYgy(YQic-qHE9>PEA83w|@Vrwv{y4y})ygPe-z6Kn!17hyf}x5O1!U6|z> zdTVTbEi|0XxmoSBO{3)HLewJOCsO=a{0*RNK8Q@vqWPeXT$$>jSXT z^QT*2dWEQ6Sb5KBg4x_Ok!0=M&Ua_%l`f zx`mE-TW)EN0)bqmVBaCSi@8~|x zSe&jkW<~273)VJXhry-i#Z5%#!&xSORJ53RWpW2#`x6v}G2P&Cb3V-VUFV2Q@13$6 z?J$?RCzM)}XswFl1FQPx)W|-pSD6@>Aa@%VD)|>#T$FuQZQbCA>->0ik>FyN3QJ#5 zUOJ*ikpe5Mw;s8{&TIif<n1||tusoojb)oR8`}=U3#}A8<3;0G-Z{uZ!&R;|GIUm04=(aiO|T>(YQm1MS z#H1I3y1GmfAQemQng*oe^+f$_bebCe3NNj)Dl7K=S+r9kM9erklU%zQXl~rW&1@jvBx@It=p0#i}mg?03R!py(@4$;UiKWk&*>jl8>3-zkfMTl8Vtp|3 z>D+z+=!qJ(Pn~yFM@P-EQ@W2gzM(udg{SW;*+rcYfueE5WA&`{yW1KmnLz&WrsKRP zH4j=lHW^FJP31)5YwKJlL_t?IZ4)Kw(jH^}C{IanajA85r%Ns{cgc8DS4nofRveqw zhRPkXE_8Cx(lTRHLVg0TOz}g9Sr61hHPuK~-W$C6d2Bj98pb1uhPJ#G2YO%ObQ?T)h4kA;g7kI*&r&8!Y*%~Wn?68<6+V&)j1;w za_IYGP*3|bJ$T|PrR+WGpLvOC(Z9&={ISXw{>pj(?Wf}x6*?vEWfi>TG@FGGd9B4f z%DkD|q|Bd1$M?=af&wup+eEzdP2|udBY^~Dum%<^$D#YME_cbIXkOm4#V**V8H>VF zYGS1dv_zTtQ?Y#SIE-qfxQ!XF#qm|0Yj2Zkuq{J{r4>Bi1ult|dKH~7$;$HaT}>!% zuS`w#1S+i3D4LEv6%$;*YhM}r-01MTMmuBRlpx`>Fi?E-00}7i2+h$U&cQ{&7|^?S zFr@A}oe!5z%EU&dCIz^K;`nY%z5esOot02){;mjzKS&26fABMoSgvxVdFPSytqPCb ze`+3DJLfg5?;7zh)FvyWM$WMywHh0t@5eeK%IjG>ixx?Pd(`Pg1wpzGfqy zRA7ZGd^GUx&HDvC%p=IBa=9JwqXw;}!&G;g`1k>_C;LsD3aL9T;;d-%#AT6IQbb5o z{fzKdyzx-GZemkrx3(3`LPDXuKw6aQy|pP{Uy$V#oDcCCBZdv1UO!V!TqE%q-7!mb z2YI8k$`Z2PDfAuP3LfuM%I}Bt`YM=NV)}%r`46ri+&sTKo`URW$c@w}P$h36==$`g zeMsL6Qc_Q{u@iW`?2C2D1z7{DqDg&MwNUg@U6C@bm~s9x0xQC|FLzULQgH6Do_eroF^T* zJDxk$?>{DXz2M}XBBq^RD9yV2k*OCvLMO%ql+xd0nLw@Afbm+$Z$g^H%A_-3Gtc~+ z!bsuWGyy_^rpN^wub#>YCmkC;@12_UcF#et$Uz6&FRR*T{>TEUg&d~rhW#4{m$pRC zZ|%wv^TD@J3zORi9dHG_%aczO6P#7AJuq?WiInns17%L`O_M1MQ+l}0utsd!`r*8g zTxt*MWGKb?SIEmVU6SrDpR|DZd1#oA)t%vVb=>F_y|C%}5-10O=}}7>l{?=<@)pk? zB$N-t4>pjMo9&1W*%iT4`!o=>y808w8b$l2&<~%>*97wvU$QQZzmx`9Pb#}Gt;~ge zY!TltpYUYGExuLuSggZAq6#K6O^g3tBwVc~{iZ+-5cg+eSkeu=9^`trQvH?nhgZOT zzEX>3$=X-jS$zBta2VEzoSmJu>zcVaOtd)YSh$#=Rpm#72`Vd#YDKL~Q%7hk){H(~BSA4Qyu3NNfepc>8RNc8Js@^ohGhjQ%di%`1xLbfZXLOQ{qc zeGVInhEjir*M?p>Yl%Jb1%sZqc++;eafZB3NSO*@(KUXn>lluaS8*?7=a)2P;k6!Y z&VjYUN$law8^B0?_mloLFv=w%hfq?V*Q3%>?(#l>Uk(6}wLf=WdvnTwck?7Pw;GKE zpT!7MK5z)myt$A)MRxJQ{CFyKHLD28>bfy5?Vu^~9m8 zQasYu4CGwG`jVM1I}jv8LH!#Wo9@=EC*B(zKYoogyL&Cv!jd#!E0x6`arkx$ukQJ> zSbiB7wW2`41Bl@MBlqDfjVH$=zTJ}V15JPpa_(N1i%*8f-t)){3bmBU@2gH! zPG&bzJNFhV`ciw)_PxUP`YlL%7iPZKx93NvXyv@l>m%jMWSDI=F$p7Cd&g#9&-D~r zrc*NEq}e?L%MKr`=hEuNWB;ebqT?P}^2pmMErzA|f?r{n#3wVO(_DLU!>_ zD=hU_^oXk!11~OQLU^kZI%Zn=ft>ENRMc~qIgO^mSKTvfx*ThzH(Ad~{jh;(v{`es zK9j{`paz1gACT<#9Fh`+^f&K_H$*05OTyG%%ap_kRBJd07uwcAi?Yw@H=f>8_YxLb zXlG6Li?xEK-f^zyYFL*`>2K1D9`wv+84!`qx+WBSkv8>&UOxfu6#yC$3WlN2vIL6Vi_`@N zJnCZlmtL(fGnWk`$@#4ia;^ATw6yJRZS}8NbotjTD!0Tn;emOR6woahK zQ}sA#v9N*|t-tP(mpgS@>9~bXCNg^bahrGiDo|TVZ7lS#-mQLqsKXplVU(B|9rRk| zn@6{93?J96#E1j<6c6`LE(w0E6e(qrA!+TYg)r1KqEt7|Dxg|1Rjy_bhFpZNj^;7%W zmLe9`7sOF4Jc}7$ft1R8pKQEXv}|Wz;^R9}u5g#7#T7Qi#~Ro6|A@L%q-AF>V8vnw4pY7G~HF>MGKy930o!85n*K z<^_hXnUI(stZI)pBq64_xg`{X&>Hd(Qim_;;Ml96Z3hk4O0SCU!jIP1agXO(gbZ<* zkHNA@wk4N z)x6tcL_p<;GwUsMYMt+7(7Ig&BzHSg*!M2?biYqmIrj#XcgoE#rO|!H#(7FOEVkl~ zzTyy^)j7VdjmxuQ|C(tI4vut|cR5Zi?>g;B@=GZ9+c6Qd3v?6)u?wcef{@enSGyO|EU92Y3{F--!ns z?7l1Ww?vh0q@9fk=Ujqwc%W2BSN=thk>7x-C+*28GMUN6_Ma^!5{RKP8SQ4iHlj+3 z(!fR9qVZv6*Du9Xn5Lr1lQ>Hhibk%vRI@H68Btdkf_DP>cA-xEwd?26rC}9HoY3p( zz0q?rnPuixK#R2z0`h8Lw-@{}PFpq$dJ$~0Jq6|R-SM-8s%$0&I^62DhnvKBOzJF@ zy3~db#`ktb9yv!89z&XCcUO78SbU|lP$IPl^05iRm*rd-ALpcs^m$g!tpx)33o6mLVW6Z_-G)1L6NE1I7mB!iO=3Z<1 zLd8*v@B+P8bB;nj>+jr7W>2~oT!+U+sXxQ_*GVzl7>;V)D5L0uLk1JUkYay*#VxRo zjxsZ>253cW^u0TA(R}|-|E-2>9j=>(*YHLUi9yvc^BrJGqwx=pzy14nwyr20TbW}% zGgR*di1)k!NWqSp^bn1_LTktYH7oDn!q?h8kn~%LX6xZ|efIgPSI@LNQD@X6)kAE# zEGE!1Oi#(61l|0#z#5a>SikcMYwKVlNrpq$SplQdufcyODE^%t_n9&6NQjl@EdxUPI zSTivmD7%sRq)P>ZQ}HjimCpvtswIaQQ*mJlJk-wT6DeM7+M4(ch#u2v4jYd&Wnccv@LhIJP^~jcu|LN~Qd$Jz^9+LaKT?_)LWh!M<&) zxxDo5tb$uOt)iY$FOh~ew{$55^}0US>+_bouZEc&Pgjo?dR9?ca|)r|HrP@o_^Uho zl2=B@?sMEPK4!rmIqIO%g3}ARV&OP5$40QT=CB9+HGh_PZ5}HP-ADW>3}1?}7c2 zJ*Tsl6xv=b(i3Ep{x97(hv9r&Bg(uu8azOt_s*C@1=?~ITNN9yuF0Wmy# z6T~nXR5O@PaNWeqapa0xN8&dCet6XOK|Hh*9O@tV%|70?TVl`P`O8n~_Z)=oDYpE) z^Jw68HQno6n_oBoRod&ApRE}V^y=F^~3)O->v_y z-G^$$Yoz}Y^Jf?jyY|HY`$44qHHIPl7#augJ!h^X!A_TaEy5Pq8zg5or0yd1;(L$E z8FXEYUg$_7?%T?^{8~69x%`)L^7Te>B|29(+8KiKu2Y;c607;bSj4aB>} zg%z>94KM3dPkJ#U5jOG_XZ#XyZ5g(-VbANaj(3yGf5|~ z^&VAJ6%Je+{Ce8KK?~io{5twc%;Ti>Q&gSSkz3T2Lde%|J%b^fryCbNYn+l>D{~BA z_W%GGKCbCMr>Us9?8LB9^Sm!=a$nBWRSu_lOH_zr4q!Z9k08>^SB?YF%UF1p_Co-@ z)*UU#UN;rNDKv`f<|X++wmtjH$H|7t z>cwD1df&V?U|NUC3EKmN&FI1y^RZj&H)?ZC`D|v;-61IwkSrNNT+}zwgx$hcR;w(r zM#};#zv=BGqo8h`{nK+sFzT4(QeE_|!$`e2~89wDbh&I0L<63beqCz@Z7EB4wt~~L% z=pb5JVwR<5^w&uCJV@$~vk+bglUmuKs0T}c6{_lR(pHvPp$+2M{UJ@0s9L^aS?>4l zJaFeBTvQ^*=S-YTo9kSv(}X*{=ccS6XsBZE_~-T!2RMw&^hIy0leB3lMog9j-D4|1 z)JHSKWa?Y%JM~$0Yg{?S6O$`|o0l%l@Zha+E^HHs9~|N8>JRt$7I1ao5*feYFa1V& z%u;zj>P(13?_W8eyCmPN6{v%?AWb2=MZfwI#kY!A25aD@b%(>TP!LQ_my|?#6N5@o$ zKKa>=OG*%yYOuNd6#=_g#=XO+&yd1pyb1l>@k+DYQwJ3}t?`tVthZZUK5fJU@;Y7i zJTY|QqLOEsVkWw~k>3AqpPH8tgWospeqsIGl%b8<1$u#vp^*GPxx$3!S|hsSI(=G` z0fv8=ME%Jn$^kYp+ia*1E!fEukMk~_@4j}fzJGFS4=I9dlmEYLobz8KqlzIbQ-z1o zQnOiYc~~X(&L;eXoCm`0M*E#VSMka^ih2rD6!eiQ6Or+qUP%>Pl7^8j1Q!XLg$r~# z-gI7Ak_5lwQsrTX`f0CYu&l+i|0zCLJ1;8_?H+!_6jsJiKXqT6wlnFCnvXK^?Ok^1 zh2MZ3)fc4S&wr+g&E^tx`X3}h-tmo~9RX(VrH0Db4nElS_&;B{&$Ou$?{djLO&9@C z7_oo77idmF2iR1Jd{({m@U9VI&N=h1zv(D^Xa5^A`=sw}iF6D@v_We|%DnG@a#74N z7)Qy9K*zTOQP)Viw@oR(|H=wKG`c^VE8O-QaBsrs;4*pQiy>)u!d>UfzXDukR~$-`)@nD?^mV?#v6LFcDKx;qXY;m?QXnY^DDd#Fp^mTXX;e5Clgy8eG(!^ z=O(UZo05(2A(i9Ybgy+nClZD1B|hI>$R0><5N;f>xojKS7+RpW+Niu*u^Z7mtNzpn zI`0h7rjYw`{AEA3;&>+X$oGkFK$q!v_YaR1X7?PE(@XYVv3dS!_W9okt7j2XXY5GA zgywh6Ee>T*>p#6?Tee=RhQ7BvT&4(6q5#?!*4+1LluwuUfIdoVxd_W1$o@w^hI{OL z2PXd~k`X3BPl} zaJ#PV*H@=-Q|*RGlp)~1K`^X%AVNU&FQD)*oa1oLcrI}N!N1^+{J(GxQ)|Rk%qW%B zAGkyQFB~Ib|IESfe*$~{7fQnirW3L>L!94I&;xTR6rE_Zvy+{%Ydkuz<5Zc1yl;7H z%6mk7yb_~}5RNd73n}Uu`BLV?&}yCsTQc}qXI6ZybKdDsJRsQT&MQK)0W^&(W1WKh zP1%^0-eoynE?dgW7W;Y+@LCvq&ULHRNTO1ZHZ3_#$bgVJVF01Y?f(iF{@f9d9=sHr z42`N@j_*7oQ@p1>dkA!ROjI7s9#_2uAj>4omRWghCb*bl$%Xz{t{Yj<{e_4apYGi5m2N4yb__yZE^@For@ z_)Ccua^0$g8_pIj@ZQQ3b;Q!gEW^pXOHHm4WK`#KL(6n>0kKjt(gI^Xo_@`jV487g zXcXOWMpvFVJ6bF#-fG}tYMin?`s-uO3Bp3a(nq|mpx-nC7LP;2R68GY{X~on=RInr zSJv`eOyTO$*?)Q5H`{+cZwt1aqvrGrgAP2p`VO?DuLBfa2WW7xv1GAoVdhFybS z2wYaH5`q=OAtvkE($<75QZRLW{1%e!{#kp(s~Q3_AAt3?Seb@0!^w1mppr=CpG7gP zAszw~4CYcJ6k7eOW7qk&$}&kZ5uC5nqA`sljUtg133DS->uK24TO70!gDzl=bHz+| zXe@oCEN3Q-k>GiKVV>^6ypD_KEQ8AG?h1vwYLRCjmu#J&69t`#kLaLW{HK^ax;ZD3 zDIIT@5yu<*w@5*8F8p(4Gb>tUitXFS4%)@NS!0Uhy~uLRxFb}defPgjPYHQ;5wmQ=>NbbnmJ1J;|D~M zGpAAbXj+n^Dl1jw`6rky7rWP7^BG>d&ItEKeyv*1 z7*O4LxGpGOjN|_eREev(2XqGe# z(uFirR1auW6;Z9gS3pYxzM`J<`Rk7(;5CLg6} zJW=5H1hEu#7z&>mxlPIPiRbN>&nH2?(G<+J1ExO8(bEF`GUJVzu{L5R!c&nK=E)|E z{+`!^sd3FX-m&sv(%};Oxp_IndZvxrg){FqUz8>0qr%&!pf5>x=fo7arB@k;Mu8dR-H{Y9FFyhHvsng-nbJ>riCzg^C z<{L_NEayL?R4w!GHh%>vB~PPvSy16kU%+lWQc|V?-junPU2pJj{GC&GjK8Ldoo5t} zis2$%t3R_l`a+Ys(7B_H)0;r^vaq<0VApRZTxpGKQ1x7nB5(9Y#e^-@VSGf?ja9a% zc99-0vLE?%fsVqz#oPY@g$~n|F?6T@mlg>s|HRDw-+(jD`{DR+#vV*7x-|X>nZm+kY1sPU$;@fP`5D*32^}m=DwJxfrdY5Z>IHNY z{1zn>y#0Jy-dDG<63VNPoX_!bHyXnoOzQOU4jvWmx4P(Vg@NLpfH%7_pTseiMcN>$ zTJD3g>lP~jF7_)lj{tOymad)K3dZISvWB$In|N?)J&0tswpB4C*YuxJ(*T zyCgj)s07%SDc;5!f1Y9&#_&Ha1=HXnRC$J3zapQ)r#+C5rA2qJ=FHMELf|OAUQMfl z-m)U`D}AxzT>0tcd=dL>Sp4UcQg@zNz|70Jf@jv2H^S4SyYy@h{*H{R{X>@x;)3XTO@Pw&}b|bu_ETo-V z`XVY#g^Pjkp*Tl^MTKxyV_6Tqg2!%5NTIuRYo-?eSpxIUU6({I;+AV={hFq8x)ft+ z$8!$g4XJrFi{Xuuag+h`zF4@$JfPxvgQ<*#?Wgx^F*at#UP66<&BG3R5@C zQ*00>lV4ZL0&?~FGZS?I{s zH|h8)TShvr{z@w9LSrd3QU=zio>+P#VHGWT4ei{0c|lR}0O8xBGZYC2tYC_tC2eXv zwAnA0lK8Ni! z_E+BKQ-@Zq1wU&QyS?9l`&|*g0fxTsCG84N$Go2vU(F?{uV=z@kplNN<8M%#;S`LI z(p8h=soRDv>Kz#EW)G^^1PR$TtK)wI9C07L-<-CVM=9({UnTAkv}a0umszAOZO1b=<=pq~xf1*_D4Zm5b%2LR)qujbddwJCQ{)$>d$-gMCim#|n zV9&yS1KfTCG<-w#)BbzZ}l}Tm~ebILD4JC?SIDc1<5Tftpb+rzWMFuNRwm= zL8KDv<$n-bx3%Aqb|MCXyStiVRolb_eQ`)j@Y`V|)Axf&Jz}OkzocxQpPZM5Ke)d1 z{s!FmHSsI@%f44}lB#Hu?g^u>E9|3vVvqKdntOQbMcr>e0f$G@(X;(~TZvvg%6ls- zA1}(f7Du+oGRP!nxBod9^?!7Pdgw19QV;L^`-mC#84(&MJ-9K=FV9lvhs2gXg&w>Q zZ;}m^`POrLy?bHZ`fS>-ZkBcGt0C0hj9T=@z-`KIIy`qU1y~6ucPP&&$+GW-pj(OxyJ3}X#-h< z=<$h<=qlvBkr&*{?POi_uK5w~H<>zr16Eoz;sR@h7D}zl+yp9{NFJteSp^9A^K?_j zpXu(hav!WiQ>@F4R*fsa%jKr%Nr63ohzPJ-ZtPva-U=JPt}%v1Y3y-43{wpC5cbiK zP8$@G;RQRC*&N|U3q}G-TY~|i1)ju-_&j1Rx-B%p}k-&+{R$w zt#(H6+$(CV?Cip|kfA`UQd_?g{>;f}`tDnr>DyomrQ+X!mlwIe0Yg-x+Z^%ZF*xL> zH!V5vsSJo8{&Ve)pDanO#tHd$5CsPgv`VEj| zrp&@JYVsx+m3`ew5Qxa?M1Za;rYgV^AtdZ~dHAbp$P84*;D2kKrTAV-uNu|Ny-POZ zu1kj`h-dQuAGE!7Sd?4eHar#*0)hepg3=7BG)PDdF!azZ(lKl8Jn8xnxk7x4Z>GIO= zSUXzg&Fz#+1}dc3L2U4)`0*2R1%Vty?7Cf?UmM=1%`FtX$zzj$Kg*(Nrh$B5l1s%~ zt2CivT#BShD@o<%RxOAaF}E0fg4=uH$|*(=0Ll_;z=h`*xL zzT%nytQL0O5lWPphIydm>#83}F^JuZpzTC1?&I9WOh%6>D{=A&gU3dS(+M*vFg=v< z5cGU##?*#kTm#P76VZ>;d3Y)y{SZJl%_%E~wn97iw+D+FXs5_ECw7f>Z}Q_SkwVNO zECd;dPVcT%)IG1>X|xWNiv(FE=&Z`i`6L-`M!F*PiZ`q$^jupX)U^Q!hr^j3>%!hw z#WDAMh*%V9>RdmL?f^V>Hw+Z9E-JarNgke$uv8mEO&v%aCf0@vxUnK;@JLEAEYJOX zE$Og{(-+t0BXk8Bu=p&BuX6U?B^KAH{g9x#e?`v2UwKt+eMjww(iwR3`wsfcwrk-R z8%1xdEV-0)^t<08K`D@06ZA=e)SeH~7mGiw9FhL2J0q}nuXKNkZP=#Nz|GoO*h4yfUY`e_kY3H5ZZXJaY?E*i z8>e`e6Yv_Z*3nW#g=@{o=+e(9v04u)>I` zMN=Goj|Nn}mW0&joAc(dDH!I}E1#!66U-1uzS0wKrNbQkgO+Cv-;3B}6f}V+mp5MxEq!!0eg`iuw0G?T%?`PZ68$mSOG;J&| z&bdC0N_0%m^j4Dc5yhmZ_1ANt6~f)%*~uf8E*Ct>kzf-JzHX9SYdZ{yIGe5f9rR9W zs8(9Py44;5{u_Wri;(wAYP6zl=cydXS0lol*Hal`SsWB9r@zTlROR0H+0$MksXYx5t?4m$x}BrjN86 zdX_KuWvmT}*N2`ny*5CYjSmZUAXA9i#wiqBS+!iO%mRs?5SSax*{Vv}lpYtgLA(q23Y1fs?!4mJ(^`1yf<%^%Te5cdJgdjy zR7AbFI_vbFyie4t1FaW_G#H*&GS@9O>5m~OS+mqOJHV8hwJMd*;A+8X!WrTDCR%`7 z7Az}+%lzEuxUaS7WgS;KrJuL(O|#V%gCXeGE+ZJ|9G-f4+iOz%b}7UrYl6aO6)#xc zM^9^g&4EjI2~F9US_+Lw`*ybF5XjdXerT3>=}ci%5l4wbUzF}3ZSR{NO`M?Lq3Iaj-YL&a$!X-6F2+h9bhdzON>wgNnyon5Po_8jhG~NtOCs82hS05 zRYaE2b9gFC8<5B%`N$y#^cgT&hiRS%-Vb&tx%O~u>cBigg+g7MaxoN&a^;{?MS|2v z$z#HWaSS;8nrUmqzG@V)07}L@#|bTbIn<~GuhoM%Dj;0mtm^!38W@K@%inbjtbE&C zD%#R-Yf3uHsi{;nF=^Y&`@_mZ&wH5_Wx1Ll%Q2>h)^ahnn%GwXI?-OKU$Ht149;xW zXPol~w(>NJcyiJ86*O#8O!p#ZH4v?oK^Bd%A0k-iaI9F9iOrRcegfQ4sl!9A0^Cv5 z`x8J+cH2Dk+R>7l*pQCox$U4>G5f71`IgsU-NA|%*`M%2UTXi95lZKvx$)Yi;O_UI z07c1xB54>?;4dQKwOkUnvD!xzgR=p`cpF*ZD zgKVZForLkd^#+TwdfjrT-6~1&b0tE7ih?j&_7v<&(BwO#Q>5DW;A)}Qs0(nt zl;DM+ochN1X#Q4)0CZB(-Y($)2kyO)XI4C23c-#A>>>EDL9|soc2NBgX$bWCiRJG2 zt513BDZ32LMj~cO@ldY)IU@M$`V_SGO#6(B02y$IR4< zHK7#Er;29@Iqj~Neu69K4D2~<2Vmi3#{hCKt?EM5X>pH@oq{%($7!X-)W-k;0rZQ%-Ji;jpG+>K-g;4jR+?hCLV1P&BW zsYOYu#(vYV@l>OB6sAvX+vXrv(Z3C*hfZ0vh&ojyL0jwlvPKdZzAE}4;@6r|RNLoT z=Bkjya*Q%N5DW>z5ucH2?itqL=VI_ZZ*!z#mVAy-=uwKRY;L*A7zAQ&iY5UrgEim_ z5?X0Ue0>05@^SQBwe1CW11*)XU~tUUIDR^ody8aV;QXD%hciYYw)`NrADcHzZdPnIgyL4qgLS^;d&*6!B9PWoTPK`lO z<8-avRhAW8n9sOQD<^Xy8=j{jLwyC(FyWP0-d!%I%}VTY3VO=YS^0c$RZcG>NM}lq z&-=AsU=I0-P~2-d>0rUIQg-gAT~M&`5F}Fj7{x$(@61?d?+she1YgBw>=v8^H-L0` z+PLn4gE^t(9G;Q(TH*=HT>Sa)37etYR z0f&x`meZvCBn)Zg_bGW*G?SV^^u>J>mIpj-licCe1%nwwh~&7UHuJ)BncZ2=kreX} zy?k+US={pR$kM?(amy|cSB+vjcJnN*C2oL}ZdJAx319AJZPm)N6OaxU*T{F)+8}E- zXj>l_nKdt`jQZ7TvQC}8euz_w1QYPAGl>)PQNZLpqo|lCjLWTsHDf_r!w){1%j(X3 znWef>BpVwVRd*-PUCkADjKM}=3lnqIr;;H5c*Vj1@k90E2DL(uh#w7_)kCp2^G6mNtj&} z>k&9bK9|z5S8wl*)oR1o&~b-ctCI5f7Qu~!q;eHC1K-|N4Qa!kZ%3+LBOS{>#`+`L zDI@C)>rSGbEIo&6t$;#Gd!6NKAN0capu(O#q@_=mjYTg;q`zHd*ZS}SnG`FgCTBJm zw^%;3ya8bMWjjq&BKc0s<&jc6xe8t)8W_~;3 zvSY2iEIK`P*!z8uko#G-!=rQ@$PXokTDDyxU!3A@oLdg&jz^+X!g8MW(l^@B_agE` zB6T_$K>8qao=ptW)Z#w*%8ii+vDc!wn!}ZHW4cHRWFU2XBkfaH+3mm*@7=_4w;u{;<|L#(3i1MER`voTN&boSVs zm1QAVTAatUz?Z(Whf9fAo_?%E%R*gmxxEA}3%z(?6lu5`7N>33pGRwj>`e~!zmhbM zH4$W^a8At;be`(~u+_?X@q}+xVF-5NR1m^@dCpDBcM7$kU^!@Clj<_+bp-%`kM2Nk z7q-6>S)xH=O|R(vEAkPQ8*jtWZVCVt2D>=X&dO|fQ*HDp1Ddl>ME(@^(vvBjsH1)Z z==>lodSm0@0zgzbfl86iZVlHJA zOx{x7isN?9C+TlN=|jPE?ZV#3u5q5n#p71^c9h+&ZAcTL=}e2``!n8n?Pq$Po|F%J|DlRJF_?qmIVZG zkZy!>Gt~6{Fey27-|64Jo4Ebm;EMaQIR{|E!Z-;NbX#80kgfy4Rh+if@-4KO75TBe zy6ArbKJSHcKJUjo$Nm(wJ`^l_`UF}sm!T_FmVM`T$EeQC8YUR=Ynp%_*B>0$N!P|h z0J^TXjHXfc$5j5|U(Efr@jk47H;VoV(EFneHx^_XqQ^MBCOVp{if+4_Q-JF=A&4D`^3MyrX<`$|yM;#gVJvJq;|8pRnL(%Y2$5=fe; zx?5mZ(p7u`;~oE{wdm?FwR-U*%8*IHpD6>t7PhQybxT6Vdqzn^(7E06#y2Mx)MN|yFikUIBE(zwaM$UYm|f6$f(|L6Hd;W1 z$KeczgZAtYU@*RUNdnCy>w;2|< zh;#U8t}4h%UYB1SH}}Kk!|__e%4WZz-K4_CM77z(WAh`Ow+is*y6-*4L|QAi;=QsG zd^Uw*I1;B+2^QpF#|i9R@9>V1?>L8;t33qOqm|Zk-VecOZNpPl|1+v1=7cc8NDgaX}w!kv?c9@K?=ho;S zA4!jL?<9b8>7jfH-cVph)3?8t#Ih31!|JVX+y!Z$0N45T^GI}S@a-@qd5Gh+?r z1?eS7vB&!`!hdY~Mr)Vai?aW?Y>WTxp8ng*P|~5mDw)7DIF_l(yOa4@?pHaqvbOYZ6S_ z@z3<(h=7N*b)+}7f7n2S0+HOl)i7YOzn^Y=?8(*7tBUL%@^S&31R4skBRfh10I-M^*bg0j8s| zzn;l{RMCwzFlCgJ_hZCgBM#PSyxqu7t3)rh1_=Jq#vxLJdE8-mW_OeMcJ&ZsZDlFh zu&{~`qj)$NRZcR^{bTlf{!hSw1pX7zt=L+%N7?pQ_=T6V2emhi1>0PDtp&zATVXDfHP*hq=9#RmAR z0ow>Uh_-4sBs+iat2YV2n*=8$^8YZcw()mb?YHAXN_H*MchTw0YCxPP4@k(jbHZ-|8@2-QlR z+i4>$wLTp`l0|pIXlYdr1sNE;-b(C6ZNTzZ4ZVQ)d?*`&swR4MCYfjqsDVNEy&dp& zdFK^T$nIxL)lKL57#Bt~PdDVTt~?X({*L<+!#$}5S%@+ z{&)(S6)dB+`~Xv0$s^a5f5g>P$+z42hPOh5Odpp1u~WjFD^pa}NU&Tx;(e_THiJM# zOwu8-bIiGg6q(u{@NuzO0?w+8ypu({nO$|-!>YJy&|<=Oa!MTc)-SY6HBVmGNV=u6 zI8j+swTrv1X}*(y*kw$KBk>wdv~V~!uElE$a}AwdxKjFVd;35vZp~lm>#GZ+=C&tSWKMH^nAC^=C*&-q$I!+w` zMQOntYq42=>C`Nc90rcAe2^I$-z;{|MlUCUyA@^5B{-~3nIXuigQm!sRYC4G>rbpK zk|G`W5HUy{kx(|%sskt)UjeBLrC+FGpxe+#CyI!?t^&QT#O+X#oc|gUc(%t{J5!`- zO>Ck$X%%F%GeXXkEgUG?q$feB!EB?!!uBLpn6&o|t~9qa8sE{WFC7QhI0+o0q!8Nz z9US6jm)b52wVwPMAm-x-oZ_spRv0m|yZPvK+K;o?olS*SNdglg6u&xbdUrXW9mWzr zI;|K@p)s&}r-N6A3;Sc#(ZDf>V6nVyibTXm4nkomI{WRpJMD^vv=0+HRyA?KdLGd_ zwg{MnW_cSjDapa&#mk3Xr(aa6tmWUTMdX)#kSbDBWsZfj!C+b3V3^rgQ*)V7qNYx7 z&7`6lkRF7DrVSV&<0;Qz`caM=VxBb}nc{KB_Wy5hPuNQAf66OM9xYpWGREb^!xzEf z^kOerIb0~w$KUGYpGkHxxtHPKa<^STovzP^h34hJSRF}oBM*JS?tE_`d>G0~6*q1;U* z5lJR*x*xy7uaCSfG1GTrc+WYZo_}zhKdVNscFShV#Hp{C&t`j>ZsD{*qE9-88Y|tq{tiXxansY zzI(>fPawb-eCv#2SSvV;H$F#abRu!7!v|qkinjf?6J+W0> z$HxjY0j|N~1>{yAKw%11$+3DbvWoYT3pmx0TuFIDuPYUzR``s$AD`d(RDRrB#8}Qt z=B_6)cxs{uf87|Z9BHR_h>T3hbx@;PhRzNO6)+^H@lrR@o#?RH0`zvf8D}%c@_Efo zx^y4IX<3%g27v-0oq<5sS#9wc+dfE6{M;=rBF(c1=vJYwwsG}x zSU*gE%JyQcvUX(aHBKTdwj~f5OSGe$=F_R&xiA9C>c_qrsr^p9t75~n$SLY_a%^iW zzgsNBI3oG|IEw}jWR@N=Nq`(hFuae+@9C%N&3*)+w2!eL*NMLE-69G3hi^)y$TnsW z)d9GnL$I+TUHcasEBG(Rv?|)9)J+6%1OC**=hooj0f3J6YCM)#_pJQuydjb^@{0%)3V}P4%SLKOnYme5k2jmB;TRX5>LKY ztX=yOu7`@>CZEW)t<95DB98Y~S(6_mG7+HEjEyrQ$r(+PJ4(jw$>8zkcgHhsFl&?k zn%>7juf1><>|&!7D5w@aJG1UGs`J|KWgSLXUw|Op0V54wU?rL36DVEfNKAYA=KilGmT>N2-9aVhQbWf5X|%qEB2j zuypDw5ON2=lZ<2n?nP*9sc)FP-l<=x3%3Lt?UAZ z^{yrUUZv-EL6(dN!zMV7UYwa*DG@-;U=>z1`4$uF>Z$s8pG8yz6_H zeuyjf3>N+KLc`gj`BanZgZ0m^&vxy;Z$H@&(omLvo-RM~#jN6veA;RFbYzLn`kKn#`YVGtFA%U)rNEymYhtHQ2aveWF!r?u} zX*agtSNh|^`S)9BX30ZDTpIrGUjg~aXZbU|m+Ce9+Mnz6{@B&>CMEbx0i9wN-t^|U zj~Ny;jr@dQ?tc>!>aAeHf`OwUy<)8H^D%)xed#|LVR}yzIaK)M_?j16_>%bBOe$F< z#jaq|-XCn<;UN2Z!HZuMFYIu^f51D}X>vIT5>XArB}4>Dcl9oW&&d%!iBAC>;19o! z1pol|6obLB^Haw}PGmoY{o@8EWOl)GEd3sE+kD}#&V;Wss9j%D8n$dIrSAFbgrcu$ zFvSccGG%L?PMwhmxr!@gMnc5xh-Q4vvsGh=Xey8(zd^#3DXnZ^FrLSZMQr*{KpTs6 z>%wv`n0*AwksyLE$bdcjjW!mOjS-xGR01LV2}tI6a`F>U_q=#NN>+21@-vZ!d<<>; z5^ro?wg}M)wObOykW#64>uz{tsH1c(iX=IfzCN-4p|jFnSF#o&ojCj?UOwMsxIY-F z^z7p}$bE3hYBXNoU~11=H-Rp-lMBHm!8p`OP+yr7yPedS-)~3xJaWyt=JFDL*!PWQ z=oM=^o?IP#rDd)Ex9flRcYq^U?v0a6kOG12F|Ypj7nksKH}}rFNx5sk!XN)^y=eQ9 zvpk!6B)(=Ov z_VxnF*`jgTh^vSe+$1+E%%n%0w$e?)oK#CFz#OQ{%Fe1l1vsC`zi*=t5n@=D6 zAn4G4Mr!Qr{)*J_^Z%bkYW`bP!*u8y6^E<_GmK0q*3xQ4z*PCgN8*tFCjm5rFY(^z z)migtAh<-4iM^6|0M&%gBDWHO zrd<$yjwS>xpz;YDnnT>03 zix0MrRZdB|%Ixdw--U!8+laa70G^AqPU@{&S-K&AjoW1>7-jx7?$(1D1I#c@&x5Jo z<1j?iu0Lq^y{-nxTk=3wa$N z-PfcW5elsnfE$VK;{OHEYh$otc@21=3^Ujr6QqYvZSM`#$_w9<0!yB4^NA#ujz*KZ2zExkm-dYihU=InUW6sQonP2DT zzYE7B|DVF~D^84Yz7E?zi2Z0u#BGL3imCjYFy>XhaI2!zHxULAyan_Co9qyK0tdye z_QnW8$QHzyZ6CZUpr=|-tXsU=vD5Eh%eks3h$>YQTXmME%2E#uOt%CHF`tUXCKYLwNM%{e zD@NHkf+O#o2+x@AS<^yRXmsCa3mXHu&pJS|YAK(J-BEUGDQN3HbxLu8>d^OFsbJ-| zpm$2L(I`2&9|{c_=9&dZ#LsP6pmeA4 z^aLGdw*os^1+ULsW*id3#qqf^dMsR9G0Y){voszk%jA35mFCICon9r1Z$kHF z44%tIS*a3jA$A9P`uj?biP}y-Fp|x*0bEB86q%AT-)dWLZz41Q}n_DX*g**ifzajD+NAg0(lM#fJ9*gjyPSh(lA~kqJsldXcwEi8iFFw33HHx6$$LBO!+mSc(BP` zNvx@RV`GH3t$Du9mjiIebks>Z|nK9?MYCj;h9Mx_5K|G56zk9u=`a7-S7LD-~(+ z4zY8g>cYVNIc6W3DSIgt^~3Z1hoW>_F0^IK2R_LaX{K)gI0speA%I(F-K-zBp*(>C z+hO!H*mS%=nNK0%5k1e^jl*OXu-utZGD1>Zd0m1rFoehxN6n2%ra=mL1ctOCTiV7| z6H)Cc-yNkoQlnN-^yNIIE~o^{UC}__dx=cwnOxNu^G|I>oT5B+696UK{JjE%qcFyygn z=KqJFw;?4hM$p^wZ(W3-^`+;37|_=LGNAPv2*uhqLD&F1SjMlT9dIM)ju$2$i56oK z`w7U=mj1_$92Mb#&007%0K50=zj_0NzZ-8HqqyE$qAq8r)2NRNL1rXYB@u*fzU+UA!B$A$9J?ni7Hl}+75^n11LPW}0G0`D;jk+iqWG`nT>qkE4g-Wx~`Bd$zCfu%})C8AI zW?_8x!Jqz{sa+*o>yPfLwXXlP3`xvNJDoSZ{_|eQHAH^-m;cvWsiKX(9-Y|ilnkFtzD`lf=($4*dzI3YJ5}0n056kQ@g_g7xCdX_)h>^-no>Jaobo? zqk1;ek5c(7X|-%@&4}gop8(Jh2ZJ1 zhgodi%etP$Y(Lt@e$b?|@JBE(40J`Lo4CChGPDVoEUoMhvFN^=yfm-_bzUMrY8G^w z=p(1Bz=9p?>rzD)`$&pv3y+fqo7kk^?~lJ%WBaUQHiIYOcmKw<>WUYX`WHbypUk?A zgFw4Ca_WC~C**C-oS0f~;a&~k(7VUQZ;8+FcX!WXc7nEXQJQo%a;FL7n7Wr%oPT%k zb+mNjt2w;)?NxVt^S#KaTXKJQXVWB2-`#yWgOfd+IWh^$9ob}2Q$##c8lH;FKi;FQ8AXc+gfhWj0Z~Q#3{%1@5{B!~Z3W^#| z5Ud=P7Y0s>nl?YAmNS>59qV_0Z?VgJO#cS(3ZtrZlVy?fQpDg8SJAqZB0#~g(-3?bME}PbU~V zKIr8iXCM~1Dpp7){|f4NdUJ@!h=F9@Syx@4PmPFViU;uk;;tDf4>iq#VAOHn3FC)n zc~v$VmSv3WNj)2t(6P%IaqGSP{z)bsMu&I7z3+W?b6bIR&swB(67vN54PZg&j~Ot) zX#CPGi$Ay`fk6|e+!(G1rc48-z$oq4Q|Rb7jd@~F?f<|OSzU5zKf;JDbrcIe05?>- z{siEN5#eS`c!A4pj!U{`LPmsQL-u63C5t2-7Mu^rE&`0VQ_Wp_tkA}2K0e^*o&V4`upAC8gazwTo07CKncjY zjE?#<F#QKdhv&Ewg68jS(YsBljZbe6AeqS5ezr6i(BsR|6?`fa#@6^3x zWpTYEQH+O26gi~QvZV>Qf*h1P{jnU|{a1o+2x(IFczdRzt_D)ME@^tGdZ%{vRyeK$ z1TZUkj_L94#*5!SeEa(&*R3BS_!zXPIW z$jrEkO4_|I2Jv6$p6mzD%ckPk%!+0n82#H2D6gL)Mm7*b(obf7f{|zX7wKZ~ z3AW+464;ckPLrA!gUUhP7mv)tCsv<{^F7q&>s2nIQ3pRB`w_-y9nu2;N)mT>^E9Yh zY6F3l8J$uU1?od)711K97X=9$do@C{-yQ#!s>d zd=Zu@RALVAw_R9#POITIT^qH@I+WV84m`gZq+9`cUSs{xV7I7b<80gd+zF#7ffg$6 z0p-f+2W6Hi$Vfy~>WV{0<;bEVj2+h_R5^3~i%RV;{ZFFy%=@$WHKw)?Aqzmf*a>EX%GK7zN>G=zl(bn1Ng$obpwzaF4h@!elk@)l z;RS~1;jBDzrl~pbwa9g^XUcq@1K{SuAKH+F71W`_-`UgW=rI;9q15IN(*Av7nvzBN zh4kPXV6?586T%KANeu2RhqNVD3mN}O zJKz^1ihS?J@y4ge6@e>6@!Gu8j<#=b}M++h$yO^V2y zyPuZ{z1tqeFW;-Wt%E^_*mF8gVi>bs^u-j9y$S)Qb` zjao>JM_gX4Vd0e8)m{bX-M6a35G-o&xU`lBExEAJ&mMow_=!Jsd)6oHvcdM z&qS8=eM1(3fB&6V{Ow! z%%o_Q$W;Lb@*qu-ks7s$qVhbqI*lI(kJv6ZA~@s=JVB2c=K8gPHFSPv$-}$!mY9zZrY`r zYHf2d^2%qcvrG?KOLhg|kIOyc<`kBS$P0LL;M?>hStP+h>s)GRLxTmDqEl7T9I{+n zz@7^q#R!UU&=H#tY(8^wny%BE%`E5sgURNK(0rj@c< zr1Herkdr&OV%_`D2>}j4g87L|BNvgGG*BJ!*bo*i-n%``eA-cZ`W|E_zNWub1j2cSN~GKtBN< zCHKP|qwWsCKBm#TQ_&4f%-t@Td8*&a1>dk$zM-{upTlI;d6W~r{ji?1u{xjXPo>P_ zKb127J9!;pR9*DHK+69edA;aQ^7@T*4^1k@oR!Q|lz-FYVZLMaP89fwZj!M7)Z}3z z22~&_H>_N08DLU&O@OcD+Afz}`CRD%TelQKph&VQ`anTIN@p*E6*lTMt-yrd5&B48 zloGSns2f=sL;VmW57va!O_=7yM7{+h)VG8Lt2D5h);{CtXQ@Z-V`|PE1g`s+*TSZo z*TY2yy*)L`^Wf@Tw(@=_ucMKq;SYzDT0z_EBTaZ545Qio#@3K(sg+=!csG;w?{BKV zthe#6N>FK*il!?Ru?QNf6>X}{N`}#QxSE^VX3p&LE7E%lDEJhzzOH<&22CQ7mCx&R zsyGSC28$zFwxl(Ar$usfmbj(>gH%czG1)5fMGtoy6|=oS`j|RiyI@Bc8(G%$49CXA zNcdEyw_c^6)#_0fkM(;Xez9?K7?%03BbdeCR@7D}7J&-1Ec9igI*BnWV=YS*qbs z=8SM&;;P7`MvzL)^ASr|AajT?jajAO^4IRSqNQ4?sz{ZgMni5(q9;}gIbrf)++3be z$CO+cJEGz%1!4G4fPIC5*~T2ZklRs`=K!r@6Yr$!gZjn%kd8>{N5fyu(0WvZuZG2E zgfq*!*13h+PW+AZD2t0Xv}Zj|51Ugzt6CNevChn7>9arJ)&-TbN=slwsDitlWzu*l zr=!0VptKhNRxGQ;igj8Eiixto=i~XGdrg;=BO+okey6F~ZphNYm4J^4!iK=0>|vfQ zkaBl*j7q5BgJxV^(Yh<~WeTla8LZ1W(jZ_{$|<>5x4O1wnBd*1c37B9;IrhQV$vK^ zH{PO+()KrZxg*gXHQT5^@$My@Sk^InVFj+`s-uugbX#p@w4Siwmg|c|O2WTD2ogfc zie?i#ZvZ48_M)Wp^8clB{mA8C0&jShXD`T11_0z-9%;|G_M$!R@>#VV7OU1Ux=6~s z)lMZyP|@wuXQT(->zMKw7pErKkIa5-fUp1QRESYuGZ*CcVuOj?6BlZ!Y70^LWa@Wt z_Sk$8Wc`Afang$ZJ&o{f3_iurIOiL^=by@Nk(EO=u3Q~LsIk~HB zhi{A28^4FXGlUbUxr7%LZgfp~RS+BJ5!+^qkmyN);w*@s^6|Y^!50)Y%mrnib8z|% z)JSY!I?6`P6~xKO3fn=`Gcf`61WZ6ZhLro+GMXxAXqY|cL(q^meT)O??FdR}!Rtw8 zq;8I^qjzBv>xq4B5lZLE;#>Hwd)h;=#vqZHW`TNb3|8Tm^Gm@3WeVdu+uo-l3fUUx zAL-knrekMj9;)%PD7o}?D%KecOSFe0$bKQJP&wUWC5r_6H-HV*fkW{gAKt9iyf4IZ`*Z&kX; z2O)?f^Jv;>JE>)l6jy@0eLh@@8&~j!on_sZl9LmUkdkiEo@uMO@o_4?Xm5JV)HbFb+JI0P<&?X*6L^k^yMnrb=0r^^h#ao#pOfyjKTLkld zB$;OJjILPb2#V7_w9EuH>#PAB(^R%2mXhAbdx@}A9z#tYNL}<8NJqGQB*y5j{c=@U zo0@ICl73um5orv_$*U6mcP@Kd>n9OCS3eE+mYCvSVr(V_LF1h5Cr*b#Cf_g^8B;Ax zWb98j2yn+;R)o3#Z2EdhIz-Fm?GQ#k1^Q){<7H0QL@s0rK@%*WWhx-yj5O zHA(va>-grQcZDwhvbdG<-n5Vy<%avz)-7+`ulF-zD6B1@3uJNu`3H(zwGzJB)%)TZ;5f9D0 zi-X@6oftB7cJY-9e!MF#yCUIj)m9IIEzKgm=5x|G?>A}DDjGAZX05%eB)h>u(Gfk( zWi;}FY_wYI{IT-JcYVKM=^Nw;SdDeUoe4}9NU?_tr^2BL)NbQQQ+*G!=F7JERSzT8 zl8ZFXA*-j9tHn~f$)EXlgF0PRmGsj1A@mDQH0|P;msz{=Wt92T!1yL49#gcKv#EsJ z^~8_EV97brVW(rO%bqqal|;(PY>b7eEn$`6&QC!6`vo0f^3B0(HjESsRQiMeyynWs zt3Kv-;f5Lsq1Tg>gc;-UNP0&#_#=y9YUrcyW-&MvuB1p!ah7yhq&mb0H}uZ9>~%I+ z!99?6ENj3)y-Nz$k+g|9CdKB-?e`gr>EmW+QhOL>jp&jF3xbz}cTOQnCR45)i=v93 z{J(`Mi5&9c#f-~BA}Tiq7cZpNqUS{?AQLzcpile=5EjGY+O6I007IV{7V2`Mg}&*I>ts?;Lf(YJEGf_@-cy0a4` zw69qM0~Dpm$Rhq$vQ7IPx@8ePnsndzZ=$vYcC5{&t}bLzbQG@_HiIyz^~3u!-$6XB zjl=j_O&UuyonN;T8rLsonHwqQVRy%N=W%S>Oic0ZJ8x~f?Z2;Fer~4M6k{OM658_= zAiT!pxB7$R6X3>2WoH4+uK-Ls)>sb!z+_JYZ2_3PZ5yTy&~pChuO>>mn3Mjrf5{^e z7_a!9Hd{2N9^T(vbZUu+{=z~0-x>C!9{vPkcROu7%D%k< z++Jav9(3ta_)InP&`M1)saU}pbfRb$rqgK)kFe|Ksh}o7YXQYQyn2G zB?e{sDO3}CU_^DQ7V+m%W?e0?jK{!L+o7Bu~qR>seIsY&ab361Q(UgeMqA{V*uO zi0%|tBf)d+QhKhJ%0OG)kGf^XiqzxY$7jBNu8K@XxTRl*9uhb-8jo%r zz5&z={2N~&%F9#^Uv^JOIkQywj#2f?nlLk_fr+%6fA|FLT}&t=rZJ?4QGnxs7v6)J z4$#b8zQyOumbkkar6N7=p}ku{-t&c?;4hAPYI65@`l41eCqADfbcOlgOcv%D`Ss~T zjT*_Y3OFoI@OyaeLWDeq{8wXtYy^1-8fWTEU6Y-Kb)imabv;eI52r^6)6;+4Q+KH} z{Jc3OP$I_yw?g0Q&t_1nS)!hLFFpN@|Z9$4GnMfV!L^!w_6}y4VZqosU zKX2hL^lG!n2REL-q!@p5mBD|fktDnI^#=|(&Vk~-;z%tyG!_} z3(;$x{wyu#rigUKCG%12CSQrY6NKzrL{PiiKq-rs2xJ-|re|$JzePJ@Ry&pK*+P_r zP=HJ2#B3$m*reaRfpd8ssECmv)zGbwi=x?NFB|??^H$M9gPl%KeT6(Fj3bi>BiUHM z5#FFUTCeBCV|hQLvRXQrh?Q|l$;pEk3FhXWhO34URk2b~gq#E~4&-#k2(jzjr+=`= zSAnVX7&{$0I^oe7lU7AYdFSTATSbJv^CHB+ONzOV66kr%ZkFr@)WiOy(+9ZUJV&$u zxCK38zubPl5bY6SEnfAF^x8G?K&D=b4v9$aE}g_w)TWtz9P)3<$PE5fMutFhB@n~+ zYnRY-ypR!%i9#;^f8~8=R1{6O?kEaK4ibi(k(_f$^6ka)O`NuMf6SQ%&eN^#HdxvujC|y@ukQ5q4Uk6`=2_ku zfoqr&3buyH>t)f~afKt*?-<&Q`~t+KI=pXo2E@gmZuWN|E}jlX#;wS=dae-#3+~G4 zQ|~^d#pI+*-AG~gh@7Znk&TR;3@-Oj32L1#94L%23W>squCzAy-PNJRQiYreM#3wRQkD76qyZQeZVQp2jZQAcAnKqL|6+ z&fuHsmtY%}77&uJ|t7V+thsxTO)@7@kL=wCfA zOE*XtmsQB=DhNXf^asdhJl}eyRePZ)3>aMYud^JsjA!=*%1hEstq5(vob!^jxu)Ps zE^z$vmC~u$91T`oYP^vvtM=k)jDj%~gY@=F;1A$T=%!6-l)JX6r=4B?Vr3q}{-t)h z+qg~pW>URO&Szl6qMj)IE=$J_J7Io3Y093lmu3Hzp{$cA5*K1}vE-#_+>U>Z$xtF~&=ly-LuK536{h&^4({)Y3`Vh3OTG5@&%i z3$R|Ts>JrV{8}bbx&X^bTqpKUHeGLEZ9-{|L7Y*WLTeQ{If;sJqug}6RyMR~na!xw zr7%*YzVIlf6gJ9-yh5B*&E|F2cYi=Vqp`$U+I4oo*=)ygoS&H@rqnfnn-X^ zZtz$xaDgA*yV-|;#5p&*cNBqBOqki`R5)4P85t+asy|)D6*H_|JD5k*=;x{BiO+dP zhg6Jq7m0N!0?SSa8>i3l+)>w6UM=l`K2C7%^_2Tqe#2CJ`SED~P{#%J=@qp4Z&22* z4=e%vurihHVEaa51HDZPNbN?^h^!{OdoDDv2tw^jg>z=Xhf>(!x?t_2tq3Z@iwO6lBOYQ zv?Djev0i3apxh&(j25ZU~J59#n`65V_v-qV;LbR9Qq8;$F8K)3Y zB{pR>KSEa(9NmGdAS05T>CZqkx|7!qKsVXq**Jx@erPBya3Q6_0uTSPPTl16VK@*= zo{gs1ojHNInJv5fP4gZ;w+Or{_Wp|k^VS{V>E%_52QdC9L*E(m0;P1ZIQ~j!RfG44 zD@LllSb{N|{E~P+ID{V(sC6!qJ1(kv1f!JUViF+1J`|s%nW{0 zj5yJ^74H9>?@>}|d$?k2f08mQiO$PDa>WzTuC26yc&t^s;KR+EyYTeB50=uWRw+qz zDY9CPy4%;>$uz!#9_W3Xvx&zuU;XU*twfy3XKCK`Xo)-H4T%e!#YgjJNlW~kr8t2} z`|$A`Vz+I8o$6MnThxGj4XHZiA z;~5kPa^c~A!=0B#+eu?+#yeM!ry6Fty!#CGKIDDS*92y6+%ZA;B1^t>Ok8gf>d)9> zGSnOJmF;Q@L`RiMgL@^7aTLPWa2B-JJwBGfA_{jXJuM&Yb|`6q=k1)vUVz5*NlNqz z6pOMN@rgCZj6>ua*Y%{Jgvmtv5uZ&goHcBo)8Dl9a_p+sEdy{Z*(;ZTWsi>teU7$;Ad`Ez?4cb+6yXCS)N4r>u>nL?m^L2e}q}3a3Z!Ko7+Nu^> ztf))eg)lBGU2*~O2(u_fyKdtlj-i>`6A8}=7jtCod%P0ilB9#ju^vVu@*KW;I(q&m zK08d1M05!kV9o7p>Fa8?5txP~I>drqcQ9uhB~2o&D_o-*q!wKR5v_;m)5j-Myk4q& zt*Di3!we_5!0AK+?Otnv<_{M-YR_C5V$$$|M2s8}z?`tP!+TxO`9_FE(1U55Yf;iv zDIR(Z+Te8Q?1gxCK8oO-N-e^|{o0$b*n^;c-9u;7kTN+$TcJ*la!T^k>4GdC1OiIz z8+v{8kroAJ?Yg6MVNyh%gf^F%F=5fLj;wDy4Yor(o***WHAjGXi+iz#FgXJZb_Iik z_NT1+swM*p7TPn2+$H8XyEwE{e84Tq4$SO~K*T? ziD$ofCouVJtZ1T|g3~}Kaj}Lk)@T@#plY87vG!|PtV_P5WI*|_RUmTf!R3?d6z!|( zsi#>9bu`iMeecsRt@Z4@Otc=5g$RfG<=Wjj%a4v2R{NG8&B=4@m%bgk&zK(;RPs54 zmel<7y}V}c++P>r8SB=Oa~8)1Ww<10lJ1PmA*-u8D&QIyX0JR`1tL@m*=#an&g=~~ zsJltGn`P~2mV!`6wk>RC2a;Sa+1vbS1(b$W$^IUcC&3y{qKBc{8K2h7nnM=8f(8g) z-e8cw2}7vBu|`cU6guz_bs8NbvA)ble5MTx8?ue2MD``SdEJlSR>w%@Uf9^@n6?_I zcKMNq?)fua#;x3E_QAPQXsb_6Z z9^CaA6FW>Zj9yB7bA>x5%*IqEa~mHD6Rqo3t%)@*bZOF)v=GlwDjX$J(8$*)BqQAm zT(3J~vS?T(bvpm>alYp2$o!Xe!rCZcaDUyzRbzeVlldLluOONmcl#*{R#J|N-p!Be zs?wq#Iq~fRa5+-j0>m-%if&cqvd&;n%YK`^H8$BQkekZ7=VBg{m%@r9|Hy%{TdJyfh=+ny)M44x51&Lf%daTC|w4dR;*m^!TKir1^t-Q`k!$)=y%A zA`EJ-N_v~F!{gEna{6QdWJ%CwzZ`qjt0D}KRt7CF_&v$?SI`_@>N(2e0ut^>xr$>2 ztfrw-O}s>%>MV*w*~r$?^%x6d-P{D%_7_|X=;hxrq9xf-TNArn*>UDWJ0jF)p0rgj z;7Jc}hlroiG500{bj$_wG-l$U9hYXSO}Tx)%> zM0y@Dg?6QS8Q~*FhE9NSj>G~>i0)H2$NjC_%G^5PwX82dw_{C4(*8n)rhPq;J)CFe z5wGLGcV~f_i$fSGk6aG(--%_sJRks%e15?7{*9&2HI#aBXcbHNMrl9uxd}5HY8tP` z!X8~ImQnkCG56d!E6NY3b2!W}6&!x=T|{Qo z#c{x_lj5dUib zGk-Hfqj82>j+XgAnzKN!_l9`l$WVAMQ@p5C9t2LzL>R7XmtYyuqJuc5mR~8S+=j=s z=I28#<*Rgu01S9Wl;M@CYL7R`oeJsY_ZxsSxcl>DF!-ng&Bb~i=N-Ow@OkcdkvGnK~S1qPPk1C-en0g1KZ2KP0B z{H^(2??5UeP{D8auq?2dYt(}$Lf&Z`D1rSH918@%df-Ju= z5P~k~w!EHyAFTW22R2h}khLpn1O)ORIQNa32PR1vMHtyZmDf#aH7WFpSutKc3%cAP zTAB-w!0jZkmh<5;(YjEC6xGkBRTHUai(p$;GrBIh)5mE zrXyy@5iU#1O)Izjun|3Pu~{XITWgGFUJcxPy=>?0Rbu?H?tMME*~@kJioL%Wab)Fq zEr$giT;!9f-&PuhDjD-+zOJUxxRrYljSRao-LvTT3t!IPx%{4xrODXZeur6_?%BiG z#3kOCI+Xv+Nc2H!;aZ26Le5OJx6~*3I=#r7f06Z3GHOgei}IE*W2Bh$sh?(wQc$@L z0?{#pxJJZH(WT&<))jbpVyzjC1e4%b9ZU(!<*{$9`ZAViujq~Qq*UE@JQiG#PJr%) zzbdRej$j+NXLeSNAtWQ6aXhDY&Z5Y6t69Yh9z@S_P2=`>_yU+q#i>2!-D?#)W%Y{t z+-?G_E3mbK0*?IZZ`D079hAs%OCu(d|wWf-R#hBO)$yfDd85g<2?sH@UUcVZW!i;~1* z;6;Ca&PhF#J5Sr^Cbap*7UjCz46aK==jWwaM7{l?=WX_@0F`W@^vdcc$ahL;7VoIb z9diYNWhxj-9oQQeZkwo<%9C(JSig}be_4IhT^>+UC|Rv5BYt5q2r$9;@~HR& zLz+Kr{}^<~0)uYc|7h6~FzEK*Z}9sz=spi{1t^=Y+t;ZE%;QQIL@!l8VY~8D!+D5N z^3%(qVz&Sar^??$Q1eoNuFU2UGScsw%Mkd!Ut{G#d5mUJF*94xaL6p z$EU5=6U$ctV5C@l0ngqyd#7knK|DG`0;|3e+T>gRP11q<;KG()=2!{@O|$Az$({@a z!cYtY6%H3Yi7@R-tEyX>VS5pso7neB`JYHAk(j8)t(o%Dv|puZmwmb*-1uZDUSje~ z6|tL?`so1ilDS90H@4cz44sBe+F+mLqf>U;??9pI?j@!7`7Vj09!fjFM%}^phLrUR zt8#gjTW(gyaWTgLc^vt5GqmA%JF`sVduO_RDC5Hc47r4fQNq4VXXdyt%4AR8BtwZh>IPED1_haa@eFd^lV6IY+{SYSbfEi zGSA|)#S(%gWaD}}0g|m8W?hNPVmN!*7^y(AhVo743%li-+u=+vAA3n~h=nNJIbeMY z281Xqjbq;R26Qy49aDY<+0aN{=bo#hGpgQA)iUm~98Ks-3SS7iob!%B)=oQWn!eP5 zl&h=V+Hd4YCAyCc#h;Yhb&WDo(!iBmfJ{kGJ%Xk%|DrJFR6Zh|qpx4*Lm5c9xVNnO&q(5ML2D zZ>Xc~z_UuJ0ryGFbVJKthfbJ)jH7sD;8)N|+XeZrAm(H5j&R81*vsiA4!#l^+38@_ zB5t}0A$G1inEQlMeWV``#I2of!r+ShT-u&+i}#quCb8KG;Wbf4|MIWqg}_blwsOzY)I2aA>nI zjuJ6$i&Ot6 z_YH{e!3)+92J};P@&`($xRL6_HS7?Xz1{$FMt~;+nQ`~DVe?g&$ z+f}S?jRG@dp;M67qbqD%!{0U&xa6SLiyMtu!;?|dNXMh!pyhiNy`GzwJSEzF;MA(Z z_-+QkJ$wnS1(vfyn*sLs_C`aM3-$4rhuR_riw*jPL(5{s3EtFW->4u_WALCa_n^5S z6da|dp)K?h=uagz&P6F?agm+A8veAM^Byd~neo}FY$C8E*}r!2^^LX`~{a6z%Afuk|F;XmGdR7>FC5_Ns3B>VOq)`gp>Mv z9Y78Qt+n%a?{Fd&@D7^|V3~WQtaZ^5b&Z+>e)~~u`de(pcJ%%rU8)y<5(0!!Wa}}1 zGq+apV{Yx2mZ8tYsqSrKJ*}QRgR}8^{S8hPg!c%jgs=F4ev7ge2;#)TcNb(bJnD~a#5C_}bmhWcuZHXHsT+f^oWMkLXf8uOy z<`+f9h+k3dm#Q9hUvoX~V=OquQ2=w_ip394&Q0vY7eb_VJX82Het9_kw!7j8x>N1? z#Og9znW$=Q?XBnYVTSNaY))5%;M3Wvx`Im1Dz$|gBLngKdWqCrtfwHud0=rO(?FC{T7bX1GpA*kviogPcfHK^(H@4 zqA6@FMeSwiHm^PR<-B>wQV!=PQ(<5IBfqG6p&Et|gMt}bUG@mgtf9EMe%Cs_#G;+v zi^ch=Z$v0>=wG_#I1y6`=|cIR^`ZX{Z${9?Iz8J6UI4PNo=3!HXtiODJ=uwA>Bvq( zv35fUOG6BM;%PIY;;>WCe>U;bC5c+E&d@Ynn3zi1lg+m`M*j}xD7cVShZK{F)c%Rm z_!D8#(-vn(bJ9Kb?Kd3AZ}5&mzsPp`??2Xq`#$TFSB}FN;%c$Nbmh=)sPO&}BG6Ab zCaD3GkcdyAz7kqM$X?v{lOXaJ)^H-!AOnTbpSV9lR*Tjk&rV-oA@BHB_T*D`e|ZZ3 zrFcfp{S(0jAnA@q{bwZI7rQn8McTI=XQ24!h1-7&b%~^yPZ3&ZUal&CLu?75fqjdO zGSA7x4rve4w&c_9Egp8x)AH>-7*6~)oXrWcH0}geLdD+vy$%qX-oJZ;as7XNgJJFW zKG1SvQ{&U|(x!H;@<2YnM5G-+_-?ey4vUE?Dgq+Mnxp7!%+>UAXq}rWO*VKuo-jeN z>u486aj2-L>%3U*5^8d|x|yFck5T9RZFJ{m$QdCQ%PmNuTD9^-B|T4FZ5JIOooJ{` z=`6jc%LPR-T%sq}QFeX5c>&-Q@W>hEDtJucDWWHme0w>_#sl)kLDl%fFw1pnqswy? z435DlAgCVDdka@Ubr5AP>6gGPJUUI7Cz8IcL)8Z3^B5$ut`ue#a{bDI0Z?_ABN9WdXF1oS6Djp48Qk2ek4rYeLl0# zkT78{Fjq7`)itTVFhtH<$^s>&&B!=jO6K7ZqPKXjXSli*naGf`=p!TqRhMOHd1~pS zl!>aRcotscioBHpIx!NLj*$&h55pU`4=t<_p}BXU%ujHv8ecr?>>xzLFaLxoe)2^> z3ui=KJ3uzSdwjK7STriww#O@yJ>q$8XANFF)G1jh!(;~M!BAjzVRX7>>7PHnRT{$Jz*{Pn|5BB##eIL!De@ZVM?9r0 zj06EtKh14pI@q%06(;Lv0)dr`GyLj*1XjdzPXjBNAg-RLzrS+@oVJpR%m^|Ffjs^n zG_bPzav^N?kktc*A^=fKXzS6N4S5~KbWDe-ix=?;X;R?1K;AxpcLGPFiIOuc|AVLU zP2c~ur+=29^jn*yLj8dcqoaW-n@%IZugJ$ZWO~YRvGLas1@Dw^(cFv?007}4JfXPt z6{LOx;FjN|RroA+Z~LgT&sWq-{<$CEW(ogR1+Y`-)`9i>-v%Ke?D*HR{gN@ik5G0{ z_vcao=pE2St-e1A0irh55}9G1-^ugP@O}XKInZ>PZ}@`HSg!tPDmhQ%kA|0nxeS>M z@l93SuYjK;O}+7H;LD9&;-hgiD=~#^#@lLB(UQFne0jpY-0DLfW*;>#u~uG#Q7#R* zCQ=8}ST#420XHG9au5^F@!=_B>ojbB7e2i zXHOK|W@$JsMIjD@Rbdf^)yrUUnYZA2BS?F6A}Q=&<*{qW$rT1#8%loIN`c`7$f z!cQ{Ye^hleZG15?iDzG4=vI9o^hSK_UZTx{%_3U5V^eR{j=;`i^UW>v>38nB_hjP> zD$449NTyo1Ixx+M$%vyQbGa>ih?Y{aMum`y@a(U>VKw#<{PF5fRc{;o9wMJnp>Aj{ z+HE+Lc~*Yn9_SkA!T6yHy?tU5xADbN@o^A`hK1=*%l>f^7()6ZVn%)x>pv`e_(RpT z3a>*nm)l~+O<6s|Z{L{wunZ4S#e1p>Hw^iV((mCbfZO)_MX16#y$D@-wsUe6X@=_1 z2_H^Tb!WS9JAn=_8k3uW;9D8P0+ou@Yw!^U+X{4-R_UaXRtfg}C zH#>Zo?gxoGbFZv%P`zK32|et<_n8@bK=MAE)C80$UQm?W*7JtlqJX#W##+=ml zqn>l=IwKvdK(f#I*rTYsH{H)EohUT%8eSDB_DyO#?`P= z8am|gMTfKI5Bn~%ZqppKSb_SB)+~r85#O7O`R9INoFV7T1f!%>&Hdub&YEMK>Ao0; z2G|m=;Z}3j{Ka?OmHsx+eZG(_y}GmJRA;(LHF4J9`Fv9Ur>0AuHlGP667=(BCYYSA zU#!2q&cOhMk<;fCiE#*XpA7U1)8J^a`-r#y6M2^i&#U72wAsSBKIlG9_m+;&c;|Yj^d$@lgU{Z}E%a`nC3fFH%R{#3X96Cl zm)?Kw{w}%>q|EP?a*at-uf3Z+_RKpXU4Yn`e(Y!rKAjN();hI+djh4N^Uc7C`S}kNt&uN$s+v8| zCL26_0b%aMl$O+9q^+J=T?n7tS0P6Yj4~+(w+6d6A8bKT$NU({kJq!0Xn}4-x}N7D z(2Mv5fVT*uxFsm8+8!>M9IrHC?9%LV-}AVE_Az9G;O1j)37ls@KbK)j_5$eV>h=fk z;xDm2z4i#_*#`gI)$cWf_?O?ve~?Lnx1eM4&p+)ALHk~l>a3x;-vx5I-pE#NCj9R; z-TwzvQ1#KCo`uDZBO2FZc0x1R3mO5U%cT4iqoXKJ2MaVhZ}_>D=;$AV zfwONJ77*ye-*^4^

    intel-retail/automated-self-checkout @@ -204,35 +204,16 @@ - - -
  19. - - - - Getting Started - - -
  20. - - - - +
  21. + - - - -
  22. - - - Developer Tools + Getting Started - -
  23. - + + @@ -241,12 +222,12 @@
  24. - + - FAQs + Advanced Settings
  25. @@ -257,17 +238,16 @@ +
  26. + + + - -
  27. - - - Release Notes + Performance - -
  28. - + + @@ -313,7 +293,7 @@
    - +
    intel-retail/automated-self-checkout @@ -385,9 +365,9 @@
  29. - + - Install Platform + Next Steps @@ -425,109 +405,12 @@ - - - - - - - -
  30. - - - - - - - - - - -
  31. - - - - - - - - - - - - - - - - -
  32. - - - - - - - - - - -
  33. - - - - - - - - - -
  34. - - - - - FAQs - - - - -
  35. - - - - - - - - - - - - - - - - -
  36. - - - - - - - - - - -
  37. - - @@ -1398,12 +482,9 @@

    Overview

    As Computer Vision becomes more and more mainstream, especially for industrial & retail use cases, development and deployment of these solutions becomes more challenging. Vision workloads are large and complex and need to go through many stages. For instance, in the pipeline below, the video data is ingested, pre-processed before each inferencing step, inferenced using two models - YOLOv5 and EfficientNet, and post processed to generate metadata and show the bounding boxes for each frame. This pipeline is just an example of the supported models and pipelines found within this reference.

    Vision Data Flow

    Automated self-checkout solutions are complex, and retailers, independent software vendors (ISVs), and system integrators (SIs) require a good understanding of hardware and software, the costs involved in setting up and scaling the system, and the configuration that best suits their needs. Vision workloads are significantly larger and require systems to be architected, built, and deployed with several considerations. Hence, a set of ingredients needed to create an automated self-checkout solution is necessary. More details are available on the Intel Developer Focused Webpage and on this LinkedIn Blog

    -

    The Intel® Automated Self-Checkout Reference Package provides critical components required to build and deploy a self-checkout use case using Intel® hardware, software, and other open-source software. This reference implementation provides a pre-configured automated self-checkout pipeline that is optimized for Intel® hardware. The solution includes profiles and optimization using Open Vino Model Server (OVMS) as shown in the figure below. -Automated Self Checkout Diagram

    -

    The reference solution also includes a set of benchmarking tools, shown in the image below, to evaluate the workload on different hardware platforms. This reference solution will help evaluate your required hardware to minimize the cost per workload.

    -

    Automated Self Checkout Diagram

    -

    Install Platform

    -

    Make sure that your platform is included in the supported platform list. To set up the platform, refer to Hardware Setup.

    +

    The Intel® Automated Self-Checkout Reference Package provides critical components required to build and deploy a self-checkout use case using Intel® hardware, software, and other open-source software. This reference implementation provides a pre-configured automated self-checkout pipeline that is optimized for Intel® hardware.

    +

    Next Steps

    +

    To begin using the automated self-checkout solution you can follow the Getting Started Guide.

    Releases

    For the project release notes, refer to the GitHub* Repository.

    License

    @@ -1444,13 +525,13 @@

    License

    - +

    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%0Dr~50 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 diff --git a/docs/images/logo-white-75px.png b/docs/images/logo-white-75px.png deleted file mode 100644 index b28b4b872d41b417db05c3d90e252538934ac22f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2332 zcmd5;X*Ao37T5M!YDu*kdkLC~4#KqdSVquTBGws7W9eAhPA#KULZXY%Hf>2tYS$14 zRdlmUbhPL}i?k!9qN6JHSH$vHq!Od=!~60+%!l{oopbN+o_l`3d+(=v?!E5geL_iI zQ(j6+O35AL;>+DU18|0we%1HPoiCv7abtXl~ zx9|91^O@YWJs97f)b)O`jQ@e3_PUI3zn15>CN*~;U^mQOio55Z;Gg(^xA@;h=w1y& z6l~%b8BvneCY|Ghm!C--Ow#Zib51J0J3)q4Gwt;+dCECCt2i&Ow zy3{25C8j$g4RdvXC&nZNW>s4t9wK_up=ZyH2_`xbS+cAX-@}RjnCMjnbS(>PnAg9c z<|gkyD8AwjC}CcQo-i7yGNIEkY5EPU1*kA zlF+f#fF@Yg#x8H0IA?q0NuskoYLC(rVzR*_@$mY|Zo7V5I-;aJ7o2&4!07{FZC0qe z3xQJ)Jm};+G`u9_@Kog?t`^%>v!h7I)@9b8X=#*4jvbU)_~C(HMCHlZ8z7n0r6=5O zv8smap@;M|ee}33W<1L#jT|{U0}={Idf${>JJYLGmI&Yi4E!4iP||$EP$WnYjcT?zclm!!7-dDl)}7@dakSL5M9ss#+71g|wi90o`bTxw^K5f#(%}zVOAR=WjJ>*}xyjdMCQ8%^`xIfMl1=cA_DXT(78a_0ux8as)T#cl_R*-dz!C1s6~f*I z380Z_j6WcKCmDbU^?|*OqwedW1O_amAfYvk5nyYQUt z8uM~--{a8pG)_W*Y@S3Td*uS|GN^mM|JouZ%(_e-A)bcJ*ce3s7ayW-VUiS`MBU~V z_rPPv5NwBwk|)lrE_Fbmj}3ywBiyM8n|gD_o%A59@m-n3k5yfb%s!Maj*G+OfQ1bF z>KO_qLz>IO0;l3SO`Z%+%R=j6o+={AGauFv2c&9q?cOmb_5}+PAKyqhfu@Y*=mIo6Uzj^Nb~~ztT~K-x#OOK` z?~1qjY#5|YG=5?CXcTTrlZER7In{ctzm>F)KbkkyLe=~Cw5TM`yz4}P&H8IJ&LZZ+ zKw>BH!RgIYZd8scWHl)JuG&j8&v>1*|^)Q!HU_Tc^e)uh(b_~Jo1pOW@B zxI?w3G#r%s3kNJ}#d(ZW!-&`~&im~@d*7z+s-#WuTG$fm&c@O(*) zd9|ILA%bMEN*Ps{+2>5m;C>+`lIx=Yi(>(nk=vOp-VmD})an zi#jnBIAwY1{=#g@FmOv%tN=BcbL>}qG$*D;7p~JLuYz`aGvF{1IwDFwYWs~}YB~3! zMOUY2?blTs_M&ZzYvtl{JX*BDJ?HJ|B(hfd;7lnqO^m%#X+;c=pcBMp3HgN5I$qWh zBx@bU7W8Ja8e`ld>9_lC1-L_kO;um}Z)4@&?)$vqQh=O4GZ{t&B|C~Ntvk8+H|U;> z-Biyl*2j4GtS3=yJ!&pUZUU|`3coZ=Kt{{;*PLlN!^@jG#L| zG6pz;JVTeE?ZSjR4_o@0AMuwXt{x@xL?){PJXqr%e4KZ3(I-#G;q=rhY5TzC(kth= zTtb+Zk7zGrCin~)GA&5U-Q0~rbXHWjhxdGatN|<+Bnwlr0KP+xUOTyB${s#$x5%Jc zF8tWyLVSZYwBo1#?3gt>wuL-9%3ws5ilQf4OEt#d*!zV+`Sx$MmCb|(UY{*T)Ay?u z68w_xs%&DacusR+Qct&Q;3`@cxvsTBy8#PW%7q#5;LOq@!c*gXuBp9Xnr- Ol)J09OM`RxmA?Uli(w-G diff --git a/docs/images/portainer_dashobaord_docker_compose.png b/docs/images/portainer_dashobaord_docker_compose.png deleted file mode 100644 index dfb0ccf11abf93b64aa3d115583a154608af20a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159820 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
    x7^yxA$M>hj}jcv6053R|5q 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

    ws5WC%NhA3JgNox;`mbkwjwsjn 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%0D$Ip+BGspHC}fbdhIwqQJ?0&M)*Y_{E^J`#o>gD z+$e!_(&Iqk_NRmj&Ne&vs1X_(7#E9Pj6tW$+o$T%lO|buCkJHsg&u4A_m{VPmzYfMsx3`R9=_EjAzkq_%!IW<|1TZ&LE_y_+~(% z2R*ILX7MKg@I}B(FEYNCcTV^j#Rbg%jMW3Y6Ku?2!Z*_oR1!r$&el0l0mouxdzlaA zbfN2&V%QOs;XSTxGkTse>?UcT^2-U|x)ixorJ^#mw@smtmgn(aG&)YRAl{{AJ z+eQ$5;9P}*af={P0I(Y~;e`-kWLK>CbP{}_&SCEJoM~#|bowhT5(ZBypQYJ_40p0~Lc}-;ZnhtgVTD_if|+3?;dEjoD-p|-2-x*P^*HYZQBSF*Jp;J>yvK9` z`G>jnSdQ+jfW}~-o3brXtwwh7`)3d}3`8k2PJ|RIaU8>T0OrXA+Xi<@S}s*WfJ*T` zkKitYbgK`aW7#re*+k+bAI}>&#hPTw~7J*C27BIQ3nl8!gFm&wMhblsS@ zA`!ptIRKX_h25-yV_<-jm_2ijx~~b9J5^LH+&8Re!3gKQyF0=;wpQKfWgF zIOu(kjoOJgaS}*3Jw}jd%R}7YztC<@kCDH7NfM8E8Bb&V-?@1Uy z`oU)01=`%Lv~QJ~&D@hH56ynN4Xu=S=ox?ptHm$*&##}wt!zQ=zlP{cK8g1L1J%gtDiKWi1 z=^VeB2z}V{qPPkvAQzgE%j{^4POwMAMty8PdpcgwCxR@^%9`yxr(cxFo2UsUy0j%Y z4JWt)FF}uC6($*#%&l*bQdN1=#?zN;#%QPIdsB(9r8U^nOKat90bw`6Iuk#K%(S^0 zL)cLOZSBkAz?&H#Hn**C0`gh309t^7dndTD&wHyhjDvMTUf@W?VXQOdYa4VbWRB!* zai&vvGZ}s)PioM>9G2UzMtc@0Tf^PK92yS%!jHzS# zL`wcc8>T=qG4)_J`AD7maWvNKRy* z=(u7+6OvdQQ+o2@H{a1@(8lP)0+a*{bldgckltifR8H>wM_U#dMnZS8yDQNYW$oN6 zW3N_dhM7wCVpA z-hD&MszGsA==RdrPDpd%0#4FhMX@NxTo|!H-LL3YLQyMn|0&W0<+{IlSPAk0jxy3N z4&G%?vju%hA;yDie2myNOUyr#rbWoh&{r6e2g2Vuhz$sMpL7#GnygN!_x#ID@mS&0 zs3@oC2UJpnrx}*h+U(Ol>3T?|_m*g2-97X8+u z=f+Cm%?F1JTNmX!`1?#=8L{53T3~|3biASNUSiMl!CU@6T-}6NM$>TqP9gArtzY$` z{8QUJr4=qoQg0H#Q*WCy{Kaf2+(>-(=v#Z=o#jIJ(h?cn)LY%vR}M2s1KkU_Tkrxo z()pytu~$O0y61`=%X%xR*30cw{=PyoE}3Y3CBuVBR^Wq|yVBv%yWPD@byo9R@C|Hw zqKv#<1%*JOqf_hc4|+N!ha}+g}^TZ0rIpyjPCAJ53B_)T}f>;r!D)bW;AOo zA^H%V#*6*~j zvk6~@sQi~1!nf1nS}no)I?z66eEj6L>pPt~UMnfFBoTiy;nQV7j({O`Mvz>fM3^M! zMqxrq&2dc;iD~SE@$t9)iy(XkV^A)FMPfirj>ctLSd_wk3@wV%d}7oI#6{PCoN-zYOL z^-m&ROx!<1^h!DuHe51$?@^4(tp;&|E7r;TV!6_877TV!vcDLB=E3yhm&^s zq}~liRNQnU=s7+pVps_0G0nX8Ua|VUuz-9_c*Nz_6lClD=&wJiJX)*&d?M}<6$>fi zX-=c_eJlQIx57ioRq^)DfbO8}uiF`gG%RoT)4<=I+(`AdIgV2&{TqS3Fp@Et5(&K| z9HYs_dR7^~={AmW60NXBv-b(#WEzKJ(C32_{^?9UJ(;`bGt8oK%|NpU0&lHV2eJeY!y~r|&4UyHyNrs- zTQ7TqD{DJ_HfX7TV=J|v1nn=k`2LW3(~pi>3#u{vpjjwMKWb$?Lzs^<&60sOo|Rv# zLL>>P9TPi~)n8@rSuU-8ug_0r zyl7$a?T-{MG0ec;bk3EtqVHI(mM*|szK7lK>nns-Fx@~y#o@6}7f<~4d5+7UXCF5n z-~M{?bv!RlL+S?i3vY)HKN$^6mAQCrL4Csc8s#BVTjA8n!evqG&0eS|h~YF!iqRpW z;<}KvN47Wzhk&JMQcb6&h`v%NlV&Zi^+Pk2m>@T?B=)n12HX}KE|N}>lbJ-ups5`D zs?yL*hX)eVgg7>_UV$8wAdf07dAIj7x0Bdy4BZ5uTQL?;WNEH=8`XR(bbqFl$0lxP ze#1!eX@K>+^uP9NW<-@fMPylokAb;qF|lJNOH5fwq#}XC=M{$4|6B;*9PG3p$>;U# zYsekuJDT2?uUWOPj(5AM*}ZL1p^5vaNN>ydA$eb?DrOg95pxtS($e+vGO9^$sLh@} zZ$M}qDQ?TKzi6s-a>kb8Y>|@HK)ZHRSpPJAPqa&!rlH)lqcuVN$yU_w77ZVnGwVk~ z_olPOdEFv!YAMX;9$J)0+*uS!Pr1UC@qC?~fxz>9mR?xeRP3cWOxCN}&4j(qzhhhZ z4`!To5WG2rJP9+aUX51%s&T5|>7_aHx5hBZ`~}1EAnyr9b0=%dFPXUtsGm(r`}ZP$ z2VHJt@t;V*wSK?ipK{A6Tid;1zKccLp^gjBu9L;VmrE!}2 zCbT4Hl|z38M@d!%2>)?)iJ!_b#6M zi4XRKwdwqMZ~EE6DrFBLy4Cc|^s#O0E2h6Kq1&(J&ud0@*&9x8!mxwNpVDMc`y2z^ znR=Hf5xSlqqH?Cf*B>U~3`HWjdjdu3AJBS7K)VK2PlHVO=jAfq*34aMpeg3I15Oq^di)eC}-`}Rb)akP( z+gMLk<>&-Mkv^@k^tS?64hCdP;I1L>XeGC&WorxOn^?x{3cBC5C|(Bo2w!(=2T zSiqP|y`#{fdU+<%OP}|jR0JisEVD9MI~MMt`Vu5~ znkR8a$4L6T!X2c<@EkKZ0~e$ji_bO(eLuPONG1~Oi>p4mEkoR^+N-| zPd0b=uJ=Mfpkb1B_HBXF8cluB!_aQ>GVLXw{`re0!ujLs%eyZ4Dn#y0j@9Blg9G6; zJ3MK5)iqgp8WXQUZ>w6v+(I-E_r74&e)-&1D)4?W%ljq81grdxT!y!?6CK$ZpQ|xf zXzKn{uf=wEx;`;K(DW6v(KM%%XofdlOHl4Ka`G+suYy5uC79Wjg0b+T|HcJwoY&)f zVxtg@i@sDd*DpQYb#*S@Xr*egU8dXMrqw$WMNO#+Rh^<}_7}!><0X`hlC7MP9Ny;1 zkN&C7TJg{vVtqZ#hkl(VHi2{8sad;Ca?Nv!am@@%o0pqgQU-P7I5gn8ne~vny2Glb zWHB?p*lE*^m3b6~V-4y!RBq|>bIY;%>@!!VeqPel(&!@E+n75e;p`*Y+^z8J)%hTn zIPRSYPO6~(>7(uFE|%ud)R$#mulbnSJYkKAkIFpV(01K=I^>;487ya$R}CQ zqb)T2=RJmBVVqxG_Ej}~#>RXI?n{WHfMZh%mwf1EWE zB6zzxB|*X&^wM0kmv=DYtm=XB%Ni-`BqNB;?F&S+g;j4CH`LXeqR&D)r*D?~=-bU( zsUNH_n;*1>9cU1K*x8AXXM}T3YO^v}#f6yb4j3c&v~tz1UfWZAuL94eaq|$2vsr#V zNuR4_C}@9Nqq^xk9z^|)@3Npc^DrsPsjXrV+dV=fj zhKNi4|EN0asHXn^k6%{QfYA-3yO9!fqolh9q`ONn2W&JrkQC67QX(KFB93k(6+v)x z2#SOsRCGVSfBw$dxqolx+^{V2($@WCi|N`r;L$c{Wm!j^NSN=bp;>zUDr)A6bd$%} zT2NJy;Xi0^Y5w`d^ravhyIFH&mS-N8-vh8;fHKmsesJ6@s_weBR^`%(z*?*gWr%!!@bFjqz$x`>nCfMd`Ni@>L2}}o2~O;U9s|XlIelV@PA?B2j-1G2)%m<~ z;0=u)==Yq! zW8io*_AgY4&hk$fol%~>Xx{X0=`)v$zECKF_6jxm@XNm$9MkbLy$gO&J9m)5+5{_s zA_)S1pj!@r)ogD(`efYWJz#$@ZE~?xE&SQIkYsf%4R6<-?g zgEcVKguVxU?wDg__;|NA3$c#-%_&e8mMAFcLB)K?LJ5aSqVOqwjZ(f`U z+0Vvm`BNpLsiO^YE?=-~64oXF6NBMkW|V#@5h=Yra;D|Dm^oi1FXL{TQ0*~pe98ffy z4lJ9oxY2Z~b>#L3J; zfEZwt7??8fFW#%6xtO(4*uZP;#<_O(f@3Gq)7}kdSCd*gZ2+6(czwY4!G>j9%~pDB zUD}Szl8^b;-s(@=B1jzHLw_H}JbPq0`)=@n!snaC)644vF6p0!8p>P^$FlX*JpbA1 zDk*wuH{h>Kh>~Ae{6k~W#H!F$9GUR6WROb*M!=qyXg)~Mf5AYa;Ik_n7~Sj})m*@G zF1Y3y+Y)nf_f`!H2UZHxc-9TPvV3i##J-TjN~(hS>7Oo$w`$+*d46|D>}jVMV_fF5 z+`&mqb&LAoYU(J!>CD)e|;hvcoF>n&zw z?#TKa*D@^j6ETWdkuprRG1-BZLp1E%dStd?PNKI;Nt#1~aZ`eHci7ntIXr*sg*Ek! zPm4)4BuGt&J(}|MO&Yq0^?9aQ^#CLw;H2ww3Q|PX=ITr28P)12>u7sR)Yhu8Mm~ZfeGD|KELuRx9U2>=`DllU}&ssNsY%x z&n5S)`SQ3`zZHYUG0bNO-K2QzGf5J4ex_w1!tMb*i}w0}ww;hl0;s1Q{DKZ-{nqp~(`6>o{1&w7FXbjxc4@?#v z=-B^4lf6fdvTk7PKWXxD@Y{U4%G#YJ#RS z#QVJ@QkqwrXHJOAnEA+L*;F5veGs3s;e-_s*(`!4hhZM_Pd^9W|5Sk1PR{17U$|p8E8yVd|&!`+p7ZVTV&(STz7OIUDqBN*cJ=e@TSQu?5eF z4$No=Pf8BV^BwBx%IKk9%orWc3l1!-27Qb;T+El5p^=$Wkx|88x=&wRhRHtX=q#;% zQ7x>xm<)EEKUCIWRBf1MY5&??m;G++>qObGCnH$x?}zU4ZIJf{OBY8FBJs+E6mY@c zeNA?Is$`oF-y=D#JR-IG;MSRaNi{A#*+8M%$t$olcYF*9F<_+vQa1O@EMQjZh zDp_CXn>@J^PPrGrSNb~05qQp@FErT|vLA1Jb3C8>CMhuS!04K;>Kj#?JN1_A&UcnO ze$;$!2;We_zxJD9D&>D>W)p}08uh}PovO6!c150$7`Za}k!DFYPrsWb9l&q=i8>_3z)uxdssU-JNOO#>C4JC^P#tdH+hpkJA1;fTk zQb4!ILGy@c{Xug>=j=h`N%i*Uig*r?d`uR*P|X2pl&pXw40+gD=7FMFYR%9CHCFDwRV z12)~W)OSv;Ti+TiFPmTgb5uMvXQ9J8Ij>_QkO)^Qk?(^GMIAOl*--HCK^7^uW(e{* zubVW`#5*n(I!t$aH0oW8;`nq{dD?1)0eSpCaSWyGIVtg@^T}iZNBJ&J#4Kui!}<)Iw46pv70|rYeI_g~v>x zgSCfmY{NUWIzESfG;Mh$A@ndps^RGEe<#=*a&OmE0zs+k85QG+^l0X{QEw03zL{Vcw zCA{Z-)g!mB=`f}ti$r0LGD?&(nt^Q61ZH6Q@j$o}p#D9qODjIW2=Pi0da_28R7r~M zFJ6WmCMj;!2E|Qz@Qq(H(C?4e#umv#1SXD>gf84%K1bSb$?niU=-l8~4jWeK>u9ZB z2@9xH;$_OfLy)j=N>Ltyj?bQ& z{Ce5YOslJy^Xeo8B*IjJ!-zg!j2dlDvqyMPSB5;x%~x}rNz2RB&Uo%@t1%ik7TNwd zkFW@t8WBkrH$hW=y@TfKvLt6bP!qbRFfYRQ-y;3p>FLOdes|?M3!M8pK&|BG@)dvH zMXxzmWE$n6mnF<-o9`FWQ`viF2a>RB@N9zw1L&(phK>=iwKWHo%aP;(6r+ zVfYtGvA@3CIUdY% zX-Rc=^q>6qmKvpfjPaY3~=VDqs5*^6$r0e80GbAD29Bo%o9Kh#wrN-32dR>_D zL;hJCcXn}eLNX$kyp;LknF-(V6K|ugebbWr)~v3yzEUNO9=;EP(F`TX)*#Gx+}z?2 z>Tc@%^_;9Ss>pa+D~klCAmSTts_)*a7>eU-K^`4{q=5*5EN7}pE*l6C$tK9vLXn3DN&mtmF}Kzj4RS*e$I|#xdA9B{=x5^j4X4t~9f!i@k`xP1obnm@5C%0M7+_=UWoF^;AGfE zAU*=}oQKLJC1f!?2Xyt5V2cbJy8F}UGM{kg!D8p0B3?RUdB@9?=*d z_0mQ)ebzK-B=bKR_l$ZTKkV7+$*CXNtj)>gc{scHhV=Faj77c~UBT|@CzRq}?8%M$ zJk$fAke6hnKUg$Q!1I1fHS2MjXVemF=pWJL%8NqlYkT%2{+W3fjeo9`Niz zRKjJ|7T+d+dr?%Skc)pzgXmnbS%;%9Z3pDxt1)=>&6|UcX|MnNT#%n!rVR9{H_ko6 zY8O_eR2_Zo&0^qNHegY&W?a$S-rz~kgwfX{GV25m0>tnX{Z`1})VO=oY}}`9)GZ)E zc#{=`JTuJ024ah7>ffroP$RaMsLhav+SU`(DMRfjE+qaMi>~S) zC~=I^icL@x#g7k32@IV2FFC5qVHjvLn3LRUQ#rqUeT3Bw)pnG>QzS8vMHrSPhc(}d=??-*2Jo;|;66>3o@*Se3 z1d|sFI9v|sV|*UbeQ_?EtiJMR>R!r#;8AJP%^Ks$lcziR-i_ir>bDMKqeA4vve|ja zMOyCE5oZhGZ$))fCn$C_?j-VQrDbcbuVp%Rg4xE+?(hC=eiRa=!x%?|nIo>h(7C(i zebZo59(Zr^zj&HzJvCJXbCI+DYp|Pi2H-YZ)5iArB3;F=ohg{vc63pc3Cny#{6Gr!m zg7*vI5rDt+2BRjjoi>l?OvC-bmi{n-$k&A-?EuhjK}%;CTOq3XW>;mt!_dh_@$RBt z+~fO7RYr{}W(T^7m{+QC-cooX<-I%~xhCg8H~K|9!zzhx8F@!h@XjOhF5Ta0x_v-n zQ_Z1Z1Ky3K^q+>B0lM~TY2LT*dPl0j)g&6#@M-x7e3C?R1cE9zZ*G8|Mm>_2Q#vAr zw$p-^2A%Jtejglu$>AvaUCF*pWmfw$vYAch)z5_RJa=J3>oR#7@z?qh(@|ze5HH|y z<}TeM@jGhjbV^0owcW=>RJrd-aGX4~i(77zuI^PrF2ee5wO<;oIKrZq8B&JY!bnuV z4z^1bcZj>S<&!S=QRvnls?&|uT_U*+LEGU-i%>@}e8N|;1&Bu{gVyrdsS5`D%y{># z6wb5jb$tr(Ibsl~%5;u-6KsE)?k|B(EI%yib>UTsEUlu{GqU2f_wv+_F_cE~9{bd~ zjXJij8&4S%DJWP_$F;7IGUmsMc|e%>^CA>wC7yCEubEol-4QKJAis?oi10&rNg#Zv z0WU-8&QBr2Tj>E?hIdk85o|eqXPU$-DdMA)MYql8f8}grN;hh6q^CyzoL1KQgf(Wq z_P&YcJ%%zKfbARNtVj@DWlJRs%X3c(hdkSVk%(XF2s?ErpvezvnJ&j30)C>>L!t%b ztL!uoHv6>H0mb05V)`Y5&nG;?p6SyV`1_7@o1f`g>;(fOdhZj=R))RD9jpyHsHZuN z&*vcv>h!DN+zq8`Pv#gFN#)o5GnbFxDH_xXKy(lp53|_?dt-8cc;X~2u8(Bvk?) z_B2IS0|}L}fXN^|#`JUrn;QA18^3lnHomH*b9Y*3MSUR)kYKogK|7A?F!u=VS}nvEL9g z0(~4lRnJr1z*^n7B1k6JIAx5sNuFw@=|v)W8XAg+KCJ;HO`~#ebBvra?MVx}x~T8(%4e@f7Sw2wQ4E z*9T$ur?%jysL4>945+=UzKVYNP0yb<#A4|nF)gQKc;>8r@xg)!IaD`W^nIKivR)C&1fx&cthLnSxclzBM`s7X_4%X;^?hT zvWhV7h`iYmUfj`pCu5Z|j{RqEF<$Mi8_b%d|G6Kwk5Zm;QqG<0jJare$W^q2p_9*` zF2rZ4zj^K01W_-6hR%ca$v5Abg*ED6TYoQ87)vqTh+#Js6=$+!`rdTgw3`WfG1_@V z>-~mEb9a#b4^10ptgd9NpC~ytw;qUauQlBAGrnT`rZ&oB(%3ETzqqfakJ2_|Fkp!Zc7#lK669U$XP_inP#4zWp3M{*i*L7wZW z=EMtW^R=t(C>r-^Di4%Qu((X1IInTMpp(7miv?&S2w5(K9@T@_dU)BN%Yme13EHw7CeN=8u7>SU`HEm6=^;OszjG+)?MaFEvlN)u_se;E2eODd8ZEXsn~ z5^@{;g3&_)ek+}}2MI4Z{Pcvb9ifpQWIgYto?l(E)N?nvcXxhS*eZ&9x!$UG{H~%b z^m*og_hnO^*Zj=|7A=dCu$X@t|CW7rg?EnGZNfLkOMhDUS zLNf-RwP+u;Y=_?DfTq!ok?=m$)d&qM*QKi9iu%NkK|9e7X6Nzfz>c`$X1TMD2mNS_ zkh#d_^gTL<3&qc}H)n?E=>3A_rZeak<*8B-RMAAJhXuq)e*OGZNyKIL)xbwNB3Nd6 z_TgUx!6yD8fF4}N@VkiyI0BDPBg(>{7Zy}xLVo}Axo<9v?I?JS1=U&@oK79y7Y47G zhF4AdV*&b6Jp45V{^~N>MWP%DgU28#hf(=Yx2Z>nR7E73WQ%sn<|dIX0>Y`J&scGU z{AV!rK}SdQv~0=(7f)g>(1Jz1wRZc6S5ltef14FJF$T*mNK`&uUtc_WxP1h%bA#wN zfs=9@E9y5Sa8&*jsw5&^6hQw0Njr;bngyusF*H#an(M%)77N;s^3WL6P7DcJ zgQWFes(PI|hW$sv6=YvLNMH?YZZl~fO>dT{D8WyyC2-IjM^TBM!U|j=_{f%`!cOrC zdEAWsk29g3Q-Ozq)Z?$9di~(`4pcGT0GKkb5s6 zIwyNWbh)ey`{md6cZiPzWMTp zN54SLG&R!)PvsF=VTj_U6Nw+R17Yy%M22wW_lqMisR_O{O<9bjuL0<9Ho;>6`iUdj zPkhu-P4M9+cod5Mg&U>A5%>s0Q-h>Ta-(eyYo|{o3AK?J$VN-#k_4BifY8vjK8K_2 z&9xrA2HIe$bfSGhBgE(^=XN*zr#9IrvM)AYIX#_ju;~H7xINAxY>1y{n}u?h@F2gR(l@EW+6Ti_}!N2lbJy|t!ljfjb*x8f zE&kjiLuT7yBlCKXgXbgFsY0)uhlB*Na4w;PmxD~)%}qU`ucU`8oy+20jVgQUvG&+l z;vVZ$eG;PKPg9#M@o;$a!f?6eli2=!LUjcBS!9FCaLJV+YR?RXoI>{`Mtz4!QwE*{ zdJSfSBMesgO2l1_q@52Tyg;=?Z83h{GC3o=hbl3oms0F=RTa>*#bsl2KKvxKGoI%- zl<(QSh*7cI7ux7@q%?0w)4CT7_ARBl4`<2P z+0EE}xv6RC)06SGXq#JoJY(^x%-jH8YjvbAnY|=TyVUR1+n)iola^xp4U?aeL!)Qa zH!>7jQQ9z0GdD7}d0f<;k}(EDKFq9ifz$LnUb}Q^mb{)dOl=Kh)`pNV=HbwOCG8 zpH=9IipoxR$LHUGd?9IeGg{1Mtq{^&*JR%xST9S(G7%U5fmMqZP=k}w zUN^MN6=r~n)NmaWVL(b5oimjoa+PG{079|}l;z2U$7KwV(h4L4KDpdElXCxNlG0#+ zlXS{Xvz2FNoh}@Zcz%>9*iE`D>t$1U`%$Yd?Pc*Qd_%QYd@4Mr8RBc=tD#DmiuG^< z`>bFfvrfYrv)N_X3wFbU8Tu{_oyXmXR9QFoG`xWz!VTYd6MA*=nQ%mQrnAubFgVG={sJw`J{L_~RO#7K|4ARsuy{ z91Tgf{K?Q)j(iNn>L6S2(Ea?6-G_!ex@*~}G``02GP+SEHvy*WS;AaSDf$LU$Q%}c z@J?`zB2F%qqu@ghcc=6V)6g*vSbv6nGDU{G)LdHWXibeiZb&gBdwzKzV`3(rU~n>> zsd@QD>{!34v>7=!=zCIaLISz^HSC&IJ`Q>2eS=M1?R==NBD}0NBoD}E1e<_Imcs^B zT*=LJwi&t%mn$s5q1jVXPB}b1k|fLY#^J04tNX&wNB-0&E4xxh7{c@1z!?v^(!vY~ zk`lyq%4YER8n(JlSc3IU>-qME)&}0{$p>ApxHwZLn<0AyJseeyfx4Z3cHM9u-?u7y1# z6Pg0WRS%2#$MUtQKj8J-?0cIAcNp{O8e2GkEpEdhq*(&o9VVl8{icLP|Vc zfCKmoQ=>=71BHxD>52?r=YX_jwZ#NxO7&@qNBDa>JOF9PFu*d$g#*V6G%XL>_VD)W zw?_9kG{|8Ow(Jk?FrBa(ssc3Ac(>F_09nhZXbb`l2vh>2*p4e)=}t#=T-gL|wTK$G zFTZkn_v}AKbs@Z zui|MM0k>6VW_z|P4lD`CJ4_U~0eD?OVM}=+YK`8F%8(%qkF&EPa{#w3P4oxfLL+qb zlkHS{TtCx=ac3*XRnj93@5_-lX(r*FOJ9f8=xa=F9k}c*X`4 z>`F!j_lDoYunz^G?G{@QjoMl5v%4QynqJ*M;EpGQQ4{s-Q7HA?CPa4U6_6JysTb;O zQ3+duI;*L8T`kEb;_OjfhzOWpY*O%15}pM0MW$*yi2N^A3}7x(47QSW*=`!o6E$j$ zdm{TKZUtPUKFQ;0m51LfzdH_+*zI8_sq(vBZKu7?-$}vW6fZijx@AGXO~t$&2KpV( z-ro04dR`ma`Rc_oSq_$z1-cZa{OUg#D zc!CrG2b|3a)^-GY4g&OJVcLt8J8_AI_(UxLgThLLZLs=x3WV&YyK28En4ul$?7Dqd zl~0k$zY>b_yEzePuKw3Ep zK){?4u*cIx{E>N^x?BmyAJV^#lsr~>=aIVJ7sM-dRYO#m}I3_MZ}=XS<38K$5;- zs?9Xy^Qn%-2o_a2Y&?x6n~)$q1QAm&+!}4NryJv@=ag$i2a!0=d(cnIEWms(QDOvi zS;N9b9LW$id2}yp-~#i5=lwts1qXic5zG6$%}eI|J^ctK_)W?s)W^3QFBS_DvAEPV znX8O|uK?3xfTUviX5?wRW0w57g62Ac=z1(&gkJ%M3^7d+iXW2o}- zF>FI2cBd%8r!4-_yd_5%y&#LZ0Pie=yt&K0EX8K?w5IoB(I5$uxx|Y^O$5YRZ^3%Y z91uwqYXZq!ndDWoP}F*)GNFG7JM|D2T&jcz!(YoJPToqHT%4!(UTcrr#CnO~LMy7? z;s<00q82V--pc{%GJ6?i*u5}hSD9j}1S zR8Y?`lu}a_w?z{_qAeikMf-bt3y;>{i&=oB!fa=CQyjMz(6y!jkaU>{Ry@On>Nb32 zu_Gt*K8l-%m|dQ*Sm2_9?1nm%m{*hnR??Q20j!Ezl=wlC? zh_q!tzAUY^i06xqSIBO?{68#X1$o&O-Jqs+F^s(y2Y<7a6{eqQ{ z{B(HSV&mBonws*=gV*gZt|s@jp>~>?8w3?MtV5c%F~G^|jk7YU0#wPpsF~}7x&d#; zV{bxB(1NB-SO&#JajFDE5$(v*`B#Zqd@1%4B#;^ktlSA6dkaQ)I#+uy)kH7V941xc zme9MfI;cavh=UZ;LI}UG@OSAXtosA+oXe4IY^+6#%(6QHrK*=^ygQk#h9$2~U~P~% zdq0grP{wm+gMlOKw=2ur$~L#caqsj*?ZoSP&l39%N1otpP9p6q(NBcd5;QtLqYzjW z3VU+p%ZV*SciJ9({<#`=>v{04+C!KM0;|X&@h=J_wRo!(t6zp)0odHiclD{8A<8%l z1Fqo+IL$E80=2iIf8gS6$<`@?(>EG^i!!?&EzhcTZO3+Ghc&}iE$N*L&XnV`wtS-0 zi0fgV4L=FQA-YsC=&UP$>%!Nnl z-WExxg)WW+B2DgeB!tG50`N4_kc9!)H^){7OrKdYZnO#jDIdsnuX-7_m(Ad!Vbh#r zh1ZM$`vX1aOEz~G4VFbETIqqUSs}WZrIRgpqZBOfl>3=2_Pw{$G%wZz^Q9)!2{o0d zF@5Wz6$DtUB<9(Q{oFL?O9ed;hhz!66U4LShc77%X|vR#KOUY&xM-f#3=t^b%$(05 zt)2YLrc2Y6m<&_rYeP-r^&f@qG9dq)dfHr9gC3u;|r~Cwf>u z6)&U3HQo=~Q}>r{WO+q=aJFgN#6;Vgno(hq@v_jZSfBOE+;wmgB~`h@ncDLGA(uKh zjeIc9kvN^X1$h<+<^1i?rPnm)u}Ttf+&z%c;f0cWUu=jMCJ;AOxl{P^(y)Au+io0Q z!BcBGQ|`Lo)=&<&4D)Y2{|lLdx;$*#j2gOpoK|9{q+|1UO6W-~bT_T0c9!$TKC|xE zM5R86!s%P#oW3pkl;*ia;K0kESc|EoEaRN5+Sug}r4+iC50MEqh)e!DKgY|QEUY<*)Q88KXF~@`S+Eyx)5@Kv;3(k)wBNCZ7Y9w z7@xxUY-T~fg?03UQj(}+Pjm*au#GSmm%bL)!;J*#=`~#h&MgJ&rWT0)w)^o~;Y>Bw zpYPDW-F?z!uPf`;!0ZJJ464{KPeFXZ!M$-eBKs#!_`S8 z3>?ij8B_ht?B93Z8y0t9NuNv!VVf?z|(E!>xC)|koKhD+NzU0pIdKy zoU9Mc0l$TY6)(s8zI^Oa3-GWFv$;O{fCoQ)bE(wxYX-XgG`_?INMr2KRS~W&AJ`6c zZz)t;D5IM<68P~6{2W(18nHnrthxMm4-2gF4S!`6#Nql6NAn-7s<&>~`4{wjMT;+J zi7oOS1(!5X1oE7Ed>I1xk6@BVR4Z9(tk%6vcFc}PBS`__g~u#s-YP@Axux*;% z*1O9a{8ZnY=iH6tVYaHFHQxUnXF~k*ebhovI+DJk!km7V26OU5w7#53Lt~1o`LS1i z#`_XOF2X5INuCubTa_DSiy4}wH_3xQhrvr$`;>?X&ursU5^FH$BpY1kZqia6)_-+_ zj^R6M*9T#LX7|Nj50!YE0b5YuBZmoPl?&(A|5EezZbmv$%Avj(EG>M4s@ zYX0eCI0Cc19vbsL(O?9ujKGeTejdyGkNL(e=68|zcH(MTu^I-x{~&-A@Y9s9;I_}b z%G(!tcS{An?w$2Py+?dc!VZS<=VJEo^x-N?LYMRFZ|^$Oc_5#4bfCT@=&P4LXf+Ah z>G+82x96^f1|}^%vch&hynM@nDGl=<8lerx7M;73~ryGH#s zr#2c^WxpXw&UCD}6(3pBC@oAPN5q(b$`!n?&0>;W9{;2^NOUoYwm`*ipTKCNfiFiT zz+Qw*K8Y^Xj8=FRIuGw_2lWnnfz7^T$wRiN;oY(5;(tBAFV6o<{%-#9LcIR;Y(jDB z$iu`v+e-!EnW4pIAebwBoSIN5(K3XKt0~jx3)&Qbu?D5|4yKed3XkxLYY0;bCe(c3 z(r=0Of&zA@_?vWB3s1R2-zoejgh$h;3uo(z?tGSey2Gns1~R3tIs=|cNfSs)Eohf|iEP=jl)JIDnpFH;7{j$+ zQ^BWs#j*$mLJ1{XyuI>qLZr>c+B}Y3A%~g$WBtqR*H-pThjjJ%g(GR2x1TuF9ng0POW+MvQiX72h*1!KUrAwk%@rKwiuhad zuyELj{IfCY8?$nL&vF(p)WwKs0=Ha6f|zTF&xHLA+y6{i3L1#4(ml5ylzRH|gJ{Rg zZpx4o^eXJovzqZ~t<>KcV~3J98rP$8CYG@Y0`UxjXQ8;a4mS1E*bxYm2)S=KGDE-W z+c@e?PX~-R@6hMfL{gyq|Bka8{yZz5r)vTWHF8qr1zkLErp-s0c#Kd( zCA7=*H~dAkI!RWP9Y}_-8jvIM?o;Rem<~I_I%kcVp1bUZ>J?NLrI}wmGtnNxtE~UP zgM{b|U`gT;5lGROFJMxm1g4@I=>iCkna@9B#Yhu0=JKHDlAl^R;YVqWQQqvH660h? zzKocr1WNg^wo1u@OYHnd_#J>Xd+y$0EnulfksM0k(bth(5JDl}?Z#OZ2_%y9XqNS3yBu z6B>JlR~!_(oA%_U0k59`KKTlOfvbIuXX;KKVWXNdGctJ2Jhm`}bYk-5e)2haF|6_K zdPBI`Bwf~%ZRO`}IT$vMUfY*l7SJ3F?E?U%)GlfFGX6*Y>r;9;-v!=Vu4HTG{8+4r zPYWe*fTou!3Ut{SV^Tj_Xyls2+9@ZowGqHP2XWOcm5$n4W}&PPx?M%&!GQKsl&`s8 zuUa~BE`r9)a%&&mQ=&1(2?8wBnF0*L9&;~f+ujn}+X;1GpHA>uAhh!a9tdLMX`6)E zJO922?}1r5Rz=@d__c3*O3V>AS)+1PONg{@!Aet60M{H6qVJOurQO&8JjWnRr;F`X zt4woRm5+Kxi+VA4nmxGvDyc-7C?)qRbQVN3j$Cyiz`6KjhWr6{?f69P;$Fj+N{&T?ro*tIBhl8vwvkeY9RE?aJQDBi8(J^%QGlE$6(ax25+c8N1I0Z`z#Tb?V~ka4pqHRSOhQ5%XRFn5d}Q!$;W zB~_m(4e>BP>c{g{yo6g}GIb3nF;)7|$7Y->#HVFbjNRj*K@h_4$ z)yHK>=*uD#5M!8gbQx1#&2Nzil~;}g(P2Rf+Qsb#57w!usdfkp0ic-f{_O0DQx0l8 zDd2$uMidH{QOu@Pt5Xqc%xzN^)Fq&DU&Pecu=EEn4}W(r0<*=0U;CNXo_pKz52?V$wSU#;8>zdm;dm$DGn4fy3c$q9j26r5e_0De)~D z^`7|@eEGB0-tNtC13>_cKs55A05}rFM(FOPB-XW=W>4b2Wm{ZHExje}C@{UmZIQrh z(Z_v{#A1SGBl3QB=kb~0rF6!enxY^m0Md$t>jUiyn01M#Ao11l1>}T;D}^+X;!=bN z5ui}!n}lK*`2?7zZq;>@N$B3Pw_2y{&9 zJC4OGt*y40kUabmG({6ow!ZJI2|QzK!Uw&=&S*B_Tc3*n{*V%wGZE5_{Q36M^@h20 zc>XfWZ@ijD$P6Wy4gTIYsli$_?+V4T?9VHvAe?YS0#KNDy!U39$6>b@#HQ zm{b3LG8F7g)8Yo##|Uth3)+=$1PiH#RQz!)|HHW^;^Dz`$0K{UNIjoBhfw^tiZ!QU zz>WiCCXMNqA+O9)BaKIR*kdr%NCJODf_;;=8iraEqaz*0%k^RS+ura;>d&rCpj$^q zlIKuyzXSn9pQ2ej9iH$Ky+IjERBj>Bx^4)_0w5NEqVm$TE2Q3DY24$b!88gQsGKqs zkR7E-l`t_r@8u?9D|-iomaw4i&qgW0!eP8fMnYUv#$mWi6N@w7>!l?U)S*>CH@{CD zt1aqW$>-e5at_?kt{95p!Mh`FQEooV znk4**G&bNo`KArRLgX;_WF_hgXmV;iQBbs};I?|**2VFvM z{K~`gVd}p(q%Era*cikyeIjm^JSa3`7j+yh%&);8WQTf?;}v`?7V=LlCx^Td4@!-f z-Ls=BwUUQNlcsDCI(-0eSDwq*hQ0EwE)56(E0;$32t@Zll74<6&wN_F%%?e1yvx&8 zs=;Y$GS{QGvR`xE+0?UrazioU010eP%TNxY$l~`IY^*z zxh-yz_fK1lR&jOVyIeCh!Jx9f(RJhqJ7h=y0OQ} z;dDQ4WJ$?u&h5aE?E<5eBvLLJ0Hu;}x@_7OMhR%tXY1FuI@J%-`-ZDb^rKSc789f# z_#$3FB9|a_vZZW|U!u&!>gm1PqA@fqy{zZ)0?0%sY~q~^vAC^O?c=X;7s)gVMG9(; z!n!cFD2hk3n6iK3j$KH@YX|);TNFGJgMxd5lF8Hn%Gvgi?KRExD9wwg1No-Dh|C}} zO~KzXrCoLVzl!)uFU>+`@jQq=1vd&-=j}W5wT%(@JD+gA`EcF#J{3ZOQl*KA39LDS zg09=;5uYTbawDyVOodSc!c1l%;KkOR^}Yd`Z{pxw3>gX_*+0Q>lCz(Gm#$iv5m#%0 zg&$~Xx8B&nzRPt$T=niq;Z83udFcQrU)~qLOD7_ZWk>Qqir9Q4*?{jt4yXiX>&tA} zecR$2?xet|5&BPhvXcLngl8?TUG$lzJQ%ZQZhrcuzmQSiyO&lywl1qD&i zZxQ^CzWunWY;7v?TwA6aB!)=f{6C7W#GmQ^kAJpdhhcMHF*kGMzN>A{goZg2Bli_i z32Ad*F=x)2BR9D!B+Z$ta+a%_sHBuirM_yv{r-i|=ly;^p0DTYd1xx#xX01=+n)@7^v-iX6_Hx8pEB*rFO8XR&vPJt-P&x^eDb08 zb^!&kO%Zb&{!c2|HAAUt=VQQU^>cSgOu{rdtk6u7Lu8q;C)`oP&Oz&uY44jD0Ft z%r8@lt1Eg5+bmFrV9Jt|P0I+CReWk%0uKUcvYLWsVP}LXfAHFrkT$5KRiW2~7r69$ zmSd#FBy12^rj?_qBx%fgiaZ4?eERGm>-p)of_`}zK-(^pK zl@sYH2x+_CmcrG_5o5f6ex+_126>+tCYPc%a3%V5m@YO@rokQeXOJSsw$T;dI5~Y` z_j8!~{l+VYP!#v3HVKTukIo{#$$sz&Rczke>5)CvuKla$w8X~SdlZMjuhD)j2;0Xt zm{j!~f+C8L%WGwL>W6s6O>8s;+QVQgScNHLN7l|0(ugGO>CRRb>4zqGZ)nk{#~M%0 zK6CUIXyo1I(;o}^7p}d!c*^Cd8<$?xDA;z<%m@HXKHY7?#q=BH=sg}*b{lpzYM59x z2j@tYmtXL`wkbX>sT2Uf8X4%iZpwg#Yi*2f(}szX`>F35KDf~tGG4+Oew-q$wrm&BbKW~$D!uMG46 z5Fk>$nb?-99@my0^;(qHamXGz&Bqq;UYF~QlxmmM1$$O>`0+4Q|2=$Yjp2UEwhA;H z!Z4XJXdy=btZ7sYyDdq+!3#@QNv_Rvdh>g7<<%7cxy51##|~qIa@0=sYVWp^{zST; zNR~N_O2u#qC0JgmxIBDZOYrEoxcm3xr+bN8V1ta`&3pG^a?k)>Syk|-&?hnA@E5U8 z`oHjf1MveMO9m$mfDQma7*zrA%i8JqOUNVH2_5Zj z{j5j#%6@V10Tj8gKV|>vX>mrn&$+)C`0AOS{w7zA8aTD zx&6zQuPJ=Qcsp3EA(&#QeZTd7Bv&K_z6A)VvB22H{6P=>&w73~sR5^W&h2S=%9|7B zCZ6$q(pi@=LGE{N=EjDs1@xTyZ)}j#%V(kMZPNS+tTABYbO6?BO-YnU62sv&@2BuE zIpU!}#C%_0cg=+tzYQ++aQXqcAV6TBs=y&k!U|`njbR6dv2Md(j8=U7xP&u?_~f(Zh?W})YZ?BS1Sd5CKem<<_fcY9CaL=M1j z=kpJ>Z+#W3_|HcB{_!0nXaeQI_aWJoVPlE1C$&nS>t{KAW4X(!f+MMXYL0V{fUbDI zP3+%c7vs6RdQxBeNGWk1 zs%TY;Vq~J2DS*t7|B0aFzo}v(S3rUCQ{o_Srs?D4F$<`o1=0fPYoCW zl0!U(Red@yV@eJu%^ogz%i>@tWgHa@M{7jx0px5kLWSE{fnmO{MYhPfhx5Jpo0cx^ zj85^pAwpPEs-j)jcP<`r=@T&nw3Co=Zc#nE(t|y!+38!yR5>ov=r}51m9OaBUlimimiXp{{p`A}*A@VztEp;9s%xgOczw_s?(KbAH$IyfZS5v?rIw zEdsdQ*f;-*A8Dq^0V%jtFjJER=Ad%{fO`l4a^S=~33DgoInioC2S8G$*og|ZI*PC&4=@D zQ9%d*7S13iA%&-?x#^xhZL&+6Gu9(WlY%EBD?yM>p#m45Q5pfUvUy!4DWfU1G^hh_ zDUoAluk<#O6{Z2&u9KkmOE+Yno{-6mX@NAVb#hWJ*Vwd7C{^cZ4|;!^4!to5Y#;5o zCtqQ!Ej@JDHC;y+2Pm9kF`5wGNZMX?hFWEY+;iieT{FHD;9&Ct`*pKim4w;qRFRy* zxpcGeUX=!msP)Wb`XyT?1sumQKhJS{hUC;p%Q!{-3Sxc;zqjI<*|xswA?E+g86#sprb0=sHk1zA!^31ysXnO|zaM^ec#jmtf+jRr z>b=t*=(IaojgAa@N|z>$(kvDS(DU8ulAyrPWuNy|7x{VJw|*sj<#bi;Bykp~p8*)j zd|7{SN*#h=3I=u@g5 znl{gHf^dv&c-Ko|p^Te}cE4Uu@4gIirij3cZ0!@|5KIr+eXo&RYZI8*d6oy>TYwyE z()X64O%5FReslf5wm&zqIr0TGP&2xwygKcBAWk~6(Z*0Fb*RB+69xEPu{zg7`XNfW zcw86<@DeGkwWr3jR2(hpJr;TR3exS=^e-}IP*RlduQ(JPb*{aV1{!B3Pvo~JqN zcm^I-GHd#Nh!Sp)Nrkufg4JII89lp#_|*u(YuS%Uu}g4Bra_!dGh`^BN#K7DEfych z^Vu&%z(6=8(6J-^Cj$`=6SW3$p;Xr$$Y69|m6pc5`XHS(FT1Cc;|;47zCFv7Xys39 zO7OvoG8oPt%Yip;}fl3J)NGG-nK8ZNES1{j-0c<4NFx#{H`ROb3HTt8(y$B zmIK4#6Ye|!NBUxpsehh!5SkDZy*6qcj0FRWIW_|G@5kju@z*UGS;#a@GBySQgbdtL z6HFH#`+d56S5Qo&aWrE9I9C8DbIK`xP22PFzeN;-xFGpwn*}+rH}e^6Ku$%{0Kj(H zOeWHmJ2PpT(ADY`Zqo^Wqwp1WO0sChH!_8c(19u39pdq&%$!ryDVx$As^#K(vePS& z^cTQseWSzp2o{AvBfjC@2g~Z`7`P)^5@30fj{`Z?PN#`{q)I^{x4EL`ZtRL4v0C*c zTcldsF{+{%mD^ZZd&^lx^-v!;(G*5c2`*md5(Fs8PnQbiMDfrN3M5_FSE!lz2#{G{n#M-JJ-@F4^ zk{J|Z0&Eztqrb5{-lQx9YyGBu}zVPy+FO%a^6-YwD15WU(5faq9Qwa-|7!fD%UD)2{&hZxzT~_U~ zq7eMQW_!!HJ%=i{eF}7FW?2M^-|n#owf}nB!PRv51REWuP9kC;CP@nk)&~tvw-LpE zPrf}OX|k8T=A`XU%1yFKLdaEW!NbjO=MYz{LMBCvBLLhG;$GH~XHd##LAJGDzA7TZj9VjP%P{JU3F$k!w2r#%ce~Rl0fWf0b^fk zRDU52J3*-=;Xx$7y>|wx&P^wa5lTxifOuGQlJwQh_=#lDeGEhl&@6jP>CE=1>_t6` zO*814=XOISgc!VQB z3HxZcwstSv`5@}C*IDAjOOr)HkFn{a!~0iNc< zv@RC^MCan<`-Y^^Il1#d(9l?jw-b*W#$M9wgTIBc#?UJRH9T?rkMh-v>h8wtjHzFo zivBmqX~&WA%eRES2jyS5A0Qp}Ql@tI-fh{l;W{&%)?-G%YR==3fz~j}4xyPH!cBi?fdX;{ouMXzUd-B%<@AkfC@rGa7lJ(ZVjo zW>1eL)a-T9V!;Gq@A)Rw6-9V#M;7pWjM$^&2gksdF-J>p7r2pVJbTDgWbyY@X zxi>q43;ox$w~Y*MAcW-VeE1Kh4?jT929arUEr*mi64EEbjID?1Hsk_gJBuR(YbCB| znn-B0aW#1OKwn!(lL~N=NzmU7I>ZA}QLmkoK{Y~`yzR)HkE-|6h6VDhKS^9FE5tu} zp;?ehnD}xEiY=_1{v@rx<@)M^0O_By_AR5G>Z07Mb;;OckEVDFo;7f=A7$XGuH8l& z05?>@YWs+cf>;=uTCUHBdYKj`ey(PiUwlK%bK~bd(66V>*l{18@#=;yUoI|aBr5;| zPnub%;odOcMP}sO!BrDJYuI~LFL{pW8~O-{4)MJL5Md0s5bQrVFpA?H*bo|x z6TrPtVK1g6`!qFpv1Am-0ipZN}1@uy5=4G0iySAAm}$ze5239B3@FP4%&yHs;2 zX#Cf4`f}EG2@KEIPDTVVEX7q}!lz%fQ{d+T#7PaIbL6k)HgBc!V1EGayPAQ1pCdj! z`-e#5-5fr`00HY8s(y@wQVOz?!RA%q0Npo^E_R&`z3I@Hg~hUjQP|J#K`lw!z;%(l z2vL4@$(x{8MSkq}4SiEaAc7CON)`EuZ(T(L1Qbw%=k6h|>YvBHOUH^jBpyVGZfN|m z4Hs~fk6%=lzxc^3^2*QFvXM zn66^Oe?I4ex|_o5dRb|JDLIS0KGg(Yr0}fb5WRG6dJT-8#GI$;W;5U^_Sgv=?@g-E zpp16*g%86+;3#~}Hjj`?wNUPm#=W51HF&y96nDB0>W+c;Z!@#sy(h(-v=u@CPbu&-KuiMIHny$u+CCBy=fwfs>&5~sFA2-)bzG&(au#&2b=h(9@p4jgo~V7|-p}H%=hFa9 z*Tm{V+brcZpP~w^VON4>^Du}S=5(x`=J(KP7l#+GzQ~y&xQ;W8)Q+l16~?PAsvbw- zKum*{VbRzPLAoq=D?vB^p*OjH{OXPgBxdSM?heSN#U{1uZ?s-w%+XISd%AeHZz;fgJ{5xoh0r zeMTcn!@o%{F-AsWULcRb6&pM_JAPQQ-=)U=s8aJ$2~%@dV8xID%BhhbBGz-+w-!EbT8*bmLUw^~n?hsVZ zpW0})Ytk12avhW^qM!rMVK|<}Je}ZdkQY;yrAZMiiCX^J}CCoeVSf?c^Juen#90JKy)>{OO%z z=gDzW7Jd@ZDrtI1I|J2wAgKWv+_mpfTGa;hn*BP0m=-cG3kSCr0Ln2;H*T~DQ5QrJ zs~OIlH<(Q;5zW|msWEF0qN6ISuYzzN`@s?sHt2rP!7_$#l)^KC!wQpd*4@z6pj=i6 z`z2)JsprGmqOZ7Cn>_5cirx#q+M{o|QG%4|3{sB|W3#4=x%o{@!%|j|p!QRNWQBNdjAcS^9hXOuR*6@S za(uX-kt7q460gZOQcw_bSBjO`;|Tx(Cdn5N{S4@ZK3mq+WZYB?tyn7;ws-5f+r{|o z(#f{dtVLRf>@g1ylOm%$Tg#gV)w${EA|zXhPeW2j-H$R_FGdU? zh+{>YclobWU11<{0CE`_*-?nPDK58DX66TvIQo?T;J0&LDiQcY&r~T=Jyog^8XlSC zP(E2*Vc51HVtdZLp;lIu4=-U3!hQy@)@$vz8PI+*d!Y&M!rXZxSod`mDz$&zEj#+{ zV*N>K2Mflw@^wCL6ieI?=^X;U)fD3O;kU2;C@+rnG!T^u#~N>xnfUP8u3_6T*q@h~ zdwNdOMEFfi(+Ih#jNbJ2_m!jOP!WBoL8mk8L=mRgPLQ(ir?I&_5YgPp~o6IZcB9c&kX>%v?s1Ge?=KdB+)Y1=v@&(L@$P77G) z=dKK{ZHma691WoU6vc}uSAQI}X=N^5T>DX8U6ae_(_J!vwDk&^;G=%z-p0qsKEd3{~rk1c}CHUHy zT5@dFUB*>6d>$I+xHRdOa+{g`9S46-LGJJHYT|GD9B`>$DOndjz5luS4tehMK>ET< zu0*osw*Si)mVKL+YCDRK%Km)I!cg~Qm}}zsj%uFmZ4AFm9+6_nt>a09$9Ga?MQbwVvZh$iBV60YjjHaVt>vL%Nyb_Unkk zW$$;#92LiurR08qWGM_P2e-Ish9*EsMM@Yaz_e;cGX+&W1~SlZ2BVQrK+9GRmIx8< z(-Qy@jLQ;K0xES`D~@TCY0fl^dq&_~OO9#$pF_BA<7~BAz6^w^TB#tk=LwqNV3g^c z{S7RKF1Od{169I3t;H4K)mdp}hqebl3eQazH!C#@eeu)RK<5+We&5zPdK zD9Idf1PVsPFv4HLfvU^>#>`Uqmi^wFNOa_tRC(3ASJis@fgBqMl%7 zI&koHYubclY1@QIvbJZh&jXB@+)9wKX7|LVg{BpWyzx$x;BA zD~O2RH@v;6JFUp}W@LqMa#UvZWreGg^*4#eVG7 z{;x>dEH;GUW*GbR1@SHLM>?y6ZDXt$!JS?G}lWX z!&MQP^qy~}X}Kp7mwieT-BuLkG&V+p8&U(3dF8u*`sOsxFE>wX-uldvc+qU-XKfa+ zeSel8roWXU>(+uto)C3;f@REvl#CYdo2gAwhLO9^fD`=Za=u!OL=bCYRYfktuCUU4K4nb> z4Wr7aNql6o?2(jl-J`@OP+~C^(U|4TChm4LV3qHW@!@#-l0<~xK!5>?jMN_Gt0Du% zmM*0NWElX4p@<+Tz)-diQltg|ALh#N2U&9iba)F@B~)Ck2CX`u6F}Lu^*zOD_L-b( zsu?Kr0k~zvxKGnDH{(VcWp?IR@E4c|%KN3{a@%(tFJvv7C!#_iiijwf>!+g^1S?99 zs6LlLowej+_x8TCm%~0OZq-vNBu}}$#k%=K=5rXm*{NaRbv!o^yi{tSFt|1~k_<+% zWiebGC=imFMwj&869rGDZSSRVXHp=N{N_N)NPbVNg2ll2b&FOjA>>!E$a7p;6vwF} zQXq!VG3~J|k`L@ecdkuMH|m3Rpn_^XRWID}gkt0d51T*3a&10}v=6x;vBm* zr29=3$;srG+z9{FfuJopbW@U1o}3Y$K!YX^ywesJar*St;UpawV>0M#-soz08lu3!Sv=Q%_2b`0Fng-@gB}* zp4!E#U(FXhn*;%FL}CG(fTSaJLUMDAAyi}}zt(X9<9XTOVp{5p8X+EtlHm}{k_eGx zGNI>}&Ezb7w4x$llsjaLbJ8Yd7x;<1AHpy)@GD&}7|}5c3oZ9N2u@d$ zhEoN}$|j!bU{T!avc90m21*scfG8>q0BCW~KmY;C8Ezmi7upc4{(DcFa(2+M1X%Q~ z7F{@*0hZeacrWZFsR$0EZnA$*z)Am!8JL zwl+GW5TVNfYT>cDrZnvQAHprb64VmMsLnFel-Ik_nju(82B#lJG$U6wNb0Q=2Fwvnplr_`-tc7W$~us$kd#PA|Tk-N?PDS_e96`PGpeX@NoArVR!cOxwaR-y%ic5zRbZOLi@UK&cL8qdBz?&P(IjN}e#a31ISAUH z$zL?yD#laWSmw6N+ialNY6MtWh&Xm78gHeS%1hOV)S$%bJ!JhNejwrEAQ*`P3E?GF z9NTcqd9qSpIMiKrY6xzfqm0lG8oGYb6U1X38S^cMl6RtI!eYdB;hokl`rwL-9hkkS znmunOf24?${fxZ17Xt;&N`3K2$8FwR7~ixb}~vQW>0@-^bQnT)#W`i#^@^5W5Z%tA-)qqtn@psR8DM{V{zvuiM zlscY&Ha0B3Snf$+ouwhE^2p>B&lL<*7lnQl9WQeyW{F$Emz2qIXS+zmaERwPh=+oK zVh^Zd$RYUSL=iKoZ=YGmx86)d9N~YjmK~?_AO`M1pKb4HUKOHE+zK@C+dGjg7K3x-$IW7l3I62K>Zw7{~Z$rtHc|A%}iuA^J`a!@Z z=D3zo^XuGAp)bnV=*;#n8wjiInNFifD(czs=Yd|h)g@lPbHYIXWn&IQkEvfQfx{wB z0*XVZGq&K8^E+XwQ3^#U2o0@Aup=`a=n!BJ_tM4G?5oWZ6m97*(GK>5Gyt!Z@N)OS zZtRUCfT%HuW61>;UeMaL5<7Dr_P)rz=_^PU1D2cxiP5eJXvWL`y7oqx!qpr9(1$AK z!`*w4gGX5~PD#pMIQ2{~imVWONJR8`#ArUUFncB|F2+O|?5U5?uQl~_rGf3v!#OAeFLOgXp=vVwt5zPJ{0AK;|1 zuO_Aceah+H5KlMs1;%NYSajlhl*jY1C-rHB{0Mpwm7FRF{mDXz!vK9I^|6i|k3$+? zXBJNiaHySS?X@2n&5Ml?EMnvR;?a>1Eqy{bHUX}7aSi;`LVt;Mf zSBX@uYOEmzg#APX0Av@+Ho|%-+YjRVy0$Yw%rb zi0B**AV+j4oJONV|GHfe=!BM#xtAh~?kuwsnCv(#c>uDz%p^ zi!*iQZ3>NS+5^h)aGjFAVgVTwQ?zsCC@Kzm#dC8aKo~)|KALPbo1>Us1AQ$8JjK2dHwGm6w*akCzW?1@YzQJu1z*)06ji;__2V z^rP9EQ;!pTHW5Q?<$^C*ig=k7QH0QO&zKa-Kh_0PL}>tUGb)%1P4oGSY5zCUD0U5 zPL$3i7mj8>=l<~F#`CQ^EY$fG`p}1KuS9%byyc7o;sU3t3%}N%Uv-OIbqn1|Eb2^7 zZ-jphgq8YK#l^9m@Em7Rkh63gqOL0Ck8EC0%I3t$Z!z(uqD?ex+3}N2VCCi$`B;Y^ zv?9yk7DLlQ7|=f2^nR6{CvV=&IMwEKO^Obx)CF-xreP)o`c_a6Kd`x<7MIjq!K_## z95jv$uO*AR20BG4Mm?&5q?99QzW||w$qc~$DIp)M6a7V7NsG5w)GcBE7 zx?=I0hH~7hAkMcYgM~h&y*4dHX1mKF`{mw`bwV40BI_-0g&IW@PSL!!xtEv`hm2Dd z43zF3NCXo+w!lgg%?EV5upV*wXyY4FB{2dRUkrm|Dj2RS8fD<$8H{LEu@sd!(@Liy zN`~T6h_LwC)&!5PL`364dDn3wmy!pUB0Iu0vN!1M|3gz#LkbOpFR5(Sh_5u>4@^H6 z++?eY7DM4>M9{nCJwLDHzHjWQJaZ>-Sjt0`^TZx#>Uk4ab9mWmiQ7&IuvZcFy9B{q z?}PQloP>&oBpWQ%huPd`Qz&EN4Yer5%?|iv986~V{*(R&`3lZhCS)GVsYQqQ1L7~a z#kGjN{p?g5Hn+po2cgdVv>5+*kT{ueh7L_(!kKUHrJ_ZdG~Y0r z;e4T13Dt)2KkSo|SPLNN9q=-Ci?`~-=b2DluC{rP-ld&~#+X54Oe5a2?PW{vry}uV zbn%d--s}%m25?{Nj1<5VeY1kmnLTD<(~ovA{qo?n2N+n#@v#`FmxQs-AE{j^Zq_u^ z6~&=QiPiabC*TEYA+X|Z%lXL62OY&7=Reeln1aLr@V_ERA_Y;2i`)27KQ@g}svK6z z>6{A9xbSCK^HXP8B&g2fgXp zr5R1)c?TJW_q+nv`~F-U`)e3&HJyjjie^4X-I+zcW)PA2GyUttK?;)Vp5P&dyN>{i zKt8?{c$xkIweW&bzt<3!JUWl*pp4PrYBZA2k5k@oynqRdDcY83LxWc^To zy^3e6>iTfeKyo!|qyj)l#ly=aAI64o#bcq%*;Di7Q)ij8i#sFhYa`0dxUKlPqm)vG zZZGK$@tbqhnM2gWgscJ4q3U4t5{4I`tFw2G0Z3q4ZN7)p+|_|1aRVPxV@K6G+RASi zS|%}b9w6~U*K&r~%-J>)NTnd2oV5Ca6#LQInYOVw(ULs0%5wYrX?T2UsTeu?^uGZq zZn$3MWNdRo;8jlDG^oQ~Yp~{2t6F1ie%G6pxvf)kRSOT*y2Pblj`(XX@Pq13o#}9b zqrdH-gekFi1h|paL;yGb@*D3*)JmcHO7TP9?Z}lIyQuBG7k6cm0mFj#XsQQM97HTy zGd;G~TJDvpgpAvRrjtVtB|yRNKvtEzy|Bib8^iL}-1!`j2rhpiYpiV`fZTmP%er58iYGq~3 zH29CI>Ftj;U&C+h^`kT|7h8dVeH41y%>3hD(_u|yUk^*Fh6ku5!;0>L&8M?}ykvMF zhQe1+r^VKUD`SLbK}VRNqcq5wSy&kkF|Qn0Z}9Ag+LFRyOU`;Cb9VT8>k`&ptb!k* z`59ixX2?4b<#c$4^(<%jY&wID;Grp+4;L$5hVZm4OK>J4dgpE0t{xdY-of$muh73; zRDH%+S`}J(bfIsL2O#pTCh@L!5sU2J71+H!BZnMD@j9q--vxl1WO%$LryOZ{IqcC7 zyTzvg`G3-Gh4#_~KZS`TfR60-p6J-PK?xO`T8nyDpD{Nv_yo~6yFFq&oPTk>L@KUu z;$iipkZCmVEtJqL~wc{(&10d_^4T;C{i3*rRaY?a+$)%o#JtG(EC`%9(f3TjaA@ zOk95;Q$HlV2eHL*mN4O%_R!8qWCn=$!S0R1n*)=oUQF5t&tqPPhr_o9;q~?idhTX9 z4Q|-J(;BgNOscEB9crclHP`sa^9722*0bz_ewFsf^*Fjdw7(@NE2U$39axzBcVwpa z)6;J5yTmg_DBio|g_~qpJizG^ns*1A6aO@}bLX+(&2-rS!f^)V3~uwi$eS-S2>Dml z;sv2$9?xjV$<4QKTAA?2ZC_^A2L5`nc8nr+Ku7m(tRv>D5a~2T8Ci@wY7ce|mKxb` zS$ykq+${WPbLFleFb{sT)b~;tkFIO_tBSt$C;Zam81Aq5RtAsi-?s|hr^t7?yF1=} z?BveAdM1uRl_tLx$ZxV2YvCPidJsQ!xeO%BID_xtJTp5`pgm9^GyDT-&l~vWkyjABslV5cpL^e-H-xVK z{V?<%hPdY5!AaUn+}t{A!G~(iWx?equ);&FiZj^XauzUll(lErPILp7@wuxM>3ugoy1~-Bp){L<&y*`0OluQ0qG#8d7VjC2iVEggH?1YN< zhL8dm(9YPK^_?nF=RUWa`(w&r7c^pz$)F;nE&USb=7zFcvBvvB`OXu0GG3vhP`2)02Z`o)O#zt=C~?ozXOf{hap*2IuN0lS$rWV z;6@}H`r7 zw_rzO*2l)h3772V>CZMdtXJFRHA8)|w%=iTKi!51K2s@rCq!G+cvgE^{;r5M4VfUVrb0iQ2rIUb)!h)*)sOi;{DzM|6qLJa_ zyc&BwFr&t0StFUe-%kv-JnR~)6|+g7G4B`~TPGuHa-J6EwzV|c6qw1peXu*Ks`A9= z$+S!9ox-vl8-xK2nHo4s26G$lEv6q6v<#SdEz4{F#`UO+bszO+f@3Xf z8@Qt#zUpI3H>n0q?0?M=O89hj}>H1!lH z1GgY}+PkH#$#W&)(yH92R29F3ueZMb=x4_|CpZh#_+Q8ZN!f}p2ox_Cd#jv`Qp@qK>L#E%IUab6&*M@Aum$YE4G z<`qd^L1^idDt6XnErj@9n45H(!*qhM-iYFL=>_|8fq2cZ@0z8@vrfJ{<;{v-OmEp4 z_;U5ZJnv=wp-iO`4&eHCZ=sKY@E;Rub~+X7L}pDG8nUmhkOl0G7H}A1T5R1;DjmZJkzO#Y=QMrwDd)1P+rVdq78-AfQc{ zcNK1!bn6q%r3bPlohqp_GS(r|ZMr3@?Dn(Fv`zCVO7V%qW9_De({T0hOPL2V4mq?C z#P*c0fML~~qEgrt7%q5YNdX1mAq?4=-!p+b8j_8%B7hefVfkqTb~G{zf?+;simkt% zo?ydp93fQ9ZiD3yaOf@^3=1&DA2zM!Cyb1|7EL$!WePLfX1#kRYwYLpL2lj3V~m1F+~{#=04NQb=(`oOPbTMX40@N zY1UH|n-4Bd{S)T>*dqmRrv%{PHL>FTS+=^of)#t-f0MvQQ)Rlj12GGhJchPVFb@1w zXUpr(yi6b0rD&CxNAxz>b44zgKQ04&&1>Iof_Imq?&v^@n=0bOJ@eMc!Xf#%D3-*H zw4bdzBWZP~_ad>Qy%qim2G&E(c=wRGi06!li=ph*xl_F8SON9>QM4c-sw7C zxq$nP<NTrrbDpohj@+L2PgQ8nZU{NXc|`!D=&bzXSDcpoNSlr?*Phd>o7{=S!@V)M#3omB zC+~UBi2@lGs%jhQ1_w+Cr>QMi7^goI!200#2%~7lMs6uJJ-d2K3nAFpm%@U zKttZI=H0zxd=sWxi|5bk40$Yo{eJYHZ z`h8UmXYHhYmPbVZ#@JEA2|n`Hd(mnNM|mKn}G^C>(^QbFM1Z7AC@Ya`?SAa zV1PIEM|Xysu0SjC!?R3X=g8&P4}Ar5I&vPCxKmNCbdB@AI+w*}$$s3$D@V2E zoLBxYudB$nB#$Eyp@KkbCTL03F3b5Z=#5-$#`)oU41(o-dci;kHhaCT)B%0GcH zc3i;|Cp^V&aqyG>+UOlStz?A~Y@Quf#b{*X0Zq8z88slR#lcviElBA5Nb=I0LHhoa zi=hQ9%YR>uuNcH7-RX#0Zr%(f?wh z)+QxLVOghzY@6+UrSSKo< zCN(YrfrfXI)GR8t2NL5EAU}d)!dL?($s&l6!r+9B5*~&YOBDaRz2H4-7Ng$fIl3JqEj*5oWp!^e%0sf8R!(O%Fuof8e1F^d62Q+Ad&@nkDY zfXj!-<-_C}@jyDmQq7hjFOswLIx~ej;Fw-eMJdJ6$s*z0sH2nldNi=(lO?CgamE(L zmxS|NB&hpYr)dgp;P_Lc)#dodv7MPYi`Hvc)r#aA{RB&+#gniNYxBx1(LKwy7@K++ zP;Q%}BTg8QG!9_Lg3XVPkvZ-5}jy&ph?iU+x8X4=BQh zNd#0|WNhj=MyeNaLRH@A!3uj09(!XlxWz5`mU}$Ua6C_$^L5H8>rhiP$E1FMj&J(sVi9Gp&DZ;00(eBOTtqbm7&-_Ci~ z+E38F;@pTz^YpGCtv3EdQwHeU8S3{#1$K7M2aX(y3JP=uWM0{U_|fzEkgJ87?m?@v zf<3@&SAGjaL}XFxdz0SDQxfII7)Xam4$9LW_?GYWoPMceL{Z6abflxTXX7x-78Wfz zyQjj-4ux>nB5p0*c}3zp8cu{RO~g2r1lrC)@%DdvvlQHtzPHR7^)>l~QtPx9uAFhW z>~Pf8%@Ux1rMD~VIDknG;E_2uWXq~y)}U#7;HkuXLo8L5MJ)B~fIlCgdrhQXG)nWF z;Iw^7vb#QiW7wi_#3CI8)t2C|C&Se2oYfw}DuOucF=a>nQ(fGqljbLK!?FtMoQ84c zUy~6crp67nryJGzOh&gbL)wcJgB!w;2O5hJd30Af7@$1$=K`z+Z&hgkkqB$2lS0L<51&QbIAzCn;|DXSp7ClvV3{6G^hWz z*A(SUb}Yi>;hL5mD!n<&Zm;hN>pH@Cme{a0QY#16VVVJ@Lvw~M&N<%KDqoj`BUa-P z0a>Y!0O-|&w6Dc2qla8}wy#RVsW@kwdP7fT#$0*-Ybpoj!dr*+RD_uxop1T2x}m|l zaKy{ZtTman=5AxkT{y#d?WN%oCU}iMZLMMARU=9=>#TE@v#|KjS3?thtc!?ma^@J! zqaQ+^Km8F9hIY{r3k#$bU`R2FM`ZG(SN!E-J=qA9P4n(e6IPfqF#${C&gR5{mX4jR zxAx}vH+xOZRp-@AQ_y-z>Wc6L2pehX0-RznJ@~Y}MtZXN6@9crVb1%)(_yqXTfH~Mj<(zq`J^!e_hILH{W8;WEX(;|^JD7T zZrenb-7@?C2P)>gIecxIC|4i$R7@TWWKc2n0fss`lm1zpwFn0(e+0kI+>&TLLqI^2 z`ag=!GOVfh595b1U*RJQB=lS0E=ObN71O5?tF9~+P9jcIwzg6$5Bpb=QNn=2anQx^- z@*!A~@r-efdow$&URxxK6|TY!Z)7l}RQjMjVTsKFq!rIqByeOA^ zf(uc)&D=5Va2xui06J`Voo}+p4s##u*8><6g*vix1DTA&u^mth)m+EqeV^=6g^9J^ z94PLv6L#MpbW^BWxy-6CkjjMMLBFq5j^gSB`TuiUAo)~}zl`8}D|i<#TzIgl%DzDp zuLC$}euhnitUWi!L|NHDfB4VzeypMUI6qAz0>Pt+bf3Xkx4E12H2l>BX*Uu1NyAUJ zpR=v?_VDMmy%k*v*A530e5&kds=V;0f;S)uezTshO*=l^`=VSz%Me1epK3%Ef&t7X zDiBc2v-?=CuvUp|SCXR@NT8X#19K?!8R+!$nV`9@8JqL~i34Muu#O$eI~`BHl*YMT zXtYah-coQ17(jw5=WOa$5ObOMpA;`Ec}@~2P`7G7fC}TjhYmPmDt@ES{?I-y;LfK9 zoGjuV&X-(3sf^P>?T3TNnI;TKV?WwVbDv(t&H6K8*k;+bVPm{9)plg1in#S-6n}4o zZOk7pBTtfF%NJ=%k=D^w4 zs<7_LYGA$%$6HMMO)4=m83uld+r1vl8tPIVm|&ZR3iLVD@_K@8Uu#@4+!Nt;-yTCu2N$r2% z*7@##4uIJfB=*O`B(C1Cq3mSvkh< zG@4}jR4QXVs$lZjzHUtgA?(gp)RH6}mKpM(+IQFD=&SXM`v3-{iUQB51#*Tuk`}JK z)O%N*eOLPe!t6CPHS7ne0%q6*W68pQeflHyVD@%kqBZ8W5>$`7EwrvP=n^vm8TP$s z=l(FEAlmMWkWZ|T4}N#=^zaGZ2A~^OzRP|Oj1Wf9jt{g#gDL}CTl!&^bn(xK^iMwU zIzIpE^$kn(WqV2K_|$?f%%=ZB!~V9L6p6YLlNJ&SkvthzZfJ8(ecAVJymBK`iOs(T z+Zv5$g)?%hba?z@2R|H|va>&|#Al%GEa#-yN%A)JYt(z86(P7;40zFcc_4<=OY zzFHD-J3DTc6lcod>EJ01C8NFeUQu zr2V1n&gkFS(DhWP72tjJUtOS#X647rPkxH@qo*E-Fm~a6q6;(dF2B*2!44 zlNApW!uXa=P=Q}LFEG~Usb#`~!K|BY61L0IZ}l&k$^oLZ*oX8qCkoH!ZMzL@b6@RJKG;jE~GX~n;$Y` zH0|-CVdy66N?Ww=g#x8DU0Kf*f>-=B2!KEznRRSDbiT+WC{7K-IcpiW-FF?L*(B9M z8S_i=RbInHadsV{SaG@B^zhduP~T~;Fli6+9y38QwICYfTd-SmTJY;A z5K~~WJ#!aOmR?>C$;WHz-bT8GDL3O-q=J~XIanexE;3eYGLXW-z#to|K9L-4**l{! z*_`a35X}Sl#_76mB`}E$vt(}30%t^q>~bVfB9L!lnXN4^6q6J@7k#-~;D!xAQoXhA zVWv$zNaXc+*qitIu~QZ;vQs)G!KqxpV$%?*yzn4dmxf8i&q%ivNKH>H7m@WFe={;5 z7bgS0Y?8xs+fYz$P&rP5br5ELCkjn=H#+CjGPX1?cWI}=UOo>TB~Z0cvB$5k_IQrQ zWCvwKRboW6W!Y>yw>c{FEA<~oA^;R^24#|@Cpqj*uS``@0=`<>R+|~j`3!NuPtJZm zfzqFZDtS-PjB6$x_QEXM3i@b(ebR8|nd%<*TOz$YAcOD|iO~iibYjXZ6`6BQI3PjP z{J<;cxw&p2kRSs1)6BgvCUf=82?E@*DPmw6K%rR67r>ZvgaHNoDo{Q1!N{I@D?yQc z8bG}m#2Pcqa1WAEqUpcX;|aaup64q8ertsvBqJM?bwviFTNAuXIqc0KMlWENFZLFS z_)`iyU7{}Ll-{cJkOBcAC_0&M3YD;wK^CC}lm8wmHg)iie3OG=ZG^x?z%Uj=n+L0+ zo=7zy@7!WbUD>g&;+!<3)Vi4Ez#V(bt8F3HH(EENrKxTpwv-K%d;;-G-2F9w;dm#>3MjS=$#Wl zeC~M!uAeA+FW*M?Oe7r+DbO2F623R(c;UwP7$PzNS48sPD4Tp;9xT5UxSWktm!tvg z6KMFT`!e+<#k;?}1o<{a8Pov`v?xg{%4^CbO952-wcyyibogzzpAbiD@swn69)aoM z&!LNN0u00uALbQV%C3M(fxDaAij!|fq~>*aKm4Ho%4sJpveE2p<>m(HPTVZlyz2Vw z91To^`dBZvNKhQ+Cv8r+ipkpF_@%dWal8V(5kGhNqLy~0Ia=8sj|a0wf7->}x!A;7 zQY2zYqsnZcGRqwlD}J0{fK#^@*tZ^$jLRp-w54*O<680`9?C%%b*IhSOaquK-f7s; z^Y`@1bvuAQY8$A`seEHAa9l7(c&ydcAoKF*s-Twnxx=htN4ly5!_^1My;E(bA}t4Q zv2ig?CCR77O5!YPw3-}q=cl@H8Y%Xg_usk%$OCKjxQbwb5Nw9Hbxl&MzwHBo_+$D^ z91e(RLVA!lG0wB2YWuSRS=@i&2H7<8B>I zNf2fUe_8me9(H5-(T=(|-OO9(G<932J^dNoJb5ixQIiT;yXnEW!A9zFv6G;MQ}sx+ z6x@0oG{MGDH~QdEa5zAxBApF^10bgKl|v*_F2?=*ZG{jV=Q;GwWt_vG^U zt;HEl&cdPZpMQ=u#`9sg>0m$v45hrS|8~R|;Ro;F=M5<&Ig* zui7254X~ITy9}#`Y(H39)k;*fOjgcA{^^XkG`qCwj>2z& z*g)+{Apu2yK_SpZ9oZ$(R5Jj-b1k)u-D12jBUzaqqtdd&-c>YK?ZMu$qaN&5uqvpr z?V&umv$C=?wYziU?$#7kNR!o5i<_(^;HfQ6)|T_sQ6=kWd+HjKbuB&h9LRd^o)mq5 zvVO3qK{(kU%F_@}HstpFokBKxO6VNnHE!|zyW}*}?rFOAqFC!z%LLgh)7(sZ(RkbQ z=3t_EZuw1^SMffX%(!de4=bS)wv_X_rRo(cxqHjl>nYjZYy~8Z@v?FEl3D@ThP#`2 zuImc93A)fpkeo~s2Te5%>BHUHx`eyX+m4p*tz8%w#b^bjPHf=3OQof&IeEBGaIyK_ zeTBj=Bf9JS-tOC*=H&e1i^8V$m!=zbOf-3wM+JV)yf`0c26QdX=SGA{H+_x4LU$@J zKaE!Y{|jzNH(^NIc*q(Vt!Sw00wO6G4h8gswI)PNO^0;tq60QWWKE;R0$D!>{t%Ht z(#o7`dz@>#i1=uqgJb|5Q&0X6{8rz!iY0rsmjbLb0f7G(m<|R|;lvQ?1r73}0U#8B z2EuDdEFOr4u!%d36HA8Tk%GqghRvlT&$;CN*TPAT-dpcnUY}^KdR?R$4ZCE#gla7{OcQsWY^zzU;xh8;)`itB*V*Y+PENK< z%mpt3KLO1|JC!Ei#mTc~hFzuhz@1tl5p=S6SJ-K&B)ec5$%F^$w_wsq)VmF0IaHYL z3>r-R3H+3(k!|su1g*M-PIt9_e4X?f#{QXbNox^2AL-I?LGkcyurnAub1YH}&wjXr$)qNwRimas|12gRG78PNfH#X+R;8c z+b??|2Rhz)A;ak>WGTXJC7`9|kSXYGq8+!B_|wW>IK#%fW;fHOF{{k*boxFyTc*)t zFUPmCi;#0vA3d8FIB0L4AJifCF+XI~h$)}EIpL%7gdSF1v=8AHRUy|4B`fcq>F)H&jCgHzmT3mGx;Qi3zb32gKwOBZO<8~lCURNUHFR>9 z9ya!}ZXY(q9Dl1L#t_dcH4lMe?(%6)dzen4f6GK$o}o#A$db27K=opw|Aa`6T`*K= zXA~yUu>Yo3x~ZGhJ)!4u@1aEV#CxrmvImqb3QCZgUmyFA{RCf8#(f(fo6s!1la)xmpqUm{V=%P6rGp z%Nu5py-Pq*cZ5M<`4^l%Z@~WRdoarmpKWcxJP!yXYJ2ELUi_C2 z27}`Yyk{r2=REoxrA1jv1urDrJ~V-wfnccV5Ac#_QaP z;r$>w=KhACDSw(C*xnqa=*#ClJiCkf8fMV4k)p|y`z=nn{N4LEzUnAgkagplLzl?4 zW+DA1+eI~9B9{Pn!JYYMsW?*=PkFWLB6UhfL`MG&t#NtP7Ww?+7@_+R8FW~wL!EL4 zNluH1eqwATXR=W@sn@*lgwewzB8!h_ka0d?l>01uh*n#MAv}hTODX%k`fpu={;!3s zR{J-1xS=Ei?o;_P!^$g@SzT#fr5riqS=lXr?;ZHdsi7;0-|JY zUuLoQl8?`jwt0BA%J5+sDO*q>#5^~~yGMWvs26j8FJ9+0U%0W*#s=Jc@Ubv3Ixliq zr%-gp-)TBtrAtc+BRwUg=mu+5u061ZUUF*WQq_nd`#xt|Hjs`|jeh~c2EV_JHToBy zmx4dDn_Q^H@P87s42-&!58FNltBNbJo`um%mD+pht?Fl=AUiAzyd7U6pTzi}eis99 zKFt^>1x;REBm};p)lEm71!pnOIERBNRoDYVjE+VgRZuC+wAQLm%eY7^PLgn?(EN-hma3ZIQ++3BU6}8BK!Trq)g^_ zfAoKHSln*mmNxf`UDXL&@i8Oo+y|c|?b-=)++%AM@?d!xJyYn;qri)hv)|K#>fN#@}KJI2=H zcvgG{b<*$Jo_B9qUHsas$r+bLv46b3lWtpeFSL62Kuhq|x~p+nPA-{-_vH62uU5>J zDW5Hxclf_%-O6K+a3k7~%Jy}#`03i@{gYGI9!HN`JdR=$Lif3MZF-?{ zYkgB}Cj_%q2=j+EAG+0ct$#0f=Z`H%V^hV|1~096NHNlX84Y+Wn8eM7^>>)Ms4uO4i@m__%s78vz?41RXLrw)B2$6;=i zvHY1_%v0JmS#ff!lvQ}@KzTNciLD?_<*r7R&|LJtjoe13l1rv?hA}l~gVQ^gTrZ?$ zBcr$%6H-21^rr)sX7M&L`5({E4wgy+Y%*S5JY3M}E{fC%j2af?bJKnOmPY2sbj;t^ zM~3QaZsfCqwB8)CyolI~-mSR{^XZtL4}IUiaD+d$S003x?VAbwNb4=*YlQA_&9IM- zcqDwj`><#6a#8<=xwChmr^?2NNFlgTDCJCM#(FgJW2VNcn&G4~WcfPHfIF$TfEF$1nQFOOjv068t@r^ILa zd(cItAH@to%2CK_EYnFb^K%r#CcsS1p~qqo6IoA?TX3WuvL66gAdzgo$W9C#z`}Vu zBS8a^?If;u3=jN-9(@&jD*o_+fBU1g6iq0Y3AY5PIA)H(!T=)pX(a47k|`g<_?;-Z zMTAjz$|nrW|1i*do6HdaQwR|;Rm{9U_mC+Y$r%<2vWT_wjb&en1TgRpEZkWX>0$?O z$H4jR;(|(G@BRzrpc*Jkd3ktF`g;21t z6C|?=6d1!WY#qbA0}=O7%v&Uetw81zH1qH#Lm4qN7JyQSu(vA=55F^hgfRamgne7d z7_JI;Kf@J?hV!Sru;+;65oL@+g2`A!CyMb6im{9c{QyAoH4*oa@NpF5FbdvJt*aF? zgc4yB$FO@yrbZNF2paqp$wX~LJtbmE%1G|&NLv0>=r`DnZ|R`sIJJ+OHy2g>_EHgo z_T(yb>|(?tQKW{Ya08Axw}kJ|f|+Q~H&BJEeruj9Yj}uaK0z^A2{D}>n+)6MkK`Ce zD;VO^4Zj0A4D{YT$M7u@?YnWtOf=+}hzJ6hy)_y3(GaSKCzG-X-9p3H(U4GpIrNx0 zM3e4Z2HuKfFx!WPqKmS8<9r}McLFk744He8y}lSmGYPv5d6;v0zyG_+JyCl|Mbuu^ zgEMN_rWmAxF5wI>;mR%H?k?e7E8+7mu_D>JE@665$SEw{eoa9-ggF8YJ%Ta?VHoTH zCMtNMdM+lEh>$ZbYubzn#o%IzRJu}1U-ff+?o>kuxSm6K(_A^Fiw)#}^jD5@9=TKc zD1swB>VDXb9?LW#Eu;AZkNuG~adZW7=g;fT%6$~t6KH4#>gt_lsW3RA5L zf-%)oA9^?fyH<%+t&TaURFO%VSjG54BO#PWh^r*#P)&w3Qp_eAx`l;3MZwJz=&Cg# zwJ7*2Ed0F+G<_UAg@l(Q>E3M8QLEnZNQQ_&L>KnCi(Q>d!t>69lY3 z%>OZTP&`=3E{gWlu9?%=;h-2(CXq#FNTwhnLMFUy3Yqi- z$>aiIik(aNFbA_EF;g*ast57U0}*Cnh^FH5p7Ca$Kd{Ela(=ZIlw(U{U`wM6^5$<= zeOttfPzME zwgE_p1)MtC05Xo7o)beK{>UE>76C}@Ltr^K&f4iY#C9O#q70+TJYojT*o9{F<6&AS zz$eg*cO)47)EG%9L?4o=c@9AW5JOnRKT-IY45F0?$Mtl!qRXB;!f|z-J*cjfp3X5e z{0dKMju^6;*up)K12!(crJ87cU@h@Wb6ok6JuGdu8_nDzIX1^cJI}a>Lhi{h(Xr6G zqL6NATK!^rD-`l+3SvCU`jE(Tbj)0NjZj~Ws3p>=kiZLSeG5HwOH<%CYJIB_ee3V~ zHvaT&QhF-uH;Z6fT|6am4`ursHeqsV!6Vr!RXs*!M!AUY#O#mVeeHDl)@7i_9!er((a=~lBpd*$H=*@N_~URyjQTi$gx6Dwo5eBF z3Hd|f?^r+wLuE3>wSg05GToyNa;ZW_d4WdztvbD4>eazfUxlTO>W2>m8rVwM8UmRZ zSP%e~5h#Z20R#S;^ZRcPWM(z9b&%wv%;NpD?k~0g@;=OQLdLPXZFvWrj=>_yP=_2PiwX?@@ zPR|Pt%aan}(TMupJeGVYP~tezpjrI8{`KdG`ca6@!nPcv&m>f5&Ow7iIc+#*v6V6P zYEN+}Jxe2PGvn*c3+88tSj~BAFbO=5xbP7x04A19HqxpP5Hzo2iy7Y&kn_cK4gkO) ziImnv3Zjr|1)e+aW?!w9j}?Qas4sJ#C9&oqvzevz#Md|bUeh^rQ?}()%a!zxq^8)U zYt)rlN}B;0_&XUmD5&##7bC}~G++~U09$15W6-$7GAZ%wxsdO^=fc)6WVQsd7l6ZA z7y%hDI0Xb?Y38JmLNdtw;-$|=* zW9YJV>+*@bL6ukRWe4b4 ze51W`Kw5;bg14{|Je^h#sF}G_4M|9AvfcA(IUuw-F~5*MgYy|`WV@Vg&!Rt z`{r^W^UPpbraPOvpn)lyV=yz#l9=>rdccs_{19!)YU%Bbto2Y$-sKlnDv-4uf}*^> zg7gc*n))sNT3I}thKiJiKm0~!rMPhq;Mzah-MBc_+AWbp{As7Ly8 z@I`d#P;nP$N*GFNt2GwBNbo!-^|G);`TIb%MPnL?j0fCRiF5BjG;e4JzQk%mc%Qwy zd9dA#-Ag!Uefjij8>R4TdC%ADN-|$&4*U3|LC@x<6Qn)1VLgE@S?etSiQ6Hdaa$ND zM>2fu`e(+V?K%Ri0hOvBfy_n4cxoVHHyOf_4beeJGvky)UigRimMldr6jAjxWAfp5F#nV8;W5KXbvumn4TSO~chM8=`HhTAV; zHS~aEP1X)R)|>Pe$;ncnk$Em}Q*S#KTpUifX}#X0^kP)kS7vK4mcjAc11>vv zQFJV$54gf_XZyuvd5t(H)&y%(&AhD@BVKZ>bBQ7 zW?6x!EtJ5nxJL;`)2*`3^G*>*%kOMo1$~HplvOOg_mn01x0=jx^*~(1J@G{62#*&8 zLDv?^oDlBvT2UIW=t_u(0KPWFfD40NSP zV81XA-SkN=Jz;2gb_txGq)ql6HZ`tC^roXFZyKtdw#MaW_csTLE&3jO8&hKtwvu=3 z#6c-pu7qDN6z^r0e?n#_)=rSbn@sPeXWImMrJEO|$*3YG5`A@UHF+$~u$rCSH9t9! zRIsu4t7Rz6-LPk{b*9nuDR6oA{lTSdtgww;c4)q${U72sbr*^GExhKcoW@>h6H@o1 zIomL=rNItqCBrF|AwRnaJ59Yi9j__2tZKeA-8e+hwrbZk*$}cYKc4i^wSVTN_t`a) zp%BOAj@cd^cMi6ozvx%>xt;@%GtzsPJsch@)zvZ6IqA^pB|%O!;Iv<_;$Avyj1+An z3_?q2r%OW3J`=sKX$7;jLd<(E)rn!`YOAlop?x|EKsj!KW? z?B9P1g3JI4j=TAI62dbk>YIcNfLWrQu8TD8yl3W+R)78P#|71>7{99uLd(GW zij>5oIoSq53*?p4gcGhoVYKdcvh=uu`j6%-2lA`{FN4Z*`mxgYq0(=J3%t7}3@R?c zgczp53wy;DGG1#)(7W*=zCF`>%=v}K(l646@JL@MR6Sud5yi+d(56f29u|r>nBk+T13^+TJS8f+RaXkdu1moZUWx>+VPDq zyG-M#X*Id6j3Kjn?RYA^_wcu$SHA6LwT;U^b$ldea-WG1vh<$dzad$JGJRpE>)May?yWDX7mqfEc{1eBYX=i|{I6p3|C4 zbyWIqyLwJ|RPK6c?~XIlgo@_>(FoB$>w_jLI|>Rwjf~1y6DX!KKUqu5O*<~r+>KLO z7xTQNl#%8}y#H1ytM|J8YO=f4%(Sw{pNxm&dR05&+A(ZbKI*>u+ZT+zt(~h;7dl`j zRAu4)ZYze>O4;+t{iuSTXaQj!`_TF}HNSW}ut=0`Dmm7V6&G=L#M!Lr?0r8S4~i;*!MZ)N6> zY!C2RZj;&5rA@1NGW){8Ic z8S25$sbx5-n2bXh$)qG@ITYwdteX0Nd3Z=RuA_&;F$ecUP|H53_a}E%0Tu*wf>a35 z%VCk(#{hMV%={C}7XxL<#$8H;o~vmkY9pP-vu9*-It?4UvY&@VXzr(xJnQ;lWF`E{ z^=F3=hV5>aI|Ee-05kyyoPpcBap44LrCl#YCM1P1we;s9ZZjGumaUcZ6JX5-s751( zO&w?;79yjS&80&fmm?Bz0#tTQnL5|){wpzqV(I;Ixz`UQR35jIp1?Jd=ctrA{>3tt z8zve`>_gdMkxIug1=Y+2aJAEulxspGXEJRU5URLAsC=hRUNw*{3b-WVXse-e`B3ej z8sxIn795=YsB=%J@k)A6Qty5$d<&+MkPk_>)fJau?+!bs#7Yz`Ddrym{Rp_=I7k-mXJt{8h;^HxKYTS=V z7H=E8^gQ8lkLDdul>m0=SBXAKdbWs+`dFbIpasSvusEw}D2FeI|Y=~e*U80aMcP|aseG||R-G6rcicH_0fBJ|_#Bp8>I9uEyaxus&Zu9mb( zViwZKI_-!48BHhSwA63Fx{K3>C)FZvi2o7$Jqdl7kE5YFpQ;Vo(eb|g4=EXOxEXPHNaSHuGj}o zT8ltWMVP4?bZRnqqA(#UuiBt(8pnvz=_X=40#A`GMGmGw2cqf7f{SeF|>umW0zGlm`oiAM0du z0RYOZ!_=fR5$fion<&@))U;$-W_%^ztYm#EG@ zDgDZ4vN?{iSee;q8~uE!`M2J1NY$LIfX>Al6e;Hx&^9ZR zoa!;HdiK+E0jz2NIE{#$2~#gd)mULNd{V6np|N>3d?@$)?z;5Ov_&2o%l#P|6FkBP zT|7(Zq&Oa01z=`#=gJo680-??%%CrirVJHz>TpwK<#V_%yufjY2?!CpvmhMkXXd<&_{lQ4 zO;|vVD7@00jH@q%Ee%SMhX+Gcu9hQioVEru;LQ4P55wZE2Bl_(#iASV_PPqKI(Ulk zCX{-MY8g1YBpieYFcEO3)e?s9(6cDQHuf?dP6%_!!Y{uBtvUa=^`_*mn$&0Azmn$0 zbhi>RaO3qh4sP|8Q1-$GxShBfE;{qqZ5YG2RgSMU-JD%j1rFv6(ohC7_`T&c)_=QS zv8J09@m@X7%IcsPa%5sNw8Zo8tpDzj{6)nTNP=nbbjsy##(dvcO8>$(nl(x$r_Wh1nn!Ps+B`CzU1EceAPeaGn;25@8vw~=h1=@#{x7=UXinc z#hEiPw?Nc6I`)RU??iW)!WZfk$y4~FEE-cQWXucn=*Jax3-j5Ypy zc9Tn^WwrpyvDsH%9na&eMP5$)o|7rwljMqdnGbPFc)Q z={?8%n4T58;u}4$$$=$(?0dexZa7}c_%GxFBzVHP6}R0*)zjiZwpc~ z@U^n36DOw3AXY{!j$SWz?FqaqY?I#n<}5O6HzGFqWUWbfTRfkHa9gTyvPj+pn-#B{ zLL@KzC1t7N{_L(cJO(G%)jXTC;nc@FoJ!&HGV2m>5`bmR+zJKQw97;35Wv7y0DIjo z))b0Lov~_ z+D_rjvB<)V-aGK}b>F#eBo>&1(ktIUifWr+Vqc;@bZ0C4<93J9r~RCMt0QIO@qV*5 zZTxbXao>cK8tto%(+_6L(Pn7j9Q1&DBe}X-F^ojFtVi$KnRNI7ruYVWat7otMe7}d z&%-xwSToAPMZ(nLqJVf7Ml$h1w^rjWd#s^T+_e`8# zz-f}lrFj|fQsmst^>xURq1Cpdv;JbB(Fj`rMBLd_C`1k8DtQaWy9w^!)#rB9zWl^c z9+O=+J{J63N_hiq!Q(#sesLBJiS zomJkuyV(bJ&h)9BwhzDNcZ$dT-rugQgf<1bP5l0tU7d-g2eLww!jBBIkFl4JqgLBL zu zF7oEdU+0{e1YynqW=WSct}SD4SQzP}2;P66Q%QpDO7?!zDP-5~@7-(^4d5Fob{x$s z3f@Ag(piaLREwkc)8{TzgH`rdseRcX4-sgQB1o989z^LzC3#@>bXj}{PmNdh@-&E+g}8OMzh`NByb|HSt`eUM4NCX zOjF{_bbp4D6g!|)5zJ*7T4O`n7D3oL*|{g}-~y=A7Bma~t3hLqccuK&mGc>oR4 z?YL=bEA{r1+PRCr$YsB`XG=??_krrZv!MKQ;4B+!KsW>Vh~KZ;##$%C$adFb(6^bs z2L52OIaqo7K4108Py%M`tZW0^YL{WXa?@wVKFvGUJ1n^B?vK3cxDA0F-2>=z#b}9a zErJwaA%X?Q?F!IGQG7SEWp*i?$JBO34A*_epik9&K34?zRAO}@=Eyg%ruV5I-&VyT zp%1}H$_I53iT&>ihb7HleKEfI{=YosIDuw4r(?w;h#3HYP{$)NAE7xRKTVRLEY!7n zoJN(aOgb<1D$nWny|CcRZxXNnR~k2-Hl%L=NDiHm`tv5UTCB45@lNBh#D$L>SqC0y z*$t-nI&@DF5Dq|Qx^9@n#p6Z_Ly0z#D1b(_7_S+U!8y2g=T6!8D<;j3KHsh_bo?C|Dd5$-lsts-| z0ZjXUUVTkH1v>U})F=x7{T$O+T3p3ErPDBY0REHsVfu;&g}e$v1A9LI?g!hEq@Uz= zCT*m~J_Tc^9>H`Zfoz*F0R0o-0=_X&B*&oKHj$T$!%|F{(^T-*D}I+he!uA8x-_6I zHB5Q-P6$W+K{|*@j-+$9ClnZrfnAWhvwzG#oWOd;vfg*T6dcFOX^18^3mVV?l8Hya z=1`siWOd-y_?O+0Y&oBWdcRWx~79feyubhLB?&Hz|(^+Fk#UY8wr3|dC19Cf;L96os4=)_V_X0@hfgPYkOC%i{Zb# zv?(7ALqOWaGo(2xew_i}i&YqBx&d!aL;63c46Q1tEs^I}Jv{5W63d)JFH#cgFg#;^ z{<95k%kZcK&1ECx7Q>=(ge5?P49VMofmz7^6>Hdh*ex;|Y9HtF(Zlh2_(=g_b6N2) z)$(pB-=kXx4iy=;KU9%InVRmR%}w8REEpA!iY0+8hqj?8U_6zePMO19>3FmOWr==lC`&~b>B#hVE-YG*c z`%W`A`9)BJBH2l2jbmf@1 z35dpjyARxMGn6~(YV&3}8zIaq z#PCDrB+Wr4CoH!1ehmJS&{yw*@8T(C`BIP5Ou37ig$sqgLe^i+nkfmrnn4>AX?_P_m=i zXzGM81EmRwMnrp9wj9QH{EeOu5_gE3xGJOYX6wd{4yeRT07oBd zCh<+xb=mLC{GTAS0Czm$m|qwBftHlR6_t}WeWW0M?$%6*M0gA7@b?2GY4R96{%DBz z=l$`00NoTz4y2dUB<;dl@>o&{~{BdcJ=Xm zqW5E3{$u5B*=~BAPp6Tt>oAJT;t|c;9Bs`^ z+_DJ+EnqSB8f6ht%WwM1EmAR5w!QndAfb~Q6Y4bJkq@j+2@z@w$!t+k+ySN!1813=?qv(|*oj0HUK_ z#xJG7t$k90yn`w8#gFUs0>$*Q(`lAWG-f&k)cDmHe&&~_!&y&pqes=vcghU)&_VWh7>5AhmQ`OgU8 zIC+MJySE2E^v~h+o4?AI$z!hl20fz}vJ~?oS?hCtz3ZIoE^NmOw*2t^I@lJ>uKPM= z^EYTU$U?#EKU5*a@;d`|3O`;ftez^26T+xFea86nib`EA(~1jKwNqSMy2FJM5lq=6 z`ja1P_tFMVT4^2Ro#d?zzFMB(=vA;qGm?SUP31^j#Oh&! zxk5B8cFn}lHL&w%sQg0nsTRpX0nii;Ktz7$%mze=_ur@u@&H~9PvTE~PORldDeXt7eIz9<46XPo4O zQ=&A~qBiI;L_8ND$3F;jWy6<%$nO%sXqfpdcmpZP9{KgY%$*2H)3uE7yZpxXOu8mA2 zP9t#o(4;W;xkTjEJK(k@U!y)k9u!4`9hU?&O1LN^Q#6^E0VE8-Rn!wX5j`7?;5Z+7>ygw&W zXHGGR2lD{cv@PX4Ok_Npf_~QDr#w!=+(cF&N&pz49^pnbW8dnbQNU*E?u__LX%Y-7 z`a_X)?eVNqy%$rDnI8XmDf#-cuzTV2N_Ik)n3DU60GKb@R66$F7(yrj8$HY!K5BASC z%~9-yvy-`x3t*q&N$63$6CXU-e8kl*QZfjd(n$gdw|gs09QxKUD!*C8_=f52C2>^8?ewSqkyR8`3Qq;Hlwf`3HeD8s;k*60bPn76% zlSpUzDL10svO=_5k@*eCEmROm-b7Ce?(fIGf(Ax%W~n;bmB-dX2Gc`|Ndkb_kVZEV z?@r=x92C*yHcu}7;Y2ntgori_8VLI-OXn-ZdS6zQ(m?XX4NUF}!@TNdBt96Ui4w(% z=@v-gI=8om>LXRE5ChUp&ca$<{SncD6fyFUfGX{_9&PT$TVfpuXrO8hY)(lJD~dx- zj}M)Yr&ZX~N@I=Yj%HLt_<6fqj0o)A>%5O3~~2_=0iY?%wLDYN!M zJRO&NUG>2N)3bTwa{#;&XYg%nH9?_R1|p3f`Guj04GiNso+wjNKz%^kpF-WPtc#Oze<2KlQfqNU6ynPY<34 zcZIjKoVW+j+y_w&AQ*`%Lt#yyZtP0LLM@n#Y*&BQn_9ktzT{dsTNxopq0o8fqZWzW zGaTYBlbaa)4nw-X9>`n0)gLz)FFC>&FT(xJmsmISYwu&KG>ZV3Y-tdzyuuT+rr4|; zCd9#hQ@*D^(aYqHabvrlAYvxW4O=cFCM|OMn5-W? zEhiJzBlc|FxHVLbf2=n4W zyq;}OLBJ~i28uq&i6!29@hPopH<~)OpJ-Qv`vPG%IS3LgIouI%bW2WrZ)8wVuSP;! zqq)K(jGhDVukKY7bk0eh?zcy{*A==Mx<_vr!Y{q4%1B&f=@z_^&2dL2P{dbQg4wMqC{DePx6KbRL()RheIlii-c5CBX|jw#D*dHW%lS#vRvvUjLOJEwU?3~8@R_e z>Zm&j-fiLXgR0*9oOV>qh^i5-Q$JrFr844L-6>yt+_K*%eUPn|AXonOx2p(?+l)G~ zI->pGHV-NMnaY>fL{1IjHAfiz8H+y2NQY*K)zFrc&Tyg$i67uqNNE2-KGzi9@fV_d zUlIig(i}BNx@Mj-ZOk`XOcgre4)vfIxwi}{@Jmb@D!djeKc%3er5;%V2#*1l^fFvw zcGix3wNd6(Vud5*wK(ayTNxT6Q7S`py+ZQ4dK!$EUu0A9-$BK(5ItjAs#0fmz~a4@ zA_nRJ9rQpQa>-<~-wmZFOT}!ipXmImuh2~LPcxA4_!4B7FLryRnoG=j>C_d(*D9Ag zrL%Vf!DpMws;h8{PELGUbMwnQ0PZ>oeLM?VBjJGP-=5!jl)j$p`-ZJ9wBk>dkgs^9E)e|^AZcQL2@u4g;v z78~EY?`HPKigZXfcihs*296dyo)hHAqweoue9aqlnOQ^C3JgsX<@O<7Zzn#-kM^&j z_Qdt_Ll+)uvYhwN8GK{#-`J}tB2LwO|68l@pGD0+_M}DWwa)!5?-XIiXQRd9k2qSi z8Jq05d5G1Ei*Iw^iP>xILUebT4iIRVc3C}Zas7o-j!J?ifDqP(IEfY>qQ4RkLxgB8 zme*Qbx}OhyyKBh>gRsX_RA5ucC(X8 zIEZ0=W>CB%4!D8>S5quE2f zzrXYa3NbZN$d*CQ5fH|osL)*+u@x6_dSp+lmMz)8VEnli>~L~aJ>^l0u!}i?ELf-Y z>+07~v(xeaGZM|>iAfBi6D21~FB%QG#=!uh^z6s`jj?`GJ-@#3&+(=iHTwFv8h<#G zXSBnJPCPjxOcJ)2{$`{jM)!^$M-E{)7tVKo^(XaPch%?XIG?(R6E-@#Vjo34D|J<) z?`pn&p-CSR05y3W|GHvEYWZquY{hT_0GuMp>Y#sFvjBx5&vs+)MYnHC^_Qrz<%zW1jxgAdPg4t>tj!%-^(P;7-Z!>-3{j;F9Ge(r zCZs9QSV(CP9sxj(;v<&1^l#G&oCaq~8QeJ{#@7cgn~$)e&E_6)gQI&Ko1I-h1JG&$ zMv*GJSfjFbFO<|DReQh&>Uotz9=jiwl8?X;W!aVj`kU`xuo*-;(Q=&dM2bbUDhb4Z zg2jLw>C6dU;J`>uj4CchC}yEVJjs-mfh0B$Dx{_SQ2a|Au_5(xe{f|$?F>Ir z072~W$jc=4o(+;OmwTm%ijcx>pN+3=i*qp=eO~TEuPnpww0IRO`E?!_bA#;LJtn`{iD@(ZcrrnvS)ar-PFMk-w*G?AjDIQsp2?R6 z7+_YYAew}ygIK5#6oA{KOHve*0_|H&>0ZY95`=Vqy+VKUtFrdDocao-jcqavdk&dn z(*%q|28pFRq)<{YdYMdmfAwt_ATKdVAT-$VmhDw)tQHeJLTzaed@&hv%)emo^&sZc z@8VsYt^cXY@BAU*ue&P@28%^?KFjo$E55qhEq}G%D*2B)(qM63YB=9r#(AJr%@_xi z00{NYAzB8)&;-&>Ujwsoh#ADLwy%zl0}Ok`pKX4AFYow_m3$IG0Z#HjlsaV9Y^tmV z20`nt)&OfV`ByG4rVQKZNmrWu*Iy_=X>}W9hSG5@KRVC4)pKcG9$4zz`uO@y9rKyL z|F_1$os`9tDs=5{ozr`#IauCtBAWtYmjozyHhy&k*6lDMvoZ#VH+=+?Ynde$31ZBO z-`v6n%j6@*vu*-$A&qzr02+eJ_HE287OcP0A=%*G{kix9^f>#2{^$7Jw&t#f8kXaC zmSe8)^*!%WIQ2k#fJO=YobW9tMVx^X5mhD(jM|3 z8m=$2+oCUA_NO^vU+5Bm0)U zAt{Fzd!kzNIF`V5*W6k?;h^x*Q76stk8Az2Gox)lh#fFe*I)@e#6rPrlVS*fZC+Cq z42HpHr2G^LjkWT;!xvti12u3J=ZBOR--HA8#i{NR7664s9{h4C1B}4eL*>V-`%H9d zwi{ellToM5?@mU{TkD+YRJ7II`N{l_enDCt_;-Bsi^{-u7o>1-H+5mHNWXgx!_)ad z0Jst?z@@=Xx4x?B#}{BVlwq!%K#YpQHl*=)SqFR4&5p+H)=m2HEQs{i8&V0i*|B4v zhYlhX_Y5ZZ&62NZ=C^$%&V)KKs+}%Ordzj_-;_(*&aI0*y)NWNrzmN=&O3>``p`9J zW9|+du0ep)ZPjb1fk{q2>LkADPe8io6jP%6Llw*KvTO{OOGv)uGH)>`g;eS`^m0G2 zdlkxKcxYDa-cD<_T3T}#DcFTdP;qiBVGjm!Tsq|}&M&@P$cn1G7r@lD8m%Xa zr4~~--2%7sJ<&rdaC_5axpXkzR^3b4nQL_gpbNYmrN)Ja zLnxlI1&D?ZfwRy*RYDkJEJ7@YsFHI-`6q09E`kIoOubSsX-%HmJK`mK(r`X6E?dxS zENkrSzjdEyyXvZc-M}i)isQoL%!bG7S&aeWSc&Fu}FuOyVC zWz~yx)Qb0|5EKf?(2SRb%tnjw&%C!FRPZ$EJ%+b{5`f4WinZNJ@S6G?(UCv461 zlcqLH(#?+498~{oyp<9xn6ZB-pCvxW*b#R~`HX3o^iI7gqt_@_91F2oioIRj+h71N zHgH#Fg@GukQ(N!2XiQ4Kg3gaYo=&xrFsuj3;46Za9taj87oCXXdniPBjHUg7a{i5% zvlIw7JK)RLAcQ>X-ApUbE#f(bcR{5dYS`#QVWSSDC;9P(eyoy?K~YVGI;ZIMr&?!G zXYI59RM!=(V;t+qYyf&ZbY1*>SN9S z+g=!CXcec{Uo{G4ZE$~=9Wi>aX#}U0<-RKEy+f=*ZJE=poHoG&Z`}P^Mao?q>TZPZ zzPmGe*U|?3mGz8QL|4yOQ~!B-P?@^OQB0}P-L|{t&-ib81bZy&ol*2!`he8C@sk9W zo^*97`tqMF|FJFAKU0FXL}L{&R$#H)S7%pj!vAS(zVl+f`rbgBzRGHf1f?2zBiSr> zliz4QP@1mI`80%G?{rXhcHOh0Pho5DRo#?lSvF!Oa&j52+~uy+nbU z1|>l3cRlO5J9l_2tL;X zoffbVc991=2b3(f$lC1R{_t}6$3u6%YeDlvD+;BDaM9EB1wktnK6SC$#uNywBtVAI zD#yg;?FI1x~~oysvp?Ca-#N_&0Bb!n8+lYt&H`n&rR#;@aA+bGgzVUP7{rwR#Ep*?6<9 z|30$B~r!vHAiS;>!jh=i2g9e^vL8t7hKc6+?!P(gG!0p5)Rruv7ASm>Ur^fk`)^^(-a)SupG%K|=p4bCpH|ifJcoD_ zx0Zd5#DBe7yzhEJ;p(grcrOQpcD6lcTcXM)C04|sjMttmJn}CC8*AB3Z3zX7P@kOD zB3a9+4f6b;v*?RS1-J~^|5=LsD*`4jm&A}X9^E{+9PWGEA}$cNH1o3|%Yswtur5+f z)#Pc^H1_u=sc&R~5F_kjiWc|Yqan;(QN5%)**^Ybf+mn6&v3;ml?*5kJqf}ZQrM5F z3{FiY6z7&jKUi!)p6!AB4`4OjsZHTw(@EV)N7Z-Tc_TAXD&)@@1+QDpxBYyWFnWbq zEkx#9cW@*LEdH%VYhf_1ogP;{Tbb@7)VAjN;Z|GcyFU>4q)DyhxGh$lW8Rw#{{cYk z2;Hmii2i%>A7=Ia+y5FWnPmnF%)&E%+n)L`bhi}J(`0_;wS{Vl>Q;}PT084oO7mEM zx};3?C8#76k%Qi=;jN4i5vN+Wv9YxTNY4l1L$V@mz@?L)SqJbuG3f7#O-ln@%O>1k zal{{O>&<~d^aVwybb8F|;TL(TFaZR-uO~*%4#6uXtn_>2^e=8v#;QJ@MK|ELboC|z+pr14pl%5BN(Q( zOo7m6EoYL{-V|cr`$oLaw1@rS7Vg@|j%+UUn)pqsNFzUD7`(vH+ONV;OcqlgPiGFy zf={-v*SY!?KQbjBNP%}OP7L-H3L=KV6GISJfCP-}V#4g7f3Rn-w^52{H#B&{`D`C7n8tp{Y+TF=`m5VykIIA|$fu`EK7V2_miEk(%E#6vnLTkzd>y$* zJ%CEi8E9y$14w(SEB&#$n1zN5NVpdhw^&2C`Lzt`&~h|eYrWbS>`|$&njEV= zyR-t#3GKUztSiHP(tO%ZE~H6e(MVA>JfYe2P@j4DUC zY<$wWi?L&7CuHVA1_kxGrL)^OyQXfK5U*hYH$?^*oqOUh{&fDJKsoiVzy0ZUu$Ik7 zHcN#~DxdCHDxbrQ6y>?)iO~c}${mNHKK)IB!YxeOyj>SGVO=hP#+fWxq>ksI-Q2>? z*@2I^jBz)m?J?|jJ~nTpy>TP?F>3f=-elqs{%oz+_Hf>TzfaT|hhkorqfdvl$BtJr$WB8VlsO@h;0Ojwp)<6FZTRHI8V0UXHNYLAw$o}rTeAvFjLksC$UuguJZO8>5NoVPYJ6~sKi78W3 zD`eg$vJMj96YU*AmVpLxHwD{@(TRR`y=NZfz;|t^*N(#V*rYjD7zpPXLG{E&C2 zdHMV>*<3Io-PB(xK|2gPP@d`km{Z>O>-#(&BRrgn13L}Ngw57rg+L>VYbRkui5#79 z`fcGTj9AkJR8);%Oiza)^>AKwcex>{a#G67NX(~O!0ODBuaC{AZ#ZvS;3XOPlA%b` zp_9Z`+wcbOeUx^#xlfae+HZ?*P+|h%JGKqYEpby!KbG=r6s7tSsT@bT!3_-X0^X}e ziJ^DohgKLWoeVbY0{_%;9RR>nc-;vX97k<(Kc}7VFnO;UK)Lk^kpkfz+WKSnvEb%M3YD$5_6GM zh^|XPuRshMe_DgDnQ~|sX)GEq*v>Nf9S-#oaE=%D z+!J673T*xma7P86T}V6Sdy%lt9l&$$cAo7{FY&Y4LfC}{F}FlGBuga^4b78kDv0mb zER~R%qkw?p_MX316n(V~Fk_-~HmVVcmW(kE!HSY5b~tDK8@=k=~9 z@Qq$z!A*U9nCYd3GiUFxU3`{KdDi@6Q7c<6Gy7VZ?0GtB7!1@S0CYlAOiZIw^$lYo z+8|1D4?_cmnx^o=eNGuuJ>(}eTpcTaIXj! zi3XYd#;%S_StRf~0Ro9Btv>g>B&c36>Rq3n4ey?fpkLzAKbjqsZ9l~XjfOiCTW_56 zGyDFcLxKuq`T@uabap>hhP;pl@)A~w1^Y%CYa<)3bwsCeSG?6;LFc8 z3e?(z_O?qu26O}R!{_b^Ung3vLfj;c<)~taKKXM=M5cWqaSbKtA=o0oseU!@`P-9m|zq1N*!+3qX7T~u~xg`9!>w`E8 zzq4cD^lKG?#iPpE`WonZ=PB@v${XVP5yw`rrr%(pEzYsXOI?x2$%oHm>rUgSy%Pp% zzh6kb6a%=$Uhmg(7@e9685T&2m(g|A0Ijl(j!SW0!UhF0U^gudDQvg!Jn^TzUfLv~ zjdOi|EiGS=i+CAO>uYs-Xv$m5Aii{IV^i%`GSHMP4dh+lJit8k8RUJaRtox%nIb&C z=I{#Zc=yr^7?=&W&gMoqf9`oF1(G--g?Vl{>399<0}% zfRg@UGL05mE4R)*F7jX70GGSV4^0P1b;}KLGSO2OqNuPM6#3suC~e7x7}308vUzR9 z$96OGGBE;x%G@GK{=)S7tdCtLE@Ju7DbMWxVn~-M59fA|Gg24)-f!AU4tFhb9x-_R zp9{+LXS;Yv``ZW3mfL;F^rMFRK;#dL%lv?c5i+^{3{(vWRLtnv3n`D#&t4u(PKf`Fkf3gUUXp zDh#n2`NqA~`FQEp-&oqJ+}VTV#BY|w%^A;Ch{#6Xsdl(+Mn;)HD`=5|Fqp za2i-_Md#p5N3je&e&bg9}u8DtbX1!0Fmbes3i&v3$hJl%>|ij{yVkNH#1 zQxS@(N=h=z_wPjwXL9qo$3EWM@XeK$kci7QeDM34n&6L#Fo5yp$d_LG8ys ze~$kvQXLs7LCBTQ#`0N!GT*s@9u*55^SKHH(PugA4nfzH7W!x$$`8H~UwXxY&{ITF z$&_*=)s0j{RuQ)O;{gT>UT?Xs#IMle_fHPxH7q1g z9_9r~4R|Ryi4m2%aQ9? z&$>0Q9Gq?=TV`H{V8T(4d374(Vt2aN^R6J3p9>Y*$z+sv(0E+$&K8#lo#?Q;1Or_| zx)JRUQ@C7u%PbXpR(-Fintl(KyaPSA6;>l8rx4V|5zepFC)j+i;VwsG84$`|{zJs(IDu!8unB!f2!QxG$lN^b~ja)~L$k z6x%VCrvpT$pqJsKZ{J2GYHr-JAL==y8OD2rRr zb!<;t8>V^v_YW)DiePpRIe_`%HcL}nHE~u`u%!2iG#{FqeVo19Y4J0zSHXGSy_46u zg=*mJ2$Mw~5dLQES?#;Mf!gAf1M%-rYjiH)2+b~mBe8-Nxq;Yf#H3F>t@U6Ad~QfZ zqV%Z%UrUyv_uRuP)7Xo$_F@3DLgW-i^T4%8nk?Mx%PX7B_Vh$@@O8q0YI$qi;My70 zPT`K@!=T(d`jdh4{E%w6R;&xX45AnVWMQR* zSEKwlWq=V`T|^?n(QuFDYXMQfiZ-EG?m!w5Q^qtd)?)ggDTk`7Sg08Qwt-oGqxtc^ zSb}ke92VZi(FibmKhZa(bdGoid&D}eh>n~r@4YGc<@`-QqQj(X%ziF&^C|BFqp-$W zowuAAsasW34|catgR7Cahs;K6_tY`178YyeY^hG}g286B9x<*PTZKLo=xo zQAfif3#;caDbZZVN~t{dbQnAGV9dPjnTE{-AakCa;g^`vJQ&TqF26np-1C zKz4@$u{-a~>DuU^J2;+ZHC*SZDYCuiS5dmHj(N`i>;Ytg|H^2Wz)B4)-tZTku5K*g z(8O!q3{5$sUtP~(-+0DL|7r%9f+)0r>bLDbSEg!VIIYKxIEX5_^EPF5ddxr-MtT9YLOY(OTt!zW451 zhx-F%^e4U-FuY{S6Ib8mGaq7j(g9W}43U#e;uadN{%neI=ZG@Epg9qMBfr|&&_5Cj;QUaPfQwUXymGf|`fFT z5DOXA_a#n@a<~tm!^5Zum-ny8j4&^{4NxuGC26#onB$Tc9Pht(UK5@H;SuC}^vWvI zIld5uiQdu7$-i z(#?;2j#&$H?rf)r8SVIylrOB;x}HXk^_ zu>w%dJ%y&0-}l^mb%iI5GXYhLcQHaqg43!6UcrUWH)0SV#~aL*u;Bz$G3qO~B9=ui z-;Efzk6AI+t=`0&hVd+l*|TXpjeGndh_th!#9^^#PoAI~!D4uVe_ zenrtcceXy6xAeOh!HUrFag++NUU2HVQBAciby>#hue=ulNC zi1V?C!Hry#ImO1)>;WO(1zCX5@?`0ryo_N*6X8_SWOOwTS zz!q))WtFdz`nX_O%jXwGz5@)Nra>o`6X0~0pldv_)u|}@B&0R%1UqRjiMQ_P*WBrW zZ(bkWflLNV>v!PC10D^&Zall;_7HNDa`_a3dLO{wUu+9aNW-xdbgr4o;oeZspG>TG z)`}H8`^o}<0`B(^ob3Q7`WWPx#;df-8nbud8a-5Y?ehHdfE>DZ@jE5>pqUk&<-~T1 z9sp>~rf30xh8>l8>!d}eqM0dUCJPz>>rudp%zE1%6`(NjkEwD{<_oB5nN*k>i!Pl- zw;FspC{;X@#iJc=a}{2*N83MVa8wPyj=m^+55ZR*#tWQRy(p9T-P@;B&`&p=r5Et) zwO|)YZ^rr>tFp!b;HfAm`4+WLzAo76Y=aX zeAyybGow{mz3uR4AJ?P*9AgbX@w>c+O034zwDW z!GYL%foJ0(btYgLJ4j?ZyU;u9iwy{RdqywLdSyQD#j4T_og=jd{&Nf#a1ol0$WN+9 z+)KY4LuR|DEe#-8V-Tzj>zRLWCM+-@QkCxKlz#~irA0yS7sKliuA4yyHoma_adJ zjaJ4MTznDtGK!1UnDaiFx2IRB;2I(jrJoT6{g=witMf3KQ0#P zV82wIe+jq(FMu~PLQnVUotP(<%X0KE;1y)%Lxeu+Rgvj~Xd(m2DMIh_E6>v<>p`@V<-e7KV<5yX0 z6tpV}x|q&e)2LpP%G;1tb!SfjZ0~=kOski|*|L`c5=qrxOi>Furl~YgVenMtQmV>! zwdP?puRBe7yc!`-WhrMVZijw5bb38;BQ>=Q?G8s|A&(c}vgPnDO4W8Bf>ex>#hJSStsuj$P~bE?f3^_a9uZpx1+HZp88ftNYY~Rm zbOLFSH*wkHE|B$WI>wa9ym9t)MsYg5(m=kTOt?U$0In%g8z9W5k$&qhb9SRklIq|* z3Fs0sOm2gnJQ061p6`fPx!`hL;9PJ*pv9WE5Z2I+!_0p}+h zh4v$V^&sREy=4hbl?#ooS2>QPgjxXcB0=J{>f@@B_kpf%`IZP)S0UE^SFCCjc4jQn zlg<7&Q~qZ!;(m4(P@T^qccUV)>2z864T}=F^6(o)kzLi13yH}2Y}8D-){&#>{lzo9 zhiX&sVh>~fNRwt*3VV+XJ9MXbydUvzJijeI^qqdn^6#rw(he}*Bzs6JT#bXb?-oFA z{aQyl)Yoo7OFI>XvJb)fOoF}Hny=qOWT4pvr-~^}#jb8pTj6rrUh!T(!m~_yE1~LL zU}u?XJJiy(r60-CY!Ac8wV@sUh;&_e+*w9cm6Mdai%LO5fbwb>AFlh;MRd?hm|{mu z#%xC=gZ+aW^xp=%Ev&e#Idk{OkQpOfl{hfiKE))C~4wBf;Rd{N&srVVw z^!s{|p?AyhRo6bY+jo0p?6s_ncyI*^@PFj`R)$FUc)DiCnw<#0kLx>~)eE14YgQod zsP?o@8N3R-8*#FVUA;Tjqwmu_kKKu?6^4h<8rMO>ov*(FM4fw&MA{+EWgrgmjwQHS z=>3j5AzBymV(f$Dx*p=C&Yf5AhF?`&a=7Ec;HFu zTCPCJ);#)YdHVgU%Uct$#y`g`{u6!IPsZ*P55N>}Jgr9L(qRaz4qQ!dSM>v*lN?Re zPXCsSJMUWw&6)q08uU9~#Y(+<`&C~fg&}=i`O$sk!A?MjK40h3!&JwUQekHKm?5FT za?zY&H^)nD4aN5&2dw+yIls5+c*mYybxdLh0g8bd{ zaEB^;a)1dn9d?idu41LoKPS2U*)T^ zU`vb5;Jf7rcy-jJx*}NQ(PL{di{~Oez5`=dttOOt$IB;RDKC2Lzx7DOj(@t{N2nM_ z;wH~8-zTbZ_aD&3(AgJ`Tb-;bfD>;7G0|DN%9y1?P0QDE#j2nVzkCZ;l=iE>#)14D}{m@*J>F z_C28!HuKS7!g2Xb*#J^PbL0u<g4D^sk=jcVT_+TM)xHQ7qwe3!LMnEl8u5o<~zdYuBf^T9J1Fp>K}U@aTC|>wM_I zt)6q2Of5@_Ia-y)CY9{xe|;tB%}guIJcHdw{<Cid{bmAGP$h`X|L#_xtJ`QX-X zo}c1+;p=Fs_Gc2z@f6p3T;|$5^No{ebbTIYKPS}jTv`KO&(N(|ohOLB2tB2gJgA^? z@EnGTV4cx$HzG> zZMXp5aoE}9#j;9le$7k8wMEZAYH+2OQKPoZyM^GH8J3n;%@43aT;r*^$eP*t%AKb3 zUazl{ms(nv%nO(H!(LFPl?p4}mj{*}pHj-reNlSCnQpo~`e`|9{k2oga@^zPr{Qlb zhk7vl%e(KIUVeIGDJj>fw6g#5&D-#m<9&kHg@6*RH(Q@pK17#%QF{B;`tA1OOqPOWm-)6>hV(1L71Xs@~a) ztfN2QSm%gc=a{nR=uuslwpo`oTnFrIzdNld{X@>bP>7X00j<(P+sNXcAb-?tC_mXy zvF8{DB)P)Qzcpv>8f~2aH=p)kTX%rt{@%v- zuUqO5kqS@B%?8a2mX0NE?e5$#9LoKN3dpfJaFFJ6pp02W(-wj%4{#9YXYKo^BONM6hUpK>&4x!%jt9(t)b+DVCsl~^ zj7s6t#2%?3UUMSpPmvXOzFf=XcXt*3+sUtNB8}hTxi=sH>-Vqo?Z{ZQA|ZkuM4D?s z)$yek*NB~+prd>J<9+%*NAlaBx61iJAmIPeD*60>XqD=Ia^nsDU#*hlspy5a|68ln z-7r`Czgi_ZGwU*4y-JI_|D#pv(myh>Do02xbZ4Isb!5kM20e4Q>kOxeJA`aZzStfc z!=zl?`tZimu^jIUH0__TIz$@+|A5t#p1mC#V|1zW{yOx|&8bq}`Kf8Q-S?A_DYws7 z{rm6d>K#?y1?Gz0qx!&l9**W}hrj6UO26CVL3XX|OJ(=6qVF@F4qXjxy*=B9$qe(r5d-LQT1@b90)uOI(c zt7N<%EeL=oY23g^CX|}0#On){NJpqw<7s;!22HW}JX)V!eS0lK+3m0}9iX$UXW{bR zJq=Z@V``Oz&Xm5i%o+^Z$VCVo&TIZ&-QLJ&BlPlekXFBzWpUQ973ku%8*gA(X3Pqr zS=3|CPB1?)(^uK**?CsaNg1?gnyg!Md;Yak%#7DUG#!7_bGy1gutX<>T zzRE$^ogR`Wj0+Zh!f!8s*uD3?gQbBm^DPLW*Xes{xBp|ehg;+7=#qGim4n`FFOS>% z)`6q!jMsPJxl=>(LIrM`Bb#oy6JFAXcW&WthabFpY=}L-7-ggr*9;V$ z`uK*K(SKeUlRUO;eyc8<<9;t1#a(H0&NMeDYf~)u!p7yNlVMrr|5-P!m2NEbtgxkJ zw**N&`>ma^6d2Ke@sf%%qU-Fx2bh;qHJ0+C4vvkL#++uM!J3^N!oy^|d1B-MnwyOeRqv-R?wD`7v@Z%e#7_&v&v zzefwbF#nSM&H34rzo#4j{rk*!Hu(rV=-gPPX3o~ncE;3p8B&CFNE&+a@ad$CIC8~ztyDOOmZ+xr};ncF`!zv7dFht?LBw#ni{M>{DP~MSYwe2T* z83C1t6q>0?Z=Vpl{#>VgkPyi4Z_OFa3ebJ7xR?zi68CC_;TXCfdQa+bZ!FLuOD;wA zR&m2Ct9~5ctsL?Ux@eGZ_n|+O{OdGOTivV1g1_L-Xj0X!`&9g@ z{V~RapI8Y=WK~;qv!c5C3cE6Q0r36_S51wa4G7F|cWW|bxmLVT-b|sY10JclE?gEr zig8y%i(>1@AAuI15574t8LA9WIBkH}S;vY}$XC@y5f_`6 zR^BfNNoleHCaxZNj2#-}Rfhg^HSUz86tudKS?o{tr>Tsu{c8TB^A9I(nsg|IvVv@=8?L^6n@jw>8zhS6Mu0Rt}ReJx45oj-Ip#YJ)E zO~y%iPQZJch`QICc7}bPRTE&qEC9Sz9_ZyOrSn%GM473e;V@wNrs!kcPxw(fcgpn? zj9cjlFNgZrFXGk5Y=iUK;)k3-uOGTrU|d^Y9x)@hek@$qGQtn2ZduFN#O;~IkbL*y z)`l#C_JYt5SWJ4569_QEYXS~*@N4iYL~ENspy;1vo@U+VU}LDJV-QvmM%{N7N5xo& zpr^rPWQmYg(AA~@s^&d(hGBP@7h(x{9bmb)Lg3vb@8o0}$HLq4m=4?{kw(&dhJV?|t3}h%&=wiH*n*!zO75 zheR9q*x&p4BTFxi#Gf{hMCkyqO_>buR``69{++Ef%%?zXwsJx+uQS80r)&ip_R}nD z?iH=z`g=i0(hLOPGc=Ex*?60zHhTti+h^W7xt@Kn!~}E{mfDakM3nd}r6m3C`dFwu za`;jN(}6kj1{krI{fn1tz57N^Au3VLyDWw0pEOW|Md910Q*_llv71hbiYV>7oocJ% zjU)ZCf|FO$3Z%rNc&JMd07D9nn;(B-Y^L~?EUG>z7W?&xMMYqA$Jjq?&3>YqdL#P& z5qYuUsq5mdPS;H(A8kLjF^6JLUAO8L-LNIQ7F6adIEq-JV zr#Ok8RfBIswYGnwzs+_)S$|_IjU-+*W>(!O{0E0j=)v1=?528RWv#%7eDvDASd|Yq z_@;GU#8Uw<_Hrg#kiP$(($$vINThR&^APm_DyE*zFZYv>OullZ|M~{c+5V0zk_FsJ zBTXuDI*R>ky-#y}}&!GzSAL8+d?YAL9Sr3m+f8 z4q)T?0_=_yBur1AwId!p_Tf4yIu;>x*#9#=4q!;oqPbr{V-RUO{a$jLY?V1P(a%riSjxCb)|s* zy*UtS!zdU5@BT_Gq|>bUr3NV#o+(w)Db)ojHJvGSb14nmDNW+3Ee5H4-;uT8 z)d!t4FABODZ}!gS(nBH?YL@h=gQq7iRkafiuwlr6#1Z9dGFT{pP4_cM6~Thz^vm7w zi^2dzm<-`ArlCT?t;#$b);A;pKn?&LIVrq&aApMaeC@`-NE$%Ca$gw&n}!&%sQ;k= z<)#cPwpd*!@CF5lmO}Zefjty}oq}C_k|MMbe z0`~ohf#E@|Fi`0})D+8eDl&zKlL3oJpHs>*e+Ui^rFhR@(e?rz8K5F3Gl3jiGncg= zA1{psomr$>6hw6N3Y-84PIKua_+)2f&>v8mlGhrYw}`kHJrDj@0FmWD^XKv>_d|pz zkO3knq6l_^^t+vCRCP8=DE{`3!h(-UGH4(bo6@ELKuW=A!_2eu(CfCSJ1ooq&)Ih& zyk#E?rbPg`hoCT+ca#7&B=c4k(!C$@^mRm5kAj|tAPEcJExlqJQhbSSIdkR4dJ$j;{{G1PKI)jnge6jKI?(41W4Yt;oJxAp8#JI*SdwxdYQ{mrWKVSbh7tha z85;O`KLtk0<4)%GW7BonVul1BtJy0mhTNHcR^`ZTgfpcmO!=q z=aO$r?XiJ96)?C6e7;?Lj2?5Kl*^-JA85X%+F67sW7bk5@2ywc5o=%&XbL?+y|TcM)4Kj8~*k zqJWJe$Tj2aG=W?fP!NbDQiR$SL8Yb)B#zhfo8TT8x?sgpJ#1D0V4VO1 z1bCjDUo?Vki2KQxHlnor(n9Khsd^I<(!d5>g8~^Zjbon*jT>c3U_pQOoisiE3?=Y~ zcRePPCxvwWvnOZ^0JziOo?=6b6*wsx`86NB@Vw;{y9K|~QWA$AvpjRv3bCG6O8rs0sk@uFH1gvl?j|Coe#i*|E0j- z0S{nWuzyB=DYNxL5L@OCjqWDis+?;A(=~BOAgHucLZ|^?Hyq*`x#bZj0ola|a z{2_JlM0CZwgG6elN>eC|2Gu6_D&b)dEhVd<D|gUm~&T7o8U)IPb0<$s^!;g1!_{Dn)qIrRxj$-1NLd~ z^{XS;6-+I=8y+CIL+Prpsz;WgfGU*C6XcGykoQ!5(A0T70#EG}=69_LORI}}{5y^W z<_@zM*1b??C^8eu742ZuL4^8gfDAuLu>0GmWh#G7kE7-IN$Xs zXN+6Ggo?wW01^+tLIzTVULOVx*nYmR2TFhTcpL^FAh}967TpKb0sRnX>ZaBDY?X}D z^?7Tm`b8k^!jQhYpB<}h1GEFq-g~=`U_$&BoRL(q;YA;q9usbiZE5O$_#m;9kpyp7 z0}H|a#MXgu>j06h(cm)=|GA^@u+b`~X!m}!UNQ#%aivh7pTzM-0vtH@RR%O-6tDqp zNdpMykcX~1X&k=vCVpxp-?t4gQLM*R5v)GYu_Gt2L~e#ggq%`r#4ifoyH-Ef?)_ZB zr~VThAY{ZZz!FZwt+729d4P5c(5|QHowh@>$78AkIMxOte1#IvjMSY8EV%b1I;l;p zzXM*@nB)Mul)_C|V~Bp(vC@{M+NV$&x@r*RyNM96MG;V?gbYH?_ zqW2dK|9(Eg^8!5`GqDHNgF{Flj{H{<^kqlP#$ra{ZssIchbMlx5br%q zw);}bE6d;W@A{a~)}Z{@(^~v3tv4_6XQy(^1y-PgmE*O$oN-ttKXeNXU{RI}2tOvm zg%j~84YVqqKy4ut2?-P(M!5AXs(I4f0rczz=er-)=^@*VVV9;b3hq-paKY8m3p_%x z<=2{F5dIE4`W^syu|QnyLw?%B=qc3O{idTd2l!;T&X7 zDdzhg-{I{!aLfnvI6TJ_(3yV*?#Ld4MU1-Rd!Sl{MB?>KjWJFW{{l;J6A*k``i^&t zyLn*-?VQ)4jB!Qu?NLOa8(JVrVK4tS*QdgdQy)UjF#BSU z@XNVq3p{`?3D_hpU6VxK*y(WRbl^TU!j`zotQiFD4IGCY=tTLPUF>~9MlSJZ48P;= zKORYNh0-Q2)x*u!Cfwh$l|DysHB_T`E+}u<@eE91w*^QA@`$wrm%=I6K*-)H__;e1 zyNAJCwtZmiBD(C|CWmWN>O$anXdGlT`IV&x=t6?~QeGj2R^ge*@?ozZb=_TKhs=}v zkdQfe|7<+_IC=?Ira5Dg4z=M2eq(@36!Wj5A78@;9b&;`7H_>Z8f$wB-j6V4At)NJ zkYy9@PGELvJJd|MtNZm^nO4+gVEV$?}51&TAW%KJJf!n6wGgHv36jrub z!uAHEzpRtYKliN&e5<(-W<4AHg)f_lVsMawKR+Wg5##GHAQmLzVaKP~vT7h3pM{Xy1!57?XbT=7mP9(^5B?RW{Feg#*99wh{1ysn7u!4HH0k@%L9@}@*Y$!LsGC>) zOr{Faj{r1(e5ilGdX2CE{@N6uP#4!+U z{pz3MI4+-E#|wmW&i7T=Hr;e|*1ntRbSnI!;8? z?kJb%9KWfX$Z6OS;DZ$bu|EDbxU?~K=ofi!R<6KfG3p9mDGDxtWyS>P=E}O0~DYL z7>f)(?k)U5%?dF~!SRk|q04)&R>`j~;eTnBr27jWoN8QosJAhI-v_7iQe~`xBaH1} z9$OWw9ADk1Bx_L#m7lpmJZwM52EX1|gybc~o{X*#(-k5!C`Z@1Wdy=m!vY6|^&_X7 zn?G6u;dOXlz(m3yG?kB936w*tx3ntxq<|XA z?f~U^S;pR6u8)+@uQRVz_WZPhD{7wy0Ux5fEeacNw>k~|#wUzvjTP$)D^27suLMN( zxFoem*vh)xef_5Q22W%3H{!(|phB$>j;7XpHoQYN7+6iqINnyLe?@OM_TOJ;Qz&r9 z!yAGXNs4+NCLc>&<_Asz1w$2O;$7vu(&8I|)#w}a2Ht~;S>|b}2EyYY;LoV!64Ysl zR{MPtxQW@_yUo^;$Bl-MWY0jbMLH8$+oXNIWR&T)cw||P$mj(0^h&Uc=fDTM+5*%?T=O_0l^WK68GV{ zq~>3YG<|6ZK6%gP$8*M-Zg$eDGJ@zDokRTX@}CWfOP_y|KWng@WtQ|`f7M+RPIS;f zTT%8hBB?xevpmg6722(*4I>DP7`|_NC3)rAXHtfMiQEDClFxJ(z(skfa$fc zrF#_|5(-jJ?-bURocr9La9491T8fTjY>dkqIm)i^`odH=li?pK^_!2yK}w4=#v#<< z*z{hvN`ClTc7iY-AC_}<|7=udmecfF^MxlX>)sj4A=Tp13+wBtGU|4t^lDkv{d!46 zVz5V&N65TdwDGt705+2>7LawA34Gwki;DxdV)9t0fXGdvX>Lp4soK2!f18K%I&;(H ztcJ}5_Y{09-xGC#ETSN_WS|-+oaBou4r`s<97$Uf{}#}YMO+VsA>uaa=W_Rn+d@&Y zr2Drn&ju)ctea9?Z1OTF=c>|wZRv*t318NS3v0{+koyb{1odj^7UKlWo1(fX(>{H1 z4Vji~BAnkymMRbN+)sc&LJl$jg!c({<>gB!KAeAd?W;5p<=}l!Vb1zQVadWB!;CUL zg99J7vI1p3^4Zv!yU%CR_i2;IB`~m)8BeYIcEjusp_BGI7@#45_bDQm4k>ta39<2k zPJLw@$bz7}g>U_VqeNOl2f#?qfaMJPP)$T|1U<{&W=e!#!}7koMcfQgIoB+kQonZr z2!*TpZ>2!;@TB!16zIEbn#)JNvF*b^XtJ1YczG$sp`}2v;k)0`qkU#nm_~G<_~3K+W37a%eEnwEm~%pW zIaHTt-lM2>3#eQaR^S?WNZG$X#dC<5cEfjExV$rKFYzPrL0QP}dLvS*jiZ&(NnhQLWZ%I92UaW2x=? zfZbK98N!GPOy$T!SSn67vQz5c_<`fAblhPGb>U2F*){J>`)-wytY`p8*R{pr$Yb12 zamebKQ}3AVqU^sDmj`@!j0TL{o1d&k+wtGD4qA3YiR%I$*G~ZF>|PWh*%!aX<17f6 zm!;Yj3@M4S!M{YCUY0*3k$Hw+dLZBxxZxug}r+jyjH!;P1Z))--L z36yRS@sip7v`ZZc#si6@=R|?JJUO?-)6l6=AqdM|fm5u3N*H5gR8-%LnOVCaQahVf z*AA7a21pX-^X>lmxF{WEAglO9fq_SFd94P}cV9Redd3IbK-eR;kCVW{jUUJbyZoI{ULzB;}2Z(9__>Z-Ncw9VS<_H8($FmxnjP61_>1(}3D9E}+@Hk5s5vOCuw z7gHT@JkC=&fAan@tJW}Mmv_~d3gjF@&J`9u;W3;ew^$-Ho z<#u>ZupX=$Mm^~EjqLa+3#n!nnrihF_%BNyS{b6r2{-8yE!kG6nAI^j&QC?)OXsBw zRV=vXnGanx@-M%jxZ#2~wujg^Y(rR$3NiElwk|6)IUi{Ac;fIf*7a4)+tyfq!h9B< zwa7Q!&}ul~l~GNV%cnd(A;`bBXVPrxzu`Yu@7QA0*H`@9MK9Fn#@|N{-3ihqR@*)5 zTJ|~nx_gm?OVwX$H-eLY%ugLw);rD-O4fSNV>r=i>XCXD=qY}c>!jTwNAP-f>DQ=M z$$pe>)7hJM+6$=yDKKSCp&N+i<1xR@^G|evA?d5Dx97Q? z*{r?ScjjI9>wnC$xk|KM{&DTX-YU;O|3p>Ko3p+!;8UjJ=tqffrz1|g{~0_{G+>>z z{O4S;{7oy(k~eQZWUUw{wLOC#_S#aivM4DyKs_I3SQ>J5|MS7~$NtViurc3@HGZkP zpM91+c?xyQ`%%G%)@SzUL!6GOFj-pdBO=sfu(fVRhjB-eVQmzr0t3#KCOZVsTkQyr zTOIYT8jGhNTpjG`3Tk_6%y@kjatNTEL?JvvEBR;cz4UtY`oDvfB6!G!zV{b&`XGn1 zq7y^5lS+0B#cv5;YBe1Rq8~`@?P^u{(yghqsvJI0wLcoht;_c{FpzyveW0}wd7bdm zxF@5a87aa8c!E~|fM3d7qfTfqGqrADP~SyO6L4rV32Muus2alnHxB&pYV-YNv$eq% zf$u8w+3Em3{zn`?SKNNIB5Re?cA&0hI9zQ3#u|qKB5n+>t^j0P?2oeaTsF_0ju(y`!9Akl{;YTqYKgZV5mBgi@$Gv~r-qHMPs(b6?&Z*KiOYL`wXYZ57j^pvY@! z{<;6y$cLfC)I8Fo;p{MpbQTj zf8x=i*=*mp1{+M-p=DMlUkWZFh}cjP(BaRiI>pd7w%m2M8kw0!mj}8@rG3^#(B%6B zpmR8jYIR0_RuEME7+eu4h$<{+-uSXJEuc-*INAl<$<12^0z&dK&G=X*CObz`3Yv7S( z;{dl;;e}a#6NHB1IY&rl1)#!K9p>jcEmu?863lm=4rMh_(bXE#1#tmSA#Px25UO*= z@(%I>YmdEXmK9oo2|@&eGV~$ByIbk{+q(JO*|Lz$ChyqXnf9Jf#0+u8Bz&VNT77M( z%w^?}S(G&&cjRR8n4iKn-qFJ?6=ldz+IP zBtG(MybOivFy$SxZv}3~salW|C70<437L%b+u=V{19;W4t4T0N^t}obW4O|_74G%n zR*Ds${Y3j(J-D*E^%$hqKQxND3j2@~S`84W=`Ctogr?vJ9R} zAgGw{teoxkE?4xau|uaU8r~bV>SN(YAf$3=GF7t7M3w{~NKgcisrHL*Hy0-}(jNTy zl(7zjg0%xYk0p5y>LOCt6Bx!v4#(%jt9;kjdOyKRnGV{vcgK=8bzQ}Cg^b_tduB&^ z$*UhZsIHiO$b*SAs!Y}io@pcyI^-H4l2%#Kj@i5_=<4Y#LZbVK<0hY*ncj>?qO&mc z1#MrM7`iUywVUKpF~z3>&fjsu51l+tz#^#c$6pRK)sb2?cha7n^l5*_JN6vS*gGQh zre@aTBpr`%lYo#cDjx+^X5HaEfTkRdlrExZzsfFv+T&GUz&++mYxZb|GM}0_u9n}pG&U)SS{zmOYjZY1BSxf= zOe%^kDO@_5SU#UsAf#1!yy@?l2-+t@*>#kE&KcnOX6`9r=JVh^-I-KiI=+xgrrt_a zgXu7Ki-0qMbbrw0dMU|B`c0#!!|T_**Du(L*`Y7Il+5sS-pgVo!dB@tN1+jE2K20~ zV$J*?AK%HpvlA!%j}hiRTKP;%Cz42W(Qg_cr7E;6^lNp-RnLi5RhLHdWck}~KEhN4 zrl@IAT^XKKs2roT-#9*8UStGXRB!LYsa=XOe8T_Ys02K8x$PJPrdowA@tKz$3TmVhVHXWQwKY+1t>IVwLp z2T_;e?cerh5hio=qCVuH^ZOo#!}e~ zu0Z8B!@@{DXAXJe!s8=X0#-~^g`d|4i6`#!@<;f)?Me4BCi$0a zY4kCQAAd0YymE3*T43IG{ijbD{}$tL?M#GkMZ8i{*<& zZx*vytAAjANuh{Ls{CgJ5cI^;?!OdXYxHR>+SL7IQ`1TT-KS<55SgN_iPtQSBl0C* z&?@xYjov!>$x8PH$ESw?osb-kQuF$BCjCWJ75Z1id-*#hC8A9pJAjE)&0i~m_+hfS zhCemqtbZfLpj>17I z?dm_wY~4v8nVF*z8yY75!+Jqa(}Q%K*ir6^Nd|Fp_>YAJ2Y2PsZcId31H-V2e_FxX z{P^jl_2sr-B03G#ogs?|fn{aIIB}w)2o>_{DY1Y+-H<|`UJq(_~{cAaDTuz{V(UfH_?sGobCCh+1 zTXr8-yWTKo0I(4M&iVm_316!39#@(4RME`?zLE(BS@DzM@;IULPk&q!*OG$L9Ea3c zpE61-qVMvD`hUqLm1S^3|2Xpf`;zF-Nz5cnWT3tVft#Kq2w&_ISi+KdZst=3AD}6C z;$osR-U}LlfM%Lbzn#f3A2KC<*pmbP7N)yRY-X`e>vYmCwx4^v{i2{6;Y$hLd-?j% z%c`JtxBD548u#a>*tlddiYz-mfz?YZTF+Nrg5N+N1md21#U-#qHN5#ChZ20}$oX@M zHX&a#<~Uh%4rdP#z5HfYztBHw%$*2v(?LZf;bA?q4Y2sLYC&5?oisV++lu;nkLhs% z-bjF%D0P{EK83Q5MeKP|9*(`OY7sS%`o)>7e0$J3^4+a-S$OKJaOu|!1{AMcV!olO z#K2mhW*=0*QPg>4>IXOww%wgi%=Dh}zH9FKC~IC};HBZ-;))g9VbcO-Z4aJuRPspU z#nYytKXOnPGYlg9GZDmJDO<%yr7|v_xbwX&G3Xcy;fx#=2Pqk-ig}2jA|8?fJ-^_FjMb<8qGP!s<6YzSFUu}rvVah~Q zrW&74wb6ieSvEe*uIse1y}Zha=mv7h(UXao;ph`1+xg<3td$t!KenE{{PEx-IxD~L z*e}P&6DE)8lZPJRLZd>JIkfxs3bFQ$B+`!HW*=ljEhH$In3Hk zk(bAd^e^PCL#VHlPo`TF#4Qnkqw1-E2Uk3BV~IEZE`L6=bNF1+L9v5TY(ik%6DJ62 zvXhTs5dE&|{khHEE7ot(YDXN2?w?M9QQnN}qC0HgiW@u2pLzct`L9m?hFmabZt2DE zmxr>1>EMO`cK?gGVLF1-1&~-b0ujf5T*};V&Mbvk_e|72S|DbBnPug8o~u*rmkwOA zU|5r9XrIY@LeOW!HJP}fFgI}k8F7Kz{`Zvbc0;7FEmuHxsu>fX6q7%FMh7Di6uPGn zTyCC@3k^)MF#5B41+fpvqFFLHFd)~r9FyaBwNM7O_eg~y&-k1xR%Jab{avB>tZDN5 z3=>)8en6t@%7-LT-AX0EG4YQQLr{wnV*QgJ4&WcLA1W7vsOqU4FGQw-Qe=pj{M|w$ zecB!1u)Ly$fF)iT5KcQlg9{MB%u3+%^VF*5@?kS%36#7Hae+_>?y8>+3hMeXV^eS; zT?7ICNa5OP_^8nWSTk)mk%nT-*>l?JojZCDPrGB?mW6LG)kvO(i{-RW zRSN}>`+HE2eQIu0<1C*>)B=R1F37cuXR5!e^PCQy)vbWc{u9(S=*{@AzsJx$`; zqI!>_Pb!1mMd@MO!)iM^deIyN#(LoYoNP=QEitc(y85N|_LIT>9kXQ_KJ6 z)N{zxkLNsQ!0+e6o|Mnsn2S^W3qTavjOTeTKoEHZTj|>Cz9eDQ zv(c-CCBJonw!Rn|qV#gC8PBor^&pxrW;R~HCAiG+v(S|kXSXaXB=BBhzRX-f{mDP$ zbFy?64fRiDmFB6uzme%;EWc{8@4S4}q8S5rBc_CC5;$FaPruXuJ`%DfhNB` z+6*OF>rttLJ3PH##dbL#s4!s9u(Xu4%d;dn@Yjuc6qv!@;BB^5Zfe*5`S_{gRT3RJ zBix#tV~guJJu;xKEQF|B2Kjce7DF^<7iowW)ei-#04la;g2$8{Cn%7GkdA@?dbhl7 zJ1L-K9mT~96^Ci0fI2;8V4?wC;fS-6d*`YRc4nVFR!fN2f#nx%fBYJ@oXV>i>@Dq+ zYyOsH>?pp>2swgs7m(#GatIc@hF>&ei)ZSOn9(Uc=F;y`08Vj8P$owfaA{`gAbB-Y z$s>Vz9pE&C9W3%Ay;qDy4SQpEE&T|w+YY8L*u%c~r*%*P6=r?fAzu6`3n8fzi8?Bu zz>RZ~{V;SNcS7@gFM< zx8(Wl3sMCxb;j-Q0paSqY@Q?B0)yyMsOV>EnJTtlz>)xEWR;f7ud}SorXcB&Id>)B zD5Hq%JZKy%MuA@i9bO8R*+;`D*I62VA0>n+56a#WcTjw;I1*3c!6k=UIo+rM$J<(Q zN1uhMx(V_6{($b+z9>>BAe>4(Q&!_%uPV~?G@(ASt=8``M1;kS05&z&1)H4q>aCe= zuG-73_3=cim8iZ-UsTkL<#(WnpJwAKPPTVY>CIKAPxheA`U)iM`#e9 z30`L-4EM!>3G8?^w6nE`c6rmEx>~>cc?_@JsFP!VPn&-W_pOEk`kj?~( z)KcN{d`k-k?g-#KTMo!;O2A5);SRI8N#^Bvg&s|e2P^(+HyD3F#x>VM z6GA9%M2XaaeRdv=#>Xjj*CW7Bc6x^Z$}PpZ;Rzp8Fdy9?#I-@aRY=>uxMwp0jmf9J z+gWzTt)KmBzEQ}u*M(k4r{ZzhW8?&Nk6~IADxb1jS>>;fy9L^ju17NY56L$G(Q+EU zqroG(mI4ol24y(dA+=HumX2n)`IOSCV0+5Gih{(#D}furatot-bKddQ z#YFp%Y+;33Ymu@ZxbgW#kURCsCAGhok(qmH65S+n-BSU0S_>+jk`*m9h$OjWV;s*M zP`DUEWL&X4{)Ll;`9xM}eo?~GHJPk&Zx@da}|*2voFr51gAp-^>;v<9~!L?N)Y^1{cFs9wTD3;4&;6L4|_E5VzrgVrpI{s zOBBSDRW>9HKREQ96@IzEI5dp4`(UM>`MXue`PkKko%!)|LrF1W5jtJ+OMDU+>uhd= zUw3QQ)XuwRC8vN|u$}q(ZG$P}%?Rkx1xdJR!nDM56v0$};$MbNyzeyT{yX2ZMp~_Up#!S8h+o|BJ}D>E}}j8peIBKVJp=gRQw_+z)Z()SuRvt(*E~Cl+_Pi#tD9 z6w;Ynm^UkxU0souy5wxKJ#paf;&q__hH9|T6=1xa(J-a=ZtsNRg$|vq_X4!&wXZ)m z55CY7;rmu<{KeL7JnZ`Fk=RSl=hZ`F&Uc>#zGsYC9IVR==shXGNNg}`ymokLX1uEL zhqKTT@$^cqWB_ZtTnw9eZk!G^~ToF6NF^J$wbcCJO4~3{_2$$ zmkP!=Ex<94GxgwqgmNnt1m?D+ta_kBkFDR&OTqI>(Xv*R6_%CJMSB|Xj$Q90AvQ!C zK8Y^2?u2%pe23n|3YsT8J#J|yMdovt68hy;AhBeL!lHleVMPv?S?{vV`2w)>?0uVy zHzT}%mcILuD5*AeOC%O2Zf?1$1t&#&SNa{u+JfJ6UgDF1?kz)4hd1=)m#%D{7rezhMeN)qRKMia62;T1IxLNLeoW zjJ1xDly2T#hp?5ZO8DAhPPlr;N?n3Lpp3z#CkEzwcMRX&mB@_ynX`lpUrFQ-Ol~T? zza(c?a}4}9bTeXLh-LNYF_Fn1Y-Sz&89y>qSGrfW;+PnxcImF=r3z_n`q$7^t*i33 zisjatmTKO?wha}k?kOv2^7c+Nf5#nku+iSGqYV9Cxog?yuk;Qt5t9!Q)b;N34QpQl)2xf>&Op*Bu4# zZ*MxJ5;W>gdiTAbk^>4Vulwsl)TiIhBD= zQ%*pu@Y_($&i8>%iu-U08d5M+p`2WVn?C&@{Y2%{Cm&VF0J$jLNu$l5!$O+q`8bkBC)Shq{A}*TUgHin zC{?|kLQmCg2-S8}Z&?jpRZa-a;!|k=SSfLs$HKg4Vo(VsHw8xr#EdZ`nb?-t21jnXm zDbm#y63H#DrRKxh*VJ241}*FXIbf{Lg(y&~`x&9?pVs|UD1`4?mBy*%z_mgt*wofA zv^Q(@)MPM}g?pQzHl_1L*p0tQ(yn!+Y;~LuIFe8by?L-!yd}lpdfkAd-ZRPtG;WEW zoqBLMEz&{r>X|HFwOLPXj2?HCw1R(%Uun}OCu>}q8#>czuTj&pP$(bY#7~f=$wL7J zxCB()>=q$wlq;y(3mlbA@QfV6rAtMk<&%5|=(se=ZzIzQV4T6bn1jp7@00hL)7LUD zZ(dowmHh9|T7Kw#h0qfT5Q1>6U=9LE1JoRq4FS?MfsTa<_-6aN*qzP3-x)icA(3}G zTRloQd%lc+0HDAy{qxqxqT4touf+%+4k(QfNMlGbG!?TeAMarB@K%Yv&S=652c7l7 zo8vp250MV)bxqKT+m}s)P`cHecRD$V7z+>-&1)J`J(BszV`y0%JYs$5D#Q$9&h#B7 zTMZipnb5FixC$n+Sj^68;)Qcaa3FX<^i?$&7kH{d@=u^ewL_(93%1IJ4WOS{_PvWlT+DZU9=)O~gRBR)RFui$L$R1Lf)IXO@ zcoG0=pendE8FvUSB&Iq+O%(84H6!8r#`x^9;Nlal_N|n&o#tnuwz3a6qkD?6)uD15 z$|D+xmfp|O6-eK?n*?ehQzbk}iY?0n=!)6_4i?zKXp-7DOFGjT2E4}-4d=8#XjpQ^ zw9vsLo`#vu8kYGoaH<#+8!tf@!POHK&D@&!w4`0J!+bTcrNW`M)r9AHOewaCj!-x~ZYnG@ z5JEUO@i6I)yPc3bYE=vo#shE>E9dKRXZyJ;4tX4!YhI~4hNr78o@DNb4$*RG;l5~L zVaC2{6R6h5>;KHa9L?c#yKJWA#0;j}aajVog*?MEkQ%oqA0ce3JEHUVDpO}`=3dz! zCF{3l*!YAf!*<}+GizNTj|XGHu!zTpfhOnNGFg#-K|{-TyqFo7@7Q6=r$Xw5#dXR` zJ*$+SM}T13o{5yyk0dA_XrFe_m5qc>TYPq?dO;gn?&!hY51H>5crLTr`WRP6cx{-u zAr^eMHq>fNH#5ZnF9hV1r7YiuNqI>JOTP*j4!IG;DDHKZkRHv9cQspba1-A*l{iv3 zv`{?RGT0EUcQ$guUN{{}Z9q;ZSgJ2P{kLpw{G+VO!gq-r_qo1L>l`Y?m=A~)FECsT z9X)eQk!f#v1t+DL;dk4@Dz7H^ymJ*^PUstJsqXHclr0hnbH*H(7P0A9F-#!*aA4Z= zCG1>=KN|70YDg-WCx!a#vn--N7oxH6V;O9ys+c zMoARr%PwBhdr*ed1HAp1LTVK~6@RSqjz7ncCuK!jvGgLH^v`dhA1dx3skc*KIC&L# z$=8HFR(BIRx6vNh0&$^QV3ZVkh!|qdIwRT_NOMSH$yP zDS`gKU)>+k>sIedpWdJRb(e6&&R>hyy%YLQf*0 zV5ohw$=uS8)|WHEzpywO-VwyJz^4^+*=>4@0l#zD@p5-0_UrF_a^L3rh+WEqbfsw2 zUB$X>liZSc-sLg)_m2rqw?6PKuZ9|LIW?N@ZR=$PN8h@>`||#fLJ}minAfsq{pQ5J z1J0=vhb^Tl9>?sK3?hy`D3=hXUD&w?CXn^#@+J3AL9bzLH>|O#iXbjGbmK5pFarKK z!pP;PKuKlPF)JF1i@5=DFlUr`o}@4c5hH+i@t0HGDbOviVbSaR=n!!-L=KSRqk!T1 zG6Mj0rk^ zxN>Q86Da2=FaQ2UP~c#@tvXqKX~os{x~26Of= zQKAlXO5UgjzY?M~Q8%8Uq;4q3@ifOktz9%d(+A5SC?S_yb24T7&%XQx_OGYsN2CIr zG=PKbo0XXkjXbnYb-0(&U6vw11)ot55<|#)WbX|6&9;D4s98#MHs3k@oA4{31RG+6 zN5oD^o{on2iSc@gxkOY6I*VR|&qL}_Kn&}6n-FAYJtJKi^mvla&tM+Jg4YRNZ4m%~ zg;da)z#gav&dEGCIR0MQyY?4dAT#5wa~hOOHJ1{4oguLPfDv(K+3`~_l>|(aD~t=X zT1%FrfVxoM@10Q>x3e!AoHZ-FCfbrK%Ym3-!SlJ224UbaPZw7&`e7BR^I>3x0?olD zy)!yhiVM%N5q1d}{3%JlFkh4V85mM7a+>FnLQI7g0L=t;qVrYIK*4h+91D8QL8MBd zhd4+PFO(QevKS4Z$&4>_5KtjodeJciAPo&rRlsXZSQLwo8Ft`48UQH;Fr2`9Li9Dm z{Cx(+$34M{hsBkd-1uCv@|Ck+`qM5e14u~RQ8IEe{(6g9VaFfs)IJW~I- z@IwNqbkFNqg#1w?ns?6DP>B26V$)C(f3e_eIPj5EA-`wFr>sER45;YK^goIO67eNk z{pGMSF1G;itc(95gQqz*s%Cc%(Om-nWY3%B{WUy`i72UZw&XsuU}o6}Ed-Xp^Ltgx z*h69si-MZfNZ_gvnfX`#lX`^py#@y!z=4_z!dZqOh7DZyGOh>irIw*m2w>1lq3iBR zf+JFGk>Kl@I$f>mo|m;b&U`VeHV9|fL0utsFgOa-Cd^3_2}MNKyXAc?;j ziAe>ODA3gzP!9oYy|#(sR24fT49K988tBIhD3k8-K%7o+Oazs{t6sNe${ZM&rX8>b z>CCtGpH0BUM3@%zgbygs-MisohZVpe4x%o;6(}W^EJ0B?m_Z(^fhT0L;wJ-#xy6HpDEhHISxZ3(Rx!Uq7r$I$?Ev3)Sy%o12#%F*66@2j3kD-t%3>QSrX_n1xq@T zP_Hw<1+kAO$8pil8Q_v|`Jp?>C+EMqhm2ouoeVOXZ1z~51T1nt;q&>epa!#x_1pG?Zs z9&!MuSbl$`x)7Ny#-P{Ukug1WFqq1dI7Q(xd-6m`VE>*1xF+SP-wW=Oc7jdA9msG` z^{zvo2fl{$d?`0`br%sIU%yWG=bG=uViS@qDlZYk$r>jN){`q-)i40$tBUcgV(_hO6 zRN`kv2S(wvSKgoN-q?*nm*B+}aFxH{O-evAs2ic(hPZ=a=ZcfM=}RV5T3sSx$R`PyCjN<|aE#1?Cr}V+qTg zOtb{aEQA+}OZ<3R;osd>hXvRT$|lx)%@mCLIn6uW%}X1B3AO)C12X}?A`fxCXH#Qt zK3n`iWRpekzAWexjN6Rq2LPr3;7fj-VeHzN4)XAO?`}h$fqbLP zTjBi!Wnct#I3%@T92M8Y= zxzAeW3p5G;uOd7E3F~liUy-09srvOx+;{JEMn2_3GqB6I*M)N?1k0_V!)q32=Ra8B zP!IljQXl=+8G46;4Sx6{BU<=HK=qaz1~^87tZ*ytz#|OotER$BWM`?@K@~}NsGbCQ zPM`u=s8qJf&2xVB8YqCY%rJx^ji87|w8k1Q8{3Y2Fk-U(M(hK0H<66)9qj&j=i|aD zs9j`Y{?omht9GTyxMz%!ACxckJmDT+u#5yAW_=zl5cOiL#z>dT?sS zkA%ow%gcieAtOX#QlwjH=#4yNhr|Sm3ZMDAY6kpV{P}YC4oL1=oYQ8PGwa(`({FrL zpz8fugeTG(hnn2c0gn*KVG9|#$&&7lAZ%Rz;95HNLeE3*+}sN>6-IT*W7^@1i@TsC z1HoIu1`V&p$d^URSnINe(0S3VgU@F{<2UMIMCY~rC2o5hp2!50->w;(SpnDpZ$M!3 z7t+T4S}^pu_zt=RokKa^C1Nl*%Pn?*YU1C*w^U3VP=U$!EUzS@5EWR7p5-_-z^qGZq4M7vJ!YhcN?0V!-9&9FBL2idW5fcXwHzh0fw+I<0vDgb; zbXpUtNSY{bXMedg^g*^#@Q?eaKWy{hvh9YiW2uRtT1knc56FN0r2m^2)D5x5`@JybaeQi3?v4E67-lw^@Pi->^H*=Dt8W1?J$n{ zvBE%mD_m7E8fe77C6OROSQ7#V*~w2{>%Z~dg)2;>0hDa2B|ty|cpe1@n^FKB0H0{4 z1I^15w8O+*=ya_AtDsYF+B|8SPirSfG~xtSIvUjkY-x=|EhJA$p!n$cY z-!S)9(y6hO={3_O4~2rrT|$8xld6 z9SeV~nrhP(PN$>bO$WSBT}j1B3DLp>=upqu#*%=XpV&2UQqorZqj>|sd=>3P6-%KRRG~umVU4Hk)ZA<+`A2e za0YQw{PjsEPCjFa|4dO)1YY3TvI`T2x2(bVqN*3$X(C8r0#Qz$lQi-6lJ?0FN|?C4 z)xY}S7TXD{WN^X0RT4ZaBtA$Sh3c@fm1Zw)d*shNsb*wWn%0}|bw5#BVSiq8QX0QY zKCBU8880jFORn~CSaQ0R1ZaJ5+4ZbvYO~5I5GkZ<7nji4I2Jq$m&J9Xf(Yl}ok-$w z+E~XuR_gII4k7O67?ot2rCf24BvtBYEAG`eufg0ua@*_DX(81LHd1>~dn!+7XSE&xkHqH_bzGL58c1_IdmEiArkll~x zk@i-J6Otz;=sq-w^P~@9n&KTja6+|=!<%hY)LZ3xz3J=7@9H)Qf+ks7_D7Z_K_z8% z=vG*zsyskJ?;_leaGI|8G|&_(N3(rK+YGFkik^g@+@0-1lUhM0ACl`g_3^8WbUGR% zt(|XX*px1G8e*EQz>2ABq@Hx-G7)R*o|{HMsPJHb4E@DW2LUtVu*dGFPa}JR$R$o%SSs=)3ZZ z%h05@?WJ#G0O@SbkKDChM@HFfYFRD7i3#i^vizj!C2-xr!*+A5=N6SX3sk%9(l4*C zyhvOsf@0k&E^V0nF8|WA)q?eHQ$15*R-~L35e2WC`doQKb?g&h^Dub+sot-ujj0v; zuX-%r;}nT^N+!!ei!n(`3n)dMF0*yKi(IN-7yAB29=0F0V?lq~OWXeo?-rwbsZ3g>uyzk^29>2)t&ieypc|kFi%uD_C4LDSc-`U2x8l}bF&8ij7xJQp3ZbR{R!-KSpGaCox->q;Qxq#XM6};X7~sv z=B1q_^r*5v#?B>I(T`mc8N0j7Z}!z^ScdEOd#mJ~8`;v--GHSh%fGhHUoS&-_;5jR zw_9C&{f<|6VWh+8H?AmE8Ge1<>!g}U3+)NVhkK?yi%R#%12LP&>s((#4W8|zvloBZ z&LH4onT?=lgX~rjHvjf9^Fd4REq9WB8@cr)FSTsH&5HWLE6jCnnD8COw}8%L8_!j7 z&*J7$UR8tLe=cqbOC_C^nZ3C{dJczSRdMRlClvqka##I@59i+wHHp4R3+?sqGJy6% zwr_rCyWTlmdBgbF_UUt^qUpz4cbWct>zzO!bo6rm@1)$5ugv}8CqtyEqG=q&4jxTT zsPjm{vmY;np2X=hz+igFm9gv$hc{;|D|eZy1jm~0wfU~t{h|vGKPXWmwnSpK)>vLvsO12qdH_#%F>{`5g>^p= zUeU?7Fr$$#FM00Tl8uw?koOXv=T4=Q^F=xyynmOCRC#hy$9|?X2e3w)NlfTzo$MZ?PGB{)%lKG zw4PwR@%E2(s`}?W1|cPl>yqXn*b+|=3ZxH43J6Ek3up{@30Br8fK5(z?VeyIt11Rx zFc^#*U#Ke41&VC|RO=w9$E^K$1C2Bh%~JUV4ko79tA)IQHTve*kS*Ox?M9aS4paLA>FpHzX`hnSynYfc77FYMaJWOPz- z_#X;PwNGm7N5g*zmrh^4XrM7v{Ofuymgz=j_;#S^xM6?$f@J-jITwcBoN%a%HchXi z2olXy6qv@s`K(heM*?7RG1CRxbK9mt5QR-G*P^JSte(c(}QW&@1)wt#6ab1yLIJUmPgISmR_VS+uRnF2! za?-d{u5L7vcEB#xFw24`##b)&jg9_QkQO|rYee^4vrS(%KOyP1?cF)%N_FA4oGlhG z`+UIUL55-1&>OviWmhJXKHg=&XY;z7yDp{X;|PYk_ZIzsAH@z0((42el<&ATGeB}vHQQ(po_UivMcy7Ui|2Z z@n8cmt-!VAu0hX~$L$bihbK&D#u|_{r*7pO-a_A1oJh2B&js#}Ae*W~+@Rm*R-zxT z_;@y5cdcG%h?%?)ugWj=gITfZ*EPU(jY)Ba_|s_2eh3W77)eW=f5@5!btJ=}>m=Ps6^U1mZ6pBCHMpDiiTnlO3yWJb*mctxt`&}oV>cY|+@1cVd zt@mhKIb!d;yhiHhUpCOf_Xh`g(724CH58TTbJ#vROqLnOMeUaY54(D2gN8Zfo@|RU zJvY#>sa&iIZY_I}3O%)El%DLYkL(5|b+HMPSu`VW8qtTwVGxf_1=a68yz9{_l{*!} z4XV>|zo&%wUVpBdVsZx=YUZ1?{?z6WIKJ*uPkI_)Rz=LCvexcQiwp=Jl2Q$2)_hbKgA+I`fbVx7; z4mSm0K1{EW8C1v`Bj6Nsr~{R_W5@BwKAH#*s_Z1|2J}hwWql*!!$NLQ)l1ZCr`>tr z(Tx|X?*c#fyf|41o=T`Yz?sR_2^t8WptFpJQvGsdJcx^$z+N0YhG!L%!7v{!%` z7s14TcHEGfW!-b_CKqGY_~VIydMGHb@rB&Ijwp)2nZn?|MCtk4V-`b#9ht&I2G7pc z`(D1nFZJVIsqcKkPZY4xiLxR8G~#Zs8~iqAb7p31DdQt{*G9n}v3Kac*CA!=qxAu< zJ)vN(J=3%GiVFvyA~HLDLp1IC)9vxcx$*CEnM$F@3nz4*2R(a>d^8j?|5%LoSh@8E zR6Qm55=HR@LzDVnlNkcmN5eiZhkU%j6hC;QzKT&#@|;xyzh7*}B7ozq*{k=8Z<~45 zuTeS|bLZ~lo^S(y+?)UWx`iX+@oPwI{k0$;=30Cw_^N;YR;e3+6L`#rwQEqfuFvOj z!e(Pov)>P}YT&lA%4C*6a#glqkw_$6WT0QL7Js1I2lItZOoZvfb}zgj4s^#?E!++t z(J^CC`tLcb?W#o|Y>k*{J#cP~a;q!L2Z#D~il>$>;_8#XXIF<8zr%(7+Dq0~b2c&( zK$BNyjh( z2B=86{A#!;#9bQnSAG{T-9(3of+V9K$N4d1hMTNycDQ7qbWCMr=Ty(b#JgrpzI)nifhYU*@N`8a|OyI6_=?$@?bQOJ91mW# zM+3{K=rz<$O_Uq($%TirYfYfe$fp-oNeL-XId5*BwxhL*TL#edIa%rfaFvWi2E`D- zBjfHTOuC{SPR&tg-nxZ@hk}_$5ENN1O%qRhI8KvYrs;69bhbq4t%)iDG($Z6k>lqF zU!QfjPbIskxi2q~9GU*1%&xFQU6qJaw`n@;B(lZ^dj)Am7AF@`{*?%HY!bL~A_K7C20! z@Ku)#A4>Gcf5Ys)ep%rqGw^hG9q_jySgXu*_mlCJWoX5&3dWYZ;^`_{;2SjMm^9Oc zwMt)G-9|6ERx!2=!Nam-#C9^wpBa`;HgadUuC2iY*8T8w;OAOG?kaXCnL$_++4&aj z!4MJvuxHopGE#npy?5lSQ{(Bb6uK*kEWPus>++h6Op2^AS#|&VyyKe1t92@uuC$$k zYvB3FezRk)$?pWk;>tziK&>aKy4NDMrN7Cp9>S=A+cu8O1G|r?dK@u8V0N7#W3Dn|!0^fHDP+W#LUC+L8dwemcu&N^TO0E~Vhn$#+3w#6xDaqm#?5!; zEiGU*@X1#?kVe?^C9x%q*7Is@@|biQ>Ypo2>H%iAXGElyG;Eql8h&3qz`Snnipu`YQ~YUh z^A}qs`tr`GqpHWdRHEH=ew_bs;^u?JdI3t$*^{QH7fCw5?-Vb3_D0?p_{)*`+jmRd zoxKHO_{oW1NEE-Z3NR1_6aZ(q`~Mf@gashT>P-VVkh*gnv9oz7U)D5Xj@x;DxEN>m zzaVGPZ}NGuhy5SO z`E>WK!|(1tfA4m;C#Asr!H9H~_fa3-WdW52_xhgHRDc~PW_>5zJk|4i!nOdVDCPUc zvgv`nRU3PcQF+5%>e@Y-zyEA$?%dg9Y5AjX$w)dpeHlqSa2nL&zBtWak|<}wAMa_f z`Jo%Xz+l|oGZ6;&#ZP3&X6r=y-E`W-0iGfthYnWnnPwV2iz_1+{Gh%0Da-H5qQkUQ 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 diff --git a/docker-compose-cam.yml b/docker-compose-cam.yml deleted file mode 100644 index 1ad19381..00000000 --- a/docker-compose-cam.yml +++ /dev/null @@ -1,91 +0,0 @@ -version: '3.7' -services: - camera-simulator: - container_name: camera-simulator - image: aler9/rtsp-simple-server - ports: - - "127.0.0.1:8554:8554" - camera-simulator0: - build: - context: . - image: openvino/ubuntu20_data_runtime:2021.4.2 - container_name: camera-simulator0 - network_mode: "host" - entrypoint: ffmpeg - command: " - -nostdin - -re -stream_loop -1 - -i /home/pipeline-server/sample-media/00-coca-cola-4465029-1920-15-bench.mp4 - -c copy - -f rtsp - -rtsp_transport - tcp - rtsp://localhost:8554/camera_0 - " - depends_on: - - camera-simulator - volumes: - - ./sample-media:/home/pipeline-server/sample-media - camera-simulator1: - build: - context: . - image: openvino/ubuntu20_data_runtime:2021.4.2 - container_name: camera-simulator1 - network_mode: "host" - entrypoint: ffmpeg - command: " - -nostdin - -re -stream_loop -1 - -i /home/pipeline-server/sample-media/01-vehicle-bike-1920-15-bench.mp4 - -c copy - -f rtsp - -rtsp_transport - tcp - rtsp://localhost:8554/camera_1 - " - depends_on: - - camera-simulator - volumes: - - ./sample-media:/home/pipeline-server/sample-media - camera-simulator2: - build: - context: . - image: openvino/ubuntu20_data_runtime:2021.4.2 - container_name: camera-simulator2 - network_mode: "host" - entrypoint: ffmpeg - command: " - -nostdin - -re -stream_loop -1 - -i /home/pipeline-server/sample-media/02-video_of_people_walking_855564-1920-15-bench.mp4 - -c copy - -f rtsp - -rtsp_transport - tcp - rtsp://localhost:8554/camera_2 - " - depends_on: - - camera-simulator - volumes: - - ./sample-media:/home/pipeline-server/sample-media - camera-simulator3: - build: - context: . - image: openvino/ubuntu20_data_runtime:2021.4.2 - container_name: camera-simulator3 - network_mode: "host" - entrypoint: ffmpeg - command: " - -nostdin - -re -stream_loop -1 - -i /home/pipeline-server/sample-media/03-barcode-1920-15-bench.mp4 - -c copy - -f rtsp - -rtsp_transport - tcp - rtsp://localhost:8554/camera_3 - " - depends_on: - - camera-simulator - volumes: - - ./sample-media:/home/pipeline-server/sample-media \ No newline at end of file diff --git a/docker-compose-portainer.yml b/docker-compose-portainer.yml deleted file mode 100644 index e2893b07..00000000 --- a/docker-compose-portainer.yml +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - -version: '3.7' -volumes: - portainer_data: - -services: - portainer: - image: portainer/portainer-ce - ports: - - "9000:9000" - command: -H unix:///var/run/docker.sock - volumes: - - /var/run/docker.sock:/var/run/docker.sock:z - - portainer_data:/data - restart: always \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 63d05b6a..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,218 +0,0 @@ -# -# Copyright (C) 2023 Intel Corporation. -# -# SPDX-License-Identifier: Apache-2.0 -# - - - ## Current Developer Toolbox doesn't support environment files, make sure to remove any files or environment variables starting with $ -version: '3.7' -services: - camera-simulator: - container_name: camera-simulator - image: aler9/rtsp-simple-server - ports: - - "127.0.0.1:8554:8554" - camera-simulator0: - build: - context: . - image: openvino/ubuntu20_data_runtime:2021.4.2 - container_name: camera-simulator0 - network_mode: "host" - entrypoint: ffmpeg - command: " - -nostdin - -re -stream_loop -1 - -i /home/pipeline-server/sample-media/00-coca-cola-4465029-1920-15-bench.mp4 - -c copy - -f rtsp - -rtsp_transport - tcp - rtsp://localhost:8554/camera_0 - " - depends_on: - - camera-simulator - volumes: - - ./sample-media:/home/pipeline-server/sample-media - camera-simulator1: - build: - context: . - image: openvino/ubuntu20_data_runtime:2021.4.2 - container_name: camera-simulator1 - network_mode: "host" - entrypoint: ffmpeg - command: " - -nostdin - -re -stream_loop -1 - -i /home/pipeline-server/sample-media/01-vehicle-bike-1920-15-bench.mp4 - -c copy - -f rtsp - -rtsp_transport - tcp - rtsp://localhost:8554/camera_1 - " - depends_on: - - camera-simulator - volumes: - - ./sample-media:/home/pipeline-server/sample-media - camera-simulator2: - build: - context: . - image: openvino/ubuntu20_data_runtime:2021.4.2 - container_name: camera-simulator2 - network_mode: "host" - entrypoint: ffmpeg - command: " - -nostdin - -re -stream_loop -1 - -i /home/pipeline-server/sample-media/02-video_of_people_walking_855564-1920-15-bench.mp4 - -c copy - -f rtsp - -rtsp_transport - tcp - rtsp://localhost:8554/camera_2 - " - depends_on: - - camera-simulator - volumes: - - ./sample-media:/home/pipeline-server/sample-media - camera-simulator3: - build: - context: . - image: openvino/ubuntu20_data_runtime:2021.4.2 - container_name: camera-simulator3 - network_mode: "host" - entrypoint: ffmpeg - command: " - -nostdin - -re -stream_loop -1 - -i /home/pipeline-server/sample-media/03-barcode-1920-15-bench.mp4 - -c copy - -f rtsp - -rtsp_transport - tcp - rtsp://localhost:8554/camera_3 - " - depends_on: - - camera-simulator - volumes: - - ./sample-media:/home/pipeline-server/sample-media - OvmsServer: - image: openvino/model_server:2023.1-gpu - container_name: ovms-server0 - restart: always - ports: - - '9001:9001' - - '9002:9002' - command: - - '--config_path' - - '/models/config.json' - - '--port' - - '9001' - - '--rest_port' - - '9002' - - '--log_level' - - 'INFO' - volumes: - - ./configs/opencv-ovms/models/2022:/models - environment: - - DEVICE=CPU update_config:dev - - PLATFORM="core" - - server_cl_cache_dir=/home/pipeline-server/.cl-cache - OvmsClient0: - image: python-demo:dev - container_name: object-detection0 - network_mode: "host" - entrypoint: /opencv-ovms/scripts/docker_compose_generic_entrypoint.sh - environment: - - CONTAINER_NAME="object-detection0" - - GRPC_PORT=9001 - - INPUTSRC=rtsp://localhost:8554/camera_1 - - cid_count=0 - - DETECTION_MODEL_NAME=ssd_mobilenet_v1_coco - - DETECTION_LABEL_FILE=coco_91cl_bkgr.txt - - DETECTION_ARCHITECTURE_TYPE=ssd - - DETECTION_OUTPUT_RESOLUTION=1280x720 - - DETECTION_THRESHOLD=0.50 - - RENDER_MODE=1 #RENDER_MODE=1 will work only after running xhost +local:docker - - DISPLAY=$DISPLAY - - ENTRYPOINT_SCRIPT=/opencv-ovms/demos/object_detection/python/entrypoint.sh - depends_on: - - OvmsServer - volumes: - - ./configs/opencv-ovms:/opencv-ovms - - ./results:/tmp/results - - ~/.Xauthority:/home/dlstreamer/.Xauthority - - /tmp/.X11-unix - OvmsClient1: - image: python-demo:dev - container_name: object-detection1 - network_mode: "host" - entrypoint: /opencv-ovms/scripts/docker_compose_generic_entrypoint.sh - environment: - - CONTAINER_NAME="object-detection1" - - GRPC_PORT=9001 - - INPUTSRC=rtsp://localhost:8554/camera_2 - - cid_count=1 - - DETECTION_MODEL_NAME=ssd_mobilenet_v1_coco - - DETECTION_LABEL_FILE=coco_91cl_bkgr.txt - - DETECTION_ARCHITECTURE_TYPE=ssd - - DETECTION_OUTPUT_RESOLUTION=1280x720 - - DETECTION_THRESHOLD=0.50 - - RENDER_MODE=1 #RENDER_MODE=1 will work only after running xhost +local:docker - - DISPLAY=$DISPLAY - - ENTRYPOINT_SCRIPT=/opencv-ovms/demos/object_detection/python/entrypoint.sh - depends_on: - - OvmsServer - volumes: - - ./configs/opencv-ovms:/opencv-ovms - - ./results:/tmp/results - - ~/.Xauthority:/home/dlstreamer/.Xauthority - - /tmp/.X11-unix - OvmsClient_classification2: - image: python-demo:dev - container_name: classification2 - network_mode: "host" - entrypoint: /opencv-ovms/scripts/docker_compose_generic_entrypoint.sh - environment: - - CONTAINER_NAME="classification2" - - GRPC_PORT=9001 - - INPUTSRC=rtsp://localhost:8554/camera_0 - - cid_count=2 - - CLASSIFICATION_MODEL_NAME=efficientnetb0_FP32INT8 - - CLASSIFICATION_LABEL_FILE=imagenet_2012.txt - - CLASSIFICATION_OUTPUT_RESOLUTION=1280x720 - - RENDER_MODE=1 #RENDER_MODE=1 will work only after running xhost +local:docker - - DISPLAY=$DISPLAY - - ENTRYPOINT_SCRIPT=/opencv-ovms/demos/classification/python/entrypoint.sh - depends_on: - - OvmsServer - volumes: - - ./configs/opencv-ovms:/opencv-ovms - - ./results:/tmp/results - - ~/.Xauthority:/home/dlstreamer/.Xauthority - - /tmp/.X11-unix - # To Start more Clients Copy the below code and replace ## with count number - # Ensure RENDER_MODE is set as the env variable (0 or 1), RENDER_MODE=1 will work only after running `xhost +local:docker` - # RENDER_MODE=1 will not work on Devleoper Toolbox - # Add all the env variables from the pipeline env file here (located under configs/opencv-ovms/envs) - #OvmsClient_pipelineType##: #Change pipeline type and count here - #image: python-demo:dev - #container_name: pipelineType## #Change pipeline type and count here - #network_mode: "host" - #entrypoint: /opencv-ovms/demos/pipelineType/python/entrypoint.sh #Change pipeline type here - #environment: - # - CONTAINER_NAME="pipelineType##" #Change pipeline type and count here - # - GRPC_PORT=9001 - # - INPUTSRC=rtsp://localhost:8554/camera_0 - # - cid_count=## #Change count here - # - RENDER_MODE=1 #RENDER_MODE=1 will work only after running xhost +local:docker - # - DISPLAY=$DISPLAY - # - ENTRYPOINT_SCRIPT=/opencv-ovms/demos/classification/python/entrypoint.sh - #depends_on: - # - ovms-server0 - #volumes: - # - ./configs/opencv-ovms:/opencv-ovms - # - ./results:/tmp/results - # - ~/.Xauthority:/home/dlstreamer/.Xauthority - # - /tmp/.X11-unix diff --git a/docs/404.html b/docs/404.html index 51cdd706..843df404 100644 --- a/docs/404.html +++ b/docs/404.html @@ -12,7 +12,7 @@ - + @@ -20,7 +20,7 @@ - + @@ -156,7 +156,7 @@

4@i+cn)nAJmXeLftMY{kmlC3di77plG&kC+OA{{odV1H3Y&YUo55 z!K0P9Ll!rX?HwgS5TOYr%+{ZYEXj3tUC@#7@+$ImrktX>Y#CeQ7I;F;i=w}PFP_K8 z-^IIEy}_|@6>*st;%2^r));JwUoWnyV*rcE=w$ZfOdHn?(O8Kr!T)lXeJn@lu9CB; zR(R~c731_HN{aQ-E>m2;YO7{1GuO5|F0Osr@nx-R_w;nDDv8n|or7Dwl$TjN9igY) zAx5(np^;B)PL7F9Hm~)MB@VWq@w`yK|4Yc=X2?CW!|E|b=0B^?(PjUEh05U~=*W^R zUa?^HpRs3Uxe}$$(F6~|-s6!Fy-H}Pj!KG2gbet|R|K#$UmcTRb$!ipgCnY3{b#3< zAT6&^BF7O^sQ&A+A@=(}Wm2_TLCm>CKx8u9^vcbLWo%irBC(igzN&duO7V_(yHwuT zff~M;8bwTzh~qHZulb0DGG{s%LemUkpUZax@84x!Mg&|&O)`YO0-evv&tok+zcGXr zL0z2$T$)U0?&VG;US}s68)+#rcl55St#H5@)!=neoykwHn?E&c)Y7E&ZKZ+PxZHdG zara-vff&~zpdf{BJOQF`fWs+;2sx<;+N`kXtYS`IS3%$B0$yHW=Z~U{?hs2}p}x7v z-~p3seigW*JYz`l;#^)!PKkixISYF^Yklj(0F3+clAL0>FBLrc>yj@Rx5HG;#ksq0 zFtHCV^o!3cJr%jFK)v+SLK-I%%AO{|FE=T0#C=$ z5BcVrf1sLd5I%_c4auCw5b&UTrqtP9ohgDx$fHi}zh@K&H|teBgoOiyv(aYe;}ANGMU>)_K0WrdGSzXGJttP0P(YOt+hc7IDJc|#i z635S{ixP1if8IVNigdhwD`SdBS<9fT@mWMX=AUd92#}Xwn3tTSI!|gnT+o&;AxL}R z6Qy2)WHq|0zA>e=f^^ngbbN1VS6|m=%v1lqekQUw`%3kOyP4in*W z`XYgGd!zxqc5UDnHju=%eLX)8TaqpPQLV$(^CmUZ)fIZ z$WlVfbI597TcG#jF*%^C19plFv0)I*SdhZ2PGARMrDk|== zl&W827g!Vz+J+m{4i%90m0M*RTpuaf0!Hue4CcMstKp?V@%_nMg5^W4aTq-^zy~1( z@@4f{o%pmo@s;%>u^d1Q3PJ7aKfh~o9knme#Svyf32m3;y@skTFXdABsY)IAi( zGZcv)wQ3j4r@|(e5{{$qRtL9bzpK*r|GsJ!<|g<%yDgW2} z+UdP-lU51@pJ)rn)ALObI3u@Yfj!$h3<|=wm`{@k3U#-YJ`QJ*yM1868H#yj6Z^J` zzln(W@Ubul3IIUpD*0X@0Ja%|^H4zO;oQx@l>i+D=&|V`Y^X%0w{t4m+b{aDv*QN9 z9m^Q^!aCD+SkULCg!!$407hQ>yP&f_VLpsA!{h;!YDC{Y^bY1f6fiY2>}2&skLYUl z(5u74U@%_5k5EwQF0FW@s^fBa_|nF5c*FIMS78kerGwXR7mWLvX8jS!)^A~m?)Esv zZ{$+P%%98JHH0Zus8^3_IG(QNDQI1_o+4@H$PEsJ7!>L7;~Gd)YUL3H?0S5G@R}@n|((2KWfGM;-PcxyeCS+yyrooG3sSP2S@Y4!CCKupW06Ve3W@f1jyB_zcTj4 z;j72LIVl(0DAMKk*GM43Zkr<;q{FSc1+L%D)&4&7zTIv>da*stPoI~M>};r&zk$)6 zxE@B(ZV$B|R$a@aW_H|}2zElh@QT@&@S2HJQ0c|3DYUIPyCj_XCzq{t7hqT_5I&cv zB9=eo1~J$Iy^TAS_ZIDzt4tOW&E{#{8TWPKIy@)&b~3A+f(NoYXse80>q6wLpq8$F zF?Xkp0%6@8ucdr(NIn;|_p8~2D@hzf`a#s^0#LM=@5J7Z#ot^?co#NXi~N6ndwM`A z0g5wMxTlmwKQ{Fx_pg%e$vXW9O*(q}h7bPZ+~E?K0?KMO#3dWm>ZwerHI~!0e@2B* zl4_4}{9s12$RT4ff`%5l7EB&v?Nb^n7?oz>Q`aDVoE`(TJRZr|E}o zXk_7Ok^@6ysy37+*Uen-GK{RYb=6J9RcF$!fah-cVRKCZh{$6OjF82v2uW~He~0yM zPq}N(*x7$G=RMCR0VkL}DMg~ZZ>(7xi^HVhZ32a=-lWPJ6uj9QQ+lv?^~-enkWHSA z!iUQUiPHIGWg8IE9`4{`T@5NG%mJ22EVw+TkXjE0z5tn4{HmcsBXv#UT9z4~h|W)f zln^%*9GoNyEda8N!mtN@Y_mY8z~+deJ5BB@nf7QV0`BK?sXTy?42xvo>gPaKpEnDl z=rvMnGese45MY$Gn=aw!7^G}SITEVF)JOXyjP9o1NytSV6Y7&5!U!bB2z%UiPY<7D zpk2m2)0l1$DK8~>=U)~4i|u|Yvmn=>yK2!^IMtLl)5!(pdB6Mxo#%S?e+CFU=XV?y z?pSZwj=1Mp4>msgz#lTd2+sC+-HbJ5!Cq8)e{z-nIvsX4 zgLaOQdEL;Z?Ly(F6OOx5IfsP><%0eQh$?&-O|DMS3L#=1{h{LkLNd4Kv7T~0RKsgs zB>G&f^l&_CqL+t?DeadW429`x6qHXlRT=xAykT|V%ro6lw+`hg-D>BciWu)-u8LM(@z8#mBotuSIUpOcE{4DG8_{`IQHI;Q zKk?W10J16-w?_1)=eQ$OYkK&^`8=auU zeGW_f#e5$SLJl?HeEe|eqj90XnaK})@`x)q3emgjqb+_IPJ-+Z8sBH zf*-3ArMAWHeD2<9hza-HfJC>T_T^jo?B5ZWXt72!a3cc|A1hCv8FW-MJn*y>rwjo; zlSPQcc!hCN%F0>~Fsc8}ca<^$+K2nArmxTI<&+_e%K&DxD|fYs*=);mCs z`S>k~;D4nj{G%uy5-t~csKFLQRe@mB^F#**)Ga=$?STIgiB$KQD7TrY2k)c>VZeju z{)?CZt|>YK6JY9v0sxH@u|lKo(v&()m*-8#OyOBk3JU28gbf@01BjKXv&N?8h55EB zkLBMP!$%Z7FAtoh+Q)_!n{C+I$4**&{t$bs@8Fhc-0ifmR&PdkOWclNmijnOfdY#L z&_2d60opEQX}?|rZLRWu6nf15Lg7+ zRTXa6+ZG_$8z3Q-9#aNah|b9JP?-3E-P&+3Af*4N99v~*PP|l@+NG83h8pQT_MYN- z%qS?|?%Z`qrf@G|X@c;+4MRRm_#%m=-NUpfVdU9i+k-*^?=vfA&R4-pvc0l*^jH7} zcK9Ofz6tK3$qw%MHWtlg9lS)}sT66q34bPWJc!9woEKJr1Alj^kpQs1j%{DZewq^o z)=|6A=5a8vv5t~w3I0b0E3^s|utEf$*~0fTiuzFHbyxv6l1>N-_$r~!P2RJf{9VNe z;G*6!DCZ_nG*KK~4RwnQ&)~|0V^aV5K#aK;(9fYvz00>G1uVH2S}$F0Z*W!dNxQXi zIf8Jd_n2`4Us&g!{29-J=O9g7iRqcefVJJR&WFN{`7y(et8?0+lYuIbT6%_;#Lm zKekh;#M3oo3M$O+7CNDgc*R};fHAC3l*sBD5?30}RvbqIdO51&NX7Zm4L)qQdHk9o zKwu)23J?n8AQqDY@DG^@0Qfnu(UNkQ2e?cfqRfYsw1ixJf%-D%ygqYj$K=Ap7U47u z;y54bjY++YxNJOk!5Ne9T6X!i;C11nF!%@Q0re}KC>qBted?Ijv2D{q!KWfSzwh#)YGTIIb(=gyHuiqrbGowO7xp8cv1{QB-_5_P@JfKF z2(CcsJmfU9LAPf6e3bHWO?~B`Zm1}8Tn7nfMS%FZL2?BDUoU^vf@FT>DDVUUH;4=d zufU6p$NC%$t?#d`QRR{~^bpft!W1>(kvZQla2LgBsfYPO&185cpzdA<^{}|!{5(mOdNHc4h$7YcrSn=@7Y6X7Z?+Y? zsJGu3Iq%xg=zgiviy^q{P9jp7N}y8rSEuYX73KS~xA~6Kr8~IK>(~#K!bwxYBXHmi z_wIj;3e9iWJNXxhOpv7`PS;0;IdO{!QsGW2m-*(Ew1BgTxYzBfXM6EVRZ_iCsC`-R z0J4C4cayOm#G~=@k7D(LbwuHBL|Z{X)`T!DJbk#NV#!tk0#27qAbeZ7QX7sWoQWwt z)w->(nO9@8RiJ6mDHmyT|8iBov*_*kBhbX|`$FnlHP{la3+_SBXYX zik@gWfc~2HCuyvk@ezc1;I^9e z=j@yJky*h7;$LcTANV34qRK>9x^#NbwK=mKGc6NUtyc!}!ao~1t9VDc3{0d00t78dzh~^e0$q+haj>_3qP59SBx(H zw?*XdoUly1&{mO17(;~6$_AnYLM?^Iq<3&-KnSrFWbDQ{!9pm_DQB?+*xX2hKA6=C z$=XFKVDjuFoK?BJty8tHC-ao7jGm$V=JkXJ^@RC}$k4gN!p{?XmEqN(n9tGohDu~W z+0t=7E&LBLlPmW?F+H|g-3G6&oH;2!`Xg!Hv@fk&?%k!UGgX?tujL{dulS-W&efbO zHGy;71O;>J$BoV3V=dwIk5G7=HZ}*vhT>a;NVUnKEl5HA)bkC!n^Lk+1kj{x4Jx1DRRbH+I@45^nR3m=5I2 zJO)~BxAp~Jxi@(1*dKST=N_8kf5!}7rG3qjFI-QukZr+RYVJ#M2acPS^fGPgS#Y#lXX)vd-~9QU)9gTkzXy@WgoqLT8AG=4jrD=i>bBg`dzakYhw{M2m)3o~4E+Vsok?H>~6W&rhh`fJBDu6ObI4_`7=8554 zbv9kcV-Jf+i`iaY7e?W}5wkE~1wRtLdphrb_lPZ0&HJuM6I)^nT$E5GcWKkNcsi8P zN4JEH_k^#xAOr6}qi^tr976a|(2L&SrgB9oEr=}vLfc|w#|w-R1SYfj^Vm>kTljh) ze-`ZXR3LxnNZPPI#!#wYoi=lQ2xbzHUK?Mk_T~*P@5l;AuEzA&w%M<@*jkfP-sgoQ z>PNSRJ?UX)vtCyqgK^J`&ttrrK=UedoJbQ+_`{*5T%2f2mWdu=(oI3uXE(@o4}oa&+B!bmR$qT2e-iRhgZc|{i`|X zQl}TkuYX%w{)Smv_fHqwmWzH0N4*F3`SC`C1Dw+>GxsBAy{v+QH2f-@`*7EF6kFC*18f~L zeoeHfYSg+Mu@ZpYt;1Q-TaW_<>5hixj7)*9OgLNF(&=_)(5!foYHi&6XJV}hs_wS= zsQAzVn~xaaOom&R`o=_~d%E*tf8WPKtz(aH3YW4nG!<<#&>+c)q>-Di7*N{hQk8pn z*II4IzbUq3HJ#0Y4|_v43RPd^D%z~xQIBxze=P58l3JJeX(mI2_s7kI{D<=#W$oO5 ziS2Q~z*U(KF;XJ7TZ_H9%E$NT|0Dt5ra@&SUZN6U53B+A0x{`G*&Yi?F7cLodobBF zI21}{LqNr4W^u4zHkfa?WHKhchx43I;}7?^on5SoWPTs0>^AK&2rABQ!Gtq2fVJ|g z_Im&YN)KUIrP10YRrmp?M1?FVSY{OhYeN7lUS*NHGVw~+Q_?Rd-$z^zZc7T2y7d6D zT0l|LzJm@{6W%G*ep&@>)O=K0Ute3bl&@j__=UxA%yg}V@PjRnkOt@BUzVcY0F}qZ z9Z+e}8f4a=9BrHVg%^If9oK!g*+F5WZQ@^#qfzgv{xGSkWCs8JSqCh??hru4v&?tF z(Razfj@@+NPW!3$2z{2Xl;FD{rJ+TW{-L@pir9DfnPLL2CC=AT89($fbhz*f{@bo!T(@Ga{MmmILR6P;EFr3d1AzlcH|j5=^M9794fqE~Hk*NeF2~Z5 z8gXR11lZCEOwwzSA7+B;-*_!9x2v{yo_?v2UKUY(J+y=tSID*gsJx-298v;N80juB z3?DYv0elA=LR{igKTFNv1?uyvrNXX&o=cs;amsH;;e0$^5_+qk1$Hs^cuC8Nl?Oux zlP?GEH8sQRg)N&mqU@_1f=-T@%QzPKao{Hl^L4RuOo8^d09(&aOJA|g(e`PoxbtOu zr0V|rqAuvemtIyOlf<^i!Fpa0+Yr>_S59rO#?@Y_`*=IO_(O2I^VG>`>5AB~gijS8 zhm6-sE@t~iHa_*5jp{IMnoT|V=KA zpoQw#em=Q%IA8`QBHZ$;6r~mgoPXJ9C3@ZQT(OYx(eZUr!4}#z=b*1re51di^)0h| z)m%rdJxaQ+H%!<%`LDmc)!(H|&vta7>dYP^fcRR4tu>R(p*|bHqi6gi^cnk?`)&ai z8Gc(hLtDMHnxawJ0LgA`D?PD#j2P3C`{keYqs~)VTa<40JF&j27yjT+BJaFp$bB@H*g}qRldpFZ zzYlOtt_hfbM(pFiH-x?sR1f8Abcx|dpZB0th2ilQ$^Z6XfP<>=xx{WcsO#;rgi*w< zZ9k7t5(L;KvdlIY1uisOunaIv^_6g>1_Tg?GE=y-LPZPs*k2`AxR_;zq$ikHFEKEe zT#A*k>Rx~;P+LP?TrK<1z{IIhS}l-OZ~R#1>#Tj2(T{s_2b=M~$D7REtrq2eNjC8iVQSs5ow zmp8m*y592;@(GoZsH?`adyyU&62xl=SG zqya-qJ^gL;frO)_oXL}fbKSGypM9$y7d@nBmL4(5@*dx)d+2`-xzs6mmVtkJE?nX$ zTxMJDy~#CAS(4cWTWHcYX`WtcSVmjZ|%J{ZqAG%svp44)3>yOU#S za9B8lQ0~PDDzPM62_v+OQzKo!x=)E}*ECJ+N1)z@2bzx4N5=cpG-<9fP4eg3y}pl} z^!|yJX`s}!Os9$0kR5T9yq^ECsS@)&9G$Y>tZGlXI5yNTz(DtrX0_;3HLD0a^Gb8O zml6ch%bl^|zQ#Y#v}$G$axS@{>d}hr>?@0B?xV9Q@BchD-9O}o$?a_nvhjYySHKJO z_saj^w-hvxWFiTFCfmToBQH*qm3UTegZ1wf@MhjhbaFr?8`TyLq`4SByFVas=8N2H zB0M9L%K@wkmR)ywcV(P&Gy>g0h4^f;c>-1-pV5GAq6OAuR(IsAVW|~gpE0L%hKye- zy{fWvEjzyYoKtU`)AffjA6u@P^O{KRmn3<_adWMEqygQIA!SMv4EXTC9F@^N5ncN` zs0G-o8=_zHEp~o zI!L*6TF%su-M8GlwfCIT9fPi5=$~R8iyGAw*tGXM`>wZ@yt@~RInU~EQ>*~}ZTBod z1kDpGBx2C%&qb<2;@=I{*zv#hl-;&YwHP+9*tWF9c~XRvpiV2}rk0Bfwzf!rDpZM9 zjy76;V{nD`esmj;?j`Q@dj77}zINTAZ?8aw>1?pvO>fg&86dXfYTj)iG#lxnxG*u9 zl4oHZKEgv@E%{d)*h5GGx&0Is@lQLQ-am4>uqJwDJOb}Sq$h7xYdOAA-!LE_da8Pc zA=%@?`_WWj<&^C6q=WiuDlu4O3`hS7q`B2p5MC&EJore3PIC=iE@Y6+k&=BnYw7`^ zdhD1A7qU*6N(2EyQINa*tZTHb=Jy~)I-vbr!SE|9ZSRddE$)8%Oy@a9vDbk5E1BHz zy+?EmX*-U_$Wl_o8^zihDdvIDEU0|34)bJs=m<% zr6P$^I4qsU`NGIO? z2N#O7XYqg}(-V2}_joUQr-zEb&-p242w(HXWsE^`!%3to#6t`PIL`0TYx@ilB3Oz{ z6Lx{9+)q`5@SdZ>5Mzf7HlH4>Ovx6hG(>e*jOY={d3*^+-apLLl*%&vh}2(8vlx`N zVp*8|Z1h^s?#?qN*FEdzhnR7z zwN|=phxRFtYb>}uXvp`VgGMNbVjO*6fw--v+FdTAUypPDD)`h?TwsRCTUuFfChiwi zqVut=^Rz(i3R__1NdUg|E2)WMHux3jJe>zy@VQ3c0t6QTRDT<-IaiSH{-p=!|IY)C~~6mL@z+Gb|>B zqSB(-HsK?%awCT3OGpE^HV7wIiCX9wr{?OUJ*DxaSa#nHw=nmB=x=2Cs?8u#3s@%v-X*Zn9) zh2FsT$33+69{X&u>IAzzJFBDPWnb_Hbyar1H|>tkndXsNn-c^;FSA|s>{~Qk(plUq zi9fyG8CJ|=0T=47yoPKRdUQ%Yon?OUD;^Zjp%ZzYL3590s!M+4d{t$hq41o=!gbrh z#sIa?EZ6^+_}Rj0TJdPQ%As?GApU7r^cw9|3U3%OZIoYgd`{=IH={`tZLNY~gFJdqdeX7ho3iDYlqzP`@SPNO?&uXMT-T{xB>` z@3H&3^RI-QxW82;^WW!+A4P|9z(ZMT;yB%iG$bULvmb36ag zA+_fe`ecxEPe%_Baw9*|Z5RE@EA*gt99=mMY_LE#B|?DxxHnqp6msifZD}0JOvEGW zpxY4NgR08Tj~>9MmWCa@%Au@=({9QaXNqwXHLX3KpN7H7kB?rQ{7#Vg5w7Tn5qdC| z8~ROLQUi`6c%_f@QBqi2FU+JEp6QrQdOKZ}T+JsU!~;;D$uVO*sRC<$h%LWuxPL5< ze+CKwPyh%6@VHRn{oG_GNXY0Y08fveP8-up(==k3#ZBptj5Vwy8~fW?I=XEmdON|Q z(_7sun?o8y8d{(DOxMR=p7&0dwC%{dVfd$9-*MP*lP_xpY4nM&Y)kJWa zM;nbJRMMChvvR>R-!o?%ojQc)+w(+?UpBlo>$uCA9!nJMzmAMPH2NCl5cwz~y_fCos*Eu>~Y90`H}me3Ez5 zsnobiN~|i>iWTCC?8*-2}t!5NBU91drQLuSOh z>0;ir>SJGm8JexiR@2^%ENE_Os()S9Q`&GRX!eeGih*8Qz$b1GXjB}eRw+u?6DP7Kq1 zR*Yfz7gzaMi{o$lMsd3hvA+yd8+X^i^RbjtLUZUHdYKTvyB~-bX!SZ7f8kb`Wti}C zLTA`(rnyj;(ygYAdYTasV*rBxPy>nszhD7jWq5CzznnpQ|5E_92TJ6YEdgr8g3{Xy z54q<#`s~D5bw6JJ?U;UW25egU*|ajI$E@ZJsq;1+z)gFtO~-_f=ZFx*atxvm(>$RZ z!qw;6IV(g{2j*21*8HEVktX?-E5n#$RZu+^*!oh;S`5TQ2x@qF-RvlM{fb9}+`I4o z_kIa1C|yn1P2SiI`(mBW_;)g)_T<<%gNf0Rijt;pwz*;>>@VNnMwTpnqwISOHvfYK z)u!^wG5H^T@6h;uKj@?Y4;6ZRi_SDFxy(HA>@HmDObi2naM#Ax8Ok{(6rfU$DE59n zgH}Gw8`E3GTZM-l`p#7dkc`KqC;4)n~3xXNf;ILNW;c7I8Rh{pn!Lg zl#1A?r4^sZ>0*k%X?87e6|l*XH$HqHz5PN&IqDWg4*@9106|_s(6X@icByof8X8}F z!^u49ac_tMIlr!=0*|#Tffv-dKXwYt*Xz$IBO2p8^DQIP6&;F|lHN*_-7pTvRC$&v zR%~r zQ@IRMua9}}Fy>L*pd<~#d?y%X@4ax1c6O7$jZf&{rDS7Zsb_JA-h1HDJK2Q)e)w^y z49F$KpFU>{@b7EKcXc8a3|4Vj0Pl&B0g%WacK4C~y~*t8rIGtQX0M3uFU*DXt6b#$ zh@yFx=!n9+j7Zk#s5RCYi?&s~ADD0LW`u>w*o{pv6-7izvY3_9_s)I*D_U@h5BH=?5 zi8j)-xm8Koim$f55tVXY(z0j#4WwiW;<2#XwEf3lr-KV@`>bVxRzuk=T~ZH4H*Y?QtZRRzx3qvnwKF zd~w^>)ynp|2j(^<=>1iOY@4Fu(Tj*`pRhYpaK#W#vW?8i?=Jc1=s3`cV@{Iy83D;R zSC4W#FwHgLnRadAa@P+Xs*|~79$6{sx&L2CU1*VGb)~4_>~um{=KZ#k$a}r8dVI!6 z_1QYy9KB+i7 zh@)M!~AD!oI@N9S6olFzZ0uS#ynk?pXUP0FOsKM*ydbIBl}oqpUGqlwzg zG+b6AQWKe)v7z=LgbRDk#oH)8uF}VQBt6y_Fn;IF2knar~a4SqjvP;GQW!oj)oLlg(ZqHQ3 zmx~d~L-mWv1?msuc%Q)C82;f9X)pI{@|zfH)bx9~5lnHFIf0RGG6DYC;!vXTkkM^c zsN=W<{d+Zpu|FEpJt@kg@4!Ps-7uN`L#}PJ^w7SU#vM(q^{JU)Y{c&qdZH^9B%~Jx z4vMTfww)b6F!#s(Wdv+pvwwu@INm= zUKGc>kAVU6y-i^*{iG-;OxK^ocd#~)SHCzyfZo9{)-Olcp{k^N%F+zJT{(C7t*Q;P z#Ei+KK@M4P&8`060Z3vIu8rpC+DNE69(&i<5sZ!`K%`!l!K_&%nR*?#C7zD<3PSq8 zt;E_qNutN3GPuGV8HHFCIoqcHybMc|NTBPSNzs=Bu}iWW z_wz#9i9?ca((sOnU19b?XrA-BE=*3Le?5+5^!Cgp@nf0~R?HtQwW}HGwd4p!RnnM| z-wgPha}%Le##_y=kMMYwo-baL@Xkqxa8ZR9t0hMgzY~|OUBS9s-8O7wio}tFWLr0$sj&u`nbk)@Fy@XE+UFZ}6(g+az<~BuACAca`U?D^M zfRpT`_uToJeE2+(p)tE)Wn@_VkM)hu@mA;ePw^v%uba!nK+2@cp8%f87b#h80z8WZ*eYPd6BqYVN=D+2F2! zv+d0A%~MuvFb>Wwui=o@FJJ0k>0lUf{hJT_#ehQUyS8JeON845_=DP|dDUlOMtCGw zZjcANt|}!LDAMn~Yv1Lujl(M#Gy1y+OShMNV!V7>N=CDbWKQpwn3jHOK|U9`CG%M( zsrjKMSSYZFrLc+#pqIjhFue0m63PS znq@W;7;r5ng?xFjDbj->we|KGj>o@mY%-X2QrB3{aKInM&b7Y;9GaIH` z+;a=1oq22$?vmQ-U_L?<^e=-*_Y-+E7O3%Z>@0LMfS3vL)>{ExYQhgPboMh&>pHI%_cRIL*aA#dhAa zUDf#@?olRPpgNv>!JY58WBa)}j7f$Rxe-Arc z8tT8Z78VP5YXMaU!v$TmK!4WTO-`RIi?^aOp-eUu=|b~Hk$CpKuRZboVRH4^N6G7D zmcqV{8$U^hCaaq6O`hT%|=kxeSxL2@R74GCj&=N`~al#L^R zSc6M{>v6@-Xp^v*CZ9;sY#H2tpf{Jqv^Ye#a(gjN$jqkf(*Re%+@vy< z46rYCmRf03ApqZ*P!FmG6UO~OXEP2YNRVv1xeU6*h?0Y{Hx;L8=oa6LR>%Hbtf+64 zcKmx>u)XA{kLP8_SC@^wJ#5_w832T9sE+`6Cn_`p*iZryEJ}qYaA}n^Oc}^Yg`_PS zOu%$0XA9vQARN4Af7mr{;J&qns&nn?i3cFyLc2xuKLADJi|@sJl2KLT;+xV^1w!5OQ)6>}yS_;>DrBKpEC?GJo*7vzcEoqtpRy?NTE2mu*~1Y5{J{q{ z&A$j&ZRc>UaTT> z)OC-KA-+aLX3gmFyHBsx^-eims+g#gR(nlV^*WX^T8P)@T>g2Z0t%Lzdc zZ7Os4Bm$2LMF4ODd!KKOA^)v()YC%O!$PNrPlV051ESW@e3j>KkLOYAj(s>YOs#)A zr84Ys_j=G>p3ndlkaQ0R&t-=-bg6lhu>Bli|0>?C#pE&N15W8MCQ&HPTt1GXjUf>d z90*LX53<$=2GPDHruzUkOD*#a;PFkmA?{Yq_p4Z6bKL2WIl*>%-OXj^7iZ58nnt%lO1A-~Tf1yZ0o5f2eCmqg*;MEJRL*40x=1+u20J!^FC^S3h!^_6`Q7!HfZ7Usxi#4{9ji5Bj)@X zApSV^85iL?2V&`=6~ndbhiiEc$1x(8U{XjOL}# zE#Fy3e$y3AW*jVIXxA1V_fXU8F;6=$R%a!5ap>sa<0)rpHOKeFfNx{?1}?G|LU8CN zz#+N>$oWP(c9SEsN9221gGi>RP(}E=)x<++tyqifPkU!C+6-bz1?Xs~c z?hl@=$eF#36l7Jdu@^Ydav1eK0L%(fy9-{r#(Z4qXd4jpEEwHX*%m2(lV$lV$8W*c zuF}l<%9XqKGDU*f<_3ak;WzJgUxWaEx`qCz96;5@`g5e_(^lts>-`72(0Ie*YduWJ_of;duIRf_A05rO8oR!cf!}njPSs1UZ6A0aU zi8J^X^OT=e6OEh6dD6(lNtIy@F(?UZ8EI5_boeuASUR?*m9B)MOF5X24l4sus(`4u zaGCi*L|2+@&t0!Z6-mfn7~^i!1`S<_gLY%6`97EEy0|V+m9CmK=w@SDOT=;rrSDcd z$hxy)1sfRPd$M(DO5pVbGcDN2t66A3hSfX!uB)G4r}>UiCM6*)$N^j3aw|k|uFNc^ z|8KYWACQ#O`3o88i(MAU3xb+0n8gkpu@C!n= zC$8J4d!-L#RD1o&XP9sg@M~CIbdD`RIS`YGzZ4g5w38-!n!$FetK;XYYy4y8!saA# zfF=7}wtf0~6Id32l-@^UHlw!E`@gs!c0YZD{d#YxUEAeAZBS^;NqatRhR7w=_phcnP#p1<5oe-Y%bNwbwHnmrG8mWSvss zQvnjU|1DYWgW1Xe8v_8!AJ{B@lC!`5HJ@Ou3ogsmJ+3o_raJ0#*77@JqI0;1E&22F zxa;urE#8N<%SrC~-JBDfwi}*4SA7No{Hz0xrya_DV-#yH3-Ah;=>i&@=wjkvPSs_N zme_BkPx|pE=OLtuKcsk}?t_28HIsDp5H6v2KB|o< zv_=%Bnjig_P_I-uaq0){UyX_-Si?ip<2R2A-x*SZg&KsYZQ1I6)<#C=~HhraX)N+)TN4R-3DABuw*>cxv3 zU2m!SQs(*&)R0Iv(0Jg_XD;$B?XR7UwlQe4$;h(ham)Rirx^WBc?1+g4+Fu)LJmeP zt!1o*6vYDq%oLme^~ssZV3)J6$M>8 zTj#YOxq%`r{|wRfvks2OjD}wbN6zO)%)dj9Wx@_MD8JGdbKY)9)v+2eP<9FK@Eia3 zE5v{3-n}AyRQHiBKwQHjw(RuQTdEZF_<=to0Gu6raplbgRWd9g=1*qy+cXX0=a35^ zF;v5q->FxQLt?A$#Y{iPJP?-{jiDvqCuI?v;=0?9kR7Donzrw1cm8~=2hkxgbmC?V zCb|sTN!ax6;TTBG+q9M6Ji61WK+Dg_-%&-pou_|uWLje7TR@j}^ryDJTt2HaAcW{u zSXK`C)T6Mxe_6-UkV!Vwu-v?6=Hy_~>;A{*Oty|)M&Vwi(V=GBl(>v}o*Ut7Z(#xf zbG<>6GOV{`XP&<<7x(q0-rSYA7_9lU*?K3ZpK^zs2|iO0?Dmw%L27S7#3(d{HJB*> zyD111pjkr2p_INd4uFt?q1Ypsl$0=W5c|6$#w77Q5SOwi971NktLIJ?d5-G?bI;;M zB3KqAK`}r!F=;1^Mi=JS@+Jh*=sbdwqTUPUJk-eTZ!3E?4rMK2i%f2<-YTFy(B%dw zygK_$bHo#>wyF5pX>CeRnm}-x!-5~f<>F7fq6Qz`h?hY$9lWx=u%cbRi>rc4KF%s* zU(C?DWzQWCa6}Ovh01{h%e=$fCVBhU(3f0vKLqtFfuNM(tj^{A2v;~iI5Ol^sB#u# zPTyz`R9H2XF>oq1)1F^J#4kCY-;Db=$IMgmI&XBp%Q`boxjX$XcGx;YS`p~UJ_?@C zNc_?>rOdnkBw1$RLk2|UQb2~}U%M5^)c$dP)d9X{vr>LD6bC8>wUxcP@Dr33Dp?VX zz!bI9u)1(`tq@DzmrPBK3nF4}Au~xBA9PnZM_hX;O{So^-R4eFK<7FmMU7e4D{l`a z(s^)9BDfN#k_i$jw1df$5~;iZ_ifiky6&}48Y1aRUYg`n{sDWtr{9A1m88O6%34ct z*$=Cd&2jO)`G-apD&X>63KjxpJN?TKf=E03E-%pbQO>|_CqMAwPj;1L-ye^crDmBg z6x?3=e++vRBic=Kosu?fEH)3X{8TWDlCl(jd-kq^kYRH0GQ#_9mZ!0DcKC3Ie0CzZ z!#nl2nD>{7t=^35pn6*{-Fz_n(IGON=_ol{uh10)tJW#Q+Cxl=+>h}%YCAGVz|=)uakGmE z@v3f2S)gZ~pj?rvzUsN#UtzYKCg6NXfA7!3);_(vn|g2NSe_oz$GVVVg{dwH+*z%*%4(pgAz3QeCaBwW99tF)hXqPEzfo{I>agG z_#=C9pDmWB5O6}%+2F{|mAlE?e=6P^`2H&#@k)s0z56;N)AP6-C${H)m_*`)6;Cg{ zj4ELvjT{@n*zi{vm0uKw{=0Jq9VQn@Bj?}0CH=w?pn_P2WDryfws0OxbEEY0z>C=s z(}5SMsx{$7NNPyK3|PLtIK$21My~_YK^KHt{nz&G-u|7d4#+$Olog8}zZGJ%*usf8 zdcikb{=M|;tq5m|p9NIYO4Xc*qyx2u#{83<@fMgn)5Q_5$6&Uq;ylVr9P18aGsTOL zhS5)E-)>`=W_urwUL3#juwg6Zqn=iL66NZWD6ht1tvUaOZPEG6;EqAnJRiq35OAJV z8X^EU`~60|oo#XZmxE9?CE=~%GtiTSK$_sGcDhv4mKJmFvjRUOfMn^xO191Qmq9Gs zkSlTvCV~~8i@fOG-OJ|zC}a!-_@RU;gcI2pB>G*AS)*0T<<6=@l)kGE62wbrRqCiW zJV5^gzN0N&sMJJ=bQLC*qcRkiX8P*ZG;5!i$7|KuLzg-AaVZJvmuYD}UPiRKXDS`agGc0)H$hYPSL9!>S zSQs|I(-R`RWOQBLZIzGa@Lrnht|AN&;lro0J^MidRz^;Xg6CcZg0zK3 zgSsc<>RN@k8Nrjxl<~2d*ZTV|(ZwA8uqpmYdv0vhC3MIA#9?jHQ244yL0uRDM!PZ7 zGLkyo;~3>4Hq1B7^6ad`#*V1U_H;Z<<1%W@vdEU-**drV{+!2s{kBNa2+jU>vYq#L%&slm(2; zRi+Zfidipq>Gb}MS+j<^Q+4q8XWkFIvo>S47rdp%z5BLRD*_*H^eB;q``to@y>bd> zF6-Pqy%hh6BK~+JS#TK9()y{;_19zOHWj%%X4@f1G-Gl{MO!SJL8qDg$cf-P16f++ z!VuObDcc6DKs0YxXCacWDVzMAR*)k+kdW;TS=;I^@b^O1bwccYgRD!cTyuUs!%ICO z_u?P0WmhmC;*tgmjz%X@{G|6d$&V@AXksh5vlTD-t8)M$OfWJe?K#ZuCpBX^D3Ij&Okh%wEgcP=QIH2@dw1jl}eD$Bi;k|@?s zBsE~MNyLbOIisBeb;7ZEWM|NUpISJEDDA8D!muEf-CaMLeR&fb8mbM~eLZzJh-h_5 zHTU*4XnwXA3WrKr^b~iJNGK{{i55YqQo=f44%Q*K~ldr!!2f~vOW3h`(C7VwnoNI3py`q zY4)yJp5PrF73<(cr^r>cVU~QNA7&T48rOOLHsjphk`-Opr(bIjoWzm;*#17(UkEn| z=U6ci*16Td^>^PJr>qS)dtt}F9?Xap_wuNJfl*Uvman{@Dezph z#?ZI7sJQy>#%Hgs;V&h@;P1oW9jBw0_{(kqzy5qgB(hIc@PD0&jysk5)rpX_syXNj z*bsxRoWfx>gz&Io3^y4e=)~IXS3LYGx0xzm%^@bHuo9}2`V}qzX<}2Ld3Ja*u)i>z zwlb{4hHeb0YaryQTeSdDs;IuMWrQeO zN$^!$;`zCT!Y(Bwdk~HLE=Yt4rN|fv0cG|>yS2-tFLG5?(ytu?gO<1z zC!PzImi4?q8(%Jr3W&15`@ecZ?*aQeFDn7y!XBZ1?7K1MX|F^69w@J9{R-|+P0$)A_N}xbwyJSHa6b>?V7&~Q>t$09NINZ%Rc1*P7q4CKv zrF*LA17AxT)~Ed&WagTR+H}2FuN*yJE4njm97!>|%`khlV^*Lec7wtTlpT8e5EF9W zH1yRa|_Hqr_B5u@)sY%yq@~d5y9WoMD3A6kG4b!t>XFzNzNKUPxD) z-fW*;)GwA$Y|}*F245rv#vR<7Sp!fC03!mDWw0uYunG-zvRiWPmC-TyKa@SXBSYK) zBwp(75}ogIjCrGKr{vj-=s6fjSzRTk_Aan#or3 zsKW3q5e1z*1-U#?uU6D9<%m?SRRc&8^GXndQ_`VWo8y9!L03>77}Pgb@^_63mL$Ed zHt8XCy+Y(XRtlXGC|ix$xPxIeTeUfW2EJnPqJRbk@ifa%ooLM$WIqj-M{-o7Xkqi| zk|WsBE1b|~7yQOxy$X$QW*^hgSzQ(v^I?MhYwxOE;{>vVZKtr!p$gh}#5Q#GAx~rYq*Iea8I+#r=@J>heS0%rd^}1p$v%6h93Gr$yXui#RSO zL0ilwk`^|sAane{`HiDeRLf5B3uqiDtyShY?qp>d3P~p&a>mqSCFVJNMPgDW!=nK~ z#7Fl7DRj$^4*sheOL(ef%)oaXu@hJTul0@ql(5$vZGGEI)WW)+#k#l(8?hgf^5y7u z;N<4_-$Y$K$Nh0Tp55o)@HFd6%72kv@@{3|BB6`5ypdF>2F6j09i-n@8TG^WQ5InR zKoAwEFDUFRG?@DB-alz=7f5U94c*Y_e5F8|@VyuNbJcHP<$diBnHnGC*gK{_n#>G6 z-EAo__R-|PYbQ+4@aB_vGQE%$3j(`ksG`>>X%JT*cL`fAEC{+RWF9GzD-)L`8FJ#- zmKXkkxOTcWHmx;iK2$8I9D@=BnrJe>soYBma-9pj-#}VOTwx4uc-{f)^$IJV!bL~; zrKc!sV3g4Am}(a-8QsuGES4I0aphxyB}uB9CP@vHkPfspo;sPiL+Q|jrLiJfi|DN%mv#&<|1g|4amM^JKc)tH7uUt;eN7dit3X$! z@jWD-3UYU?-S(2i2sY*&mf_co`8I|*td?R?><^qqXkH;J0e~6cAAzg(#~mEu_#e>4 zUMiPuwtPmVojQ>wc{b7ZEoyedmaP-*9j=woSZIeGV<%@sP7|Ww*}rQcXY2N-xg)J$ zbi~lRkaioRbJe_0(nr=skwA2|OE8c8b zoAPj&6a?$Xu;|TgGh4QU^6M%a3e1{XWqY32lFbdft7k0;tdyaM#v(f9!qSWA!#^)w zFe$W>n*Vi8h8rC_Eog!okJ{4B?Yx5 zcPA2aua(RFN^}M#mAi{lXg5xwZ{P!6D>X|avx}yIn`7KieiCo#sS~P)l zh`DqXyA%Wz)Wuie0?La{+Dm=*lME@BT{OiW>j(i+ldf5yL;@#0?mG&2JV= zV9IAt{P5*t_bLAFQ+QI@l_#r6g|-92YBXJIhm^V8Y@z*=J!I3C4nc9s6D5d#Yu=AU zY{?ZNePvDI!8?X;;%?-gnT`MU0_>^XZu_e}*DufWF|6oG_(P)S@}rv5CL+x;=+)%m zgCMj9=!t1ZO^4~cLto)CMQVEFmO%}L=FIS%BC5S0u(JwQ4 zcr|W1&-K(L1UeS1o`*YU*QTStKrAtku9Kk0n*fR^6+hRP=Nc?g2Fb*r(1HDxS{n~Q zJ(gz^e;zDhH{AeX<`Dg9i<+ziqqLcs`YE6ws@(QzzO; zG^1T`=lp1QHtD$j1U~)e;*Oz+Ahza=$*c9!VNDKtWomK#(dgok^uKZm2`Jd|CRQs< zQtFsLdr^`yUH;jxUg1#8=pvCN9fS!2(mH}fJ1sRZjfjMmZ^DvmU;Q%{wdR*3`peO6 zMA_jbVm|1<+&~#P4P9E;b3u;nw9_-%adhO>PyQOCX3u;#Otyl_-rf$BFpUH}! zx%svau>hE~3D6(j`>dzfsD*aQFZ-IHvnOP*Ce$Wj@-`yy?G3Z7*~Edx#I~L3w#r69 z7)PKhgNvm(|A^spehq0jurMyyBdWn@+(_So2q@)I!?L*LwR82Xdp z{9-Ffnx@mP7SXok9V7t2iW;Ub297LXB_6P(&Mr=Nn@dJ|bNknlua8RwEWU;WPVs86 zojRNUXXq@$n(D(idA-|xN!zH10*l`c2v#1O!G09pxN?U00qv5T_1;b`cjQ80`h zkaNIEB!d|v0vx^$R))=#xH+TcRIKW_VUlZ-Dp^Ru)h2_0BLu;wDl=IcDRZzQ>w)!K zV#3b4IM`5gD!sxP{55BV8|;-n9c+{Rv;6fQ}NQbA3Fz|f<)*>d%ZFXsk( z-Y$@hvv2=o`*Kbp1`w_cVVHAcs?W+T znO;cYTNA_){%%Z3XLISHq|z}X7D4G6;ZxU0W(qBhn{!`{!z<=?jYD|G`aQw-(va^O zZ-*r#fws9~q#TgLB-~QVCfOD_Rj?v_6_8WUQCoBc3?YLEbTwE#$o&-fzaW}nW`$;v zjr!Z+1{eo@D+;AHcPPOw@-7~%z`HQgIH|HNl2&Ns?40MuNK^v6OF}%xf3SK zPWfkl6+7E$9GCMb)dPLJ%BISLQZo0HzU>w{iF!6k6-pUBMf)=4^0_6iF1ZT%TKYA6 zhSrp5F4Zbyd*15T87vn5PCUnopC12NiAL&A3W(|Ir_kHu)n(du9U?hG5 z8>4Q^X$a==i80(N=eqh*@5b&?zVep;0~Xzq=o_{8UkCAXs%^X@cX=-9Tkxk`k^==u z7x8|!ky+rBFz4?KIufA+r~GxC(<_LRoF*`rT^d-V91RsBIz*}Fqs%2F3&d^}Hdszz z>OPZHe}Z`m%%ILq@>cxgjq{F9RwW+%CH8-8LcM3QmT1WuUEq8ryEC)w>r8iAh&Ve1 zf)`hRslJi$4yst*TL$@5Yg#E?HQd{~etnN(uK6(y^VOzlz%TdK5sm%N)O0ahsjmA$&UBpgf`MIkV$>U>iKC;_6x zM@9mZ0JirJ^>!eqvCq`Wct2wd7~!a@GlQGJq(-v3w=)8VSmxAK%n;V4o|D4Z-{q<1 zgmI4YwbB_mu==Cqia>1q>g>yJz!srGiBQD9Pw*Wer5Q>kn|=RnVz(;5TGFQ`qh*Bv za+a)w1C6D!PE1tPo2@D~^R1W@kaKp1EESs4@;1p3C-P1)Q!pab`(2?c!L7Gb>atR3 zxX|iz-aGet)4-A8v(Vp8aHH78lwwO+KlsYXOmD6u1H>uLY6zEn{^d6Ph=~U?3KquB z)B>1I8$8;9um_L}{6`EtuPw}>Rry~rc#oyVx{C=o8G$t3w>mH&FQ!+WPn>@r&vT01 zhJY^fOw(A_Vf#vfiSCATsPD+tDyNQmZ*k`heud|pztq70==HdiOj1_J;gwS>q^EQh z!tkmmBj^|f5D+TQjo+29(iN$@r_@3v$C??IxjBUtffVXpXwoS?`H zF0brJwek~+43TCw+gjY{|8k_<#xcvu!wlOZh_?)n!eE^GhC8ccnrXv|;iikLB@(#cD-~%@Hog;o@sV8882eIRkiPXFRB|i00jC+U< zE_wF+o;&4>&D-`bOYa=aL4XHMHl&`Ar9{hq%V&R}!C7?>WahT)#nBr~cT({yPVv6> z$E`8eH0Qz}Cc%|*sCp%rU!ZUbY6U0dT;V0mfI9+-1IfX5_v;>;(m-4T0K(?zY4$Xn zD~ogNmzj}t?{cV27FrQ7S)M67(cuosOjS)VS<89KXYs2ovLuyJ#pGSFY#uNzE+)=N zpZP-dt_*hVEQC?zE-Tr4@T}hV^yK+ULl}^ZKhON!Sh&5ClBQ!4GHWLbSK3uxj|s`Iw(Ee?|9Z!2#-?dcZf041wQBwV9z(P_xxcB?^3&-0Brs65QpqGkBB|&A5o+8=9Xn>VWC3^MtT0ZD>vY+>09O zd2)RyJso zJ=U1l8x*1VDx9P`ks zcwjl7f5;=Wa?|=cC8cbk@w14<;v0{v$-FPg!Ih()Pf`YT7v9c&(f={Xd5+#AYGVKO zmvL)UYdJz*V;DiX7_3=af=YFO1L)|`A0g^VF#sv1tRRLp6XhZs-?n`V0OBvbjd=`Q z@9TECrzWI~;eo%tz;}$grOk7H!jychTVryGUha6xO@rrT+iCuLtcL5ERsM_Au z*`G{|+`D>n?P}{A*v-8VbnvY_3x%KBJaz&Mbpb+5iwA%M8Ihlh&&$Hn6$^004JQnJi|W1T9%g1;y?0r220%fy)k#^C^`Y0jh>CQWRfz`7?BS1hYD z0swjz!ZU(GjsS3;1PMjM-=)Cms`aViCAmNuEZkI*ij!0|L|}&FvuL^H1#Z%kYT#$q zAXtD}lKTmBdOab*Ix>>Jl2DID)DsXc%RElUHj?JHrjjzux*69fQDFrcnv2W<>HKFM zpkXqwl%z!7ibUP(Ap#qTdyOIS&9FptH25S_LRY@k0jXYaE4B#PLPB&<3(LC-J7|S! z8^{c7k(Oss`Vx^GDp+m?r3)7&$ z(YWPjKF~B25Fj&&IlxQm8OIs+jxTy+Sd}RP>wtsvw}PDHl*@QjS$RQH#W13+4iTs5~(v9*m*A|1KJY@VyQ5&oLtUoJ59ie(8NVTTmzD7a6Zh<~5^NhK@ zfx8`C=a!^yb>t|rVIQSjQLXUvRL9XNS^=VmgqYo^t^^g0Aui8tvAiJ&f5M}7x>51! zJcbV75?-MZwUV0cEOH&d?N_2yj=GzKqS0bkxN{gdQUJ#?;c>ajTwyl$3L8`?gA6Oj z8Juwp9LA^aPUXf?p#>xuT?=pi*-E@1HJK1V-?J*9N-BtR>rCK1nWS35>2JOuh}6KO zl6tz+vQ6oL{U=J;70K6Z^2jG zLI_$6Glp4})B+n~xC z@YCs6omd#+x>lz1nwbK7f6mx8?zSVc5(~fKfLL;OM?No$!?Ckw<*ID+WVc#}@dYpp zm%Zk0_Z!a*FLE1e)k~UJx{24Da^EZ+JU1^ZeG-Z+rm6i}uh(4S@v4`0+m<#9sJxmP z6jb%0Fs@Vfr`|9IH=jZJWT`?pzma=07`Yf@! z6_?~!$-2L2@(Y_|;m)Qm&Sp`D@)fu}I(^-J1NCJiHb9SOjH0}$7I)W7p;euyeDZQa z{FTaMm&E6AV`++%q2$N?vZM+a^aiznX07QjtrHpHTL^2kbTf#mFF>D@X|)pgLQMv` z1hU|TTNTUKtz4IFq*!kLJVB_;sGohU?!{z#4S+QtK=E5pe}^6?+Rc#Uw(zK6Cz_$Q ztYA`sTq%Ia$7*G(c^#Ud$gUxi;UTv1sEh%^6TQCSI^?S9`D(|Gdc&HZKal;HYJab0 zkHwl-^1?kaXIa#ftA?8y-c(jnXL$kZS<_PW{mv=i`WG(tDKe`;tOz}>HK#1&?%Q;h zAp*+?DZHWpkwarCaX^U7M6?%E)3YcXUU^pKfdCp=0I)bt#h+s2@22tJSGWb=`%{r^ z0ML~QREodnX{pSozNnW~ys3~a?ZMsP<`?C^1AYD$s$recUeTkYnCSDxkmo0BQk`73 zAHsB2D`i-#z|l*&xIH4^D#6W8y)M(`!K26`WFsK_^3>2{)uA2|vImQNdxocT5!r_> zjK0eDY?1X7LHOGu>oWlOF^h6IN~r{KUAkz(2#32KSoZn(J_VFV7Gtlhimval{2siF zHx}O18cw}9Fh78*UOaQh0ily@rC$htHyRK9O@^HrA$Ypct!1Rx-%Gbt-S<_C;#NFY zh^T0)fL+GJ3LOx4Fo;~1N+L~t=?8DibDm;{2L{4$#fw(XTyXVY-FTo!{bJ80e2>m= z@FuJ=IkYjgZa~tcclfy=$-!v(x15TUJqRB9EtRnOV50WerFClpuM}=rf!eo5US$RB zA(mB19r;si$7db~umG$0$3Lr1h0H3YXaQj0o>I9Z7%H|yg()~Fe{@Xw&xys6S9@SF zCgKOn(4uhdpBPyLP)r#v!IaB%Q3i^stX?DDIO;{*;CHQh3Gp=D=C0llYIT;XauPh5 zHl}o`GHFp@fr@0{d)olEw4=M^FoRaFv9SG7IvEAWw2mcV;4;@?&;N`KS@&pLjgKlq z!f3L(Em}c5f^X*pWqY5Pv_15HCG&=QB?5mpR% zw?Dh?4#Qoupiq$=N5~HJQ{@(&QtZ`oG)2t&!D+pDO#Hlm&Abc@cKv8f{r$Y=nQ<#l zaVr2;=?c%m3nqc&_W#IUy=-*&P>?R|Vst#0{V)@CEJX-uU-*?US-E}6aC)Jfs~E-x zELTphXRUv~x5$5Xx#PtLk!Q6<%d+@^S* zPP8LCIFWT^B$?c#5H>d@ykgwc(zc`^0#hiot$Z61$?URi|t<4*hFUybS` za*kNbNb(g&uK-a-0aGiq=Na_Lv*YTm)`Ip`>xC(W^>mT#;tvb=9--oVl1R3TJa*B~ za2xD38z-l>)eQkSHkQuA1}GfK)!N*P+TGl$979VQAJO_iVd<2bHY@C|20`Z~GLo z5reE_7@Md=lx`&bFYBxiA_D(%~@mA>jR#2BJ?Z z@mj7{*6pne$nDbQO=Ob;vV{}* z(i(Xr`YGr2@|Tx|EsIDp3Bjy`h#;T#{1HqH?n!zT)v?zGAghjE zu`e`LIvn%r@DM=&>cT#%_E=r~+WSAxvUZFr{1$93+Sywl{F-|mlGwq28+Dhu?acCc z&4HtF2sL+U21sc-RG4 zHenend-$nCN@B$>)hF+nC_3=&{d4LK>)H*$mo1E?pOq4jshE$YBt-SrBYMJ*6wWPl@9`*2oCavSeYL!KxZ%IYn<0H%bRM z)he9d+TA{T^B-8K_>N*>J3vvhDx^$!7}XfOiOa3(jrXOlHpH+ITskEGe$Cv__F*enrqDPgve_ZpP@JCKEh%XPEH*g~(tiMNG-#=Y)YQ&yb&}dm^ z0K7Qmxr=odf}g~#Ui!D``E^h0+Q&`HVhVS&(E{t)GcKXcb)`A*Hy-_RD+&$`7Jo(i zR97Q*#;&&-v6Ed|9B0egB)$m~mK@v7&cisXSFs;ObqkPuYWe_aSF@DEQ}pi>Ye40Z zJ+ZLB;`z6*<#tPpTeyFJ|I$Cnw-n^4&G0qaWHreH0vg1si|sA%THEOsg(*^U(OLe8 zLSebBb0Fvx!X#H_k<8SO79^qqr9O>@V%!PC06L_Svo_ntsA;Z>!; z(Now)hk>LFl~@ZVv%AWRh!DY`a!XBF=3CZjMW7ox?azpKk8==E!0$`9CYf+ z{l5af5s#{ec2Caczc5As7JD~Rxr%JHR)$FU*8ZR}@5DDQ5XYN?=USSHi>@${xr0o_ za8VoqFksap6qqRCK>Yv(+t6(M`Sq!&?_1loz5q!^%70CDZ{w7?Q*&_r$nOtl9Mn_` z3$bbeQJeEm&T4aLeWnEbryZ*bF1ZdGDEnl?&d>yszzg@RH~A4nzVY*_ttE&5OjM#8 z!Iyq6k`y`zBt==HD}JnO0?|eTJ@*y_5By~`qUB4Tu^*Ew zoSkHK!#cAFMKu?HXx*q-b6`|@{}=CKiWu0B;ycb(-4|{|{cOpC?1-P-mh@E%9eS?t2p+s^5-X@Z$!T?ohddC#Y}h@S=dk1m zND`S%{SA$RF$M;M_9A?P7G@s*{cez_Y3Do`l@=*x`PSA}T8VFx20R)dV>yj>{w%a zA=}UH|N%G3C+KJg-ud+d^uNz6@>*J*zopI%>T-WoqNV*+bF@qvzjW}$ESA^*xGtG z?J~S6+134WP#gdAw_G;dsfAz{DWUy*Piv!xE(&Z6>nj4L;h*m5ri_x@@Onn(Gxg1S z8Yj(2d&KPly{Oa!EcL{~DS;|>@ZjuI^q@2sG z*|)^mK4@Cs-7bd$2Jh@HRf4>q-^n)DcKMM7p71yqx8j(9(kx~pDJ|{rt>Q0veAhbFM%q1&O z0vrHuZI{1LD@3OndtL`&)te3dqeFX36K;mc@iuWCe%viTZHAY8*|2{q-(70Y^i$w7 zMebdPNxqIndN9fRnWx054T|7zINCfpkf{nhBVQNQ>MBysM=JyH zmolKOZ8GL`hlH+TCeneB#)JhwWS>?=I+g|RQc$C`H~iI8IlK>g7H1AD_l@p3{kZg- z`&)fk&g59=bfS7>)@Yao=FvTU=|k)q%H?6L1Sb#(PBJzn-+4bzBvwpbmB>X~FkSL+ zzGdT_2?pM~Jvwq>pnAPg)4U#Vg1k+vl#Ij2_Pbc-fjp_#MhF0uH(BJO#u0CC+-XMZ zf(dLJNya{5;kk1*H@;cOpo!m@B$fxH{i*|gljJCcLsy=cBkxaBpoI;4)S(#w>1 zD+M~(NzQ?{)gf-~u7!=&dUNI5a{g6>O;WvDdfEAzd=0;O29g^6=P=}+5D})q1lp^p zi<64;qA=E|xk|tQ%gJ`fEwT*XA7+8)zaiQWf0(@Mzq+jdQ!u$tWI(7#6(1OGKd8H8 z{ln=>&qk!MBdAmFCM%^i7%L!-gn9KsnV}l9FzVo7xRzw-{Iq1 z9VK0?iq>JN_kbzV6|<>u zUXH71aQB}lHC)`uEdB2C;lmI7ja$+O-Z}1m@Xf~lGJP3AAQUpLd*5|HBlZ++S)G2C zqNrDkBmcR7I#FG1U6La^j$Du_K$;rd7 z>qkFzH&+us~U0)5f>=bHL@ekM$H` zOSMvUMe}pj7~17rFi?9Q&o7z7=i2u8Q@3iM5<*pc{QDw!TCc;&B5%g2`nC`aBTRcw zWj}p5sd6aqhEJ=ps-EN_Iof@(tQ&GWPNs!8Q>s25WqrOJxe2%%%j#> zqK;U8dXxNg($B}v`3k1Dsb&*diP8SeH$d9KUc{7(4aY(}jjN9=&UEOuDor?=s`QTB zsvd`c2{S^7R2#iE9*ykj(^AZ{Ur!1Jyt_?*_eWS0b5^JNq@J|yFd*M1dJz3GU zvf)A@Zz4>cHJW^&SgU*0NNj7da1+Z^Y*A4X0@<-SLv-wjsxOXhnSzdxPo}1JdL1DT zDo9@u90O*8!j$`9f?8XttxykSv9BpiXz=$izhOo|Iizs~?s<~_hzz?zgKSA4px z+z0g^Sk7Zw2_r#<3e!|-pr=h&R9u}g|2g@ip`N5PPX~x@jk8lZ#HrjF7+BH!o4fqn zcJp<)i%u#?vEyGCL)*S;*p!(o*Wuy-aiFo;aT1H6_+WXnQz>9UR4ZU)8( z2b}*x{RkepUk>^9BF&Ei@f=7GqJc!GK%!)~i;vbWjk{g!aJ%$jE#l1@ets=n`War@ zosaAmefC+nD=20j6n)uU)WJROL(=s}YjLLTaX}1hsC(>(XTnoSiNv%jrb3cOPKxQ` zB|XknlY7BYa^o0J+jUnYIOC;M;M~cxu-5DWN(C%R4O%-RL#+ zawZFB(*7A}X_coZ&J8%>0tjWU7WFB4NqF9KhDa+@ZCA43 z(jb~`m1ayxodXMV`b^BtiAhg9G|p7`?*_U)vqF)5Q7I8JE=Zi##XkJIT0qh!^6?tJ zXvn(eSU@elyK**X4qOaqOYhct_Hm@Gz@h!G;cEf^%C~~4I3?N^A9L2jfXYm6vH3K) z$GcCI;INV6v_ia}m?f(ZdADHQ9$2?OHRPw%*xMjTe8q_X`3V~!(y}ePf1ryBd&)dt1T)jAz;ygG93GTD0*i3yf zuhVE;vTlR0ZBVbvO&xs=dHMP>l%xm&!b#8=Dl&#Fo36f#w z=WJdwRDW-8tY!YNU9To@*z+UILHiEDIsBuKoQG0f+=2kPRIMog^z=8UE^^4P4H_#d zn~CS$*yVYbD}2L*JJ%slmWJ(z=4Rqc??JUoec*8dl>On;c?7J8X-@Tv{WkkV5 z^^jI@?#WCoVW~PmnQ{Ls)!|{iym>~82-!=4Jvo??A$EKY&fN-&oM4JUL<%g$+P& zD>7UO4;nrycgwL{K!_eHvb+=T@wBZ@rgz#JnY_Kg-rdMi|3kQt|}&x-@iI3s%`ZZGZVCDkC-%^ z^3Q7+`gqYlPcm>Vb1@3NVs)h}W$BbL;@W4yuug$7vr7{}n;qi=@@4x)Yc``&;A2{VH%$_ptW%A=oadk$2b&gDwp@&2Onroipfkw=7oj>T0qos`)r<|{;xr+cYY2kQ0tlM}?r z#7mV^d`$U=8wjFGP=<~J=qx!!8r9WA zH_jh*orcAb(xfvZ0lBZQ<13K>ToCLr~0Ca%<8wQ7RO8}X4PD3U_5-YzFjz$9!kV3u~uRevM zW(U9`a;H3N#SCch%C+K~k+K35+&g!{GtzPnl?KhrV+RekcDkDLt7A^mlQtEAaCjgu zw`4<(;9rg1Rg#s_ISvsf+*gGLW6vVrWbgs^0+rGIdT80o@ZE>F{sq%oJEjU-_Fg_D zeh#EOjQ{rTP_a~Yla>rRdDytD=x>n$W5z^Jsk*czi1MhJ>~o4umi@FSQ7Td0U#vGT zQn~y~7pC;?e1B zO_HP`Y;tlMt29Pu{e0c<5fo;2!hSZ1ZVVSN37lS)TQSXP)@0IYLGS`3qqLU--aR3< z3QfsN<|19uD-IveJGn?&D>n&Rm!7@m$&j#_@-Zyzu`d3%KHRId*9KkVw~hd9A+0Zs zYd#}rBt?~3-uN(%kgZy!tjOqIVIt(7eOdlGw9-e-#XYlW0tTc;$5@DE$mya&EEFs= zi`zZpq)R=+2c^q824m(g<6g#8X$0)ln{%En-%5%Q0$(47OrYKhgBMDER5P<7c1hr8 zo^S6Mvj|6X8o@y5MKUv6s-dAE?|qW-tSKo88KL2n>HMk1q%;)Ky1UZs2SV4{3x;*q z+T42DtB|W#qqph^_%MQ)?wSl#i<7;r#cD{|0kR_9?fkcrJJmBVtisQ_l2Wf(z3er6 z*)E-;Y?T?g2HTBaeI5N;eUNZm;CZ!9KOg~8nZjdKf-20t>{e22^@~x{{}K~-dg$l7 z2NB^H?rX`=0(=9?+0TUmSm=}~hSAHnIr5Inu-c-L*-7Rk1_B5SGzfa&K$H9!WK;te z4yQIrG^3Fk(b)i2oX_7Yvxv+#Uf5jK9lfLgwAWiM2!LvEt(tx=0=M+IWUdVEuEm$! zx6<3#D7MsdMFr+^y%Fr_W0(JEUrpg=eBolXdaro{?<|E@a-e{1+<)MizNoiPJ1#W- z?A7+WNe?^>Wmltrb}4ba=~fbC-|BMr(I35kI=cnee@4)ldiWsLr!SBU4e_dYiWS_j zk$akx^ikCst=_r}2S^yEcXi76P%x(l9t1@6@?9;g?St?!io*BhQ?-9@{#evMFU8~6 z#8f`rIv)J_+t>4`Cf8Nx@K+BCA6Z-Uxv=tUO8p#-06QgC7cV<@pK5s&BOmw3!(AcT z+xy;T$2>6;S`ji((@J@qxkbWYNx5M}vl&d;1M$|)U$4}r zUH{23+FFobEjjkmH7RBqs|B_28Dt_bWrTo5tLfFZH*#XKQS5Afqp$wX$d7ng$p{Y1 z*B#r)8CB5{iJyy*a`Xk3Q|#X@Id9wyEoh#kQq#r!l*P8qIwGp z&r0)z0|jy#qc^>|<96@wQly61{f6T$Cj+&9h&;GGYt3a@#n{FylD)A^EXHEkRIR&! zODRp|P9HKdD>4zbSf;}KBUx`|A-?weZc;G6e6GZ3oAmDew#n7@8`ZkI#q9&! zYC==4Hydi78+8qRD;UY$(?I+^DiaXvDl$L!+!6Ojwsg2SUlm;KAm&y$Lvfi-%DF0q zr86rmsvLkcc*y0fuAg2j%K}FGEcpDH@7W@ zzeJ&|OGf-F=Jdohdt(yD^+Nb(?ux0@JmKxkjq>pVhgE6b=qgFi>E|7f*SYeq%r~^p z1$BY*o>TE$Kg&+JOGgnzv8*2Odjt=7ujT z^cb{BYAC$*otP=>{g~fT6R#+G%gDw1e13Y$gZHWJVHMMGHOp$hO=cFwEfB|dz89=E z0{)9>v~mCtpb!qwM}rF@h@^Moe7MeC`y_ql9ao)fh$31%1iy|KR3&$U=H^hPgc5tD>JdU#WC9+cMm{stIJeDPvyd?t?f}n|+D!4jq*)Zk?R0#rvmS z!t?a63evIjdzCM%&xU-393E&L`tv+k9~Ui&`Zl+EcXcLfW9$c&M^f=VyS&od+*dM6 zYQb8!b>F}Jhsy1JTHt%V;>v;D)%7=s^6R(cUfNY%e{?y>CE=~r`Re2M+aLeEGURyp zDRI(W9YC{`vJNQ+qjPyx;DCIBSFdO&=CuF^A?MzkW6}L2n9DNLDM||@h*P=cDh$v) zBn4|cu<>T!X2bF;PL5wryOWqJ*2zSB_AMK+==LTE536#U=r>s)EEH#9#?N;3BUiK` zZu;BJUAeP7qIR)u1XPMNou|9tvKzg0TL^otdmHI8MWELyqHB3x)zTkHTHn8Ki~ zH9YpZOxVz5_`^A?;$cXTPYZE%zsqT+4{`^~)m`i%Q|_VIjy^<8A^H~HPEn4=2EeY8N49Na7QUnrtDIyK z$bEwiVqgC1CaHGtz#{LVNuq|mfW&j$=92rvnwq|CM-f-1pAL!NP90I5=5!YSwFm8d*||6sb&>6bYqL6U%kn^G#8jW~{|Y zY)TR`LjbFku*^F^#>hWe*^t%8P)g*b{gL4#N+p5`%hHb{mPp8V!@DV4^7qpedq*sX zAc_(!N;1}p{mBYB$wFOIJ~`v-yc)F^}u_Q2K8$53Z;mR|C=SK3B zCWWKdW~}4lw5L|>%PpQ#fQ?U>e0>9mVA@*gBEI}kc;umng}emI*GpN%zb3yMcYJ74 zHk~HlK?H?Hsi1zg;0gck;#3Q2K}f0dJ$bf*v8V03TkY%Xu7MT~OQbv9ZvDXB(YE_uk;YHJtIw$EI==QYgK;7N`qOIDys?*G+A$Jwwr8sjVTq6 zC{c_Ok!JE!Bi@}RiBFh-IU@zIoO~}^(3P=7_I<0v5fy-t!v69GH?!&?6NYnCgJIXi zFst{DW8f)j(fb(2v56!H;6pP;#xZiES^aX^|Hf1gjg+zbst=8nH}_QsMwE8VY(XUtr@(m> ze5R;%qZyo%R@D|=_2b!s>fxJHT@91@Xk)j=9}M!yx$L1-MIIuc@qH3 zp3Hk4Z?6rUckUFXJ$bd*U|lQ9Ef$zu1~D4)C7t>9X=^l_o&mq{@aLEPm9`5DLyvy{ zIC?!>YyWuY@9&c@?_VuEeoUtWP`NEey*qR(3C{2#B(rMmZ>4aW$!(|dx@9`yH(5ir z(}jmzbMZtjUSZvx=+GTv%uPuNAIaQQTO|PgYz$qqt_&p zUth6?N}Sv03v9HAg(N#O`8Ot4vEYSbkKi!Uxf6WT0``LMk0;t*rC~C_1ZXh_E1meo zRs}NX$yNbSV)tqc5}ny=AjkXpM*2)NzT2slu~X!oKpoCn)&gcAJk2b8M~NwN<%JJx z*K0~+wHQ zH$a(*kRRA);Kdof#jerW`*!c*OZ@0@nC<;YnVApdhZ4Q-n!o;P{WP-8X3k!b^G;qB zkp4K`ferk=_u<}zftSiC+WE(PGl#eE+uO`d))5htc5Vto;*-KP>G5lbqkH`7_amE? zXAi$z`H*PMJ_Ej{xZh0fI1F9Dtne>PvcUeTU%a7*q%NJUjeqe3W>^zM+##@Ojcq14 zf8Pkclly(cx$Vbc%a3A^O<{A_>21fxOTsOd4_norl%B6RE7%=l{qlX|YwJSzxe1pnOB34K6f+UcTRWj%?p$6iZA=L9%A2BrBKdg|0*fialP4LPf!p~;w3Kx4Fiep?htIh-#;DZ7i^M(Z@*T-c!s)S< z&nhK`6~5;sk1%Lw7`OhUQ0leLFFQF{iwU)4Oq%+%k4a&0RkO&ry9;()`%f1OF!x$8 z=44WO?kL}tzzlRvjR$>=%#lAyVF#!wvNNh2z(0VGzRnCNaODBP<5_Nv>mR!<^dH83 zN+!G1pv*0;zC=QE!*bw*!OZvNp%4}dl^Kvi!SD~a#VRo==k$j;^jsv^2NyF8Mhszi zmt?Un?6}0g<2>W~5wWKpP@Q+%`tCAm*Iieoz7NRe*?V#3)Uk%7Tm2jkCavT!TZ$Wi_Q#Y#J7=9BRw$r{Fu5b<<1-uj$=CUVC}rXrBK&2j;tb;fAIRZ>;mFKq2}Uh7Z< z@CDfyHv7;6>xw|QWA-=`jX(FY5;}m3#nN)G+y1yVCUv~&T%1xGc7e|eeUkRViL`FHl$f3D~oedDJW zt=*HpjtEFerz>A7VDXpg@0>48SN>|9bN-O2yPpQZyc@`7a@TT_Nt3lNug|~BDh1Q$ zv|wi+Nnv9qkBa=m7;07fC8c_diOFiyqD-GfJ%u(+4OjEhBe*$pxEEPD zYU&LS_O2<$m2f@Nf_QFJ?Gk@eQUXv`_A{1-m}>$2p?sOBl1uoUT%2rqs3%%@Uw&3b0;wE8N(c( z6UjSt%&7D~Ls;yTq=0_mq{2S+T~O>W*QY6n;zMeV|MOw?0*|75c9xG-6CLh@<=Y<3 zYEOK<_Vd*|pkDqg!8fQJg_@B&seCbq*Pir5KcGPLsW=8s&zL6-FjvY0*j>hw#4@&+ zwcY%PpBSjbNV$vsxd!Ga`yn5&_vmUSirpC7vk*zMU z!7mbf1eMuc<|SC^XoUSn<_)fLTFP189l9YU{wo{sR?jyzuPlAn zeo%%0^Vxc%`6+>M`$?_+@#Qi6(Y`s|H)-`Le>Y*0H^&dA2j^v(rNka?M`ju?inCLN zCsamM)2<7Qu)M+;D^Wm8iiaTKH0-#l|1q+<4B=E>g15Cu&c8)L3)89FM!xV!KsW&1 z!I?={^mW|uNf5Iu7O~J&NN4Z-%Bl%A&ONuo3BHxXa_E=ewa@#REiP7qoz4l1;bh;! z!TwN@bUeHV%Wgl$yhUYY&^n7~%psgmKPvQpmd-t#$^ZZ3_l|aAb3QZYv*s8=+l(B` zshs6lk_xF09XDp?*a$fmLK2$Dp{SYD94bmk$T^jYlIY~O?{)qD*|mSR>%Ml~_x;}e zdOx3!2a^LoS%%0igU@jw_l_XXvtR*uoG%s1j7C9%F}$)X6YGgP=W*f9{sO@XLFbR0 zY&mwk4>OmSwDdY!P~iBvALs`FaIIND8G&^ppf2K2C3uI+LCBmwL_X)(+&W~HEzmH5 z@|Z*21(31PFgnWvz#&&!PduasWxV#jkH_6#XPlBs0Y(^vM4v-$(m?d(Uqmc>G-cnN z%MX-r69hrgzj^#TCy;b;ert5ktx3T$P*Pn`QHAS&F9``eH5 zbVX8@VKZFo8c&IB)+zfs)h-NT!qh^`GTW74}GbgtbrtC4dCjy_a(RU{ze$!EG0qg}=C*9Yl z*MkmGlF@pau5XD5tyaFZ+-Z&@Fh6oyZ`->u2%Ve9XmmyA!cw3fy7Fb~d7W`D zhvjVCSE5YcSu{)u2@yu5;&ErF!bRKglK4G`9*W%JU0p51{$vYP{}9q%#xCKo+XTV2 zAi*Lox&V*+h{rANvV=b1aie9hQCAqm4Q2=cMnO0&JmdfpQ00TDTxH$EWL>56+_mzS zIYNgM@_OdNLsk+BH3CnpB)vskm|4wy#t}T8hvxG!Ua|9^83@k6Fwsch6-SUm#5@2n zuVMVM0ft+4aW4MG16)C(Rsj$c#6V`jTf9?!3Lekh5Ew_t*{6tBu&f);ejQ=$x+-AJ z_drI4pp95`HZ+(8br^vHBXIBrrk)_!mxRk{Ox?Pn*PbNeue5)t8n?{3=sgGX2B43n zq24T*HxB9pKm$22A0j+B8a}!X8zt~xuLD5t;W8K`xYQ7z3-HzN1ErdH$U8o=ayJ^h zj|JP0E9ox0XaPD}4d+Vr3I_}?G_SW$fePPq~bH#`*!5>r4OW)uclF(!fD7)j??x6Att|71owg>0MTxO|3q4q4KoM z9X@H&P6lblKJA`$|+`!fs^ z#}dqQ6v&Od+ZTk(pE~W=in}&g6UTzgtuuyO50;(3T<9S3CL8Bvh?`+!X9z+o1fjjs zaAXYF#vB*0j;W1y#Da<+yUTn7`*k+m{;jdE#|;}tjM~LJk7zsp1c>=0p%)`q_$YE_ zU0{(@e>Dha;|hitK%Cn7GF{MW8mPlj|=dBaZ;?)q#U z4eG~$TW?*qU|X-E%m2f?VnK!o+U+B3p|@-v3mrbr25^nS7cq4N)IBz8goqfSqB_`^ zJc2`)R7SEZ@_O`x%R%R9t(d|fyh z$^bE2$N_bzpF?yQOC%+{? ze%~QZ9%*Bv`=e`yTm`Yk-fbi3g16|@bC`ZtbUzh6e4~+NhHS;7x?C|e_Yf;Afx4kb zek=h`;PELc+?xuI;d9km8|wj~1`bLpz41QbN*$r8KL}Ad<^AEOg~mqQ>pQjlu;2!0aD(232Cx#SxzYcRdXie4og!EInQOqx4{Xv!wP+D` zP;~%*(6Er435{V-l(C;t+f#p_+k&{7QSIs(XqHLSJr?p26*)N~2r&>^#KA|S;a~%J zC>3gLnPI|$@_AyX=3rWnQT2o?U7t`5(U|&ZjI&%v?@&`4@rq2*-WPr{cO9F-!4=3Z z!EONPAmV1(f(%Vu;hf-!D8vg_#3_tm4ixagAz}f5LlhLwKJ;U6o!_a1P4Cfl7RujqB#P=AXzF1#RswRcMlVB9E*e%v927i1bRMt-L-2f zuM12&B3+*Fl*)EyW1g|mpQ-|ZvcNBSfho)Ahq#XVbqoVQ18nTx6Wsv&X>U|1xV$RM zpQGstQR_nhge(2)3`aTI;zZBBw@ug2S)#hd3IEtcJ?wt6l@g^3dTMzA_l}CKA+$&>T5ta*q~_rGf`i4f2Jzqqc|cg*(+(PQ zMAWkFPxRmb2cx8Pp^eH`)*XrqAG+qp1*qJ2tEhPm+$0{y&A9#>T`G_bCR_%i1OfM5 z;7XSc?k(q%^IA{I$&NW!y4;1{1QnGFQdof=+`iz05CiSMWF}-(H(2hJ9 zp{)#|LlYvrsfWLZ&4w*n)?O6}DRCe)jt=c$?%u&F=Qf{Ik)romN|z34T4EmJ`Y=j` zT7rPFKhEmS^-$_ChSme#xZDWzGCN-}I8BfJeaL@}hK6!&9;Z0Z_X-K`eQPAiH&+S; zr&Pzt?m(eG*PiIa>~Y-cKPs>B&$4A6Kk~;C7dwJHCt3>9g@&>wvikUBCzmDc!`+fObGp>P+0_L7Wc4LIt7Pv5i zP*f1?P&&>Lk1OJ!AlZ|ye^AWQXAg*}pD0+t57-SNHZ!bHb@bi8SF+n3noTph4>_}< z!R|iKbQB|nzrA`*bH;ATzCe&P(!2$q0@86^;%LvICnJV$)Npr+xH6&?%-}X06!1a~ zH|R1bK7IeLoJdSKx1T78`t3auFjTq^gUp|S#Y`^qPaq>QC%W*+Bo-o-fRI1} zEiO+4lzPuHC)a0sdLKiq(9IDPtctJ0PQ4>Y|He3b0Glm)q}0%-^R-rtK~%-fuua{1IK=IBq8HOTe>! zey6Ln{91j7pu?N1HNvm(A4_MnU2f-WhY4J)o2wGk`c+c*r(^2n)eOYm3q=?O;R^){7cQ!`KMR_f`RRS_9`26N>f1TgvTiEB z26;^?HG_kgwZdHtLj3r`81?^@+t>8H^sK3IbD^|YMOS~smFj=dQ94~KRg15mKR4S5 zdV21P1v*%-q#oyh`2rBonYab_d4Vqd8^w)hewu#C-VN*;Uk;fMZIyNYcWn|Kz&Ml~9iQU)fd9?Ol)|Bl2^Kl%=uB&pd__uLah4cDXVzY5@A>f>|dT%MNgf^Xi zx^?N`_xD%6%gle^;x54ZMt@eGcsT4WILdH2gc~05uE$Hdypx2DBHXcn{h@bp%%+sT z3?x>lX@rrLY3Emm{nJ^v-%ZxLbSwDD$}=HT(I-=&+@D|1$_NTyq2I)L;L)@fIL(7e zhI>A&yME_sitM|JdG-0bhUGVm!4@YPcR6MUvzv{)xgS@p_|NAk+VAP7Qy$Wtf!KW- zzYT-UTocwl>%8#&Ei9=*Qt5ty)BlN6`7B_72IjE<^$bK%fwCGoZUEe;Dj7=+;?0@j zAkW9%E{k^bXGOw8uss6WS6(trnhM<2C?P#pgx@~=G}$aSR6EZ_mPt}Wp90&SA0n4W zk_vH8V#S^Ax-*=v8MuQ^PuyeNuMz1jI{fKKLqO*hnCy`#+Y7s%^xp>#efFl;9s}XD zJ$3dmCGmxg`$43-%{C!f(`Y5CXPu0Y zC*LAta-z~jadYz9JNx*7OX|N*u1`cw8SGvQ2z^i|ebB!kIUIgb*Vx;uAyCiux!B<` zUk6Z6ntZ^oxR0;vv84iK3e=`wy4XMZ=O;KDKwrPe$3mTb=a;{%%v_uaF$a=GA-Lo5 z`1U_y?ayu}30!W@sj>tXf-%bGmgm3NP8Sl|2-^KDfnWLx^KYS|J5 zUQif0^;yy%kg}87X?ASL_YFx{F0d`Q{)ulnU25!?{6u@NOIuCQuvF9wd4b;=NqBMV z+%}lnpzv8#K{$kvPZ^)@`eOWHBnzF9t5y9;~{~UBN(cydzWkXEBH5_YRC~A zm;%6bU`QXUyqi@Za^~LMB45wV&%5^NxkcG-Re_{q*>W6`qnp#7UgKAv;kEs`%}?GM zdnEk<&z1g{6J=;E53@Or*G~P#P~gEgMU?jhC_$-Cb9MHPNwY=0vcS?RlgISH47^pM`fF5V`G}X$>MuD5rN{RT*Tu;YW?`%DfqNn=erVhA<{1v4$DZ_ z2s;5I{MMn+R5upV1UBwA2d%F2jpR;@7inzRy|=fnXt@=fMDC+<9yb$yKQ9@W^rdG)JRUPB$oKJWg2<2x2nz?SmG(gy5d)Zd6DVr>v2Jh5bGQc~0oo4KCzKrnf6Uz03#Bn)Sq5Z#LlpN>8OzE(q z_CLO-kH#X8i^jaFe=kmJx-qjjl^kbYdA4%n#Kh75=9`~avS&OFJ`A0jpnXA+?`tH4 zZJ+94+>uglS1FD%sMxIGNd!e^C$Ef9-@x7m=PIp~%@d^~WKKWeGJUcX_9I{993P@3l%`+7$rJfy_*pl~h@5yYNAaMP6p)1J{;3UYq zv)Pobo|ojgM>&JUY$c^%g6tA)Sp2SdOpR-=>dd%k5CqCaHZ1u1ZHFkjZ#lx83(Z&~ElFuW-Vjl(dAX_ged2yGjfcJJ ze}IUWc@ej~j;UaRx1mzqM7YbESA%H9NxRJ0gVP#cj4}o8-BNb ziM$an9>7Ws7ucQ7iFryRY`9|rP@@r>`q7AJ{)Fea^J@oH<;Ku`e;<5!b!l1QVxnM_ zlpOP|>ExlS4}=qbJGdShH_gnoKZ}1txJ&YH6T!>8WDuj?qgUJ8(Ysz2y0hq&w>yMTff2JF#&R%48Ev zFDg>UCpPsorFU?5sw1&3v!T-G%AebmA<2qsWnuVv;!;Z_Tuen-*wzX%=xLNJCtbf8 zu~8fHa>c^W^;ft8MmIdLczlBPT9ggZxgGaBg5}jfm(9$>RC_9+8(4h>!`$FVYgIj~ zc3rg%!VBi?v%?>F5nO=5JKo>2R|8SUFDm4OilZ z?pO6^=B&1siJpe*^8az?u^t~^2Z~mfS?%H7))su-=DXldZH+(NUru>s38fkv^p6dt zZt2L2j~yWG-cUaCZO@6OpnLH{zkLg2*3;mYG5IDY`#u-I6d;B$j!H#zZ zP2*U{PvxshzsZ(iD7g}>YLF8c|Hz2{KxgrUB~>w@cIiygU1H^-$AA4yT5sC}hBuY+j%v=FeX`YJu_JyVBv|bpZ|u}|!}T^r!4ILmN2gUa6WI6= zxVO<>ABZHm5!qC$`mYcseS)|OvKnoIhIkaMHxXOrTEigN@1khGAT&Be_UC$H$99qY z=;H-#1%YoGyT52x=iuC?TyH$A-t|%F1-a!=>uUuTyjQ3jt8G3`ds%+))2^KJ9=Tul zHG8jGKTv5z$8qo1q+CvDZb|B_AE7(9L6HO8`vkLw@+8@^eRCFO-P-z3PhxKW5=bLj z$ZrsL88Vr)g0^EkrDIIFW3@1A8ew?8t1dbfxsRi|z!*9y%pl$fi08n2kfVNC-@iRX zUE&^?PP?)wIq|9WX*^2+ls+9={NuX-ZYg`-w*X^-`1cEbIpTIAwM%jXCcTrkKDxj9 zRrfMF`|Q0otCNhhd%e8kjyOo^$04=rL%D49K0kz&+NF9sT2I&}>OXgb&rFR*e$5d8 zMETw8Ns#^;xk0Jz;IQ3CgzbW`ZHj^I(p_1_uH-6O`ATBLuw$mh@b#MR^2r*NIvY-; zEAb-D(2JF9<3SOh6DT+9)DgAUQQ^_V>;cVAG55Z$DWU(qRkVChlaxY;m?8KvfL#pR z9^lzyM(neUnTG+!nIM6Ik2+5+jDBu&32{$<+O)Y2mnG}iQgZ}S9c*_dVVj!CD`_b zq$aVb_nQ$4_Q8~YsQQ) z2_x*?zhwK-rk);>u7*SZ06)fhpu)TeE*>PjK;KI zFlsP!9z1)n$&jnkoE%_JHq1;@zxeuY6z{8Nmv$XOzJ`gAVoJe|nE!a~JZ86*E<)BD z%a^k#7!&a1fi6ka6m6zuzCv|1CP!9{mHNBynvEU#k1hanV#xF=WpE{21rJAp$)!m1 zDf`##XaKtHp6xN=YflN?>=(H>5jLG$>)CZ&6{Sc(pb^h#9IvtFS69T*?XS?YB9kA= zuGzpIdiW#l&G2ciXf3Ujqf*s*lgY#JO!S6J%0uSKaQBy*nFU?fuLji&nj*`hQNggQi5y?DUzYR*~ml%kMvE0!{qQlm8Q%tRaiAewBN;RgY zfF=M~;py4tOg*R^Gd>CChBW8PjYoX=fjyaKZ`m>CF+@s!TN^wHaUUhHJS1Ul%y}{D zUc8eI=2I?s6Ci>Mh=)2-mc7ev@@vgW&L4W4+@U4li>_dT`CT954{vBeFD}8H%H^kW zJ*yNN4JtxOmvJ3sjtHOtY(t=@dE-)z5ypJ|5s8TY z46>iTfsg6j?QkDWD*yxh^e)0>tC@N-T@gk~sMA)XWl z0|bZ_0bRd#m_7|;>C%#TfT@n_sVn+U$=xrv5i1uZi1Xgv88g04oYQWDY|cU+F9Kjg z7o&X$LZg=s_FZ-}kXUq1_Xf+mf`rd)k?lbdCXh7-Y^$k5{0?MpPdxw|hQv$c&1q{XyzW_&p2`#Q zFkSXkK>R0h@__=vW)AAb`_Q8O>c_%~_3ISlmDaCqE_rM!wFNPI`E8mjP|cv$%`MC2 zT|4^Eit#q*pEK)>CgKT+8GbPJ+AIpQ?RazMa8k`ws(gSGH)y5)l^xS8M~5+YVcMBPX^{n2|Fwxz|tq_C00$@G1v(P@&Zt zbozc!<#N<>CCXp{96dcV(jkEvr@9gvZT7q`8+THZz#=}-H7I#Q<2+verC#*d>+D*F(_)$L$K zbeW*UhQtkYx`$~v0Ib!`g}i(A;X;-V_A2?S?$fey;RptGHGsA2JqLHW6jSdo{@YnM zD3D~a4U#;Tk+^-^+M908X8y|xb?8GGw?{ikC40yF2u&Q^^OOjWv>OUaITLO9Dc%n@7YCSaNSGiD zRj1Cea(-lGR+h%3jONJUo=C!}f>sEt6z21P=?GS6-K6Q?w}|U~`M7!C7QEvJqr))z zdIN9MW9xMK2=zn>*a#1GA+C8zgnInPoeJJ(Fd@uIranJ^D&d&y!b14dh@p#;V@YPy zxos}q9~bxE%rjF)q?OZX@pRf;k`03is|l?y3q036wmX#AeQab*JiA+~sts5|MFm%W z{?+sgN%4HPRnOb>oZYHp146DKARgy>D;ukF&d@q-s4@Xe{^@!_V@NY)yi%x59GJ;G zm*l;3fC)RnvpPQ)p7_Bo`OD+Hb$nk{#*s#lEKfXuwDLTed0Hb)Di0tX-#Yo4mAW?; za;MF=WUCza1`-wh-CK3ojN!hE(thE^|0#98o=(EiBnuL)2vOB_$;Vi^7xQ+Pp77tWd~YW~v=dA;(HMopvyg1$(k zcYQ_;Ypbi-1&q&qUZrMce@mY7Vvy=OhKjRxbsK(z*cZRk5sL8;eN*FtPm8g<#o4PVTw2$b9 z<$F?_&KXGbu#^wv=$`ndI+&~N^&kpaHoISZ{@*ABU!U*9MDg*!?56TWu*#_P=7IN& zr{^5c3faCF10KaLRHw=AxZG4!*nN_%a%ThsSR-x#R99E-!D><0BPTz#eC}%LxwNs^ zh*1DSoW*~Ad@DJ@4xNwHJ;`t?xW7vSh+p(HiKG`P*W?w%fY`Wu_-H$_3GkG)RF(ivpEx~& z>v&xDoF^`nt<{E45;XP3T55A{W22vB#QKJv(CYyx%VM5cZjXe22t}jw&xVkCrNc_d zywQy$>wwFP^Jgz@2D20ZRyY|}UA0WQhVVHnxOW1-IqnBE_s+yWUB5oNzistg(H_73PBc)l0@ z*$o#5EFp*(RQuq|P-FsuR;TVy63afIjPxSCq^o2aAFNK1WY-|mhYY^Ow4;F`E|RDc zFM*@Mc7g5p-QtWWuA|+pjm1IRg^&I@P5XZTad%$6@+u}YS$)m>3RzlJ2e97mLXk5+ zwg`1%DiGApg$T#c^j{;SWXnGnU_`Mha5Rq;ejtto7SQAnp;M)s*U2OqPp79y7tBPw zY32dUg^vz4apY%hn=wItVCpM_&ecDsNye1<6t$|LllWHHvmK-NFdy)Ma%sx%gI1UF zbu#se#WwFtL*8#rKB9w18px6WyI)(Yp*!NVL+5wj)Lhh!53h?C7PX!VkW#kd5QV+L zBmpVt&NM0^dPHDX+qf|Y_C`I>i2BpQEQ*=#eDr}vx*w@o&$+Q*xuoWVgOGgHhx*lB z3%}R_m2}+@`+qmjVK14xt$Im62$M#9l;^wP=MF^?5Tx^xfbE|+Wvls z*j!PS_p5jWA|`+=#RhKa0vB}rgPru}6eGl;k^mux^dzZKeu^S9CyNa*?NfM-Z}6sr zIE0+4CI}@6EX^Lq0z{@0o2>G7&9vXn0dLeu`PDq3%AwdC+*-*hEWq?3! z&v}7%1tk$~slu0aZ#d|dF}NT5jnoru4tleba}M)|=ETq*A$ivn)bE;-1eF`x5c+5C z4*7pG%us2hr~@p`VBZDd{PkP^6E^G@OQb!C8?oeRiY7#TIbY|25K|6;ywucFBF#ZU z1J53)>Zm?=<%5N$8w;k;zBk?enJHd1 z)D+`_;K5|$MQa^5xDgQA6Ao|~{qf1##0|ZFVN{4hJVK~0(&ac6Es1g@go|wC!Kp3WA*ttDGSI+vSCx`G zxUbjrEEKSRV#?{OB=&A+o!SlLjp@3APs9OCk-9JShu$T>zT@|`v_{Wr@DNms@-cd;_B#T$&DiW;d zYU$`&R#!uqMy{p(UZsVx*;9ntJB8ZgwHHcAk-egOwg)p&hHR7sMN_7R2$gvA*5PI5 zX}xxaN$l#8Cm*zPUAZtLfbIHf$t33ciD?6XfU={X1bux;4Zno%b;;dKD@cB()`ED% z6RGHYHr=hNyDxR>&A0xwl^UDXG!-Lwmag%G>KZ4|2j!=SPW)pR(%=>E9tv* z@tps88<75>eUP49d^lA<219OkF#cgHxQp3%YOQ;{@IuW8mk&WczZ85-eo$G?-15ns zZG16&fa;)GsF+eIq2!^-JPWLk32H~2)OaalalcmXP>lf}bG4%K3kNe{gk`O1>mQO3 z*_XXqu00cDkn^ZDdXrt&lN2Y7m_J9KgNQ0X;gQg2d*dY{3}==F z1Od>HD%LqF^Wl>2om4{;aTk~f@b}m5mZfVpL~~>gzY%p?#vJfZ665H8ML9l(y3VDH zd{GLrX1XmtXg#Dq(0;D-6G^5>G*~Cc7fN6n|PdGiR<5s+XUe%2yJ6N29+qO;fn zHta;+94ooLup;$ur)Oc^Z1=^V#FW7&wDAJOPGIyYmd;S<#Cmk{eK(O_7N#xW&&I$5 zbRre%d}iwPR^t9E0)SP;O61|>rWDO6-07a%IQ(|ksRQJE)b@zXFcdWKSW7dpb?=n(&`JGf(%Q7$m=qgmAtg2EfhFM@R z07gu`D20MJuIE+hg3_sJmk;>cCzex}?6=;5Pl9yDXsT9;yiY@~H(tPX2CIGOA zKgD}sgl8v&iG@}4X)~}rGfBSj2#ICi8H5_^oh8>Lz5WY`t&^TBLA~)W$*RPOLik4z zU|usbrRV$h6hk=ITg6*TY>KP>>3JUi+y)F%q>IP)g zIu^tR6?K^vP7xCS2B3kJJ(vdZh-Yy!D9UvHDjQlO*^QO`7l` zu16HN{^rY!1DYH{GO;lnd9C>@=%8v6TQiBk9IkwWd+$tzZwpYjyELJ*4&`I{qamcS z-J`p@U?nlIlIxL652qJx=l={SsuzHDd5TsoP^%G}e_h?C&0xwJgk0GzWl4ud5f8>u z!=ZC2mQwOe#4Dvx!*9ZfPKX4RsKj_4x1`{vMLD#t09=wv!rw~MLiW*9p8kah=P&|Q zAqMMVYVKm(*IdoY^tQSYs6Xe2H%^JFcwk9YuQuzhnveBO|4Ywq3|N0KnqKH)vr%bz< z1N{fSWGh62#t>{lnED$ZZ#?}=qilFba1z0xLL8b9ltJ1_%TU|xzTFPp%QzI6 zds|R>np{J4f7Am&Ip8!pghdG2qZ^XwrF=)fxhD2Pgd_WZ znjuqwx=#%1Tht>%SCXdFgaHm>7&xchgDK-5>Ye}8ccFajtF(;!VdKHuu9>CymEw(Z zQoOCXKMl1+RoE_)CaPa8>qi{om?PuILr)S!GkB0g*2vaGrW5_?cVe5sgL z8xgB;JU#JaI=9AQ)nR#{+jwj>bIXRrt|d>}WGT~S=;h+NC&;QGV2mg-3^Y9Fkein! z0ge!E+;pU%=v-xoZU9uKn!iKS$!2Yn(Y#yHb8}AF+&PJ4sR5MOkP39k zZ6EnZEHcI+8PkO6AV3P#K<>%Wzbh_Aw~^>E8y$L(!}#PPzR@EwE~N*AfibusC6RGw zr5NJ2DY7%%PSir8 zjsAq$HlEVNydqKcDHI5RxogXS`kED!f>K}^L;)5@XqzJ|#?=-B9{?cg`bR3a&S+&# z&zpK2K3^MsldH#v#r(J2msY#{5xgfz-+>~UPfN09Qmi+-VNXA2N%Y9nkwm7W8W<#z z$taR4Noeh3+)e5e38+X$7bPFW|7Mb9-h=TkftXYF2ZKru+lqB?ur*Z0HX%1V+Kp2; zsR6rs0N&ulrCFW0{v2J0UV6$l;(19eeY;fW=f5TMaj+(lThl_nuigXCCH|73+vdlR zhXLdmM<^Hc?sU>Au+7}cm}b;#?rez4!|Oq`x59+7}>&hL|CPITF2|u~#->h>;aDJB7TC!%8)-kXO0etvZjGFT<`Obx^ zzQ{Udod-s%Wb1w3RL+byC{gw;MeJYeCf^6$;CUH)YYt{z9L<73gHRT>H$Op_YaK1K%M7^V_ z(j~d3tKiJlo;+q=eAc1~JYR8ZekD|~slpOnsfDWqDMt6rez$tx1leo2e}9jazmK!) zy1i7KeeMG^z?YBf+dL*}ozw_9bX@!rElw!$uWz8;)9wy$esc5Jn91(Fakf30(&ezv zgX9moC0r~=0-URRtVxV3me8*O3^QiGsA5sNNzxvsNV_Rx>x*OH*qm^tuP$`ZNQ|r@ zMcK!Hr%mTCE+l&JvoyL)O5=THnwKPWaYyd}kIOBcn2ROPtBKzGvEg@7TbFp+OF6nv z`9Xl+Y3tTj>#rshVyr|FC04OVTC*oumJ%#$N;W=k?@S)p9FiY^y!JmIX=zL92&|Sn zRiX!yz}<(HkC3G{QfB-d*687k(nG2SP4aZYccfsOI1!XRc_hY>d24<(`O$-WdOcij zjF-BljgIDzOoblnv7bIgQG_@Mpt~1XBAr!)eqzKl2<_@T$pJ)$IpoLDBzvyv_9>yd zmpXIRt7GoFStV*xCY>ME-|uxiy*`JQN0)?W0fDc!>6;wO_!Dm_-b z|D=_A)b`M)CFncq6x3R4&H}X_OuZ^gmze(a87ey7lMZ?l{VI9W+(#=ppv%E&yRK~9 zQ8kmyk~+B$`gN3H0p`5_k$5Hc5dZn`X?;rSZTc4fPHFM|=0c*Qe2+mh*L19nglKuc zWwSrd#y}Gc#C1za(9cRzuwy`W$^%lJ0onCu=K{^__|Nm-_sr*43?QR#97@!WOYkC} z4$yee+PYeNC&Ak2Tid6z7ayCK^e2#}ZD1Y>2by<(+YD>&Nc3FR=n4L9o;_QKDdSKy z=yG-7f#K6%aocu^@j8#cjmw=PnT;jMQeHI-+7PK=-)egtplVL){AD%ks7`hG~oTeE8rPUfo)lC1HyYc^70u~O5Y5V97mK@P&+ zm>l$wv|TIFye_pCWp<|fU4y%iEL1<6Qn!bf%qCl$1=pTve>ibAK=#3fdwZ=vH5J|2 zDQwzlFMj+;k#0TKZAmn=9`iTjKnC=CVp4j@`=O$1y3%zZU~SC?zmII0qSswUSEA4cFCj zYJy}nyGVZ`NPkv^{zM!ujwRtOh|KTD1=9B?e3}IX2~dM=Qm{&PxvRK<-n3;x2(&DF zzBK`Jdv&LrixFd70D1~m%efQ*jJhdigv9}vs3=rW4Hcjw42B%;nZ{`X6*k4fi~XU} zmOxL4T^4=TE(Dm49+i0L!)nW@Qr33Iw&;Tois?j}%p}$YF$xS+0#jsoxbu zei+vM$mH|Uo`^2A)Ek7F$1D(T-iYtTV8y+v37*Jh`))iy1=>^{AXpj*F^5wRyPkkjy%eV2%K^`0 zgzco|ExOBF7j|Q7=nqp-tqZ|aOjiQhAB z=y{#|{O}bg?3B}lyGQ+i(dab$=Ear51AAw)VjPvPFivVHGJds-QZFkT+$ms;M}!C( z$mJxW0bWFefQpnhIaRrYwTd>K^%e$btJ^~5>n}4jRTzfkJ)S@0(y&0bXF-KE&=8ME z`y&@iEeB*D&6$?UETnSY1mYZvj$VZU-H}B~Tas6_<50B+r6c=%!pmT86p?Gvu)M=k zshWLn8PVl$6#~kJ4loY})%XKzBJP=c)y+i+PKDw5d2VK-OF6cf#;6=}9VT!e%p(uX%ZhDQWnLd z0CgbDDo7g?QCgpf#YgZUjF9;iFSv9Vv*uU<|Bil=*~RiXTI8@I8P0UGlc~=~zSnVe zg%U#<=VKynu|UL26)nKJX@81)5F(iwCPgcM%;lk}##6R0d(@Ju>%~&YN^0V+#sgsw z$eUK-A}_@xt{c-NPftoGb;k*|=!Zg@t|uoT1LBWOK=Dem99nXH6ABWgmln7Hfe-x)inUHWJv=#{HGTpUGRh%U8j=t#CZpz)ZN6B-IMdA z+-eE2hshPOGla=DqX3HnK>?9S-;^`uFKj(Eri+#gU72r9L7YV8h?ZV?80p!`9=EQk?XGe*)CmuSTAnAUh3x(pB+AbAEE zoe2*J_X>FFQe@A?C^T@AxfUY7(8UNdaJL%Kr`#-qZ@@xCTATEo=yqBXR7g;XF?U%ZAYqUIh`2vkl|)H9qE+>T;WDs5cPz~4W;L+-u;FM z;fkr-vhP>z_I_ifm@LthqWZpwK3L_0C|cpFQYt_OzNsL){Mf@k=>7hnM~|}_Zj=Mb z==pp14TLlP8?C$dS?=@dfp?NG8?%j#&?P5;)x-BsPYDK<@o*nDlFWua71(rSr`qI- z0y1!p>g+n)qdddaAlrx^mGM#9?erCQ)p}=T)9;gBiB(>mgWEK$-n3>&0D1rirQi-o z@sORuPKgA4XO4 zaI2EnhcrXxXhf(?MeTF*y*^$MFF6O zm8;fss5zQ!L$Ky0Tkk76TAGzwISau#pxGRdq*>}2`!F#)$ux+jl(m>!)GzPs0_`jp zoh}!RQ{t<*0iz}S_@gqkr#kupM}SY|v@e4nqeAWGo`1n)g|6c*%LFUG#D&jTcMK zB{1P3ZV4i#oG9X2Wel|`ny<=L_9@HoDeGp z`ag=!JRGXG594Q6GYrN)jAh1_eG3U`#yZw)$=+D96QU^9%ovO%&Dcpb)=-3ywZ^_y z2q6_EDJ_yp+s`}ib)CP?f9E>SbpZosY@|Lk#Nfp8Jw08}s<-1pT09-ak{+YBn zi38|CgNC44GL(>et962MfwqtFa`OGwKcMn+75G`aR5eXYo(C`_`-VXvIs`C40PCzO zVh7?!!r&2Xc)==WD&#bM0G}S1w-WM#HbT|d#+X;14#bPPLq#61S^Zv<{#YSHYVP-M zQN1}TX^c-d4iMy}iho@dKNH7W&4&56s`th7oFyA`GmJ$RMRROEWl#yAAaSEbQ>aRF zd_?o%Ye^7A?7@JRLcDD)3vZ4W-8aQ27C4{OuR3WB;gpP%e?*p=X|0d6@E+4jlBP*a ze4SZz>GOEZcS0+3#957@_9}gSr}ZixEdaER?);GFs}9jFSNIQ8$s0_;52)}1fN1WT zK&imZgv^U(d`C8&QRsfzy?#vH8zWSU?Enn0%+qyM)$(|+`S~@UzD?{(j1(m;4~6JN zlcrGQlS$L6CKW=;0cv~|dfv|PxUc+`WcUR( z&w#MTpEE~)enYOr@{i5(=ILs(pwf%3S|U}%8X?{7cq{*Yt!pgvs;~IXVgCobQW~iz zlc*)}VY81}>t;=5Qf`*}wvTxw2LixTO=|g^4WjHG@nB6h-dge44pd(H>LX0xmejzY zKr26FcBhlWb4lQdl)QkXd22P>FG57naq1qLS01#A#+YL}h!Rb2f_@NXx<%zj@D7rJ z(wLw^f~(>oKnnx5DY*w-X@kZGBeJ@EUoO~x5cz~~BT6&2W5Eof5NGx3e zty{bEo#OHjq-)E{K~iuH@00F*%ZjqM>a3OIgFmi0wGtKTxsv$6AVAp#w;IcWd6d8? z+*Q1F6nWRiVEgVtZ$Al3J#wl zBR*F;eGe3`1w}`=#xxK`gb=bJYGDm1Omn4_B~&snKn%4eJ|*Jv^d1VESl195lEDj9 z#;a++8Q}6GVqFA+necNiJmmzQf>oGo4T34|nzf4LwmvgiXLe2@-p)#%oYy?ZtNrvg zUM<1)e5Q!uTBNR1N#LfaVbw{*#>~K1NwX%IJOi)Nc2Bq6pYj7Ubz(mEzBhFohvj{7 z+An(&i#Cwg5blwcNBP$mmQh@q-W0A*KCy$aw(M z+>a&Wk-x9~h*H>Gz|P`bB@QB@5cP6wbPQt2qCyUlwq}u22t#aC5l;s*}LW!SMxZ z@^-Tk-UQwP0#Af9QZ~&!e*sxQCN!?{jRBg)y5FPv#cIVp#Hw_{3at{_wPaq4E!&Ie zuL;Rk=t0kvv{m0Zd)JF7Afjs7#fy9x(wC6`TY>hc$oCTa zdod>Q40Xx%bT$2IwRqx09oRdiU*gi5M0$YepY&TL=Y-pc*c(5S0}Q`@gaRM&c`e0X zqdZ)1Zwis|5Z4L7++}0@UaI>#|@_#I+X9lOX92 z!rJeYM7=kK{SkNkc`Ple(oqL>pG6qmsE|=hYET z4bo)fg9U6fbNBEXJ9yt!U;l&hQ**wu16tllkvnaY+tl}%z?~mRO14%et%kR}lS&7Qh;)jEPvpsl+ReobOzAb*izw^TEcA5==-x;S= znvZ|It(DVcHxBZ2J%3D)RNIk{S4N*UwzObUB@2ecJOae@sJ$oFFx*{R2~jF4f=TTc zr+C->Nf&efBzeOYOZkvI*e2H<7mU z_6GUT>V&0VJ{wTv)^vD1(<)afN5BDLu8aQpiDk3Q+imQj&!ud2jesX2I` zszOWoaB}{ZeJ0-Zh-oeCZC1RBH^a+M^>@fs`b@P!XXk7>P32Rn6K8%skpU|)si7Nn z`0waPPg4XHz_J|`=p+tXLH@}t^NHcZhl2tqZm-~dIX=n@TIp=~12T_tfXwWk6mE!8 zcE`N!8~)BWj4wzG{XkfaDlClWUP34VA$R~94BEQ;Kv;QA5)&ZSQ6ZKKTDY92xpc9_ zS%?!vuiyWp^0NZF|6}d*7k{)U5sg+t>D)rzARvF_L;pTK%71eAzca=;grYnG-LM=z za71TJ#-q`Yav(u;V_0PIA6nqoi?xdnX0|F{=J;Z&JCltqz) zl%nDRh*vF$CfOR)y@<#-u1Z|2~!(Gm?4 z!w+6~x0{a>xAvb!-<-Or{p9-db7yWIPW&)(#r}}iRGD_b2yTW}Wp_o<`s`eZZXg_4 ze~@k0NEO@4)wUf`{1pg8DO=>bQ?kFSiF>z&&vz$oeVAAGNbtH6*v@&$#@UO zGetjoyU@aLcJaO89Lb)bmB&j##q{(5`1V(R??#=G5s%2uG_oWo7fj^ZO^Yj&}W9PdZ(7A0@b7lK0%Kz242o z_#yw-=kU%#U>~3>buyRHsM?JIItEOrNYev!1|O5x>;SbaK{g#^~Q8kQ3n=F2d*FZ*mVn~z(yZGPC|VUlXNA! zlJFtJ!q2?p`@S#uHq9B>)g*l#F1Dk5rIiHGm5LSvv%;;tP8Dk!N`^c(bz5q0Pl0=DZ;QPT?-dT7jCsCE zaWwlUCQnxEEQL_00Jov-7?4mEg%qeg8yACe-2|se$B&W6P!r@~6yR`%KTEaN@KNS$ z+n!*~c4r<^A90F`kU}4+Mlgx+rD^L-mD1puo1Sem*3N-DiUL5n9`b1>Kz2H`;d{i* z=^tY}-#D~kJmlJOPtw^@nOiymyb*UBf80oZoH@w$^?)ddjVOXkY%YUgr2;$*F>2D;bZrsZvrOcGx$-_p72OWjPj-jF&Y98H~<7e?ghYT0-+0nb|yriJ{BSS zwtl%eJ@_^8`1!?`??z9@{1SJ;9zlE)LB+h;6~A(t>vpS%5w}RvrHfsf3K+$`+HXOT z!ZM^oNL5nxtn|!uT@-ohwN;_#h~mrDDmhSnXx3h-)C~@tDEeN6p(C7E5R6ig;TOM2 zNmC&cvwd{%!nKZ&vy zx-vaY)q%+8y^a&UZ8BAnMj=acO_Q!7*5fB}qn6=s7$KfKVKuA4*TJCo<8ZBjc# zS98zAk~jbAuy0A?D&USxbDVH{UElbrD(S*(b>&kMycF6& z1<%r{G0_vP4XW>q@2iDv3SGS)2iM+1P;52Q4F)6pqUwzm2T~1BW08PFKRW`Ijo}hub4-+9#Zm&z+U zR%a;SHfpv|jO8pSOG!jHM}&DDy&4^5(fbj-PeD>dOy6L~2tvBGaXHZ|DiN~dMA=q6 zBLZ&Azu=xK#dS|9=o3>#`x!iiidpEQ=5%G#P~LWGYSi|?^-pc@4(rA}el>D0&C$*h z_Zf{KLIcr)>7CU!8^mI z)6SFmBqAby7oaFP;2YY*6}N%aapYV&2*&U~ji8vmv^)k<9=QS`cwx7eB4s`@uDWjJ zOMR)ZC~PN=9!f|RbpH!ntpBPW^Sk2OkF{FI_OF=JAD>OXFp>d+pp2)S2WmNRaM{sXAj}1{3^g)^+s;J#UmM% zC$~%#M@4w!tc*3(vZI$&NS|i?A7Co0v!A9JVn$2G+EZ(Kr^_#Y=X0AfwOH!Rs*(;B zyS;!aOt63fxWpa1p7ABesE@HubneK1+(v#L=)(o8yGZlj=HG{Y$A; zA@prWF+@;Q6&?D|XeUC)SVn9Xa(3z&q z#7Du-7Blz4VG6-DNOT2MzGy#KXfa&}tKtyKhCRv_GatmIqhf9wMjo=1_h=O3p#O)&39oDA}0AgtFz>U)<(^o ziU$i>t`HN)Wk$ZyIQPoq`h?zRPs3B5iKX8Eo_Vxny>SdZPCi)?(x27RaqRvT8xC7b z_m%klPXVDOZ$AdSus5Q`JWgF$=6K$z*Nxlt?!5--G&;2PAIxl1=glRal;7aXPgFHZwT`b-Q^L`Qy zdr%~}HFq&BJ?sng*a1(A5`s|3xwDcLLgB@TROZ>hbVRfSB8&o$UWJL3H-h7%k)k5M1`lQhTOva3=>RZ$=!eKv8wQG>`c`Z>-R+ED} z)%M@2HSQd)=ueN@Q*W_Jeinkwc0n|QV$8*?+s<9MP^aVBo2C?DzDP9v13%$VK7Wp!l?l|7Zg1%*^(9%x5XSI62kM_vXbq8S!NaTFruSg(e7x`-LD;pe6mq<4{7 z9AdwY5Hg4a^ z>Yvc(Z@x>uo}td2`zqcljFzC(* zmzsdixZ^;q>?b%NpN=*EWsE>e{}+2?6Blb3l3DLAAb9^`kC0q)yZVEQ;QIbcKNTqL z#C`j2T_nJUbXJ`D^%UAgJYdV@=`T16P@qao=u&KmSQ|W|8Sdy@OcdtQG-1iig!)s^ z%j2SBMq-N2kYl(|Vk&i-f#|1DZSq4^hZ1Q;g6ai=^nkEpB&``8zGoT!u0+V%9BD%n zszRoQ79;c+mv1GX1!B({c^;z1o;|&)Sb#>fNg@g9?`cBV&jtBXE)Bburk^XWawtz z=;PYIPvuiLd0cd0nTk*|j;42^R2C-1vQ$c7+7@UAo{E@s;P^?0g9=slW1J+-I=}LE zt?}nEAwE@cy)AJZA|9<5-#!Dcr^dAt;kK)uop{8HN_ZFtZz+0Il>!;Y6(@wlJUF7( z+;1)o63Kzu@|28piqeo`qVw>H8iWW)h~bPn0={CC>NFCYNDV=G74uJTNA8{~^^*wO zvou%aVwm0a0cU-C;j&7ml*7SmTDyunyJ0(`N|L(AWY!d^&XB@w#nXTR&ZT@<)jHh+ zqx#)QN_bxe$UKhe+yw$r(t%_(!;_og!D#sC zX2^0I%$5lWU{;+j5;K+(QzSzprmFaWsqyRJhz2XDb0urxrH4{#YH>^ospsE6yHHu;Qz2xD8v}*@otW>}LvsKX>*|`|!m=LSs)})A-dAl<*e&k|5aGZouzW zI3T6l-k zYUB)I-uCvPKx{eC_hn753?Miihztcx{{UE$P>*m8DrQgPC z9WErJ3b%**kB=0Rg(|`ot!Vl)3HnxGfB^vJ_k`mABJ1NuZ7qa!t4FacsWzRy65G~i z*ZKxS##lkt#i>!RCdc%?m*)$m2Xw0Cn@VL*9L^EKe*II&7OpQ{Ie+JXJ1s8SVp8>I zOQG)NPYH`+?Wj0k_-QUNB%B;M%qYV@_T4{d4-u*LI#0u@DK_*8m_m8uT!( zKY)CqyG0Ig9_X2o>%znCOykh6p?0w{zw+(dS=_;KN;mXqax2_}+(hCGF2#wpWJ64t zIqowNt{@d>mW&L+C5p)-3>`kYgHA=Gew3LX&q-WnyZvHf@FmqeSElb%oB(F%0ZShN zM<1ahK0=N&V$m}Iz$bhlY@RP_N&T=;efeiLe}2HdoR0#Lir1@kjYof^DZapDMm)$~ z#@MtQX=Ub>-y!#oj9b`G+#+CqT$m_T6a3DcP+LXTgE$Y@+CC|3Yl%;`RDl=4z$?mR z3-5`aGyB?3lG3}eymr$9@0k35oBMl-0$%~(`81@yVsOA40jy)!D=k?tV4Y^)i60fv z8`RAJN4)7Y(t%KB{iuErE_R|dQp{}zMACTjqhv_2c}OzhiFqE+3np<}&1rM@$-~;E zW#{3x?Zg|8e0pIt>JRF>U?)pAC*`3~Wq0$&=$X5p!g9rD0G&9RIBUTqYT|H|!lUQ% z*Pnl4^OY&oUp5^DetaLvX*51k82oe3%QsVYsL={WVr1) z6O<&05GH9&s2$o1@ccE7CnMV{PIpIT@)k=CeT@CiFWo~!T2t-==tq4O{Qvy0%Uu1V zk%`4jKkBA}gykNiq(pU=yG zFUqn6_sQaS**sg~veM{wSkycC--%XfS)Y0E1u~M0<~jc9bnNk0->?X+sto9w(lk)9+gSymP7g92A^y$)c=dSPd^}bgWJOvE|u@r249-2Sy}6eu3=4i&gE z)8y!5Da*3R{bc?*Y{BVyz3zG{>agr1*Z9fj%x~*chp&$>SU>W(KKvpoyI<|)){4s8 zw*#*3x9{IOD%1A+<@nJfn8=ukgQ_oAS9xSM0=g?elFkkN@7ivC*gmEy*Iz6(?#%ys zwc+EM>_6pzv|PJm;ZuxD@PDxa&sRUS2P`C0g1ahU8u$3SS|L$b_p}Q(fHOpxeadAX z)JDJT0pR@`vR+Cfqo(1nQtV0kkcfMO2RVKcO%Y2}2$Qc%R_nFgC9rtxKDc4TZ*?B3 z66$E4@mirRw4tx2A;@wgIbzaBifm}t7z(+wpir%IX?e~Z0qMN`iv8Zu*&Y$pi+C?v$P35>jDsO(71&?yDM~krUrUf@* z;qTbkf75bZ%K`zhqsTn7`kPoW3NiyGbA>6j?2^HUgC#U7)VIK2Xp9<^ODShu{*qyt zncYa?S2^)2eCx{x=46+f+#)^~q(c6F+q&fW-1i^lJR8MM4gBaz@_wc;DHf;U){Itj zAZ-;5`Uok#1jkMmaN&_~<+(cNDit>XNTFG|;_vu0x4owg>nYhs18wb=^|K*Eg@>QN zpWASH=5*7<lcT8Cg$pULhXyq&RB~{=~vscWMR(jD)ZF=!#ipdd}Sn{ zcRI^`GP_u-Ju)$q&iC`virX2h8{W^KeL2aY!UUDMgxS?|d#m+8#?-Xffb?$vH$rtv0&)L+B!A6_k)b@je*CW3GpXpvxb+E8iDsT}-$S3ryAZoW-M6)*=QwXdOYrolQ895mo_Hpz+FY=F{MMBwT@XgRP>snzv4Mj@b-J z0U*#}B6()IE!FuUf#JiY?$zPS*U0rG<kZR_(@G*w?X}`?e2%2M%%gBQ+Zm)T=MVEFDHC+G})p1RAWWLTq0%Kun1Ba==ANE?xVwj~NSB#Y zVRB5_$G82N(xStbB64)JIn&8bb&#o&6-MO#TsIZd0H#nrYwuKNO}R(PjB<9gYs+iw z1?gFt==6!W+tnnkhWgrE(^>WAtOU5a{9XMCyQ-e-GC56Nxqdu#5uNQ=c9!ByJtaPx*-h+J4=2to-lg$JgoLGx^= ze$JYrB|-gTFbJ>?E82ezw$R)u$H7XziSu^0ckQNpKC-U&Y||<9#_x|A3DyW_9eq)u z#Q;n5KYA|mdrFy?Wat5SFOr?W4-*&qSb*w#hP9bc3$dIL@T4kpr1EE__!5a}#Or02 z(3W2*x)V&4pJnD2v??1|**R8ZO{z)OR8MPMx~5_8dTF8PM;FX-kS}L{Xh_0c%aMLN z_|!?Xr=SVdLaJhVP-t41$Z;n?B$*D+(5DRf!338<#pe}92Msx~7K<MyrACTo2kv zw37bXt^ZyNusR229RT38C5<287DrGhFq{CL{($t@=;G>C6hIhcGKOO7^#%~N+wjOt zIzv8SrS0W@mxUzfUHqpVanaHs>XXcDsC$l}_=`e0dSw&bsS`rS(ehJO8N{1Ry5bI| z<&tAv07S@EnmNie@=#=2($~rF^G?xubQTyrm64@VCy$H(?#gZxkYQuyO3K6%-fm!dHDOqZF|1yw%~itwN^vHf&M2l4j~_~ zlQbb3k=aOu{Yc87cIU^*g|l6gCwaeVi?8Fz%FZA@cS7^!fZFgIrHc+OPu(ajquz?@ z!e@5hq(g9JkmnkTVTcn!}^d8d>3QP_vFl1z~R|!ST%v%9#na*xuEqb3c_bEmzbq zVf1NR)a&L~^$GG4Eu@sgdX;(1v8o^Kr+2t0go3$sC6%r;Ty$F%cyx-j@~z%QTw1)q z0I4b_d(!jqff}gA@ukmOv5YQvW&eWrm!oZ;`a9(muLZmoT~05_?t8@5SLLOfrbWED zE4mXrQheEXBSg>B(CQ!TB~5ooT|CnBDei1xv&)@4$2wI&8p6M--*`khQs5!_ul7tG z7?a!23rsaMUd)85a);N$*Gd5K@4Ls|LRA~Q6CT4M zO*$((5Z-da7!c1&>CnL&ExhO20%wjMvTW0(X4>IoX7?WY$Y$yaDS+zD<3rJg z4RfMPX$e+==XT*;qP1btmP?Pedd+_5F2uNJT1E}=$s~W_;I`U-zJ6TAa}=4!O40GW zQ#senJVly}iC7~h^ZMh=mOrH$s-za_NB+E8fM4#Awh+C3I`pOEU089gaDHT z3drkOMV6V+msshLlalQx9-@*pr-N$`iZFtQXVcy6ttZ2$R~<{&6)@HDPep)lGU1Li z^o3P(o;~Y9bE9p~FLSvP3HC@;Mm4{pNpDm*zxROGPc zZHJD&Kh1_piGbXwzHJM!rMuOtGAuWSvCAfx$qikm8l-hzU!h+2q3G9HAdCj+pdqNO zb9;#z{N6$2=6H!&JjN?B)BBB9X^BZGtH(*cxniQHaE7<H* zPilxb@U$T;=!VWOIak;GsN20!>Z*@S28_Byfad${&i^+mbjlyO6L6pWTdGw^d0|VP z#W=*_V*cu20N35A!jodcfAJvhl1N58fhU1+?ef9K_RWklV;LkP$RGnghyg!vX)G}* zl92+>=Sja>wg9;P5nGzpmfq!MyaY~AUJtCkPlo6dpmxqsD;)(In{LUVOO2(HNOS@T z>ayOpd^i(|?Ee&Ry#MDRY^m760%}EWKSq(EGZb7p>l)v5|5tC&lq!RCH^}vFZ&lY` z?}xNiW&R4(rpEOMpWzeH&$_{|4hxpu=x2#enM9#FR9l2&3M2<3Z+0ybV=YaG@;ij= zv-P-k-+P82VRQG^-pN5z#d4d0X`Zu5Jju>fE+=|`_lTIvkvlEwz2-;wUZWPbbO)PZ ztT3?f0%_DENvt1-nri!Q|bAz*a;sj|hOVoD$_gG%JbhwbER3-iu ztxKetX3Bl8I%trNki9h2iU8f&7p9XqR1!e3#Atink;xyE$@E0-(@gGj`)*Uvo>K}C zODMt=rblCVRe6fg0rRWwK^q$jNBNe%U*unwJs-Zfj(h^mfQ#nGDZQQR({14AIW+GY}p z!tn7V8^Mo+nvlX>L-_d!Sh+;}wTQ4G=+0Jb&>J`aKS*B(aAPJOGgX0DYwMHAQZR zZ(_UV;TUc%wU5sjwJ6R1gr>~UP#4a^jy8-vz=>-M7p|gm5*A5uQmCt86q1SwO3|*>)aw3V-S;6x z?ta#jy}5C(m2MBHw%eXCsi*(`ST=mf&W*_deXMI$&~DKe5`NF{nMU|68aJ9Seq>Ge zi)5b#ZdTXv`E#8rXVQ^xdhVwPKltnXkgnE=aQJUcE+9HP)_1BccFKV2f{C^{XWCtr zufV8)Mm9Rg_Dv;|GmK|!k_qtRIH(U8I8b2DVh-GSUp7033+f)=P!25~%#pu9lIWRr z8lQcrayZxvqKI~y*LnPaJBne()i5-g(l~c{OJX2Keh|H8r^GSH!h84*3LeCP2X(r6 zBH*G(czMo~z->2B#Uc?n_SF)KLcuK!hRep9zNah!P;JXqCnDO8xoW(wpNZau->LOck37y(bd&ZxPT-&_Xrz=# zX5x2|qrXH>8jI4UMbBN&c|abRQ)yKg>|23ciI2VVjH&x@dqB<^WPnT64HKanJk7lW zetN`{HAmC-Obs;Ri5g3f(t$4yFOm`IfhurggQ`pyhOla;S>uw~C%7RwHKq=NqKivA z(@A0NkdJ=wl=%}Ey)qcx$2Omut~%X&?iFMNb6oN2+>-0bQS02lVr+*_>(TVyRpPi= z5p?ocFT4E5?9$pEFE%JsyjpJ=WaVBSXU#$yhj&aR$LX z5~GvRX=VCwlQeYUKPcoceWm|;z7Fyg|4Smf7%T}zl|Na3l>V!rzZvWB1 zf{B_bJ4d9&?#G8&CjprARJwkx?hubPOOP)j=a9w zV^u`pJm>3hNS-E}fM&y+Vcc)(Z6QYh0JULSg=*C&r*-Lb<^i+jTDyGc5&?Gx?2(_c z>Z3!gb`~sL=tIwqb`Dq!py3c)7Hj?)KRy_MqKF|WjiD?|>Y3(@s5-x$Hp_#03OfFo zK04_a-v{2#W?eagEbMz(Cgu+rhZv05ei(xU?Y(|!km>NUJ3GudO9kWRjLya}*rH5* zL(b+A*ue(6?Vx0%V+Vhb#}5B-8*4gYA9vTKfWE22@OIOdL{_COu3HqD`16?-f0p~3 zCRf^$74vtUU!nKlVINNq(*_T&q)i5$_X#_mU-f6s$1n}czg6+6j=-j$6xf(dQHqDn zMlPl~sN^JCtvo_yufIt4z9kAZWJ(Y>i~sqc_4U#;ZSDSD zjDUW&Yc_nv3%9!78~%>tqrcznQmty>ocii}!(>sdeU(|nHowSkgO1X}Z$+w!Tj?F$ zMm|H|p8Qp|fiBqby!>FW))D<@E_?N@-vf_U!$^Q2-6p~s{luR41;Fh~a$loV}O2UR|rW|uU)Xoie(-n?SKI`TO^BP8{?*~=U5^fLX- zRRIihGb~r2>V+)^z9iwP$Rvr{Wo&D^aoX(XSv@$uFo5s6?Ye>2ddrCZwg1krp?1|` znP>;bYSXY`)^hiL^JGQkm-p5m>PDLR9pCcZi#g@yb9>{9PUh}^a1r21gs6SDRN=z0 zJ`c#VaChy_iyl$zCMDTp2&5B&;3B z>da{0hOj)T600DwSbBRBRcSGx%@YiC(%Z=ZK%#Ik0Eh_?!+7uqcI?LBWq0UGC(bF~ zg&sI01W5_Xec|`=yC-NVh=}$tZ_^I51!oJ?rv#vL5LJug#SSQwKj2(aa4OLg&5kB$ z7tyT`OcjIp>ReZWa)(di&O5wN;&ze?>X!=&S@#BQhuQl{V}SgV;Z?6}UM0Ag_5ah% zcHVDI04*&4`79^W_vJ*)%60U%Vc&$5A-6G!GPv%`Pzg`;_%Rr7}gW}x!|S}SWO#4;toIgekY zKH&UN-yTpfqIvbJpVkHhon70U0kLUV*jR=SCp{36PC}=Vbka$6bW-zzC3(j-_MF|G zrMi~(+nID#?aU8-J6nDJJ8jzUw#T)LWtND)^q&kxzO4hHv^{q_Nl-gjg|!<2YO4cl zPP_T7E6aIc@AU(hZ=dSef0Kxv5aL)HQ;=SzncQqG{tdR3`+3gz?g&=2p=J1V(0+77 zXkE;$$HZ6%8=bC*#=ptCPfp+D`F*U|2kRIA>lpoa&(Z1wTQ#A-YxfNwKeeF%1a4%9 z2Iu37qkw9e=F4Yv=kPkFhSuF8sXx}hCfUkM+9wK948F7e&vHxruFowMyznqz*}>3Wr=w?nd|Yx1yLI5Ju~JW-szbY#%YNlhk~5n~ zgT8n#qvC>FO;ss1KE>Pe`B;~g=CRMeikd$3HUvFO^!xMv^YcW<0kiR?>d?1|g<6j$ z+uqN-9KE@q<^N3e_x#qI;^>o?FaB-``f}hJ1tOf36koW@zt`rPgNDZA@*WWPjZTK}%}+<>#JioTMCHj&MOz^yohK^`mT zHv^h}R9;|qu^{j2SwMB&c<)kObsjc;8zg92(l74{)AS{PV45%vfE8Ya>VG19JEc1e z6|vQcv3AWY<@2D8E4Eb>>ifj>B^I7eo|_N#yDU)2IGMbUNks&OW$uhubhn-_l4rR4 zP2mc@j*nEIpQ+>vt)+xy-5V_$k&0}xHF+NT1Yd^<26o{b85+mf7njJGv6ko2vd*OU zSRax}{C+V*2H1T+>i2ff%KqiS-jt@7;h*{!{N6YJI&m^-DdbOM$BV$vnw_=XPEFJ| zYDVH-0%m(`;(F_}Y4oBwD{VGR86B}~}PrQhi{0!T!#7=|3 zdRo4?gX~lph;qK2edD)f$AeV>U{R(H;C3v3IZfbA+X(Aw9<-$p$SlM+`+I#i1@Hhh5VFamVOOV zh{}KnJGP5?G6pb_6)?>bj{~=vjzaq{O31Q%^Z}8OAZONewv0@WlR%NuwFkeh_&OUQ z?mar?3T!Xm)&I_RN}MrHJY$V-BWYQ^x6Z7iVU-m@(x*a543TaKrkn#eBGEF0(i~ES zgRKn%cg+Cs)yqyiBij^F(_4s13Mos~@KWUAiOk3GQK=)~dfkk8Q}h{hRl}LD&3?I& z5^?lmn^lk&gJ`Pcl3gZrDa}G|eOgFS*b6OZ`QBoeTaFsiMuEAD4@=BkzTiRq4y_0v_t@Q#sL zV679nJ|^#J5_QpMj$NwQH#gih@0cvANj+uz&iLmpwhmbtk>WbItpBET*wgOFj|%(+ zhl82RT&$_ArGS)D|FwbPY+Xq^3!&>|ywV4_p5(-pXdPa+*i%|Z!M~q;FyftUF5v4@ zI^}2Q^ex1Aj+}V z_TUpoC}43m09Rob0R+NjG0G7q;~_MU*Qkl1#{+z3Vcpif@!v+!Bk10FGF+EKM4%5A zFKSaB=wAzJf?YP7Mg=vJTMizuUsPv>MC9w5QH9k#c1rDpN6DsP-23yYsENg1ykwO>1pq z-<(Uk9g5Q_Pd4#BTu#ySS6Q#kGjVVeLFuuGzeMASTAg$Krp zX=+i!y2FYGbE{|4K1=gQZw^;C)Z7=bzd5dCvtlG=eC2Gd-F=@nGwo5w8KOV}+`hHa&XU7Q3-D-G$LVSo|L z$y5q}NJEb|A2zg;uV^0_kI9_S=>-dN=5gqflc0}3@gNkLr!b61+o?QIulHJsX1drZ z^6-=!vuC7sZ~kuGl7Z10G9qGg7YAs%*g)mtE@GNW4idWg@=i+nkc4sD#a+8UcU_O3hB*pJbZa11ww+@G7`?IH z#H8gr98g`_O$?*|nagV5G{m%I?5HP1r;bKkXAq|eI3WO}!kLV+gaH%*E~L|lo?1aC zmLGSi5mRrc^S6h3jvmbhOgbQ1Ph3kVmtdk*RP#k_m`cc?qfSDup`*u_G`<* z)Y&X-qc2lZET#AKjz z;1mLPG=3fj@VeT9r{>#006dnc6lT#;3K3}nNs|3#IoLTuK$&O7wQb&nX>edKvK&{j z1(G~OE!t8A3)B%6o2gjBBdmEf&ZruzUoHLPH5BBvk3`b?TZp=Z4C22`t+3S4G1i79 zpEemBS1p-}E}jw-Rq6%(Wo0XJs2EeKkSTSqkMFyXi_?Ea4LHX2nZW2^`TzP~DK7d} zlIG}W9u;0Tt>m?a)LRW}(WfrU>VY-t=k3o`WCx;GPbdow4`<^rL(VW4?T&tkaxPSj zswn)%=Pb#zL<~Lvxd?I~mVlP~Ebkl#4)9X|Is*Ap#&XEjnvusWzlxe&U2Uf$MWKik zg1c=dh`<3QmAr{2O(6gzlqSUMCd=%Xpc657`la+i8+|^kM5`->w%LyGm?ZwFO2^*B zRH&sZYwxa^S=YWsLP*H>Uh`UIWu>}iLb9`}YtKZfgzAzc8WOE< z-~8_HKlt3w<9yzabI<#{o=?6D1rs5SRTXN8J}Q^ZZs%Zz1DM9APZw(u*@X^I z{*oj2BjsZYoDCgGRqKGLR}x$}z0q?~MAQ+s2-1avO)P7OR^tENJiPDUCry>Vd`b<+ z{D+?_lUc@Q(%GDqrB#r)F-5GG4z=~?L(2N3Qtg-!BMOCsGt(3tmBgouvv{?8M$s%5 zi9ox*%3*thfplJj(ex7upn_zGVL7iM{+j<2irr|VEd4DnKwLL~-Vqw*z-O}%G$@{g zLlw)ErwK8F`P1oq^Rhzw+3r5o7355$j_ntH)O|lVOyvFHx!(<@m#cT202W;}fJJxkZ<> zUYM6jQ|Qq>wz~P;svsX>Z#a0YN8*X|ow)gi)$wJPB58Y2*}z;8wkv_z-^} zG&qs*-~40JPZB9Ajr7w@yb7vU0s#hhUT8LumT1_z>m*t&cbEq(3g{9s2WIoK5G+A zLH9KQ6nIm9SdE$%6MhJA@rbhz z#0EVdDF#9+%d?-AV^KETpDsN=9OK^*Pi)!o%M?|T6I%Q*k@ImcOvysMrb_f|u>y1GX-)6Bw|$Cfj5GK{*vACEx6q7i2V@F1}|Qq+D+?WnBe=Ex*emP2Z+odzhZq@r>-{A(k!p^O_4;ouPQ)k>Be)Ow)p;w$LrslPPXD4e- zW^}1N8@h8elIjrF2+aY#9x{B^=VQ%IjAsT6o9*9iJn8Zl`y#3^8&k3??4QA7ce+ha)Jr-Ghm<_!k;gPNsG zY}Jw2m!l$Ca!NOUZnpfwE&eP*i?T#y4NIovtrMm-rLNqRMxBagmuBv|4ggmNN-N)h@W07v z?-N_~lhy4QvJXmI&6tF&|C#~S43o~$?N;?26l+IxD2K$&Z`&fwyDFU9zSA8Y7Th9X z0uuG6i+%$RZz|KT;|fLhS>i7M1e1kmk%d!O2oDy59nFm&y4CY_0zP~woq6`1NQh6? zktI$W>cn%_{}Myyu?(lC&WPud?vSk?!@>Afxr>oa2S^`f6&Gb;sOb@bRX7)$MS`66 zeXia{K3H$@Xat?`SA|HNT@Zv_yXn5?^M~|`f5=Yy#;wG!GOsK-Q`)xIn|CzD&WjgU zY5n-5M`0?`Aiz($csin2eTWY~iikhPSd{?&?2?I{M+HX>0zf9oX57<;S-Wa!>oB|u=7_Id>=9RMZ+(YB-XXK6d)P z1n%Va#lKybuoj`? zqv$BMUz6b;cdjj0T_p(mG$wulS0hvgh!UFJtuqKwgLR zC-QFTbaiOJYlbyf8$}Shz!u5Uhb}^EHrvp5Iv^>rO?9jxCQC!SKh1(VA2){f1cz`= z#Ak)dP=s}Z!RJbbwdRiFSC%acAvbj8xFywT zyk3m#y%@6}hUz~MOd|I#AZl-VLI~_UURT$;7#SRvCZ1WqfRT_+F?e6lUzk&P!gtE|bvw zklw-|@sfX-U5slU?rxGzXe@rGF8QB3?`1`?oy=0z*VCS23EhKAE`-l>pzZk-_w`;% z+oS9n{`TzwiZxi508HKyqtWqEbi6fPu2N&_0LYO|>fkuu_qsdJ)S4|OSe6fQ1GEq7 zLzfR#KwHPwA9E5+AA1fvNd#hFqPZp1z|iG;;lQc>1{Hw%ePF;GQ3-I-Xz)fN8gFlK z`TN5;U%>SuqpOv}a)w$Hp?Lsek;r2_G8%7tlHO!YXDMN;FP*B^_ zI5$mE^rpVw+jRDIqAWyS*;C7D+Pnnp6!YszkbGIWlG||lRKt-fL(Q++7TKG2Hb+iY z8rx{io7P`Y?FY$bqJbm+bxOaspy5{(kM|m`EeCLULlULdUc1t?1?jS7YAbA z4BsXO*<2Ct4rTxh&F^29c(Ic_cr1-Z0|AFn4?!%2^>!=(U2=!q=C8V!G^)>tA% zkfB1MPz#Vy(p_$S{ui3w=djvx+po=R~sYbLLmu3Ub0_XOsl1~8lHDGra| zaQ8HWw82SPM}kk7lLE98yoA zk~&J-#*T1SSMW+Tse-l$8POm?S>C+uC`gT>?r<0rTc~VXU*ZuHDsQWmj#Q{p>MLlt zN$q!Tz{rc(7S&#s3q7JQ9&;$Ge47($P?m3tF`aCE0M6}ei@8=jXZXoAS1iia11bc} z>W61{wDy8BJ28!qYQ_YwMX0XgkE^625D<2U?08t_vByO8Cr3l4a0fL};3oiJwRc(2 zm*eY9Fb`_yk*3E=qCID-;X$PNNVpJF5vu+~Frc9{2NujTYE2UtTkO&j6XwCXp@Q|v!BoSnV8)LWgg{FA{=hjxT9CAqf? zEqBZ_odR{U@(vS5`5c^|$k|o~J_%OxD?-{i{OHjiG3h^k4g^~{fSCuMdNYdSRL?x#4(ilT z+07Dj>`vKndH&q?nJcgBPu8jKkB#YKu4Huau(U_oJ#6toeY z%~L)_?1?}smEj!|1F}V&YqQ?npqPz`m{o2mUzvT(b4i?+-{8@eMT$U5i>dCDt-_Mo zip1*&R}N$Txz4M;Yp02R>Oot~ylo8v9LX+=9eYAeLsL*A><|zB6bW6lDfWE6SPHRr zt8-pjBXGwK!<^>=c865&WmkDdLGF#0$b)dvtYx1AMR#_MWc0kCfqHN0vlh5(vnLwi ze@yI@+h&HRH_H=C#34O+a!?HM_xiVJq1lnfPh?(o8Isc!I0n(er4c!Dd(P4nkH}N~ zOb&;FJLa~N@6RD#jm!muD&N z;|mMRKkv3H;)jy_srWp&GgdFz-1_~_UW z1!S1>GE2tjRs6S}cDV&r9)R{rfk|)g^*?s~*K9*oXekS+siua%iqK*zyH(U{<<+iw z3Njtx06GWS>(eSo9#hG&I__gW$CFTyahxX0mBG&Hi_pvSEe{tRT{`*C`jV91bTodY zZB%Tpk&{6ky7JGT013E=b#Wd-sfJ=hZ;%tXnrB}66p}_7eF496X%zA5B`F8`Rp!dp zBr*(fL-~bV-CA_VB^RNh%VAxD+T=Yu9dDbzRGa6O`zP(xrrwR3n@$-WrXzUH0<@p8 z8(mP#J6sd76lld;5c01Z^gu8I<`R$}&`9G+*=q1?3x#*8;W|P!-@o-?T${Zr&kVTD zf=&A8UPz#$k|8YW<~}#jwwaaM`Q8JZnZAVwmvlN;O`nks7dv;}wKkcUS?mx7MIv2|@VbU5^f%2F1hkx5Rqw>SofGg1 zluUdpMzyzFPE0}dw93y2PRf9>d1H`lBlJ0=1F=peCQt&wMX7~cn>|9&M^T=eUuD65 zjYf*Dl#i?a97+pfLGYu%xHc}|_b|bXCHiG3g4H= zZgM9TNu(NIV89i4i^$k4Luo)aCjIb4wUnYx7S&yjYp_ZG;11I4v5 z0LR&&&(I@F0ZA8f@Xf@Jl1(2-07c-MM%&QRA3=y>=R3{1Y#&f%BQAcFj=H%f?eien zYmt3StrJG8_%F2L73w?iz_1aDB3Q7MV*zNHR$#!I%lnp08Vevtaz;q|yoH zM_Zp>N1mA8RZpSLF>HRakjCsBzC6zOV^VMNi^M@=z_yjn1_-!F94+<8N06B2h1Md4 z`@?r+3spCYoyX+Hoj2g0tM3JwYNcMhGtXC`mSpsvThd+b&tl2YR)9ecqI=@?nqp{@ z&Emh`*99KSGvQIv@5U#`w=1vfyoysvjQerO^K<(Yi?jbI*ZX7ZmFeZ|D>&enJ6-%c zRyX|e7`#T*j``Po!>Jy2y{LM{!@aT8!`OIzRsYg4Ke6E4o0g0=wHd={XK#+L{T@L6 zMiHURBQ)4CC=VJGPNYqezH&Ef$Z7?*TI$v8Y^LjK8xz9@EZ($=%#t&;)}`(qht?p@ zgqjM(wEZJV@x_{|ZNF~bUIc)~x7z?^al`Hb7Q|OnxBM}L+OxqEEVuk8NG{1_wZ8nk?IpvnmO%6<@W;1lnd=d5jMm2K#R-evO|_$yt|UG*I`@ zWuxjxUN`yaZmv?yk##^AKSOr;@J^TvVj`aP?N3;0dG3Deyqdkr!Tuwj-;ZR*$GK4T zs{R1Nc1zW@QEy8jlE+LfxmlItf=W4gqvXqsvr0E~qRV+k<~wsXXG>L?HNAZ#X7R%* z<%t+PTTc)bBg4c_lH$WA;`N(OF#LoAN$*i>Qc;luTU62X>Vfh#Jh2*^GV!iAl`D^V zI5&d;Xs8E{d|1-9wHoiN^bWSbaET?eoC|US^A)Y{ko^<;H>^z8<$N{*s+h=f^%CNT zL1R-R^{K)2jigzwFGcNK+m0!{wt*(WaHsK-hWzE>rr^ct<%C_XM|`CTAN=yjR#n_# zOM$9Y8WZIs(DI$T)`x_BIqUtl0;y9fJw5Y~Ox0_MIWE=pUpMZm(%1*88PPld2;QWs z3j&^#ZnV;QF52s8@w+Y!L;h%};h8_mry^B3Eubnm)q+ngt8)^>883=9kVK25MJnkE z^&p^bfO+)W}aoB8y7B?X~F3Uhkd|;5WomvB?0MlB8 z$y5|RWPk?tc6uU}@=~QonbMN!cT8?OxQ9aDM-CAS3{dtd&g7=cXPa8gF8yIxC7K_V zGL=Ex70*tU&y#71$4Wfa+>;5m+76@72hw|LUd5<#_9tIAV%s+FNF5bWYb70gWL4se zq(s!!P9M@`j+^Op75qFMuBye)SWRVEXSl}XI{RekrjJxuK9R{(amEp=Wq?zGY3g+( z(WYwA)Tc7kJ%#go{A<-uHn)Vl=-3Scx|hl27=2h3@U5hYV<+OqM{Vyh7sD2m@32rD zX7G7FU^(~xGUb6JSyjR`SYguw+VZ*NQBXV!@i7wGXL>uH*0kx|+~7pu87A<{H1MYq z9`H$vf?H&EZ^dG{DV!AlQ>uS3LUFjP!4!Je6xkdmn+O06mKEh`&_qh=pK0?8fE4NO zYmH)yiBysOPuznnnFs&~ysL)Q(u=>MD$1kg1Ck)3rPMnnT)&C7`l(R`f9D{qW)5Yr zkNrFFiXN)NF>)4q!ZbY?6E;Z~q44VuEGiTa$&`ceu^s(O=Wyz0`5S2Hk~xF#M@5RA zDoV^8&r`T=$V!{v+5W@8gcV|1m?wV-3Ja|npKq5@UN^qqp;Eu6w2qb`B2T23YOez< zt_`Aqho3}jqh#KqOnOO$tBX#{ni^wL=5(>D*E=n(8P$1YxCTuQL{BcI4#iDI8(r|;4DZs~BQJr5!A{^CK}F4! z`}aPwRVz?XV`sdE+{v@k>%3S~q@hy7Q3k3#nyIgHl4Wn0aB;Fo%7LZ|EbzxgLpN7N z@bTku7ILOC5xZ_#^UqI*ny2u&XGI;!!CAxol_Q_+b(r2Y**7#3oM1boTJPUAW}64e z{=VETb&HO^LVUX&7`^K6wc@Vk`0jd&_PQ#+&dJW7T2Ewh7u5_qBBs_Ea_DfJtnJKj z41opaAfgqBU<7Tpfi6-<`dd!IZ=MukNXKMU3-MHAV+dU3heRnGroV))h_t(ZUl2Tu z0#}YdRIS;z#R1<1fpI!_tFv)?hw)4e`H&IFdle+Ht5n(KbfJ{nnEZM3bCPAIgMO4z zOHRToitEAN;+~fDjXjsRb{Ci{(a6%R`aAVMtxyQ#j%b~q!rj&zo1uc#SFfRfl9J=k zoV)Ah`{12#fwhu1znpvY9raC(FqNkoF{1`YMZS>fL{VsO-F7u5OzXL=G;FCp8;JEMmC2C$%0`BT z?K8>P-~+$eGRsIEWHvPXP=56p*v5$ex2nuP3pE+BCE5xQnThr6mMyU8^r@CE z?5K3ifSrgxUC45X-;$4ek7^JGa7FaOqx2bN0Ur`+jsvy+S^CH4)2{W6nOpQV4mfKF67+R=SytA0vjTZ9pZ&a!6DUZVf>Sq;!E#u%(y(mGtZ8?d?8BP zy4^@hKPr{FJFc~i0AD%cia4hc#<#w@8clz_P|#O%Y30W+lnUgtg4#P@UsXbn$IA@(dT)DVBNp!GQ}pQOC2o);S*t;4(s zX)pc31a`+X`1F@_teWZRdRLG-;S3l1v?4`t7&H(M62y>r@;VSbGX755Tv1Fo(|}PN zV30s?+;ENk$Ae)-IG(w5=iy7`snn|L9>!zmWmVS~W1Ps=5A*!al?$sst*<8Dzt;>}a%KG|gosCb2xq@fTf%G4_kI5*|N)Hum)mW!$x;E4S zaOMaoQ3U#AQb_$1cj?6sts+KG6YtPHJk#|Z6-$RK%Dg&Yuw5_5hXyJ?VypfW9GNJ_ zunaEFoDaIS_Y^CZEA;PuJoXuo*m3fa%eCo6)6Jw7LZEsQ=LAO58S9+ zQ)sRhsiP|(U)jO_Q;lUGpUb;HC4<#r(`tV^;#s<%g3FE(!2L(T+7ys0Ad(oui>0H# zU-`h^uPl?j^K9AZqZdOY-e9#Kp831S~ao| z&pq>1z+?y{j6I%Jdf$EZCd@Bi=jzfeo&q-7X&|Q4EN-Hf+lZ2mPBiA7XY$y4bI+?S z_q=Eply*~G_7gv}ELwgqk@j9i+(q(;fojxjkD>@L&4Nx7x%vt44&v+&$}Ez!rk09j zP0fD!q`k}#!tQXZR%k1;Ks;d$Iws+-Su(Ur)L(HRZ(npaZg47f{u)W218|6VqHxAe z2%z+odbusesf8JYr^?&z7)7foLh!VwIz&(cMf8Rr|3~KiMJ94ziHqQV+nRuMoG_{k z>T@i6-rW~VX6wiJK0h*eW9s}#`m1=oDvYj7&@G;qg_p2czn2x4+C~2DxOaU#AZMu_ zugtY}fA{p4FE_>=d^*vKB{gRgn6j?~42_y(WyCjmdJ?|Y#uG!*rxv(hsT+Rl1;3FJ zP>pCg_3*F;RtM0N*)t=_vuM(q(Ii&#ua=wV$()$8?>G8y89lxmEaX!yPRy0$FnDQC zUt{ji-!G93sC}#YR!fGRAqsiF5^;TcII`;t*s=Ax9E*$PC!|bLzD?jQNr5>CS3dn6 z8{vDLreEnMJVat1f6j?F8OMdO2esW)!hZxzn8ZU?0=bPo72f~!>cJ>q+&Bn%5kL~4 z-29DHvPN1OAcukjg*B;IX&ymy%_|nV7d4tfM;dDRb;C*;krjn@lJfplZNHQ(?XQ)c z-ChLI6nJU6+B>VEPdjc+TvfTLbaAgPt4Pu!Ny)b|_O^?nW6su=sSZjKi1{w~#FjB% zeRvlD@L*Qs$Lcof(o(;lsT|g*tyvUcmH%GOn#}_FXJ+udxO;)%1Tp_1vNCi9f5ra~LU1*_ zG2y`oqfjx-FkbvN91zh8y8*O4srx56m-qNaff)$rLDozo>`kRI^yL^bg2(k4<_wJg zTEUr~AX^wWx+MZs7cB$YoT9pcc$aylVV8REP+aK`^5q+*LOczK$49U}W>E?;vGw zYn3=pKi4k$u$xK+60oJW{M=ZjVbnXp%Hhr3JpjNrS?b=5vIan)`@ZueXmN|y|6!}C z0oD#52`!1o76}qO5+!A?5>}$QOk>%FG*hlkO(U~J9eu?Xj@gv!N%H=OkTHQjo@jOyGPk#RCN<$Q-6aOsp5OMaFucSnu{J z@h9`m^!mr>Z8mD!8-prp@c_eVqtG#S2g*xUyWQbT7Fz2NGzlz(m7b$kgh*#@{BiTl z1ELUeWj5Yxa-%uDluNWr2gDRehtd7Qg?{gQv?jlW z32lhWV$_HC_qx1GY?be6l*VsXcr9{BWI$Csip7;|$|OBcsjpN9vIg9|J@^+buR&p| zSkN6*AR!gjXxtetr&C?%(>50u(h{p=9}a@Q^^1CiczoK9KrWxQe(RhAJ$k$ELmHO>-Gr7{HGZs&0i=FAx@RXcF6K&+nQ{d@&%UG zAE(Nn^g|WP6EsQI9$5Y>RH&>f9>??GQyL+8MUSniQ&(*PjplRnf_9f8^oiu$G}j|_ zbeMATTOsL^+*M__dvnYn{0qDt+8m<%Fhg0*Gk_LmJtjJeBme-BGc*$}V@)=>bvn^- z7hPy*;~kNiM)PR>kivHx#MoETpdH(+)Th^Zj2gv2U5g%RJhOoDdc_bTn0@_ynj>r12<>s+RAMIPeG-vrlM;YTKmUevzW`yOWl&t4a(K?Ers`8xHP zzE>>nY;D#gT)pSCVHHPy^P91kt}ySM(A^dE57o0B|LSgvG@pprXGJY#X1evH{U#`v zl>s}Q9n4c@ej_FrVd*hkY2|GptB%)ZdPZGa^_h{4v7U<=&k%FEwygArqQkmvkrB=( z2n}-)YpWl-arOxW&?lk%m6XL>0f6U`2+r&mfjk#Q((GglbAh-7wu zPZc)LonJDaUw$6%7|YLvbc)Wq0b;@|p)A;Ds)cGpeRP+TFVt19OqdeH%USdw7hJ1mjvVm!QX2|f4?_Q>b0I;-3{rmm)G#1FgU#dxV5W;cN5jS|Eo~?TY zJpp0Z00B$qXC0ENY|X)ZbTS`r9y2vOJIkxy4hN6Q>3y1ek=h~(K@YbKj>3BAWm z1(tv;BPduvRn1)fH4DPaV1tF*h%i+qSPxor@hQ4_z~naLFj;fOdiwPBu(|B-!xdt&O{k)FX9(0-@p#7}O(`jNoeJX9K> zr1cUhV7@k1Oc@%q(K8**{H_h3*V=vxVuAfgapq5J-g~(IzylsIFK5l1Pbp>9p+g5= zivwYY-4SQOBXQixS;yZf$WYwEj+8(@a)z6`nK3e0kf;x-%34l_KXrFC=7E`7*!5en zk+Y#0K`&eae0PlQ3N%UGe0!tzI{>&M(zQ>u=Lakf2sIPZMUt7RCdeO)!qj02$@KtR z!;{6?Z7)*!Z`kl?8cbQ~Y8A#d)#2vFmC>`+pdxzR zIlw~Sy0BCj5YC`Z5xvOQ!w^vtYJ9A&2G7Y-p7fxm*a{df0SG6j!vw1dO0DPA^7^t4 zUkp+WQWIY~gA&GrK>K4#RoUpDl8b!mvbd$%fU zTz9jiX|u1b-SUjY`75ultb~DqHe$97v*z_k`MCDw_T1%rse+jrBYcKqpd3e9lO+ve zKE6z7RWRoFdq>vbe^A{eDk30wQ-A*?DcULJv8hXB(A9S%nWlzxABQb^U#W|+tazNa z?3)h1Vl8>~K~klG_ZaovwS>U}Wv`ug{LFOn# zlTW;i>qM%o)C;~0bGsQ*$|tz>%MLXow%}Tbozhz^7Xnv?Mo0nE;ZpGVB%F37A-0Sb zk{V3PWgQ##!1?*n5D9s?&#BMJ+`BAD7#(8YhO?(Z0BrtYRv~23Bi|2{A4<=s7D7UY z@)xQ3D|lo(Ii$TI6$%T_f1>nC2p21RI${Vym_I#qH4PwxgbBLN>72ZxlIvoc--3BW zG~m|`%#7=|$bj-+B=9l8GGxRA4OL7;E;Y!UjIw;DDOr^zaXm{ymS*_MGICW~RpFxL zXS$#d7C}V-2fFBdaMl2T86_731auDp-9gFf`{Av?1fK+Z(3BVg>)1?>qsJ9AJ`FQM zETY>qE|uzM^Opsl?I!$NgiV|02J=a~eV0A8X(Z?p^Qp(^%$E3O2sE#x)PV)D#UAsj z4vCM?&0>WRf1JMpc$aCAE@V>|we$R)@(%s|@+S4m3EGOQ8j5QyTr2=w1%PNQmj{;1 z6#!1O!Bi*}#zdG38)v}I16UA)T?ngSDyVC)Xd+kc%W~=(g3Ur!YoNMH zQQe$Xv^L$ri{xoa@pP2PfYlZ32acw>>a?t~_lPpwrohjyK)f60P@)V202DzNO1XYG z3Gfkg`R1>CZ$zNTVlqU;L>nrDc=1FHG>|R6?j%X@H1u3LD~vOmFUm1sSzEG7JqYJ! z+E5d_nIJ>VtOkZP@2lfk{IH<7m%=GD4pkHG#D+K$V7TaNn)UI|{!vyJ8Ipz?K$^Ry zLiQE?s|!CEK8YT@o9&Ke+^E5S?}n=O%cVlN1d(!fJ@Ai zVSYMRZ4IVu$bhi09p|-9WvM=%Ju{$>_UeR8||;xp~+Hrbc5< z)8Y0LH?9`}pN6Au#xl@F?((Q?zEd?dP_&(b?Mi@j5$&p$CL#`7tGOJ#YNgpbDm4@B z%JB)ywLxU&Yfow&>!f-mx}U!{8Inc&$F5cz5l(Xc9efT)!u(r?L5KLR)eHVh+DgYg zn#Tk*;eHC^GHF>n2kRF4SjY2VZny%PePOe!BkC<*9#p!;Cf@>_4KUUr&h#DQNYXFK)SSU zJ3ZYC3X)`l0@}HochehfVS$vC`L8{41rVj(o^8J(;>BQ3cH;hcGZYnm_&Scc3d59u zF|=!Bsvmm#H>!?|I7jB9QV5`;YTt}IzHWU?XkZ?`X3emsjhyXlV0%*zC8dRUuWW)` zXcbpPd^j(2a7^l0QIPpUkWpgda1FS53HZ_*v@%FAM^&+qm2JqVXv8HDaH*XuVXGsOuLEe~@~pl^Eu_{1!bZ)V5u`K|yDlyr zz1^Qmq0u;7G+1q1&rF+6T?1YkBnZDtYh0^}SP5M-`0@olKCoE4rns5&p>$8qWcM;JIl+p5^$lB(kTZz&*XReQ;wP~yqt9r6w zyZv;FlumDm43K$A3FgAQcMH~LHFCbUk#iakhIBZr>>s<(*Jc<{Ke;0G!W$9$aWDa6 z8qHN*O}l1!tjwgdj_TBKH5xISi#tun1%XlTlJazs08(@cDJpEt1kY_Xe))dRuU+4J zCw8K(UYq+PP6b20yzYy+Ed~K4c4ylD|cgv2n*Y?YrBuHvHrO~lN(;u zb|Q_0A3ZjvlxL7e&5N3Ru2O!{cp=jn)r7^pvx`exMfJW!Rj?MM9^q12LheK%3jw_euy#^G-E zf^sR0N)~9WtbP$ecw3Ac<8nWog9H`=XvleYlJT5nJle{A?rerFu4eAT^xW;0)@Btc zWzEN@{+P&z6b*yjoC;wv6ome*kimhF0Y*q4elV)j{D@7bw*X+1)FBhtJfR)N3Cjm5c z54V>}COqa9{Apq}xI6Wyb9qUCHaG0x86UM%ewwKjxnfEQYK zSNn_ao7}Zi*K|ucv}=Fq6^-aw3VD!}Yd-N0yJWd74v|TG>la;C8dX*>f9$wfeP%N5 zbaj2U<*NB#1>yXa^L$TO+)pgiR(d5?tsTq9?}$9v#U(LUJ?0g>n?+3|uKPZ~L84y0 zIO}ZgD<*}7ZU8MJ&CfZ0uAkpA>CEOkZQPt({#HKfj|RH4jX4n27*^OWlC-Ll{HA-t zcc2Xwp}-YS;5gq$s8NMEv}#y~F-o0q@ea=W*^66HTdG@4=A%A#*l2OW95O^YJ8Juu z3F2=Nc2ZVA=gFm4KcEqW9do+fOkpWiM97zro41RxHEgRn-bSiDf3k9Uq*>eevO*{+ z?|5Xrzth`8lH*$*?~O$sVbH-!iY9vC6{@oUx%>bp{pr)a`zwBYX@V-;TQ@#$@c?c- zz%!aiXf@XfCYVI1^ecop=B7ogJ&XaJi5?R53cr5e&p9^$vPLfMo5#r6W7e*|2|k`? z_>1?$BVI#f7nRf%UMMnM@W#*+eU97f9C1Xgo$n&qL>|n*qX_UCnsgu2xu+y1x1ZHQebba?Ch=xI-V4?n1`KX%`~$R zmwL{teLnAX_h48(_VkI^hx()kab-3EoX-%Ef^1)q#63OzDUw%MG#?jz^oifXr^v6L zUVUCU?7#m;sQGh>6z)qa&W_17?fd0wCXNq=et*V>rcYOnYybjh?1Fk1WJchcMc|o>#D2&R;s=L({}nYhd|59Qo(p zzC-Lxtuc2sJ8a>_a*k~cVY?v;9d*DcRH}KWYU@`>_+5lpDc%+;!nRz4*DPHM(oi4N zR$qS+LtcOtYj{<2f2_HG;PZI>%;Q{BE~>EWxL@JhujrL4theX+NSVo#=iVFwAR?QX z3U#Y@hS6MyUF$@Z#mmDe&7O5YW6VJl+w!u+@s!nsPn9}F@(zg+d=`&+g* zAQ~8e(?+M9h`=>H5CY32vQiN!gi^W2JU<69TcqPwns-~HX}Se0JARZ)IiV-;U~jC@ zbIGrl1`_+;BvftVIUlw5MB${Qa>QcW)Kg1xopBBn>AZO1Gkb_GB;lTpSWvVWg5t!W z%&!ECo49|5t3DMgIgQ&7{Z8Kbc4WSdQusGwS}??^NQ3ux$<~3QO*Z`HUvEWTvDbrl z^e^uHd#_mXWFnTURc_{nWkuDA$8|P_vD=U9&)mIn{HeV4tNUjBOI3Uc^w;MTwavE* zew*$fuV+b}`J4Rv;8Q1#hbC&5(` zde*HdhhnBayhn!2^#5MoIXZ-x(VFSQ8mX3#^CRILHA%6( zgZUE-{Fp)KT3+d*<1y~yCzOTrIwl6Sp9GfR*FW`;Vgv&3yjx+* z#qdqx(V1En@FSM(GwT>j!CB+lvAHMvgBg#Xm^>}kc>$Ie)U|;<@LL zDun+oI?LB3)E0yo$3+S`5DV3>+E`rI9=+TJ1|&DESD{*Z`GFdWbCvU*QT~~j+bne2F=^|| zPXxfmbKtFM7SSW4@0N9~h)D_jSgI1Yzx`V&^W}^!>-V{B>>8mAL^|sR3!ZXaB6S(MzYcO!~n(Udm8i5C*Qbp`9|NI04mdrAZ z*%_%V0Fc-_%xyfZ*7Zv+8j>Im;G$?T(G)YgpYY2mld_Mv)6aLzqfXJH>n3D86Ps#N>%7tO6 zUAG{h@Ey@e>{BRsDNsikRAhYla5&EWZlyw2;z)*7ydQ6Qj?|IBCY#E+yG7UX9Ao$I zJvsO`J#0=EVLQFPh)nA9&07 zWxKxBBiipC2o{L;lQ{mVVvPP@G3F#;BthEpNdB+2Puw!j$)#~kPD^(FPrSTkXTwJKLv=Z42|*2;B8 zz8`cQ46kA2PhL#4t=_!beAwE>bh*Clw&x#30z1J}qC8Ira|^VHd)_5_m}b#6&J&0L zn6wmRI$DSZL}^44hsSAG0BM^-eB3N2<@weL#6GkxG6Iov72#lR{{+)a#cPjK{yy#K z>a5{MeX|%zj@C#xvL$R~G?|XOqV-T!)*DDtwN9Nq}iUYp@m62s2xduX8#lbT_!C*xo$#G0d}JS!nVvK-g^5Iyk-_bgps% zcgFk1Eu5#@c`Kz7Q&h&meb_>p$afY$FfR=J5@JXKfLT0Z6a-gdty$Og)GkKJitZ`^ zHM{wNu4z?3!C@IuKg2`E&*JGc)>5rUnhWjy{Dybb@J-&)Y>Dp!uc|$| zWRA~<3Oqgj7|i5(xFZ>?REV&(PUSCYYnMEgh7A0&r1PTIlaPI@fhZnUXCc`tSlV(- zljw}{EJ%|UT|wEVI7_?sFw9IBu<_?Qq?uJ6WkUQpWPtYip!I^&OQYBNKfF(M@9TAb z@41&>ca;!aeiUe>WD*3SnUH9}_vqvuPyquXjJM|b;hi53>#3?dt)cO`8=9r(K}JG^7zK(;yiHVL2T_ zph2_?=!|0&u<$%F-_|KVu;ANU6I7o&YKT`R#qh-A0{$qk35bWl?2VSzzDLmyTpjXAzJN%VQ}~)^YVXfK!86)+DdOXE!a$3 z#_tW$`O9*&9MnSje$8H&jhQgII5BeJ)cE#s95ngwfmFiqAj{VBI+rBU~b z2voljvMX>?cdI8dEmyTX-R>ovOoeSNKlF{3r?Va&l^fA=y>?gG*l35L#9?JARizGq zh++stxj3Lf?0Sj3$ub60Xb2AgY~2OX2e^6xB{n<|XbEHMUkDWr)94%dofSaHB>d(J zj)E8BF{d$wE*>+RCdbmcdr>xdizs)l8e@@;k)M0s$yh6IZd%W%RYz8@R;O%duuj)X0a zpB)t%O2X-EFqAkMMK%QF0}|aT$Pz<9Xf$X!60pu0a4M`V;2U%Xgew5iHtoz0B>YUZl>Y5-WMrSDX8O|mG))p$(!qoF3-TC*4O4nlh; zn;xMJV0~<=2=FjW8H5*+-FX=ujw_8PPd37+B-V61rJqH8L6_=5fid8y$y7w z5r6=OvCba^_( z?dTzqPr2JJfhxj&|L!-V04r!a(gk9$0RXZ2d*a zi~;hz-hX_Ey5Y)FafUY(@JW_$&YL>U;P*$T>uZdwQk?>lA&+NGYcGn@5e^?>Y;W1m z(U+WjL^6_Q9zIB$lg_Z!{%GsB#~@J6KynQENhHrM0Lemb`&787p6;^&SP(RajGIdOFUSbObzRK~0^wEdvTvKfr#?Qt!#;DN^qZ>!JZnT5~(mhJLR0LGsfpm^em6moOAfZTygn%@n zfQWPmC@Q*lU(V+f&+pv#b3fPhzhqHwx^fQ1=mqXs22|W2sF0!s^ItUohEo7Hff4-Q z!kL!dx_+~pU7L7Kc>JSHmA4f)T~(wa^W(fqT z6r#w-<=InT>!vJwOm7s(m=kM$HL06&!YvOH^x7c~+|v>M5WV)nEfkBz4)d-dG^9u- z+6#IPE+uCLwTRCdanAnEe+K&fEcVe{LXM3pQ^JnI>$DO}mUi%fd=xzgCT-g?&Bdq% z%RNAq#2TDI(+>XdC4-O3K;S#K1-r3lm{o?$fG0fO4Id|N`k2>igm)w=Vgp3mB~>^^ z6g344mqZ6m^lB}}xh=r}gIG<)g{_FfU%~JMc0#HOX*L~MVsy-z2brFGc-^j7_nXUg zP-cxQ2Z2Y}=G+xZZw`GvK(ExF6C=%VV=?WUm;`uc#iDSrC-w$&?V_5bMv5j_0*F!; zOJEHWiDoBu>?TlPid(%~Sh2RyYP>j+yBA!>FHqKZS?u{}{A6}9X|M#uWIYNlPA3JoOU%gS7G7lNgo!Oo0-xOiy%q@o2?e z81Kh8e-&6CH>`yi>$V8}7nEQzQ6WiD3F=MXctT&<$H@i*A{8N#9-~_q6|wCJ$&1Tm zyqfnJ?gG8YSE;OXhX z2Jqmke?aL-uzXn5Nkw85`+Ewaq@KKON&7H#1kbky@mLv5@u4%*Q#m#~m=abvrg7Fq*!MT87LuP5?`oM#;`!(XOKcRH{-5b?g#L{|>b2iBbBfH=aSZckIxD@1o{j z!XBR`cm@sNTwq}$oBpUxx9Z#82AMcioHK?xiaiduR!fx}YaC}2O>CBxocu?m--P0i z*x}z3)`@e4x!LeEpxq3h3^}zx?yjF6;~eIv>?h3*zC$9uz;6PzCA&4G(VD|$`-Y6d z7t&it7*CJ3ok)4}-Pss%B8cn{7JU;fn6Tx|3h#J_@8(Q+>8GDz($ZS`QB$WFjKRZ? zMYzy0KFGNLU?f<-dz`Zunir)CsHkEN8A5pzu%3(_+b*bI-@*=y|D)TEPJsS1g-WSc zCh@+MrLN>Xn2J7x9|QLB{}Q%>(r!w`x?- zr8b9V`aJo`FD)p|Xff^dkyk?$gx%>A(J^PPduLwe3iJ0NoCI8SH9^uPQPwlBoAbTz zP@>Wet^m-0jy*sL&j1O=c#iD;_lev60_q{0IVroBmJgfZ;Hg84&U(c4b0^eSxks~m z?Z(73xVy zN+%vRC86tp5TGX(R}B?ogE_+$fiS35_1=BqquBEmi9J)3_6i9V|a{nBS9?oW14BiJjPsKQM*xd71^x zA!(--e;yl%z7WhIFg*7sM-5>ggL#1{Kh^}QYJ7q^cT~bm`iL`A(lBWM&UJ&|oVZ*QG>3@6j&leQ)_PORaOeXu>au+Cf~Sck%7Z=g|lMn5f?JpS&F38u7o69BDt9Wql}`k&#mg#j8ZY zHKUFx9_B_ETERSlI6Kof|0O_O*m>Mt%9f5|mycqFYhpjXh+Vk`bLfGtynVF#{;yMY ztlM@3j`&E00{Hnj;qDjr{&X)!o*zFv=eGPmeSIWs?OJj?a*;cP>x{f}v%x;?N0|Ea zK>FWDUKODZKOU6X73L{h^pW87idzpH{eJ{pUZx8h9vK2aLSSAlAV%^kgOa}t27l4h ztKA#TBEYI)S^`7?P_XI#_KDyi2q4dsY)v;o5b{pl0l;Iia6nGzAy(`o(X9(lo2=rO zFJ*fiQnK+XD_;(0n6q5_b#|xD#_YLas^yr(tlbMI&4XpdTuG}+tzd!5M5g7JUaFO9 zb>g=~3{vTMgh_O0tIh@!RsuWBN?_euDZ5!V&nPx zt(=O8p4;zB^|Bm&)ucsV)mV2)wLIV0Twn1ceBF@oYjmmnz>k z-{r{%9$u=RZOiE+C-)l$-D! zgUz8j(=SHz_lGN43Z~p(UI(Y3oA>+Z>2;yH<2NMQ50d{W*BFF3@E7+5TBDTlz8lhC$@K0To4F33`h4-NxnV~nOC_aDt`2!#7puPn0kdnz1Pel zpsGFQphPuFKHWe3DDg-MY-dkI0l0_EI<4;;M>8J^Py^lj0yL&tUrpiHu&s!?SZnXE zrExF)D$i!>FKP`l&9rG1<8d|ShIZC6KQ?enH;fGUabq^{))~gW_!O`5M{TLsK0&D* zQfj!8ve%Y1Wp3Y$P)h22^meZ?2k%SrzLNjAYr810<9yx#8xM83offHSkM7U0k5t`y zXlG5hx9ph5quRy{q0r@hh!KNxvgu?|$cfJ~7;*S-dI206DaDbJEZIF^(QkBkBN~@o zxp8d09Bn-_tnv=_xzfmcDLzKW_4?+ZIewtU^Rw?DRG5kbAP9H-jbkaVu5|U=f-O4x zK7OOW=>7);EM;{$H>A$PSe4!C#{Go=iiCoY^#=KyyG5N!>$$xiJBALOGk!`E zl5hP@;cF!5-U5)x`z-F-%_A%yLUd)*E5JYnQ4rV-8y2yxx~`{XBmxlF+5b{A-pgR( zza)%k0zl-kWQ@Q!FlzqR4#zg)Tp|sUQ=RU5eDj_6zll9R?DOYiH-m< zTbCfbrvC_Vk@7_Jof)!A057QSS;DXyYXvi{bgab8jEMG(hfMN^v6q*~Hcb^qzf(7N z5f*Q5U90bz;aK~YUB-$*6q=<>irP4_rSP7AO;w$g$-D{(c=G-3^Q)RBK5ai(6&n(R z-uAh9gUlqcDfXn5+=(7C=fbn z?)s^1NQnkl!(XRW>)gMBs_)psvVDg~s)eEpvOMAR-O)$~1JxE?E^ z=gnyfUaQ3V`@F1>u+)i`&ft>P5#+j_r^($%9~NaLa8te9csBuEJPQ%K{5E68Sd+a| zRs*(fA|);!vNA`VHr$9UFSN}RC;aF$*$C~J9Xt0}5{w+CVmjRteEYv3C7ZCRgn zL_?T6>tks_z_S<8b7LrgE{?{Xem6;dMv1w`C0RT;g3G|&O5Z}*eo2R%+{`wiS7YF9+dQl3P__cA6`SaMjy<$7`IQRHT||W4fe_=Jn`AcbzZm0C;YtjC zb0%z{VJv#pxV7R?8>f?>__gJFNSD(;IR!o|6CbC377v!2Seox9Xz1N583)M#_Rl9wnb?iWb$C_|vRr9mO} z%0q8NeBg782ZN77FjYS!>zyx?{a?(!8F8B4PxNZA;jKb8+h@#K4?7fPWb1d9moKsz zvr&GpT9OLs{$$rB7Tt{XRax3JuQB|JhB5qfca9`WGP79keraiocD%Q8s9nUTpmq(N z)%7v=Pk=o4JdOAM211F(Bl*ar}wx@gZ_0ieNj3B2h#DmhI$ zj+J)+Q4;_b>yR5T3<}JK#8O+yCR??DeHt-hTGHA{7Wnd%62JON**D(Hoh_uVoqDDSzSuRj-v`X$0AK0Tv>9}@l<}WoEb9Tl3jNX@$J=kkoL^S(6@hjyZ@kF zZ5|_!l*o^9=PAO0OqlF`_4dFdFhUyzvT_gX3AbK=vOfgT>4!PVzdxS1R(xvVw+fM2 zqey!NW`1A<6*K)@U_sEJ%z^8>i9Oi41xB3{TmR0zpgV0?-IDIUX*JG4={8p;J=b`+ zUuRF-rhTUI-%FWsM}?JgHbF-wDZAfdx~d4XOpjM)FT~v{y8Rx+daLM?LfZ=IN*x@W zkb3+vvbq6JLMJxTSNL@*sC1LQ8nE_dgpsZRL-C(fX=Gg}ffCzNsTi08U}6mEc0`n^ zlrXhgJAoXIs$+UpKW^?=Z+U-;T+iuSWgCz!E;Yf!_py@oeG(PXB-E5dP~3Tr13zB- zM{98`$I4t~wCQN-d^`LY%82~ul)0k^_b3wh%AIh|_q~ZzuwY(jFmVa0cXke6ZlX`| zPi+MC*brtu?WYEwvlA0PLk{L8Q=j?WjTv_weaT=RBAgRg;z+5hbG8cqtDAfeglFn@ zbV{+;i7DdSk7_@62IvI%m4?CVhB|9S$E2wObx^v|6q~LA@CeH- zDu;*Im_Z(HL_Bnj^cDadK7kjDpe-2w`s=|SeG)waVm-Q}(;yZ0g&U7>haA@9EY?@L z1<(i_N|i1(B~^APo$(OFFXnbx&uNKGPB&OzdcxyCQ`A}VNvtB;i=f385tkN)OJB;) z9pAX9Nw_kj_eYb%ywy1n9nFuU{=@!+f806UV8Nos>iRufp(Ydl?I=CfOcZMwhE7N~ zh=P{KokrMQ{vkxCnuVg4joh|Yjl{6%3JFEuVglV98(DB*i4otjgg9h~Y6%z{075<$ z!k_XC$syZ80NdG!!$(~a1@co&NTk?}TJ}kQe|kika1Aztp!>?Y*D^EtZJUK`1M*FZ zg>drGtnzJ~LRfQwY5Ll^5sP02y3$64XmHVhD|I7kHHc3+bUh#(tP%<=K$w;7p1g6;S*t8{e`HN%n@(@v=ghxY0o9;D8#r-QR7#YxVJ@}pOhDMHXyPGu_ zXWBRDIIi2q;mmk-Mo-Z^L09zl>pZE8LSS+;jcM zuOFPvixm0iK>c(}-0wu(4`i7{9JIZdziG?Y1GcV)S_U()loeiYccKf*BGcu(h~=?XbHTtOEubR#nxaW02%t7g+`!8Ay@Q zr-cuX8{(k`J^rLZfg>~q>X34avyPita{B3B;9;-aKAuNKGA!C86Y)Ha=6RYzaxm*{ ztjlxjp^claw|^@}I~quRe^bY(=W#7l^skrHa?(Lpx9@F}{g>nA4_I?dBZN7g>e*lN z(r<_^MA^+>xb!L&aqa50`cONm`Dh%Dv^&+hc-o5yGa35ZzfQ8TNGjqBVdftJ@hNzY z1T^Mxxab>bD+Y=2J75JzqqvVTy9t1asZL^B)w9G6y&)a_e0MM2_|$pNhVK%vZLzl? zJTo~=3P0aOcfdc;aiR4~ zpP>(n)%pVLR;9$@-`D=H<`S6FXcKg+^>(m=HCMhl5i!59tkpeScVphrraOcikGWSo zs~P@sawv|V^!w!b!WHi;*OQWj!4eL6-Fq3C>vlNnnplrcLS|3i^~&M#JW`Ki&4p|K z>Sj*5<*?pv_1r@{iK4ZFuVC{kx8St}HHl`)mqO-x(w@IVm`@rThLUW22iax(8=A)T zy4dL=tG+hB5isM|<8N|%J2KdyD>z`@blq}nIf2+p#u#+h>3~&-I^U8; z2h;@aVN8&a{uXq?>VEO{f_+I77%p0-0*;d!(b0|Ot@Qp^liJ4*!LIdu-px-@=?pWp#5U*4(*l zZ(mwbL5RGdM!$f?^B;_Jxt(RN1Qd(5<3RF8pq1iUTxPIPsr)B{VuQm;lhfBS`x%a4 zH~5?i7oB}tE2JUWHuIb-Ym_9Db{A2-u$<7~=o6up{D=MXRiBmUxT4!UTbCDK`2L*_ zBU)S@Eb&Z4b8O=M@_Rw%5MFMO6a_{!KR`zZ#M|?o;Q|x(8XuOg01h2saPPfM(Zk~4 zCFD)YH8E@I)48$V6uSf=>RD2^4r?dZbbK2ZmMa~~|ZbG|AXaQcyy&j>l z5S=Snov~(mQ#oLuM@X`T%qix$z#3CvmGjGXXpjrcUXNf$B zXEDr?`=@2S66gB@FVv$huT){FP7Y1Vbn*%2{#9 z^$!2fa{dSPUAwA%*RrI7v}D4-5-MPcGpxW)6i0p(n?n?vF?NWAp&TQUXIh?iJy0^u zHs+IOC?>)kpsEJOeqzQG@HFoMVAfBE08o(tJXsM$-vZDx_tIZtSRqkbw?WD39?N~{ z8NA;7C0bHf`I zVU&Mj+8}K4ZAHGX^@H$J@crPO+;M;_lCH>*evB7s)Jgi#6WI0-oT2* z(Bo6j(C)zi(BnQ+MEfTd*0Vw5)$)OcLTJRlL)M+}xE+?MWKY$|t9+9ve!itiL;$tp~?D^4>u3~u@cDVS)5 zyCYL0+A%kt>U3lx`L(5Sj2j=C3C{{+;Y+jEt3}>xJplIkE1o0G%5~4Tm&%zjx1QfD z)yq-K@v*G4Zt|S#%<;8;;oKY2`Ze29$_fZ6)f`K*6u(hi!U%SO;fp2Ba@`ZBh2!Y> z)cksdssrp2;;1S8ci*Kv)g(8=I`CM)r)UIDJ{!S& zHI(zN%x3l5snotu*{RGADYK)s z2BiR}nhX|eAk2syMlwxTt5uTuxUsV_zg|wYIMa<@_^YY;OHDbWcl6ijPLS2(a@p`V ziRK`@0uZVFqQuzl*9%2CeWM9w(-1Cyh0hB7CJL(Z;oJN(5qqfu>q(L|43Khd;a)6* zLIo1TMI(utl6=SMrQ4;cR?FUXwIXc3 zP5yc-{)xecg;fbuKiM22Ieb~GgDiAefO(JmtmXzFloQ}t^Yi1K>*3a)Y%Rj?=UQwC z3$xq<^#tcR;z6E;F^M3Nk1;=w4mddcTXf6B<#u?aOel4^7x;R2u{JdQvpwwiHnhZYZ*Gv|s3h=4 zL~h038@k86P&O6jUTvIwj*5PA*6}nXP~ryq7LF;K8!9&;ZUP1a{J$Vj1ONb1)Z~i^ z*c$}E$r5ciw*j%F_c5GF!eNA1+8>V;G%Pk~DjQ5@m-qQN(o{a2j?%Vz$VT6zo*{Ot z)?u`{ax4$+_OAFklYn}}*GAjA(U;HPKf^pm@EEpKPnR2HaSlFjsrm3+>^k;|VQcMN zoz2S|mm;PK^bIckbg{Bi^jb`i3Gfs@nQ4*tp#qWpqpi^~`=uQ1c=qmE)ng;Lx7yuT zL|n>UdP%1g!Y8f&U_2BF@h{}QjOFtwjg5ylxySBrG*O@nU3Mm`Z`C=`hMw&_E?*#9 zg&UPrfo+?;s}3Qr0;?T57&m`RaK3s1v^(CKwbM)%!G^RY41@Sg)g{rqUH zKbaJt|LFCv)9nv+&hNY5{P}tOW$f9_x7~mLT%7KGe*g9@i3GsJ*6ICoGsjiI;lT90M-tS;5-)r`;ZBd4~nCkTBXpasS_W=r+9v&ji*9Syf`_zTZ_ z37QNrEHJ2lAbh#0x>x@=Ek%06YBJS8Bs?QwfmtW*K1;@zF9>?m9x%gCnwrgAhmcJJ zMZTR=fZ+~+(aH0wTAEg;w;7mFKO%0>^U!bKn)LVCs(G$M%d7+9At>Ih%HB{w$6qt& z?f6!fqBgsweP`1Ze)W#RaoW|5lE=5pi>nH#b=FlNG1rb`P-$01cR%dZI_%2R=Wo!E zAhsny{Y!BzQ7WAq8vi!!(o}+)CF(Qh@KjrvA+j(>bw1&a0I(4TZ@_FMobIWAg{beh z30raPVZTm&$uFZAyi<`3|2pp)P?a%u&_(;h%uaEGn@d;q^F!@)jt*kKr8qxv4eq`v zW|&sB&;1bHwb>0n>SuYUCEc-c@gctSY+Me>a4)2CXSjX64efo<4LccyeFAJ1-)q&~ ztbC-lb+d;#26(Rw?b4g{rpk+>Qx_#;y3Vt&_b!GYnA5KLFDI?c5rYqY;6HcPffy2UG9!$4 zpEF?ppOk4}ps17cN9c9mhJlU*dCIGmZ{*Wk4}EIuFjUSl?HeWOqSDIq^LK_t)%Px5h=Boc2h}tE`c#)_WE2i$& z#!~$%&7PX>UD-^w>-5Q_JsIwwlsb;5j>2^ux^~D+mM0g3ZhhAnUFQ|(LBT%%uEULb|q1& zrNMFo$KB`yk14I!&ggE8Z1AR|DCNed1lWT;c-Ag@xi+H^T2uVon?yZ+L{yT)6o}<6 zJCyZkq~P!uW73)c_pjMlo#z9Byl1Fk1%r8gzc<3H`xU>W}IGFBTBg9`@9L%=7=w~ek@O){q{9|(zc|~|i z)@>Ah&6{YtSmdyPi($fl1SZMPVZ(A8K$?mLm^-KatK2^-qUUkV@-U~c5@(jncZUbTchl_KQDt|sULY|~r*2j{jzP1594FPwGR(uq+Ip401 zW45DH1`;fV+)WJl9y9l6Rw#<4;SkpVQ@Gk?c}s#vtT1qFdu6JZF6s%TJuy()HoXyC#ZT)Uvv->_*XBol>yW&!1fDOQC-OUh^9U^jB>h3*HfbFEAk5i1sG?PTDo^wrAq` zLwaI7)&DF_rM0y@H#zXJ|FgUp_v7w2Ze}eC%v3u7$i&D700evXEfIrKQJw&YGca%j z!$@yQD||zkijP2gGzX?re7L``3?KiLZDdGuLsM{!!1ZMa(C?x8->&6JPCcSKd&c%=TT8ifCU5erO8yDo*a%3a59|8u!j(PY9~2-4c=(_!aW%s!G@3{BL_m*dx2V(la zR`^+eKH!VxEsu&vT%6D!lD_=;{45hT33KIc>NTO>ITj;M&?|ARyET;LkZdE zahr3*zo<0Ge36Z0BJKlBnsez@<-gQY*8GG9NY|Ba&meoViyMixKQ-7ttf1w7s|MQjsqYyk9* zi?Ou}vDx2Z)=~5uXx|f$xP=(Hh;zE{m{^lAi8TVnZ-9P(Erf?b@}fEH@*9%$^FIig zAIdH{LWBnspeaP!8X|R84}~EKLzRc3?hm4AoI(gGB4dNNQqV}cx&Htcsb}m--HJ); zc$#)HCu^R`QY)7&7M zRupv|kun`g{Q#hfAtFX>V*0=WKia&nozU&0_~ZMpf5$MM0HVV}_aRNjW6Tmlu_-%Z z%1d`?mK2ch<%F~tg|xK7HKxH))Zx|9+WEzy5&xB|w`M zM-_yGO=Dm_DEK`BWjKcFkU(WkL~wT?vPvkN(a5AAYM=xLAgTJAm|9|^il#Gb#E^G> zM6@f@e)PQe(G+e$>OqVgQ>U6DJ_kV`BI!a=sevfk))J~Nl-C^kW+>jKCI+#vMrDIX zJisH!{0Ym!P;hV}#R=lY8q%2~7eM7U5%@P3nU65^$1V!acNqh`8G}Y;*hG;l0PvoO zcs~UX|3y=9OcUplmkLmQ)Xf8fB>6YoClqdcf#m(pr}!NIpJi28%7VqUGYsrHZhAwC z=Ps?C9v!bLRn8PGfTsI`gnc=NenBB|0N{+w3_pftnZh9qnf&6&@E}Ssj#lEj{p+Qo z*Wtdy=qy2)!vKc^TRUT$DQ)#J#a$xh+*fE!5L8788jGa!EJ55_gPI}f*7aywiIgKq zs!$Tzbe%|f&D3!PlQWE_A;V>xj}b@WvW`1BOxRq`=v1wB_K(#z^rarKQd$6@E<+(Q z3Ghq+cuast0YDUnD$oV_Gyz$TrN3Ou{|*#LOk;sxIy5KopX6{HKWG<-)KeI$^6;`9 zvIq`^v_#U{A!)VINEtkYG8hbzrRdc1?6#GfF{Ra9F8?b+JA_MG>!BStEjHkc9(8e* z$|#OqgAT7jH7wx|g5Y_kPuGqSkwmx!Ko{&m-PS|<00Te9Krh!Qb5XRBNXknjB%_tm ziHK-F4sJt*@PEs3;-C)eeE#s=b2o9MM0T()I z2H15ZOpjPdk&!S?#89of{uz0O`NEjlVK)#J&#Q)G&c)56X@3wXzYytHr)Vp#7Xrkx zX;Y|WPZ@xQXs?00cfrDIU~vLi7+o(00P-b}m1A0UwIs~D@^0wub#xY&O#`>hJ+Wz; zF$~nQ6@fj59b@2Ei8L{5&}t;)DIO6TMCHOsJ=#NAM4%3Jq13gsh{Z!eET&s(h^IYN z#b^XTO)Tj_l=mR&*T@SHf#@RAj1lXno;#}|Bi^BO6{;~&)z5mLF)+};o66w0ateM} z))ai0-~f-Jzf(=0aNmkIO7~Y^JZTCmbH7&6f()AcLE8{SH;ATd`c1jI_Okgm*QV{@b*J$g5q-f0;#rE=zl$@`y-TAU)vHFF3x*7AI3ho1=^uRQheiJFH zh7>M&4Q}cOufGOk!3`L?mV30zM)n@_Z=9*S?~8PAQZqKYP%q?A3>`b3Mhsd#9JHw) z3=PW3z(d1{P+u21U(+F9B+R!5;<4|CoANV3g}Gy(HbFTyql2Nwls~xW^8fTO1uHb5 zkYp%U6b&$mL1v+;I?1SR5*kT~Aop+(vh*;14YANu!)REVRzrXGfpNMytU`kO%0nbc z8991tdWbIq&@krp*WzffdJ2dOjl@VHw_Rw9YpzlT+j}ZC=tfjPGb)UJXQE1J-W@+Z zUW3-Lyi$3LWAUUN%((IaO-n{CHLTHe2GM;3>i(3_?GotR)+TDDkk<(iz?4FdNMSNX z;c#41Fol@DoIG~${IF&c*h2wj%ViiFrf;JA97HpxfxJfr+}ok8Av<w(}=tudZzT>RsJ>xpUZ6ar-gof@u%?gov1(Vp= zgJ>WkaxriU9DD^Iz~4`nJJ1P_$5>P`%IZ_54wuSFz01*;&V8j(U3ld^8cakZ7x5ss zW9VuROh9u+NE0cp3FbnNF$CKO=~dWOJ&>x25@hY>GYf4IqizivPi3QSE1?-d1#}<# z$Nli%5DAcGr*14kKyjVmliAk7I@mf`jRp|JfOXNx`%j3tCq&>m@q^3!=QTt=Nix^x z0C^YpCe=-EEJ{5K4rJRPi`Edss+uoB0+Gxz&(u_;*9BOgXmDu~%2SXI{8V|VNC6X= zi7!%I8d>^i4wwRs2z=^Fc`$7IL5YV^O`3Y)-bxofs2xqyiofS@pJDwqk{v_-)gusl zIobIees5N9OXvRL{zQ)({i=fefToVxMFx(liUu=@Kj;%Po*rEv%^qd>Gx0h7;6I9K zs^%S9@Wdvs1JVHi0*)a!rXU}rkr^7uTX-tq80Jk>_1#)CEPenhjq1FAo7ri+b@c=3 zIA>&vny2wo7bX=Bs-Xz(h2b*6y)Y{b3@S@8BaJ+Gozr+6D9$@SOLCdt#6L%OGmJuM z`dz4pG#Qe`xrFPRa~^Y@hAp!9%KU!5m`!DzWGiF^nE0{~5wtKx}^!8X1P(uBC* zb#gHq1Dc14C)JDbuV38Jk{mU6=URu~SI&v9W zygj@4X0O!N9XU+{T!Bg7lcXKH`w)U#1yGdWCQ9%LtN~RfVuTdX*rF5ed(jZpYrM}M z9Nkh)MlJ2P{iSa@riP0K_5%#>P2sP5s1tONQ>JiglJqIKX$p42LPMf~6?H8A4FsX!NsC#F{BHL2lsvOo!? zdjlKU+R6a(roVcRp*xD>h(T0rr5ib@u^QG$SnrZX9>q~l{6p3eX&Z^O54sSLU@{5| zo4J9ub|$3}uiQA(U=X6ag*-PcC84{1-k5&&DQrq!8h)bw z_LlS?3WoI|q@O0zY2pE)bcT=JuyHp}mQ1$Q7rAc?xqbiCPR!I2_T-7H%nhj49$a%k=f5fDGZoD6KL&TwLWb3Q~ zp{bkp`;Q=9-7};OQz=C$qM-zl>Vh;kLja`+0Ivx&g7TG2*ZX4U0D~-6I$OG+^$JDb zHslw*w24ev2#0xvmg_*|Uq%sQtA_u)sxOmUsco+St!Z=IHB&5rIfXL_nJaHO8C9q? z1P(e~l(b&hzl49=6~#ZhmFP5BXt`(A==dfQ%4M~0)9n5kBo$xxCn~9&B19s_JdCy*q>)` zzLbN_qiJYlDpJsKRdsu232sjqW@y{tSdEBRGK!l<1(^Ve>$2M$c;;> zlKxO}xW{maC^#Dk8n!lIrU%4gxyQwGE1hbF+5$cQh_hCdd?9MnUxUaFZ0Hys@;!n) zpz92Imyz7~AJI+r#Si9<$twqX-?d9mdLp2$R1MgHKF3fJA>85dkoq6q`Q4`LN6(3ex z=CXK$GQ=7!BmZl0v}?9ipJd{Syfa^mw-?gstV6;0B`Xz{Ntw{BjO-sAc5 zDZG(8VqPvo6)@i<6m@L9HsU{K1-}^D3!tGwYXd~Rrlv?^;cTP6q$2}>=3rX@$j9k% zxO zJ|j8xdi0ct{B6lKk{7mCr2P=9>RC|grau?8$iRZXwKNm2TCAF4J;~-aF=`d;GclT5 z?*oG2Z6h_@`3=lf$@9K!4-Iyycz`g{6#qJnroa=z%_Y-f#uzu9i)sy3+>ld^`Pt}DbF9QKU(6Nw zC0+k%UBvv%a6_S{yO~$OC8Q?gC~c?~MeyPGEb;d79%Qk#*^6wwu79VJ#T@=+SJO8o zru`~WwzK_T^O%}9%3FD_eiL*>oe&7mqLL!#u3x8kn%5VTotGmSP9IaUn(|WPsphaJ zchbixG3)ZNb0d;utsz_n3Bwx`>4h4-r{Jy4inF7l+-JX*FO|%%B?|4Dx)rRJah{8j zSvHt@)gd%ktk{AX%~Hs2Bkd~785`!ANcDQ6s``5pt?pEkwK3ZrfD%BoL8YSvCzBcl zHOo>5yf%8ct=D4cPWQncI#$nO(;<*Sa*1Z=rr-F+-_wlnq!oz zIZNudVC&buHxTbSwy16XJ11*jKTn_>yb`HG_z#@TFTtG{hlt>MqBQ&b8ttTd{)bnu zfXV6#R~DPjf-B*cw;!+WtXXgH=UR>TJw1@Lx>OL*UZ`w|l>BRGIAeu&8XB-u)Xl0y zLvxm-2BI*rz78+SUU`47udYM5O|^wzc_THa-o}|F38`(hzG|Gy8Gc(&ri$>p*P}j_ z)0VUny(Inwc7=Nr3{XS~Sx<&q2@QGQU?Y`|Zf&-5e?%5KUjAm&&^^}-(C)e?05C8xtp3r;S?K{ry#r zU`C;nnS#mweoGO1EKOT?@-il#blgQWjwxjpOvb*rouNJPG^b5_xqi}zw9FG!CF}TH z`w7na)!fm$JGQSixvpMg9a*xkSECO8f-rlc^Q>f>kIqYQeW4k_-dLHI>5}FcP5hZ>ta$2dSOuPW* z5fBu#?5>tY)p^({>GfD}D9Nxf<-xBl=e>Ef`#@&fp~6mPKGcevkwX64pyN==O3jlt z<K>%{a*5t&d5%d5cNjg4W!twzyYaiZ^npLr-)B`>NQVyZNw6bEQrWJzaGl z^KoC7okxrY+t55!BAkb<@9gSIy)#)C3HbO;t_bzC^i^5Ji!h;yP^AJN2E>c{*S-mZ z3C;V%UIlsNEnk$Mu}LOP?R_6{MiS#4*}r$1AJ_8w&BSZ)-roPbJvTe+2A}Dr5|~eM zlq6@91q9l!*bFZVx)rD%$n}reedKmDYLb#?@%h=T{K=S)_4lLIf9bEs|87sVafg}H z@!-&zxYzG$b?v0J(*|xmZT?}fd(zMHxXVJ=Ha>Cv{9BD(HO)R%!<#Sn{*ysOk~jx> z%$xL%9))E8SIyRH6S9rEdtZ(B_vhBsZwoiBw1qWxODa6e?R)FrsC;@?+c?|3b1*P? zywg>b8#;bi4CLDe}rRK^S~(=+;|=Mq5-hW!P~`x_T`gq`V(X-Lx%~JVX5`S$)H(ldc9~ zS%UfLb=AW*bEJgkS9obyUt7bXY`~xN>5Ec3F@htzfFV{R_t(`|0&h>4u2EZPmBH0+ zK4241&hoF-$QskASSLJVr?s+aZd`k%<@Q`Xvpcmt9sNNtrx44Bkariu)R%OSVv?c# zD~j^ds?Ztav3;NV89^p9UTiG!C4l|giEx)!%fNInpAi_qOh6FQ7n2}B^+qePlz5Ub zO2mFL;IhRl3ZuEd`y8HPyI_ zj3^f!HfHfic)Wd5Dal^ba6D0QoC@cq?eGA)M1lWKl`OtZ8*p7j?YP^bLT~$6CD=5F z+-k9uHe*wCnLlbUh@%Eabjxg7lMLW5e!WdPDQt$nPA`D2&vfS`X*2A^DnCwAsT+FK zl0xH`WyPFkJ^R9wf+l!_0G6W&k;;^2BKo$&yhr3NsvA6~%F|KpBrmEYYXkW#7fk-n z)myXrk<6nn@EW4UEdC$m{RKMedX!V;urI`hi^cLB;ZGbBMl-_bUkfr5+Tp_9`YGJ6 zc|H!r{?E~Qhb8s?fB3Kza3L<-ptwiwl>-qK6%A*u3irsBnORu@g5pNAGBd-OrJ0qV zva-UNnVOoJ+QLy;S*cms{J0#oBn`Ukg$2ot&7Wq*1&qs+L?pBUYYz`tyal!PKN$E`-toF87ZAyK`$Tj=Q z-Yd7r-TV@deTB2n@4dzXFckd?pAC-~d2W~Ak~`8rTKH;zaVG7~;+E63)|-K<_YAun z^9cpx>kzlulWa~6V}$~6^BCP=W)h3R&C@|iTsTsazv2b_@fyiFcRI!?#_@U%3vKZ8 zMgtxR27p(qzAy|R1gP{*OkZvZet_h6nd2=jZ{9n1J>a)^Tq7~zy7Y%aFfo+H#rUcZ z7s-gadu!v8`o+OZgP$1#PZzdVhQn2J&&8P&=Ko+ym+Si;ovWe^bqdDrtHJN9Ni^e$ z{giPac=TrCxXJwWhCAM2pa-WV-GSk8h8ct#3jR!@GvENbdqM>F01JFyuZ~@%`p#!^ zl0^Vc^9NT1m$5$|=N7}`bpk9C!b-83jk5!jOnaFkP{m`S&Ua9q@ z!tDi+v2_L`k-^BIvoYgR-zN0cIdCo@fj#B9c|RGWDhDgPy;>x%;JCB<+##s606H#! z(uJ5eMR3TSz|l!Ng+dUF4mP2pV`>B57d=tAwerWmw1Ki#U6GC%W0(cx532yx0Gmqp zfB}e{panIKXdvwE3%V+}IV5mbP0sJe-<^DJcs0lKzd3Th4?;;w;@>nf(RdI(;BT+) zb-d(eG=%(!uQA;qEmh;UI@!bK=3}WGw>UU4F`$Az&7P&lT%Jbrf`CpyvX$O)WFVY5 zd^fN6H6}QW`}j0($6;2nV3Qg%h75@H4z+%EcD;LGpWi}v@bL`Uhdn)pk`EYgmS-c4d;M0%41SC5FHMkEymqmM_yov}rE%~PJi0D?-7g%vV_ z;p;(g;1S|n1X)jlml!HRc|)oY1@j=F?BeI7l5FKRPbS$7rD8)!Q7Xg4!gvw z{zxVC2R}?|Ug+;hM+L3v7wkC-aT%7Sw$HV3>G28(sfn5&E4G|buT3ihK{pAyO!gai zEED{+BsH*Hs-SN(`~n_I-GX0|G)WGZ248;qivRSa)vcdyjo&RHY}uLGVZd0u@Z8I} z+wQyQ3Xk1)mAu^xzaRJDwHe|sqKLBWn*J%g0t*zwfRb-WVF;W5BK5`Q9kHWFEc8gS zD|`*jIIpl;g|#((=asyPU7WmNIJ|YLZ8)s$Wf;JryX)+F>l2EZSCMm{za;U3lj?sm z3YN8j1Y-a}RnTP-Ohtd1fhiSV260)J7w-0dqjCH!E0%*_eO$w*Lko$}sjxZL8L2`z zMuM#Fhv3X4nlu*(Ix=$3^Vqwnsc4o_VBz1Z>9Fya>|$|Nk;K$G3!x8_K7iAtYBlWuEZdm?A7+V0$D7>CK{4!?pP945`HcP#e zI+-TNt%6IX$rf9^d<=p=tNBEi*oX4d;V9eA*)R;1n`tC~U_#>(29X}|({1jddb?+hzfM&MmM^2YyJlx1wO?FWqndfVY46+( zaH!(`FZv=I>Yj9ahO!Q{#C0V0B}W&irfpA~UK$G)Fz8@SXBHs@J{`%?i-U{VMc>D- z+;@C2yHq=?|8gsW2I2|vlK)Nyqw{oUCM?Yep7>b^)?_OJMCRNO4~Gi zaIh!x(Xj5GnW%S9{eTrnz8%>8<&K1q<%OpCHvX#_sk>77^{xBI7Eq{&iQ(rZ@-?0P z*VY~d-9z@=HPFB9U%PdSdu*a&HzzpFvphyg0%;$cx09Ha1hjpq_6-7Nlh~oa)KjW< z%Y3bLVQuNuFQ>himle`F#egRfpgVBWHxbI$VhhF>_q4LFRU)EziI1@KbW@3t*>K+| ztWM@lN_8ASXL-_~xi390m=@oXM&z_9o%|%V=hXP4{Yh*)ma`zCh7AU`=$;{P1o^FX z+;XwUB0~U-i2>8K`8Qs;2;H7vnpuX|E9O7pTkqr|fE8Fx4h(3K_rbu1#^v{Glum9X z-nz{?V8ar7=_!qpPMg(7$(^jyEk3DO^YD-t?7)pmn@`pM28_%gmV~i08gPb(H;@5H zgJdRM-!9Ikz=vS@!CFzYkKX zr+fr!3_6q?3LV2kKl!;UP~jq7t@aH`iK#g0KdATE-jP2;>iH84)FMHQd2{ziE`5^u zD&3=WGUg2+5ua+WFTPihpSSij+TgKUp^viTo^C=$1lO}E^rAnFwc{#O|C&{Kev0mO zXk#ZdOmP{d2NgPFS>5h~zk)$>YryAM6AXCFRSdhNT4C2QrK?ipdWK7vQ%xrM)?`Ud zbqI&Jiy^vVFgsC49-jv?S)JUH^tl{*f^yK#@gUzpD zB{i#~HENn1ci0M}HC>Drgn9YJ{`~yk(ZZmDa+4*OWT$ia|D>QhGxU?z&V(X2x6ApG zdmKjBwx(DkE#Dq#tXsX#bE;Li*eB3kYhajI@?YrC9mc6U}m8u}Xd zVqZ5K2vP0avShG4y%$dVH*9;?=|hK#K8HOI>^cphb5^$xyKEPAy!L2 z9ndehe%VoGk~0kWaP1mJA#cXp`)GkOTh<~y>0@y)4F&v$VJZFGuG@K)9>5-mMh2@$Y z2sJD3{HL=aZ)RVo&g4G&NkeA{e{*D$W65hUmmjrmr=84LkyxVks%ZbgWrw~KH#wYp z96~`Ir*tM)w9+Nl7T9EokzfVKaif(#PyYVOKQK#V6H+a)n+(DqM(e~YC>(_XB!e;t zt{{bIR0x zc#-v9N|zG&>{{x_@1KIelJ%M4-5rrm$L#<8H4>-2+}`c>=;zkuaGK6&>us!zeYk?ta3km1k84qboNX=-{$Qk)5R!^!k<1CYIfyi=_ z*IO=!3w!X{Z{$`en$GmC-M>eq%QGG@ZLXvpefyMh+9C|x+1ge|JTe?&xE*2A-u3L+ z_4NBTi$Gy!LBIovwDdjMpRF4r5@-FQUz_O$#d1yL-8Icj%;kt?vb=fHg)<%%Eb2Eg zw1xeeoV4Xr^5&%Htxqk_iKCG_<$%5@SD4GdpT%N|%?d!5BCguXNda36MFAB5gWB8_ z*K6>K*9Qj0L!(5x^6=`~MZE59sJ+ffBFsN5Xx-e39*F{@7!={w%C~Z7psMk8>0gkj z-pet#!QErwenT4PNgJ9Y78u7S$V(()gV_ze(6{H6la`e{flx>#8Gp2kYN_FF7@hk2 zY1WgB!og?>)2lsNlT3hbrVThphBbQxRxcDOP1>_B9jP5Q{ODB$%6O_%6Pk&rU||Bt zI9j2t;t7hwp(4}UtuUkOK~prnQnx`{69A&mdqad7#}c6Jpoy2n)#?43dlDMvG#rv` z-pbI0aQ#W!G82+Cuvz(4%D!)laEWx(8*0*ZJUNRFk;{oN0nH9s5qN-cCxLRoyK7~y zHv7qQqLFLSS&r?$hK80KB32MFJ~7tq;+S_+vVm~l8g{(RaHp;JF6;iFlRBpy8@?W7 zp|o~~MhExdb$p{UeX1UM8(2R1J=e(;!BTmjd?LLE)`&7--T^S`{ARB_`sCNLYWtP1 z<;UJ#JKaHA>^c)_U-D4($=wyg22tYKAp^M^M|`YYDe|_5&6|K6l4`T*SQVu?^=R#T zm$UO5?{$1*-VFv^`IC4nqISZu&EsrJLtD0k<&;7vn_{7H^_^FAR`^Y9+vZg5bLpKD zMsVxbGb;WjPuvyA^72tjpPOZ(lCOATzAkp2ovkT#(mjLQwpJX*DxbcWTh2%Kgqfs539{A>9K`rTD0Xn*@Tw zeet$sMRsL(W~XbbRpniys?qHLs+!t9=+v5npwv&orOKl0(%|FK2Cj%9w5Mu0qQI^K zLN{4^=UPZ;2sSI8Q!FMb`*HlTYB0M(G$xIRE3RI#_K%_FQN1w_)AD+{V=(E@;Ng6{ z4DljReNAWhC!V4`Q(2DPQ^}CYsn3k>dsMwyVS{tuoswsgVn%B;rCBKXhFiDC$;w)Bf$7)x+f}-g= z&ARVQH7$3q7uh#+6nxB>vd%^WkLQOS>>AkU{gmP=n^w`VV)D#*P=P;w&HHK2#dGr; zXGx@N-KCR{OkJ-vomJF!I>TvHJC?(c`PBsnR&YmvwP&v78IWQ!o}2E^0pxksXDIb9 zcMyexExnJ(%BDK^q45V+AC$yO#wgiG`CBj>Wm%biF#BZa+v<&rJgXnLcExVSWd)me9&QhsQg9C-F*4k^H7uDtM=Y;o;sY~avl z{l79e-DgXt#JlvNzSg6{ONkc}E=m-C7}?184w^`O&log_*Yn$5@;w%Y;>Z1N;denkP@ABb08eRbJB`HuK&?(qqZwz6|huYy(M zOl*9*>rOf|53W_s3IFISUj0yGd9bzQ7+L3STwz*6qRU79JY}Yn!H$5wcpT?L?t=U}0!e~6DQf*)=x@G9w1YxFAZ$wQf~G4!81co$Z0 z;Cmqai}w<$w#ZfbkiIwM;mMM{U0?h)6#Nf^I$ym-X)BN9sO|f3vpBq4OJ4YtgG^py z{Pyq_bvJ6?T1m={L=sC+`HC=kKk~h3MCoe5SCcf5#4fB+Qr8_bd*4SA_B*{ai0>Z+ zR+{B04`<&5;O3NAfG*#}gX)ocy(&BNPIq#*y*n&U3n={%+@=Ej4HI{uNqxLOiue0> z=4_`Rho803Vt+tF{_GeV-Pzkd=kl!O)U6MF z;IE@{9ZvxC$+Re>WJqYz_ypS$K&_L`pPD56dSDa(M7m)aG6nF5sG^XV_Gm2BlzTY^ zL}#7p%!{;&7Z3gMRZ~r3(EREeL#n6;P|dduyIQ1rs})H=glVvB$z1n#}T|Mb>b)W zh2JK-`|t46V}%+k*1P9&TN~g1eN)PblE_q&1Hg`hs<(TiE?k0~Ggp3a%ough9@7xK z%>O|zc#!^gtf=J0Rp?GrpEYk1ckRIx&A+^+y~$?xBKLUDG6-R3SL3nl7SYb2us{#r z04pH6WRsdGbs*XP0z-zD^m<*am%23i!lk;~{tb4&)!NBvHYe?m!Vz=7LbB$!ziuY8ede8g`k{RW zqbvtI1%KWvuPQ*Sitj@S_U{2{zlgYRa1tmi1NXkRzUcQiil{R>d7>%mpZe3K)J97} zoiNGGHXfrkRDWc+Kczd*7NCPVW_(h1Q#xNY-z7=4zZfwQ4oD8uHB4F1ORtEV!2YWf zbDfaUmrqt*8>oD^RAeuDtyToJpky?B&wbXFD+3x;jaUUaSoQDvgiWV-4|O#diA8lM zg~^^eJ3PSDgNuPpS;Oa`t-cGy5)3pND14(0a9kA~^L{3czuYHnz$K!~i25t%I@aVn zB{kIMUSCzys5j8~Bp=-1^JY6K-;-IniNgR084Grl_NoJrlju#JWBq| z8kXQ*Hx<~uD=4zpp>{E)cHpbi>jU}_V_l(}1z9sU6-jMpdgMSHkZh-Aw|B1Lwp+5w z#sl8Ttof*U$<-M+m*D8Y)40)u>n^cdTUKl)8nzM*B;SB`F?EcY5JX*X@3;XeR7I@D zPT^_rZCw7o7~9?Nf|B1H=0gA$1cYR7Q)IU^(ufoTZlVN0Jz%+H?4o@caz*V;&gxuPWMiMXu=$_z(*x0>-(pP}*+B1~Bl!+f6` z%~-IgvO&TDeDetjr~1-kn{h|%v^w6)!KGW3t%&EVT@if)SG`zL$xygXz@!u(q;@`n zoM#=YYIu+IJNLO!wmtw4yk#;_?&zjV9vC`D3j6H#?tq4kd_T2BrRCv@*UHmXu-s~Qoq@p z>jW<-C^0osC^^&>Z3K=Yn?Ms!#SWK@-n0VySHJPe%Cqlu)o5jSI5H@+%gyiKdX@BI z@V!N!mo32DR|W~~Gn(gRcdHmm0d{fMXmP=QaYB=UDQ>&4aH#==?X(eB-~HalxZjJ^ zM{LUbF$g`JpVT_m*gDiKIh%OqR4-nQS(w{jGgP|=EoM7WSKBw>U{$6pK)CI8l_$h5 zBtqj%Srbw(!SaL|6&PRZL!*`EsrSJNeOdqtXIeWwGdN&Mf8$fz>`|R(-`;DN>xvPi z&aqv6yrIpXT1X`X=b5DsUaYcX{ghO{z@Sx%+2?RLm5S6+PGb7|5iyw|Cs-kgIvQf; z!lVZOI9ukDowwS6_4|?CIw37-kB}ZtbUlkd{iXv@7n&hZtq%l&{M%jSN#YK=0G zqbbPevX0Hc+!M65jr_#v?;u3vH#Fo{kCna1#5LAtt@GIZovBeTHE@>@Ux5 z40`B(Fa;?+4L(O}S6br4-%1+4bdPm!FqJ}r03^uK8pCvpwv_j)#L#)CWYU>?49h0N z#mW+o(QPLQ9p7*lIwFbtk*^FWeb&jQi|lq1cK#hR?V%~lHa|wybl`o5Y2-8nn5e&P zJkYGT*MGLv!?BIj$v}59NIi)%YxOQgH6GJTb0EIu@RJ%O{!%bH%2BHfA#9no^U&YL zQ2wLw^gC7h+yE|v9_^|Mz}0)a29hF+(}&v{j-CD02V27D71CsL@AfSlLk&f=9{n{h zD_nT;fO2<6?rnZ`rU6hz7n(v_e{NedC8>l)z1`aT1kR-%jygAJcs{8Erd_;vj%7)2 z%+Bl#mUg$z?rSjL9a7mDfxS!`{Y<1=1X0@1UA;to*OU!hI*8u4!SBC@2ZnoP_UGBb zPu~bZ+|)8JKUqTb=tZ-TGA6xsrd6dWeO{Xv^9Hc`b@@`#{tpgI7h^29#grwG!u)<#D5{5#jD>f8osc>z1 zs-)vj(FfMTkZ!SdLCUAtYeE0^*jAJtT}jO31shonupQp0s`0ZF`D^PL`{Pvb=XMRJEs-BF~T;Cc(5;EmtBg z#(iABQ6PIz;QwWZJk+&yg(0KH_@Oummle`)X#hR<2E}uR^1y&m&OXnEZBK8BCpt_2 zZ3;5U`D&TiXWsrJ{{d_Jy&n$u@%DO22 z4yNhKt;?S^^P5vf0xUjw)Y*{i)Eu(yqBkz*XRtkCB6NuRd6GxL_cv05s?A%(SkT@p zU54jL(rYutKX9C}H$D*{joOO^Q1i>O`&>1ye)59aPq?900C{MyJoJ`y=d^^pJIsuJ z3;eKm8El_uJCsYFQ`~N&2dVz{@n&`W(5|x{8P)1wezS9wf2W>v@__VKW9taXFB&A1 z>lSDg_zU5F&)3}mu5;y2(Hql?54?pBRkPn^JM<@b-f%n8$#k*1_xts|gBgu3Z1;~h znvS?7o`CeGLmYG5`qKMPpM8JPl%>Y&CgB-(bU@OaNc2{tiz$?2!YWM$ImRqE!bUuHD+ zz^o!NPo~H3{`#A+=SYzKFv;&$y4&{IDCgL$?I}6cds&h}u3dd3xvXE5ELU8tYj@-M zKZm`k-R6{mpFyOVFwHpJ?4)|BTu5~2u=5L7rNbU~+y=tFA3*-|p{MCBL)5Y}m@fT` zzt`@o4myz>C~CP5x;-92w@K|nB96MH3Izi_jM+P?a{NTJS+CqC9o=qaybbDd>f)}U zFS|vLT}AUxaZ^4#H^&~(MK#@VDfcbt-G2Ixo?Gs*bpv03@mt|PrZnABmY-Uy`gz8$ zSn2(~_7!5mouklS5WDks*0F42-%~m@TH+ijs|2Z%n%Qln8gWyuDZ-B37i6oU0@>effRSux)a%a_J!x&WVp4?r zC;oOGfKVmzs@6aWKn4>EiF)q9>a1&YexHV~hvG=z((|^^t5(Ia?i&hpkrcd2MIrfw zjt85!UNhix+I083bFx8SMjd}MrMBIWP`+B<&)V>Eh-p3Vl3XeYD)Hlk5XNhlQlsbd zbzrGrUJLts4n&5RQv+?XNegsCm{$qFbS+1y00H#1;tZ6#$gTPS((8>9@Cx+K;As1` z5q{N(@Zq}Z@zt#ls#k}>7uBu;$ic~Q)K z@Lq)&U=C`Hr;JSW_~YZMdX4KJ6Mw&}-W~ps<<98wAFeyL7HIake11|_GnH^#n`?ZV zN|q9!4I9`ja%&Vz*3WxM**HfqWWVCPxOr(O0e13a=%xLG_EaAqeR)5}Lrq*_4&$5S zCQ?iPF7uTUS*hp)1h`*rHzflk9@8n*IR&OD@~5X$X66#&zzO(c3@@Z59856Fsl|6MB(r zu`WmqeLp4yFH;o)0NV-!7bTiOEfg{x1O@2y5@mp%S3YWHd3CVm*63*RM6Kj}`E1sc z>&H8{3>728FP8IItMBb`)uG^r=Xi3JqzLwH0P>y$%7_*RlCijYIsHN3dIh-;M0<_C zIeC0Qud{VZfNM?1?T_u2+k=4{PoQWwnn^7BYvNsnXLmk++*Y5k+(yO$=McY?6RQ;v z4Q#lJW7zILN9NWaTtWT{6~8!m<=ms=-`_qi$Ny}V(5&*%E@s{P6unt~Y(?r8E1!C> zq&�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⋙5_0hA3$-4V@cGj&JI8ce=@&8*t-M82l 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