├── .gitignore ├── CMakeLists.txt ├── EnvVarsAndPathToSet.txt ├── README.md ├── common ├── CMakeLists.txt ├── monitors │ ├── CMakeLists.txt │ ├── cpu_monitor.cpp │ ├── cpu_monitor.h │ ├── memory_monitor.cpp │ ├── memory_monitor.h │ ├── presenter.cpp │ ├── presenter.h │ ├── query_wrapper.cpp │ └── query_wrapper.h ├── os │ └── windows │ │ └── w_dirent.h └── samples │ ├── args_helper.hpp │ ├── common.hpp │ ├── ocv_common.hpp │ └── slog.hpp ├── gflags ├── .travis.yml ├── AUTHORS.txt ├── CMakeLists.txt ├── COPYING.txt ├── ChangeLog.txt ├── INSTALL.md ├── README.md ├── WORKSPACE ├── appveyor.yml ├── bazel │ └── gflags.bzl ├── cmake │ ├── README_runtime.txt │ ├── config.cmake.in │ ├── execute_test.cmake │ ├── package.cmake.in │ ├── package.pc.in │ ├── utils.cmake │ └── version.cmake.in ├── src │ ├── config.h.in │ ├── gflags.cc │ ├── gflags.h.in │ ├── gflags_completions.cc │ ├── gflags_completions.h.in │ ├── gflags_completions.sh │ ├── gflags_declare.h.in │ ├── gflags_ns.h.in │ ├── gflags_reporting.cc │ ├── mutex.h │ ├── util.h │ ├── windows_port.cc │ └── windows_port.h └── test │ ├── CMakeLists.txt │ ├── config │ ├── CMakeLists.txt │ └── main.cc │ ├── flagfile.1 │ ├── flagfile.2 │ ├── flagfile.3 │ ├── gflags_build.py.in │ ├── gflags_declare_flags.cc │ ├── gflags_declare_test.cc │ ├── gflags_strip_flags_test.cc │ ├── gflags_strip_flags_test.cmake │ ├── gflags_unittest.cc │ ├── gflags_unittest_flagfile │ └── nc │ ├── CMakeLists.txt │ └── gflags_nc.cc ├── include ├── cnn.hpp ├── core.hpp ├── descriptor.hpp ├── detector.hpp ├── distance.hpp ├── kuhn_munkres.hpp ├── logging.hpp ├── pedestrian_tracker_demo.hpp ├── tracker.hpp └── utils.hpp ├── main.cpp ├── models ├── LICENSE ├── person-detection-retail-0013 │ ├── FP16-INT8 │ │ ├── person-detection-retail-0013.bin │ │ └── person-detection-retail-0013.xml │ ├── FP16 │ │ ├── person-detection-retail-0013.bin │ │ └── person-detection-retail-0013.xml │ └── FP32 │ │ ├── person-detection-retail-0013.bin │ │ └── person-detection-retail-0013.xml └── person-reidentification-retail-0031 │ ├── FP16-INT8 │ ├── person-reidentification-retail-0031.bin │ └── person-reidentification-retail-0031.xml │ ├── FP16 │ ├── person-reidentification-retail-0031.bin │ └── person-reidentification-retail-0031.xml │ └── FP32 │ ├── person-reidentification-retail-0031.bin │ └── person-reidentification-retail-0031.xml ├── src ├── cnn.cpp ├── detector.cpp ├── distance.cpp ├── kuhn_munkres.cpp ├── tracker.cpp └── utils.cpp └── test_videos └── people-detection.mp4 /.gitignore: -------------------------------------------------------------------------------- 1 | # ===== CMake ================================================================ 2 | 3 | CMakeLists.txt.user 4 | CMakeCache.txt 5 | CMakeFiles 6 | CMakeScripts 7 | Testing 8 | Makefile 9 | cmake_install.cmake 10 | install_manifest.txt 11 | compile_commands.json 12 | CTestTestfile.cmake 13 | _deps 14 | 15 | # ===== C++ ================================================================== 16 | 17 | *.pkl 18 | *.npz 19 | *.npy 20 | *.obj 21 | 22 | # Prerequisites 23 | *.d 24 | 25 | # Compiled Object files 26 | *.slo 27 | *.lo 28 | *.o 29 | *.obj 30 | 31 | # Precompiled Headers 32 | *.gch 33 | *.pch 34 | 35 | # Compiled Dynamic libraries 36 | *.so 37 | *.dylib 38 | *.dll 39 | 40 | # Fortran module files 41 | *.mod 42 | *.smod 43 | 44 | # Compiled Static libraries 45 | *.lai 46 | *.la 47 | *.a 48 | *.lib 49 | 50 | # Executables 51 | *.exe 52 | *.out 53 | *.app 54 | 55 | # ===== C ==================================================================== 56 | 57 | # Prerequisites 58 | *.d 59 | 60 | # Object files 61 | *.o 62 | *.ko 63 | *.obj 64 | *.elf 65 | 66 | # Linker output 67 | *.ilk 68 | *.map 69 | *.exp 70 | 71 | # Precompiled Headers 72 | *.gch 73 | *.pch 74 | 75 | # Libraries 76 | *.lib 77 | *.a 78 | *.la 79 | *.lo 80 | 81 | # Shared objects (inc. Windows DLLs) 82 | *.dll 83 | *.so 84 | *.so.* 85 | *.dylib 86 | 87 | # Executables 88 | *.exe 89 | *.out 90 | *.app 91 | *.i*86 92 | *.x86_64 93 | *.hex 94 | 95 | # Debug files 96 | *.dSYM/ 97 | *.su 98 | *.idb 99 | *.pdb 100 | 101 | # Kernel Module Compile Results 102 | *.mod* 103 | *.cmd 104 | .tmp_versions/ 105 | modules.order 106 | Module.symvers 107 | Mkfile.old 108 | dkms.conf 109 | 110 | # ===== Latex ================================================================ 111 | 112 | ## Core latex/pdflatex auxiliary files: 113 | *.aux 114 | *.lof 115 | *.log 116 | *.lot 117 | *.fls 118 | *.out 119 | *.toc 120 | *.fmt 121 | *.fot 122 | *.cb 123 | *.bit 124 | *.blg 125 | *.bbl 126 | *.glo 127 | *.glx 128 | *.gxg 129 | *.gxs 130 | *.idx 131 | *.ilg 132 | *.ind 133 | *.url 134 | *.svn 135 | *.dvi 136 | *.fdb_latexmk 137 | *.synctex.gz 138 | 139 | ## Build tool directories for auxiliary files 140 | # latexrun 141 | latex.out/ 142 | 143 | ## Auxiliary and intermediate files from other packages: 144 | # algorithms 145 | 146 | # ===== VSCode =============================================================== 147 | 148 | .vscode 149 | 150 | # ===== JetBrains =============================================================== 151 | 152 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 153 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 154 | 155 | .idea 156 | 157 | # User-specific stuff 158 | .idea/**/workspace.xml 159 | .idea/**/tasks.xml 160 | .idea/**/usage.statistics.xml 161 | .idea/**/dictionaries 162 | .idea/**/shelf 163 | 164 | # Generated files 165 | .idea/**/contentModel.xml 166 | 167 | # Sensitive or high-churn files 168 | .idea/**/dataSources/ 169 | .idea/**/dataSources.ids 170 | .idea/**/dataSources.local.xml 171 | .idea/**/sqlDataSources.xml 172 | .idea/**/dynamic.xml 173 | .idea/**/uiDesigner.xml 174 | .idea/**/dbnavigator.xml 175 | 176 | # Gradle 177 | .idea/**/gradle.xml 178 | .idea/**/libraries 179 | 180 | # Gradle and Maven with auto-import 181 | # When using Gradle or Maven with auto-import, you should exclude module files, 182 | # since they will be recreated, and may cause churn. Uncomment if using 183 | # auto-import. 184 | .idea/modules.xml 185 | .idea/*.iml 186 | .idea/modules 187 | *.iml 188 | *.ipr 189 | 190 | # CMake 191 | cmake-build-*/ 192 | 193 | # Mongo Explorer plugin 194 | .idea/**/mongoSettings.xml 195 | 196 | # File-based project format 197 | *.iws 198 | 199 | # IntelliJ 200 | out/ 201 | 202 | # mpeltonen/sbt-idea plugin 203 | .idea_modules/ 204 | 205 | # JIRA plugin 206 | atlassian-ide-plugin.xml 207 | 208 | # Cursive Clojure plugin 209 | .idea/replstate.xml 210 | 211 | # Crashlytics plugin (for Android Studio and IntelliJ) 212 | com_crashlytics_export_strings.xml 213 | crashlytics.properties 214 | crashlytics-build.properties 215 | fabric.properties 216 | 217 | # Editor-based Rest Client 218 | .idea/httpRequests 219 | 220 | # Android studio 3.1+ serialized cache file 221 | .idea/caches/build_file_checksums.ser 222 | 223 | # ===== Miscellaneous ======================================================== 224 | 225 | build 226 | vs2019 227 | release 228 | docs/tex 229 | out/* 230 | data 231 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.0) 2 | 3 | project(openvino_pedestrian_tracker) 4 | 5 | set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/build) 6 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) 7 | set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) 8 | 9 | find_package(ngraph REQUIRED) 10 | find_package(InferenceEngine REQUIRED) 11 | find_package(OpenCV REQUIRED) 12 | include_directories(${CMAKE_SOURCE_DIR}) 13 | include_directories(${CMAKE_SOURCE_DIR}/include) 14 | include_directories(${CMAKE_SOURCE_DIR}/common) 15 | add_subdirectory(common) 16 | add_subdirectory(gflags) 17 | 18 | add_executable(${PROJECT_NAME} main.cpp src/cnn.cpp src/detector.cpp src/distance.cpp src/kuhn_munkres.cpp src/tracker.cpp src/utils.cpp) 19 | target_link_libraries(${PROJECT_NAME} PRIVATE ${InferenceEngine_LIBRARIES} ${OpenCV_LIBS} ${NGRAPH_LIBRARIES} gflags monitors) 20 | 21 | if (WIN32) 22 | if (NOT "${CMAKE_SIZEOF_VOID_P}" EQUAL "8") 23 | message(FATAL_ERROR "Only 64-bit supported on Windows") 24 | endif() 25 | 26 | set_property (DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS) 27 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_SCL_SECURE_NO_WARNINGS -DNOMINMAX") 28 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") #no asynchronous structured exception handling 29 | set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") 30 | 31 | if (TREAT_WARNING_AS_ERROR) 32 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX") #treating warnings as errors 33 | endif () 34 | 35 | if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) 36 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251 /wd4275 /wd4267") #disable some warnings 37 | endif() 38 | else() 39 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") #treating warnings as errors 40 | if (APPLE) 41 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-command-line-argument") 42 | elseif(UNIX) 43 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wuninitialized -Winit-self") 44 | if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL Clang) 45 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmaybe-uninitialized") 46 | endif() 47 | endif() 48 | endif() 49 | 50 | if(MSVC) 51 | set_target_properties( ${PROJECT_NAME} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "$") 52 | set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME}) 53 | endif() 54 | 55 | file(COPY ${PROJECT_SOURCE_DIR}/models DESTINATION ${CMAKE_SOURCE_DIR}/build/Debug) 56 | file(COPY ${PROJECT_SOURCE_DIR}/models DESTINATION ${CMAKE_SOURCE_DIR}/build/Release) 57 | file(COPY ${PROJECT_SOURCE_DIR}/test_videos DESTINATION ${CMAKE_SOURCE_DIR}/build/Debug) 58 | file(COPY ${PROJECT_SOURCE_DIR}/test_videos DESTINATION ${CMAKE_SOURCE_DIR}/build/Release) 59 | file(COPY ${PROJECT_SOURCE_DIR}/run_test.cmd DESTINATION ${CMAKE_SOURCE_DIR}/build/Debug) 60 | file(COPY ${PROJECT_SOURCE_DIR}/run_test.cmd DESTINATION ${CMAKE_SOURCE_DIR}/build/Release) -------------------------------------------------------------------------------- /EnvVarsAndPathToSet.txt: -------------------------------------------------------------------------------- 1 | INTEL_OPENVINO_DIR C:\Program Files (x86)\IntelSWTools\openvino 2 | INTEL_CVSDK_DIR %INTEL_OPENVINO_DIR% 3 | OpenCV_DIR %INTEL_OPENVINO_DIR%\opencv\cmake 4 | OPENVX_FOLDER %INTEL_OPENVINO_DIR%\openvx 5 | InferenceEngine_DIR %INTEL_OPENVINO_DIR%\deployment_tools\inference_engine\share 6 | HDDL_INSTALL_DIR %INTEL_OPENVINO_DIR%\deployment_tools\inference_engine\external\hddl 7 | PYTHONPATH %INTEL_OPENVINO_DIR%\python\python3.6 Check your Python* version and adjust 8 | 9 | You will also need to edit the Path variable under System Variables and Add the following entries: 10 | 11 | %INTEL_OPENVINO_DIR%\deployment_tools\ngraph\lib 12 | %INTEL_OPENVINO_DIR%\deployment_tools\inference_engine\external\tbb\bin 13 | %INTEL_OPENVINO_DIR%\deployment_tools\inference_engine\bin\intel64\Release 14 | %INTEL_OPENVINO_DIR%\deployment_tools\inference_engine\bin\intel64\Debug 15 | %HDDL_INSTALL_DIR%\bin 16 | %INTEL_OPENVINO_DIR%\opencv\bin 17 | %INTEL_OPENVINO_DIR%\openvx\bin 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Standalone MSVC version of standard OpenVino demos. 2 | 3 | # Pedestrian Tracker C++ Demo 4 | 5 | This demo showcases Pedestrian Tracking scenario: it reads frames from an input video sequence, detects pedestrians in the frames, and builds trajectories of movement of the pedestrians in 6 | a frame-by-frame manner. 7 | You can use a set of the following pre-trained models with the demo: 8 | * _person-detection-retail-0013_, which is the primary detection network for finding pedestrians 9 | * _person-reidentification-retail-0031_, which is the network that is executed on top of the results from inference of the first network and makes reidentification of the pedestrians 10 | 11 | For more information about the pre-trained models, refer to the [model documentation](../../models/intel/index.md). 12 | 13 | ## How It Works 14 | 15 | On the start-up, the application reads command line parameters and loads the specified networks. 16 | 17 | Upon getting a frame from the input video sequence (either a video file or a folder with images), the app performs inference of the pedestrian detector network. 18 | 19 | After that, the bounding boxes describing the detected pedestrians are passed to the instance of the tracker class that matches the appearance of the pedestrians with the known 20 | (already tracked) persons. 21 | In obvious cases (when pixel-to-pixel similarity of a detected pedestrian is sufficiently close to the latest pedestrian image from one of the known tracks), 22 | the match is made without inference of the reidentification network. In more complicated cases, the demo uses the reidentification network to make a decision 23 | if a detected pedestrian is the next position of a known person or the first position of a new tracked person. 24 | 25 | After that, the application displays the tracks and the latest detections on the screen and goes to the next frame. 26 | 27 | > **NOTE**: By default, Open Model Zoo demos expect input with BGR channels order. If you trained your model to work with RGB order, you need to manually rearrange the default channels order in the demo application or reconvert your model using the Model Optimizer tool with `--reverse_input_channels` argument specified. For more information about the argument, refer to **When to Reverse Input Channels** section of [Converting a Model Using General Conversion Parameters](https://docs.openvinotoolkit.org/latest/_docs_MO_DG_prepare_model_convert_model_Converting_Model_General.html). 28 | 29 | ## Running 30 | 31 | Running the application with the `-h` option yields the following usage message: 32 | ``` 33 | ./pedestrian_tracker_demo -h 34 | InferenceEngine: 35 | API version ............ 36 | Build .................. 37 | 38 | pedestrian_tracker_demo [OPTION] 39 | Options: 40 | 41 | -h Print a usage message. 42 | -i "" Required. Video sequence to process. 43 | -m_det "" Required. Path to the Pedestrian Detection Retail model (.xml) file. 44 | -m_reid "" Required. Path to the Pedestrian Reidentification Retail model (.xml) file. 45 | -l "" Optional. For CPU custom layers, if any. Absolute path to a shared library with the kernels implementation. 46 | Or 47 | -c "" Optional. For GPU custom kernels, if any. Absolute path to the .xml file with the kernels description. 48 | -d_det "" Optional. Specify the target device for pedestrian detection (the list of available devices is shown below). Default value is CPU. Use "-d HETERO:" format to specify HETERO plugin. 49 | -d_reid "" Optional. Specify the target device for pedestrian reidentification (the list of available devices is shown below). Default value is CPU. Use "-d HETERO:" format to specify HETERO plugin. 50 | -r Optional. Output pedestrian tracking results in a raw format (compatible with MOTChallenge format). 51 | -pc Optional. Enable per-layer performance statistics. 52 | -no_show Optional. Do not show processed video. 53 | -delay Optional. Delay between frames used for visualization. If negative, the visualization is turned off (like with the option 'no_show'). If zero, the visualization is made frame-by-frame. 54 | -out "" Optional. The file name to write output log file with results of pedestrian tracking. The format of the log file is compatible with MOTChallenge format. 55 | -first Optional. The index of the first frame of video sequence to process. This has effect only if it is positive. The actual first frame captured depends on cv::VideoCapture implementation and may have slightly different number. 56 | -last Optional. The index of the last frame of video sequence to process. This has effect only if it is positive. 57 | -u Optional. List of monitors to show initially. 58 | ``` 59 | 60 | To run the demo, you can use public or pre-trained models. To download the pre-trained models, use the OpenVINO [Model Downloader](../../tools/downloader/README.md) or go to [https://download.01.org/opencv/](https://download.01.org/opencv/). 61 | 62 | > **NOTE**: Before running the demo with a trained model, make sure the model is converted to the Inference Engine format (\*.xml + \*.bin) using the [Model Optimizer tool](https://docs.openvinotoolkit.org/latest/_docs_MO_DG_Deep_Learning_Model_Optimizer_DevGuide.html). 63 | 64 | For example, to run the application with the OpenVINO™ toolkit pre-trained models with inferencing pedestrian detector on a GPU and pedestrian reidentification on a CPU, run the following command: 65 | 66 | ```sh 67 | ./pedestrian_tracker_demo -i \ 68 | -m_det /person-detection-retail-0013.xml \ 69 | -m_reid /person-reidentification-retail-0031.xml \ 70 | -d_det GPU 71 | ``` 72 | 73 | ## Demo Output 74 | 75 | The demo uses OpenCV to display the resulting frame with detections rendered as bounding boxes, curves (for trajectories displaying), and text. 76 | 77 | > **NOTE**: On VPU devices (Intel® Movidius™ Neural Compute Stick, Intel® Neural Compute Stick 2, and Intel® Vision Accelerator Design with Intel® Movidius™ VPUs) this demo has been tested on the following Model Downloader available topologies: 78 | >* `person-detection-retail-0013` 79 | >* `person-reidentification-retail-0031` 80 | > Other models may produce unexpected results on these devices. 81 | ## See Also 82 | * [Using Open Model Zoo demos](../README.md) 83 | * [Model Optimizer](https://docs.openvinotoolkit.org/latest/_docs_MO_DG_Deep_Learning_Model_Optimizer_DevGuide.html) 84 | * [Model Downloader](../../tools/downloader/README.md) 85 | -------------------------------------------------------------------------------- /common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018-2019 Intel Corporation 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | 5 | add_subdirectory(monitors) 6 | -------------------------------------------------------------------------------- /common/monitors/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018-2019 Intel Corporation 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | 5 | find_package(OpenCV REQUIRED COMPONENTS core imgproc) 6 | 7 | set(SOURCES presenter.cpp cpu_monitor.cpp memory_monitor.cpp) 8 | set(HEADERS presenter.h cpu_monitor.h memory_monitor.h) 9 | if(WIN32) 10 | list(APPEND SOURCES query_wrapper.cpp) 11 | list(APPEND HEADERS query_wrapper.h) 12 | endif() 13 | # Create named folders for the sources within the .vcproj 14 | # Empty name lists them directly under the .vcproj 15 | source_group("src" FILES ${SOURCES}) 16 | source_group("include" FILES ${HEADERS}) 17 | 18 | add_library(monitors STATIC ${SOURCES} ${HEADERS}) 19 | target_include_directories(monitors PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") 20 | target_link_libraries(monitors PRIVATE opencv_core opencv_imgproc) 21 | if(WIN32) 22 | target_link_libraries(monitors PRIVATE pdh) 23 | endif() 24 | -------------------------------------------------------------------------------- /common/monitors/cpu_monitor.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | #define NOMINMAX 5 | #include "cpu_monitor.h" 6 | #include 7 | #ifdef _WIN32 8 | #include "query_wrapper.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace { 15 | const std::size_t nCores = []() { 16 | SYSTEM_INFO sysinfo; 17 | GetSystemInfo(&sysinfo); 18 | return sysinfo.dwNumberOfProcessors; 19 | }(); 20 | } 21 | 22 | class CpuMonitor::PerformanceCounter { 23 | public: 24 | PerformanceCounter() : coreTimeCounters(nCores) { 25 | PDH_STATUS status; 26 | for (std::size_t i = 0; i < nCores; ++i) { 27 | std::wstring fullCounterPath{L"\\Processor(" + std::to_wstring(i) + L")\\% Processor Time"}; 28 | status = PdhAddCounterW(query, fullCounterPath.c_str(), 0, &coreTimeCounters[i]); 29 | if (ERROR_SUCCESS != status) { 30 | throw std::system_error(status, std::system_category(), "PdhAddCounterW() failed"); 31 | } 32 | status = PdhSetCounterScaleFactor(coreTimeCounters[i], -2); // scale counter to [0, 1] 33 | if (ERROR_SUCCESS != status) { 34 | throw std::system_error(status, std::system_category(), "PdhSetCounterScaleFactor() failed"); 35 | } 36 | } 37 | status = PdhCollectQueryData(query); 38 | if (ERROR_SUCCESS != status) { 39 | throw std::system_error(status, std::system_category(), "PdhCollectQueryData() failed"); 40 | } 41 | } 42 | 43 | std::vector getCpuLoad() { 44 | PDH_STATUS status; 45 | status = PdhCollectQueryData(query); 46 | if (ERROR_SUCCESS != status) { 47 | throw std::system_error(status, std::system_category(), "PdhCollectQueryData() failed"); 48 | } 49 | 50 | PDH_FMT_COUNTERVALUE displayValue; 51 | std::vector cpuLoad(coreTimeCounters.size()); 52 | for (std::size_t i = 0; i < coreTimeCounters.size(); ++i) { 53 | status = PdhGetFormattedCounterValue(coreTimeCounters[i], PDH_FMT_DOUBLE, NULL, 54 | &displayValue); 55 | switch (status) { 56 | case ERROR_SUCCESS: break; 57 | // PdhGetFormattedCounterValue() can sometimes return PDH_CALC_NEGATIVE_DENOMINATOR for some reason 58 | case PDH_CALC_NEGATIVE_DENOMINATOR: return {}; 59 | default: 60 | throw std::system_error(status, std::system_category(), "PdhGetFormattedCounterValue() failed"); 61 | } 62 | if (PDH_CSTATUS_VALID_DATA != displayValue.CStatus && PDH_CSTATUS_NEW_DATA != displayValue.CStatus) { 63 | throw std::runtime_error("Error in counter data"); 64 | } 65 | 66 | cpuLoad[i] = displayValue.doubleValue; 67 | } 68 | return cpuLoad; 69 | } 70 | 71 | private: 72 | QueryWrapper query; 73 | std::vector coreTimeCounters; 74 | }; 75 | 76 | #elif __linux__ 77 | #include 78 | #include 79 | #include 80 | #include 81 | #include 82 | 83 | namespace { 84 | const long clockTicks = sysconf(_SC_CLK_TCK); 85 | 86 | const std::size_t nCores = sysconf(_SC_NPROCESSORS_CONF); 87 | 88 | std::vector getIdleCpuStat() { 89 | std::vector idleCpuStat(nCores); 90 | std::ifstream procStat("/proc/stat"); 91 | std::string line; 92 | std::smatch match; 93 | std::regex coreJiffies("^cpu(\\d+)\\s+" 94 | "(\\d+)\\s+" 95 | "(\\d+)\\s+" 96 | "(\\d+)\\s+" 97 | "(\\d+)\\s+" // idle 98 | "(\\d+)"); // iowait 99 | 100 | while (std::getline(procStat, line)) { 101 | if (std::regex_search(line, match, coreJiffies)) { 102 | // it doesn't handle overflow of sum and overflows of /proc/stat values 103 | unsigned long idleInfo = stoul(match[5]) + stoul(match[6]), 104 | coreId = stoul(match[1]); 105 | if (nCores <= coreId) { 106 | throw std::runtime_error("The number of cores has changed"); 107 | } 108 | idleCpuStat[coreId] = idleInfo; 109 | } 110 | } 111 | return idleCpuStat; 112 | } 113 | } 114 | 115 | class CpuMonitor::PerformanceCounter { 116 | public: 117 | PerformanceCounter() : prevIdleCpuStat{getIdleCpuStat()}, prevTimePoint{std::chrono::steady_clock::now()} {} 118 | 119 | std::vector getCpuLoad() { 120 | std::vector idleCpuStat = getIdleCpuStat(); 121 | auto timePoint = std::chrono::steady_clock::now(); 122 | // don't update data too frequently which may result in negative values for cpuLoad. 123 | // It may happen when collectData() is called just after setHistorySize(). 124 | if (timePoint - prevTimePoint > std::chrono::milliseconds{100}) { 125 | std::vector cpuLoad(nCores); 126 | for (std::size_t i = 0; i < idleCpuStat.size(); ++i) { 127 | double idleDiff = idleCpuStat[i] - prevIdleCpuStat[i]; 128 | typedef std::chrono::duration Sec; 129 | cpuLoad[i] = 1.0 130 | - idleDiff / clockTicks / std::chrono::duration_cast(timePoint - prevTimePoint).count(); 131 | } 132 | prevTimePoint = timePoint; 133 | return cpuLoad; 134 | } 135 | return {}; 136 | } 137 | private: 138 | std::vector prevIdleCpuStat; 139 | std::chrono::steady_clock::time_point prevTimePoint; 140 | }; 141 | 142 | #else 143 | // not implemented 144 | namespace { 145 | const std::size_t nCores{0}; 146 | } 147 | 148 | class CpuMonitor::PerformanceCounter { 149 | public: 150 | std::vector getCpuLoad() {return {};}; 151 | }; 152 | #endif 153 | 154 | CpuMonitor::CpuMonitor() : 155 | samplesNumber{0}, 156 | historySize{0}, 157 | cpuLoadSum(nCores, 0) {} 158 | 159 | // PerformanceCounter is incomplete in header and destructor can't be defined implicitly 160 | CpuMonitor::~CpuMonitor() = default; 161 | 162 | void CpuMonitor::setHistorySize(std::size_t size) { 163 | if (0 == historySize && 0 != size) { 164 | performanceCounter.reset(new PerformanceCounter); 165 | } else if (0 != historySize && 0 == size) { 166 | performanceCounter.reset(); 167 | } 168 | historySize = size; 169 | std::size_t newSize = std::min(size, cpuLoadHistory.size()); 170 | cpuLoadHistory.erase(cpuLoadHistory.begin(), cpuLoadHistory.end() - newSize); 171 | } 172 | 173 | void CpuMonitor::collectData() { 174 | std::vector cpuLoad = performanceCounter->getCpuLoad(); 175 | 176 | if (!cpuLoad.empty()) { 177 | for (std::size_t i = 0; i < cpuLoad.size(); ++i) { 178 | cpuLoadSum[i] += cpuLoad[i]; 179 | } 180 | ++samplesNumber; 181 | 182 | cpuLoadHistory.push_back(std::move(cpuLoad)); 183 | if (cpuLoadHistory.size() > historySize) { 184 | cpuLoadHistory.pop_front(); 185 | } 186 | } 187 | } 188 | 189 | std::size_t CpuMonitor::getHistorySize() const { 190 | return historySize; 191 | } 192 | 193 | std::deque> CpuMonitor::getLastHistory() const { 194 | return cpuLoadHistory; 195 | } 196 | 197 | std::vector CpuMonitor::getMeanCpuLoad() const { 198 | std::vector meanCpuLoad; 199 | meanCpuLoad.reserve(cpuLoadSum.size()); 200 | for (double coreLoad : cpuLoadSum) { 201 | meanCpuLoad.push_back(coreLoad / samplesNumber); 202 | } 203 | return meanCpuLoad; 204 | } 205 | -------------------------------------------------------------------------------- /common/monitors/cpu_monitor.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | class CpuMonitor { 12 | public: 13 | CpuMonitor(); 14 | ~CpuMonitor(); 15 | void setHistorySize(std::size_t size); 16 | std::size_t getHistorySize() const; 17 | void collectData(); 18 | std::deque> getLastHistory() const; 19 | std::vector getMeanCpuLoad() const; 20 | 21 | private: 22 | unsigned samplesNumber; 23 | unsigned historySize; 24 | std::vector cpuLoadSum; 25 | std::deque> cpuLoadHistory; 26 | class PerformanceCounter; 27 | std::unique_ptr performanceCounter; 28 | }; 29 | -------------------------------------------------------------------------------- /common/monitors/memory_monitor.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | #define NOMINMAX 5 | #include "memory_monitor.h" 6 | 7 | struct MemState { 8 | double memTotal, usedMem, usedSwap; 9 | }; 10 | 11 | #ifdef _WIN32 12 | #include "query_wrapper.h" 13 | #include 14 | #define PSAPI_VERSION 2 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace { 21 | double getMemTotal() { 22 | PERFORMANCE_INFORMATION performanceInformation; 23 | if (!GetPerformanceInfo(&performanceInformation, sizeof(performanceInformation))) { 24 | throw std::runtime_error("GetPerformanceInfo() failed"); 25 | } 26 | return static_cast(performanceInformation.PhysicalTotal * performanceInformation.PageSize) 27 | / (1024 * 1024 * 1024); 28 | } 29 | } 30 | 31 | class MemoryMonitor::PerformanceCounter { 32 | public: 33 | PerformanceCounter() { 34 | PDH_STATUS status = PdhAddCounterW(query, L"\\Paging File(_Total)\\% Usage", 0, &pagingFileUsageCounter); 35 | if (ERROR_SUCCESS != status) { 36 | throw std::system_error(status, std::system_category(), "PdhAddCounterW() failed"); 37 | } 38 | status = PdhSetCounterScaleFactor(pagingFileUsageCounter, -2); // scale counter to [0, 1] 39 | if (ERROR_SUCCESS != status) { 40 | throw std::system_error(status, std::system_category(), "PdhSetCounterScaleFactor() failed"); 41 | } 42 | } 43 | 44 | MemState getMemState() { 45 | PERFORMANCE_INFORMATION performanceInformation; 46 | if (!GetPerformanceInfo(&performanceInformation, sizeof(performanceInformation))) { 47 | throw std::runtime_error("GetPerformanceInfo() failed"); 48 | } 49 | 50 | PDH_STATUS status; 51 | status = PdhCollectQueryData(query); 52 | if (ERROR_SUCCESS != status) { 53 | throw std::system_error(status, std::system_category(), "PdhCollectQueryData() failed"); 54 | } 55 | PDH_FMT_COUNTERVALUE displayValue; 56 | status = PdhGetFormattedCounterValue(pagingFileUsageCounter, PDH_FMT_DOUBLE, NULL, &displayValue); 57 | if (ERROR_SUCCESS != status) { 58 | throw std::system_error(status, std::system_category(), "PdhGetFormattedCounterValue() failed"); 59 | } 60 | if (PDH_CSTATUS_VALID_DATA != displayValue.CStatus && PDH_CSTATUS_NEW_DATA != displayValue.CStatus) { 61 | throw std::runtime_error("Error in counter data"); 62 | } 63 | 64 | double pagingFilesSize = static_cast( 65 | (performanceInformation.CommitLimit - performanceInformation.PhysicalTotal) 66 | * performanceInformation.PageSize) / (1024 * 1024 * 1024); 67 | return {static_cast(performanceInformation.PhysicalTotal * performanceInformation.PageSize) 68 | / (1024 * 1024 * 1024), 69 | static_cast( 70 | (performanceInformation.PhysicalTotal - performanceInformation.PhysicalAvailable) 71 | * performanceInformation.PageSize) / (1024 * 1024 * 1024), 72 | pagingFilesSize * displayValue.doubleValue}; 73 | } 74 | private: 75 | QueryWrapper query; 76 | PDH_HCOUNTER pagingFileUsageCounter; 77 | }; 78 | 79 | #elif __linux__ 80 | #include 81 | #include 82 | #include 83 | #include 84 | 85 | namespace { 86 | std::pair, std::pair> getAvailableMemSwapTotalMemSwap() { 87 | double memAvailable = 0, swapFree = 0, memTotal = 0, swapTotal = 0; 88 | std::regex memRegex("^(.+):\\s+(\\d+) kB$"); 89 | std::string line; 90 | std::smatch match; 91 | std::ifstream meminfo("/proc/meminfo"); 92 | while (std::getline(meminfo, line)) { 93 | if (std::regex_match(line, match, memRegex)) { 94 | if ("MemAvailable" == match[1]) { 95 | memAvailable = stod(match[2]) / (1024 * 1024); 96 | } else if ("SwapFree" == match[1]) { 97 | swapFree = stod(match[2]) / (1024 * 1024); 98 | } else if ("MemTotal" == match[1]) { 99 | memTotal = stod(match[2]) / (1024 * 1024); 100 | } else if ("SwapTotal" == match[1]) { 101 | swapTotal = stod(match[2]) / (1024 * 1024); 102 | } 103 | } 104 | } 105 | if (0 == memTotal) { 106 | throw std::runtime_error("Can't get MemTotal"); 107 | } 108 | return {{memAvailable, swapFree}, {memTotal, swapTotal}}; 109 | } 110 | 111 | double getMemTotal() { 112 | return getAvailableMemSwapTotalMemSwap().second.first; 113 | } 114 | } 115 | 116 | class MemoryMonitor::PerformanceCounter { 117 | public: 118 | MemState getMemState() { 119 | std::pair, std::pair> availableMemSwapTotalMemSwap 120 | = getAvailableMemSwapTotalMemSwap(); 121 | double memTotal = availableMemSwapTotalMemSwap.second.first; 122 | double swapTotal = availableMemSwapTotalMemSwap.second.second; 123 | return {memTotal, memTotal - availableMemSwapTotalMemSwap.first.first, swapTotal - availableMemSwapTotalMemSwap.first.second}; 124 | } 125 | }; 126 | 127 | #else 128 | // not implemented 129 | namespace { 130 | double getMemTotal() {return 0.0;} 131 | } 132 | 133 | class MemoryMonitor::PerformanceCounter { 134 | public: 135 | MemState getMemState() {return {0.0, 0.0, 0.0};} 136 | }; 137 | #endif 138 | 139 | MemoryMonitor::MemoryMonitor() : 140 | samplesNumber{0}, 141 | historySize{0}, 142 | memSum{0.0}, 143 | swapSum{0.0}, 144 | maxMem{0.0}, 145 | maxSwap{0.0}, 146 | memTotal{0.0}, 147 | maxMemTotal{0.0} {} 148 | 149 | // PerformanceCounter is incomplete in header and destructor can't be defined implicitly 150 | MemoryMonitor::~MemoryMonitor() = default; 151 | 152 | void MemoryMonitor::setHistorySize(std::size_t size) { 153 | if (0 == historySize && 0 != size) { 154 | performanceCounter.reset(new MemoryMonitor::PerformanceCounter); 155 | // memTotal is not initialized in constructor because for linux its initialization involves constructing 156 | // std::regex which is unimplemented and throws an exception for gcc 4.8.5 (default for CentOS 7.4). 157 | // Delaying initialization triggers the error only when the monitor is used 158 | // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53631 159 | memTotal = ::getMemTotal(); 160 | } else if (0 != historySize && 0 == size) { 161 | performanceCounter.reset(); 162 | } 163 | historySize = size; 164 | std::size_t newSize = std::min(size, memSwapUsageHistory.size()); 165 | memSwapUsageHistory.erase(memSwapUsageHistory.begin(), memSwapUsageHistory.end() - newSize); 166 | } 167 | 168 | void MemoryMonitor::collectData() { 169 | MemState memState = performanceCounter->getMemState(); 170 | maxMemTotal = std::max(maxMemTotal, memState.memTotal); 171 | memSum += memState.usedMem; 172 | swapSum += memState.usedSwap; 173 | ++samplesNumber; 174 | maxMem = std::max(maxMem, memState.usedMem); 175 | maxSwap = std::max(maxSwap, memState.usedSwap); 176 | 177 | memSwapUsageHistory.emplace_back(memState.usedMem, memState.usedSwap); 178 | if (memSwapUsageHistory.size() > historySize) { 179 | memSwapUsageHistory.pop_front(); 180 | } 181 | } 182 | 183 | std::size_t MemoryMonitor::getHistorySize() const { 184 | return historySize; 185 | } 186 | 187 | std::deque> MemoryMonitor::getLastHistory() const { 188 | return memSwapUsageHistory; 189 | } 190 | 191 | double MemoryMonitor::getMeanMem() const { 192 | return memSum / samplesNumber; 193 | } 194 | 195 | double MemoryMonitor::getMeanSwap() const { 196 | return swapSum / samplesNumber; 197 | } 198 | 199 | double MemoryMonitor::getMaxMem() const { 200 | return maxMem; 201 | } 202 | 203 | double MemoryMonitor::getMaxSwap() const { 204 | return maxSwap; 205 | } 206 | 207 | double MemoryMonitor::getMemTotal() const { 208 | return memTotal; 209 | } 210 | 211 | double MemoryMonitor::getMaxMemTotal() const { 212 | return maxMemTotal; 213 | } 214 | -------------------------------------------------------------------------------- /common/monitors/memory_monitor.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | class MemoryMonitor { 11 | public: 12 | MemoryMonitor(); 13 | ~MemoryMonitor(); 14 | void setHistorySize(std::size_t size); 15 | std::size_t getHistorySize() const; 16 | void collectData(); 17 | std::deque> getLastHistory() const; 18 | double getMeanMem() const; // in GiB 19 | double getMeanSwap() const; 20 | double getMaxMem() const; 21 | double getMaxSwap() const; 22 | double getMemTotal() const; 23 | double getMaxMemTotal() const; // a system may have hotpluggable memory 24 | private: 25 | unsigned samplesNumber; 26 | std::size_t historySize; 27 | double memSum, swapSum; 28 | double maxMem, maxSwap; 29 | double memTotal; 30 | double maxMemTotal; 31 | std::deque> memSwapUsageHistory; 32 | class PerformanceCounter; 33 | std::unique_ptr performanceCounter; 34 | }; 35 | -------------------------------------------------------------------------------- /common/monitors/presenter.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include "cpu_monitor.h" 15 | #include "memory_monitor.h" 16 | 17 | enum class MonitorType{CpuAverage, DistributionCpu, Memory}; 18 | 19 | class Presenter { 20 | public: 21 | explicit Presenter(std::set enabledMonitors = {}, 22 | int yPos = 20, 23 | cv::Size graphSize = {150, 60}, 24 | std::size_t historySize = 20); 25 | explicit Presenter(const std::string& keys, 26 | int yPos = 20, 27 | cv::Size graphSize = {150, 60}, 28 | std::size_t historySize = 20); 29 | void addRemoveMonitor(MonitorType monitor); 30 | void handleKey(int key); // handles c, d, m, h keys 31 | void drawGraphs(cv::Mat& frame); 32 | std::string reportMeans() const; 33 | 34 | const int yPos; 35 | const cv::Size graphSize; 36 | const int graphPadding; 37 | private: 38 | std::chrono::steady_clock::time_point prevTimeStamp; 39 | std::size_t historySize; 40 | CpuMonitor cpuMonitor; 41 | bool distributionCpuEnabled; 42 | MemoryMonitor memoryMonitor; 43 | std::ostringstream strStream; 44 | }; 45 | -------------------------------------------------------------------------------- /common/monitors/query_wrapper.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #include "query_wrapper.h" 6 | 7 | #include 8 | #include 9 | 10 | QueryWrapper::QueryWrapper() { 11 | PDH_STATUS status = PdhOpenQuery(NULL, NULL, &query); 12 | if (ERROR_SUCCESS != status) { 13 | throw std::system_error(status, std::system_category(), "PdhOpenQuery() failed"); 14 | } 15 | } 16 | QueryWrapper::~QueryWrapper() { 17 | PdhCloseQuery(query); 18 | } 19 | 20 | QueryWrapper::operator PDH_HQUERY() const { 21 | return query; 22 | } 23 | -------------------------------------------------------------------------------- /common/monitors/query_wrapper.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | class QueryWrapper { 9 | public: 10 | QueryWrapper(); 11 | ~QueryWrapper(); 12 | QueryWrapper(const QueryWrapper&) = delete; 13 | QueryWrapper& operator=(const QueryWrapper&) = delete; 14 | operator PDH_HQUERY() const; 15 | private: 16 | PDH_HQUERY query; 17 | }; 18 | -------------------------------------------------------------------------------- /common/os/windows/w_dirent.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #if defined(_WIN32) 8 | 9 | #ifndef NOMINMAX 10 | # define NOMINMAX 11 | #endif 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #else 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #endif 24 | 25 | #include 26 | 27 | #include 28 | 29 | #if defined(WIN32) 30 | // Copied from linux libc sys/stat.h: 31 | #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 32 | #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 33 | #endif 34 | 35 | struct dirent { 36 | char *d_name; 37 | 38 | explicit dirent(const wchar_t *wsFilePath) { 39 | size_t i; 40 | auto slen = wcslen(wsFilePath); 41 | d_name = static_cast(malloc(slen + 1)); 42 | wcstombs_s(&i, d_name, slen + 1, wsFilePath, slen); 43 | } 44 | 45 | ~dirent() { 46 | free(d_name); 47 | } 48 | }; 49 | 50 | class DIR { 51 | WIN32_FIND_DATAA FindFileData; 52 | HANDLE hFind; 53 | dirent *next; 54 | 55 | static inline bool endsWith(const std::string &src, const char *with) { 56 | int wl = static_cast(strlen(with)); 57 | int so = static_cast(src.length()) - wl; 58 | if (so < 0) return false; 59 | return 0 == strncmp(with, &src[so], wl); 60 | } 61 | 62 | public: 63 | explicit DIR(const char *dirPath) : next(nullptr) { 64 | std::string ws = dirPath; 65 | if (endsWith(ws, "\\")) 66 | ws += "*"; 67 | else 68 | ws += "\\*"; 69 | hFind = FindFirstFileA(ws.c_str(), &FindFileData); 70 | FindFileData.dwReserved0 = hFind != INVALID_HANDLE_VALUE; 71 | } 72 | 73 | ~DIR() { 74 | if (!next) delete next; 75 | FindClose(hFind); 76 | } 77 | 78 | bool isValid() const { 79 | return (hFind != INVALID_HANDLE_VALUE && FindFileData.dwReserved0); 80 | } 81 | 82 | dirent* nextEnt() { 83 | if (next != nullptr) delete next; 84 | next = nullptr; 85 | 86 | if (!FindFileData.dwReserved0) return nullptr; 87 | 88 | wchar_t wbuf[4096]; 89 | 90 | size_t outSize; 91 | mbstowcs_s(&outSize, wbuf, 4094, FindFileData.cFileName, 4094); 92 | next = new dirent(wbuf); 93 | FindFileData.dwReserved0 = FindNextFileA(hFind, &FindFileData); 94 | return next; 95 | } 96 | }; 97 | 98 | 99 | static DIR *opendir(const char* dirPath) { 100 | auto dp = new DIR(dirPath); 101 | if (!dp->isValid()) { 102 | delete dp; 103 | return nullptr; 104 | } 105 | return dp; 106 | } 107 | 108 | static struct dirent *readdir(DIR *dp) { 109 | return dp->nextEnt(); 110 | } 111 | 112 | static void closedir(DIR *dp) { 113 | delete dp; 114 | } 115 | -------------------------------------------------------------------------------- /common/samples/args_helper.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | /** 6 | * @brief a header file with common samples functionality 7 | * @file args_helper.hpp 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | #ifdef _WIN32 24 | #include 25 | #else 26 | #include 27 | #endif 28 | 29 | /** 30 | * @brief This function checks input args and existence of specified files in a given folder 31 | * @param arg path to a file to be checked for existence 32 | * @return files updated vector of verified input files 33 | */ 34 | inline void readInputFilesArguments(std::vector &files, const std::string& arg) { 35 | struct stat sb; 36 | if (stat(arg.c_str(), &sb) != 0) { 37 | if (arg.compare(0, 5, "rtsp:") != 0) { 38 | slog::warn << "File " << arg << " cannot be opened!" << slog::endl; 39 | return; 40 | } 41 | } 42 | if (S_ISDIR(sb.st_mode)) { 43 | DIR *dp; 44 | dp = opendir(arg.c_str()); 45 | if (dp == nullptr) { 46 | slog::warn << "Directory " << arg << " cannot be opened!" << slog::endl; 47 | return; 48 | } 49 | 50 | struct dirent *ep; 51 | while (nullptr != (ep = readdir(dp))) { 52 | std::string fileName = ep->d_name; 53 | if (fileName == "." || fileName == "..") continue; 54 | files.push_back(arg + "/" + ep->d_name); 55 | } 56 | closedir(dp); 57 | } else { 58 | files.push_back(arg); 59 | } 60 | 61 | if (files.size() < 20) { 62 | slog::info << "Files were added: " << files.size() << slog::endl; 63 | for (std::string filePath : files) { 64 | slog::info << " " << filePath << slog::endl; 65 | } 66 | } else { 67 | slog::info << "Files were added: " << files.size() << ". Too many to display each of them." << slog::endl; 68 | } 69 | } 70 | 71 | /** 72 | * @brief This function find -i/--images key in input args 73 | * It's necessary to process multiple values for single key 74 | * @return files updated vector of verified input files 75 | */ 76 | inline void parseInputFilesArguments(std::vector &files) { 77 | std::vector args = gflags::GetArgvs(); 78 | bool readArguments = false; 79 | for (size_t i = 0; i < args.size(); i++) { 80 | if (args.at(i) == "-i" || args.at(i) == "--images") { 81 | readArguments = true; 82 | continue; 83 | } 84 | if (!readArguments) { 85 | continue; 86 | } 87 | if (args.at(i).c_str()[0] == '-') { 88 | break; 89 | } 90 | readInputFilesArguments(files, args.at(i)); 91 | } 92 | } 93 | 94 | inline std::vector split(const std::string &s, char delim) { 95 | std::vector result; 96 | std::stringstream ss(s); 97 | std::string item; 98 | 99 | while (getline(ss, item, delim)) { 100 | result.push_back(item); 101 | } 102 | return result; 103 | } 104 | 105 | inline std::vector parseDevices(const std::string& device_string) { 106 | const std::string::size_type colon_position = device_string.find(":"); 107 | if (colon_position != std::string::npos) { 108 | std::string device_type = device_string.substr(0, colon_position); 109 | if (device_type == "HETERO" || device_type == "MULTI") { 110 | std::string comma_separated_devices = device_string.substr(colon_position + 1); 111 | std::vector devices = split(comma_separated_devices, ','); 112 | for (auto& device : devices) 113 | device = device.substr(0, device.find("(")); 114 | return devices; 115 | } 116 | } 117 | return {device_string}; 118 | } 119 | 120 | inline std::map parseValuePerDevice(const std::set& devices, 121 | const std::string& values_string) { 122 | // Format: :,: or just 123 | auto values_string_upper = values_string; 124 | std::transform(values_string_upper.begin(), 125 | values_string_upper.end(), 126 | values_string_upper.begin(), 127 | [](unsigned char c){ return std::toupper(c); }); 128 | std::map result; 129 | auto device_value_strings = split(values_string_upper, ','); 130 | for (auto& device_value_string : device_value_strings) { 131 | auto device_value_vec = split(device_value_string, ':'); 132 | if (device_value_vec.size() == 2) { 133 | auto it = std::find(devices.begin(), devices.end(), device_value_vec.at(0)); 134 | if (it != devices.end()) { 135 | result[device_value_vec.at(0)] = std::stoi(device_value_vec.at(1)); 136 | } 137 | } else if (device_value_vec.size() == 1) { 138 | uint32_t value = std::stoi(device_value_vec.at(0)); 139 | for (auto& device : devices) { 140 | result[device] = value; 141 | } 142 | } else if (device_value_vec.size() != 0) { 143 | throw std::runtime_error("Unknown string format: " + values_string); 144 | } 145 | } 146 | return result; 147 | } 148 | -------------------------------------------------------------------------------- /common/samples/ocv_common.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | /** 6 | * @brief a header file with common samples functionality using OpenCV 7 | * @file ocv_common.hpp 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | /** 16 | * @brief Sets image data stored in cv::Mat object to a given Blob object. 17 | * @param orig_image - given cv::Mat object with an image data. 18 | * @param blob - Blob object which to be filled by an image data. 19 | * @param batchIndex - batch index of an image inside of the blob. 20 | */ 21 | template 22 | void matU8ToBlob(const cv::Mat& orig_image, InferenceEngine::Blob::Ptr& blob, int batchIndex = 0) { 23 | InferenceEngine::SizeVector blobSize = blob->getTensorDesc().getDims(); 24 | const size_t width = blobSize[3]; 25 | const size_t height = blobSize[2]; 26 | const size_t channels = blobSize[1]; 27 | if (static_cast(orig_image.channels()) != channels) { 28 | THROW_IE_EXCEPTION << "The number of channels for net input and image must match"; 29 | } 30 | T* blob_data = blob->buffer().as(); 31 | 32 | cv::Mat resized_image(orig_image); 33 | if (static_cast(width) != orig_image.size().width || 34 | static_cast(height) != orig_image.size().height) { 35 | cv::resize(orig_image, resized_image, cv::Size(width, height)); 36 | } 37 | 38 | int batchOffset = batchIndex * width * height * channels; 39 | 40 | if (channels == 1) { 41 | for (size_t h = 0; h < height; h++) { 42 | for (size_t w = 0; w < width; w++) { 43 | blob_data[batchOffset + h * width + w] = resized_image.at(h, w); 44 | } 45 | } 46 | } else if (channels == 3) { 47 | for (size_t c = 0; c < channels; c++) { 48 | for (size_t h = 0; h < height; h++) { 49 | for (size_t w = 0; w < width; w++) { 50 | blob_data[batchOffset + c * width * height + h * width + w] = 51 | resized_image.at(h, w)[c]; 52 | } 53 | } 54 | } 55 | } else { 56 | THROW_IE_EXCEPTION << "Unsupported number of channels"; 57 | } 58 | } 59 | 60 | /** 61 | * @brief Wraps data stored inside of a passed cv::Mat object by new Blob pointer. 62 | * @note: No memory allocation is happened. The blob just points to already existing 63 | * cv::Mat data. 64 | * @param mat - given cv::Mat object with an image data. 65 | * @return resulting Blob pointer. 66 | */ 67 | static UNUSED InferenceEngine::Blob::Ptr wrapMat2Blob(const cv::Mat &mat) { 68 | size_t channels = mat.channels(); 69 | size_t height = mat.size().height; 70 | size_t width = mat.size().width; 71 | 72 | size_t strideH = mat.step.buf[0]; 73 | size_t strideW = mat.step.buf[1]; 74 | 75 | bool is_dense = 76 | strideW == channels && 77 | strideH == channels * width; 78 | 79 | if (!is_dense) THROW_IE_EXCEPTION 80 | << "Doesn't support conversion from not dense cv::Mat"; 81 | 82 | InferenceEngine::TensorDesc tDesc(InferenceEngine::Precision::U8, 83 | {1, channels, height, width}, 84 | InferenceEngine::Layout::NHWC); 85 | 86 | return InferenceEngine::make_shared_blob(tDesc, mat.data); 87 | } 88 | -------------------------------------------------------------------------------- /common/samples/slog.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | /** 6 | * @brief a header file with logging facility for common samples 7 | * @file log.hpp 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace slog { 15 | 16 | /** 17 | * @class LogStreamEndLine 18 | * @brief The LogStreamEndLine class implements an end line marker for a log stream 19 | */ 20 | class LogStreamEndLine { }; 21 | 22 | static constexpr LogStreamEndLine endl; 23 | 24 | 25 | /** 26 | * @class LogStreamBoolAlpha 27 | * @brief The LogStreamBoolAlpha class implements bool printing for a log stream 28 | */ 29 | class LogStreamBoolAlpha { }; 30 | 31 | static constexpr LogStreamBoolAlpha boolalpha; 32 | 33 | 34 | /** 35 | * @class LogStream 36 | * @brief The LogStream class implements a stream for sample logging 37 | */ 38 | class LogStream { 39 | std::string _prefix; 40 | std::ostream* _log_stream; 41 | bool _new_line; 42 | 43 | public: 44 | /** 45 | * @brief A constructor. Creates a LogStream object 46 | * @param prefix The prefix to print 47 | */ 48 | LogStream(const std::string &prefix, std::ostream& log_stream) 49 | : _prefix(prefix), _new_line(true) { 50 | _log_stream = &log_stream; 51 | } 52 | 53 | /** 54 | * @brief A stream output operator to be used within the logger 55 | * @param arg Object for serialization in the logger message 56 | */ 57 | template 58 | LogStream &operator<<(const T &arg) { 59 | if (_new_line) { 60 | (*_log_stream) << "[ " << _prefix << " ] "; 61 | _new_line = false; 62 | } 63 | 64 | (*_log_stream) << arg; 65 | return *this; 66 | } 67 | 68 | // Specializing for LogStreamEndLine to support slog::endl 69 | LogStream& operator<< (const LogStreamEndLine &/*arg*/) { 70 | _new_line = true; 71 | 72 | (*_log_stream) << std::endl; 73 | return *this; 74 | } 75 | 76 | // Specializing for LogStreamBoolAlpha to support slog::boolalpha 77 | LogStream& operator<< (const LogStreamBoolAlpha &/*arg*/) { 78 | (*_log_stream) << std::boolalpha; 79 | return *this; 80 | } 81 | }; 82 | 83 | 84 | static LogStream info("INFO", std::cout); 85 | static LogStream warn("WARNING", std::cout); 86 | static LogStream err("ERROR", std::cerr); 87 | 88 | } // namespace slog 89 | -------------------------------------------------------------------------------- /gflags/.travis.yml: -------------------------------------------------------------------------------- 1 | # Ubuntu 14.04 Trusty support, to get newer cmake and compilers. 2 | sudo: required 3 | dist: trusty 4 | 5 | language: cpp 6 | 7 | os: 8 | - linux 9 | - osx 10 | 11 | compiler: 12 | - clang 13 | - gcc 14 | 15 | env: 16 | - CONFIG=Release 17 | - CONFIG=Debug 18 | 19 | script: 20 | - mkdir out && cd out && cmake -D CMAKE_BUILD_TYPE=$CONFIG -D GFLAGS_BUILD_SHARED_LIBS=ON -D GFLAGS_BUILD_STATIC_LIBS=ON -D GFLAGS_BUILD_TESTING=ON .. && cmake --build . --config $CONFIG && ctest 21 | -------------------------------------------------------------------------------- /gflags/AUTHORS.txt: -------------------------------------------------------------------------------- 1 | google-gflags@googlegroups.com 2 | 3 | -------------------------------------------------------------------------------- /gflags/COPYING.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /gflags/INSTALL.md: -------------------------------------------------------------------------------- 1 | Installing a binary distribution package 2 | ======================================== 3 | 4 | No official binary distribution packages are provided by the gflags developers. 5 | There may, however, be binary packages available for your OS. Please consult 6 | also the package repositories of your Linux distribution. 7 | 8 | For example on Debian/Ubuntu Linux, gflags can be installed using the 9 | following command: 10 | 11 | sudo apt-get install libgflags-dev 12 | 13 | 14 | Compiling the source code with CMake 15 | ========================= 16 | 17 | The build system of gflags is since version 2.1 based on [CMake](http://cmake.org). 18 | The common steps to build, test, and install software are therefore: 19 | 20 | 1. Extract source files. 21 | 2. Create build directory and change to it. 22 | 3. Run CMake to configure the build tree. 23 | 4. Build the software using selected build tool. 24 | 5. Test the built software. 25 | 6. Install the built files. 26 | 27 | On Unix-like systems with GNU Make as build tool, these build steps can be 28 | summarized by the following sequence of commands executed in a shell, 29 | where ```$package``` and ```$version``` are shell variables which represent 30 | the name of this package and the obtained version of the software. 31 | 32 | $ tar xzf gflags-$version-source.tar.gz 33 | $ cd gflags-$version 34 | $ mkdir build && cd build 35 | $ ccmake .. 36 | 37 | - Press 'c' to configure the build system and 'e' to ignore warnings. 38 | - Set CMAKE_INSTALL_PREFIX and other CMake variables and options. 39 | - Continue pressing 'c' until the option 'g' is available. 40 | - Then press 'g' to generate the configuration files for GNU Make. 41 | 42 | $ make 43 | $ make test (optional) 44 | $ make install (optional) 45 | 46 | In the following, only gflags-specific CMake settings available to 47 | configure the build and installation are documented. Note that most of these 48 | variables are for advanced users and binary package maintainers only. 49 | They usually do not have to be modified. 50 | 51 | 52 | CMake Option | Description 53 | --------------------------- | ------------------------------------------------------- 54 | CMAKE_INSTALL_PREFIX | Installation directory, e.g., "/usr/local" on Unix and "C:\Program Files\gflags" on Windows. 55 | BUILD_SHARED_LIBS | Request build of dynamic link libraries. 56 | BUILD_STATIC_LIBS | Request build of static link libraries. Implied if BUILD_SHARED_LIBS is OFF. 57 | BUILD_PACKAGING | Enable binary package generation using CPack. 58 | BUILD_TESTING | Build tests for execution by CTest. 59 | BUILD_NC_TESTS | Request inclusion of negative compilation tests (requires Python). 60 | BUILD_CONFIG_TESTS | Request inclusion of package configuration tests (requires Python). 61 | BUILD_gflags_LIBS | Request build of multi-threaded gflags libraries (if threading library found). 62 | BUILD_gflags_nothreads_LIBS | Request build of single-threaded gflags libraries. 63 | GFLAGS_NAMESPACE | Name of the C++ namespace to be used by the gflags library. Note that the public source header files are installed in a subdirectory named after this namespace. To maintain backwards compatibility with the Google Commandline Flags, set this variable to "google". The default is "gflags". 64 | GFLAGS_INTTYPES_FORMAT | String identifying format of built-in integer types. 65 | GFLAGS_INCLUDE_DIR | Name of headers installation directory relative to CMAKE_INSTALL_PREFIX. 66 | LIBRARY_INSTALL_DIR | Name of library installation directory relative to CMAKE_INSTALL_PREFIX. 67 | INSTALL_HEADERS | Request installation of public header files. 68 | 69 | Using gflags with [Bazel](http://bazel.io) 70 | ========================= 71 | 72 | To use gflags in a Bazel project, map it in as an external dependency by editing 73 | your WORKSPACE file: 74 | 75 | git_repository( 76 | name = "com_github_gflags_gflags", 77 | commit = "", 78 | remote = "https://github.com/gflags/gflags.git", 79 | ) 80 | 81 | bind( 82 | name = "gflags", 83 | actual = "@com_github_gflags_gflags//:gflags", 84 | ) 85 | 86 | You can then add `//external:gflags` to the `deps` section of a `cc_binary` or 87 | `cc_library` rule, and `#include ` to include it in your source 88 | code. 89 | -------------------------------------------------------------------------------- /gflags/WORKSPACE: -------------------------------------------------------------------------------- 1 | # Copyright 2006 Google Inc. All Rights Reserved. 2 | # Use of this source code is governed by a BSD-style 3 | # license that can be found in the COPYING.txt file. 4 | 5 | # Bazel (http://bazel.io/) WORKSPACE file for gflags. 6 | workspace(name="com_github_gflags_gflags") 7 | -------------------------------------------------------------------------------- /gflags/appveyor.yml: -------------------------------------------------------------------------------- 1 | # Configuration for continuous integration service at appveyor.com 2 | 3 | version: '{build}' 4 | 5 | os: Visual Studio 2015 6 | 7 | environment: 8 | matrix: 9 | - Toolset: v140 10 | - Toolset: v120 11 | - Toolset: v110 12 | - Toolset: v100 13 | - Toolset: v90 14 | 15 | platform: 16 | - Win32 17 | - x64 18 | 19 | configuration: 20 | - Release 21 | 22 | matrix: 23 | exclude: 24 | - Toolset: v90 25 | platform: x64 26 | - Toolset: v100 27 | platform: x64 28 | 29 | build: 30 | verbosity: minimal 31 | 32 | before_build: 33 | - ps: | 34 | Write-Output "Configuration: $env:CONFIGURATION" 35 | Write-Output "Platform: $env:PLATFORM" 36 | $generator = switch ($env:TOOLSET) 37 | { 38 | "v140" {"Visual Studio 14 2015"} 39 | "v120" {"Visual Studio 12 2013"} 40 | "v110" {"Visual Studio 11 2012"} 41 | "v100" {"Visual Studio 10 2010"} 42 | "v90" {"Visual Studio 9 2008"} 43 | } 44 | if ($env:PLATFORM -eq "x64") 45 | { 46 | $generator = "$generator Win64" 47 | } 48 | 49 | build_script: 50 | - ps: | 51 | md _build -Force | Out-Null 52 | cd _build 53 | 54 | & cmake -G "$generator" -D CMAKE_CONFIGURATION_TYPES="Debug;Release" -D GFLAGS_BUILD_TESTING=ON -D GFLAGS_BUILD_SHARED_LIBS=ON -D GFLAGS_BUILD_STATIC_LIBS=ON .. 55 | if ($LastExitCode -ne 0) { 56 | throw "Exec: $ErrorMessage" 57 | } 58 | & cmake --build . --config $env:CONFIGURATION 59 | if ($LastExitCode -ne 0) { 60 | throw "Exec: $ErrorMessage" 61 | } 62 | 63 | test_script: 64 | - ps: | 65 | & ctest -C $env:CONFIGURATION --output-on-failure 66 | if ($LastExitCode -ne 0) { 67 | throw "Exec: $ErrorMessage" 68 | } 69 | -------------------------------------------------------------------------------- /gflags/bazel/gflags.bzl: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Add native rules to configure source files 3 | def gflags_sources(namespace=["google", "gflags"]): 4 | native.genrule( 5 | name = "config_h", 6 | srcs = ["src/config.h.in"], 7 | outs = ["config.h"], 8 | cmd = "awk '{ gsub(/^#cmakedefine/, \"//cmakedefine\"); print; }' $(<) > $(@)" 9 | ) 10 | native.genrule( 11 | name = "gflags_declare_h", 12 | srcs = ["src/gflags_declare.h.in"], 13 | outs = ["include/gflags/gflags_declare.h"], 14 | cmd = ("awk '{ " + 15 | "gsub(/@GFLAGS_NAMESPACE@/, \"" + namespace[0] + "\"); " + 16 | "gsub(/@(HAVE_STDINT_H|HAVE_SYS_TYPES_H|HAVE_INTTYPES_H|GFLAGS_INTTYPES_FORMAT_C99)@/, \"1\"); " + 17 | "gsub(/@([A-Z0-9_]+)@/, \"0\"); " + 18 | "print; }' $(<) > $(@)") 19 | ) 20 | gflags_ns_h_files = [] 21 | for ns in namespace[1:]: 22 | gflags_ns_h_file = "gflags_{}.h".format(ns) 23 | native.genrule( 24 | name = gflags_ns_h_file.replace('.', '_'), 25 | srcs = ["src/gflags_ns.h.in"], 26 | outs = ["include/gflags/" + gflags_ns_h_file], 27 | cmd = ("awk '{ " + 28 | "gsub(/@ns@/, \"" + ns + "\"); " + 29 | "gsub(/@NS@/, \"" + ns.upper() + "\"); " + 30 | "print; }' $(<) > $(@)") 31 | ) 32 | gflags_ns_h_files.append(gflags_ns_h_file) 33 | native.genrule( 34 | name = "gflags_h", 35 | srcs = ["src/gflags.h.in"], 36 | outs = ["include/gflags/gflags.h"], 37 | cmd = ("awk '{ " + 38 | "gsub(/@GFLAGS_ATTRIBUTE_UNUSED@/, \"\"); " + 39 | "gsub(/@INCLUDE_GFLAGS_NS_H@/, \"" + '\n'.join(["#include \\\"gflags/{}\\\"".format(hdr) for hdr in gflags_ns_h_files]) + "\"); " + 40 | "print; }' $(<) > $(@)") 41 | ) 42 | native.genrule( 43 | name = "gflags_completions_h", 44 | srcs = ["src/gflags_completions.h.in"], 45 | outs = ["include/gflags/gflags_completions.h"], 46 | cmd = "awk '{ gsub(/@GFLAGS_NAMESPACE@/, \"" + namespace[0] + "\"); print; }' $(<) > $(@)" 47 | ) 48 | hdrs = [":gflags_h", ":gflags_declare_h", ":gflags_completions_h"] 49 | hdrs.extend([':' + hdr.replace('.', '_') for hdr in gflags_ns_h_files]) 50 | srcs = [ 51 | ":config_h", 52 | "src/gflags.cc", 53 | "src/gflags_completions.cc", 54 | "src/gflags_reporting.cc", 55 | "src/mutex.h", 56 | "src/util.h" 57 | ] 58 | return [hdrs, srcs] 59 | 60 | # ------------------------------------------------------------------------------ 61 | # Add native rule to build gflags library 62 | def gflags_library(hdrs=[], srcs=[], threads=1): 63 | name = "gflags" 64 | copts = [ 65 | "-DHAVE_STDINT_H", 66 | "-DHAVE_SYS_TYPES_H", 67 | "-DHAVE_INTTYPES_H", 68 | "-DHAVE_SYS_STAT_H", 69 | "-DHAVE_UNISTD_H", 70 | "-DHAVE_FNMATCH_H", 71 | "-DHAVE_STRTOLL", 72 | "-DHAVE_STRTOQ", 73 | "-DHAVE_PTHREAD", 74 | "-DHAVE_RWLOCK", 75 | "-DGFLAGS_INTTYPES_FORMAT_C99", 76 | "-DGFLAGS_IS_A_DLL=0", 77 | ] 78 | linkopts = [] 79 | if threads: 80 | linkopts.append("-lpthread") 81 | else: 82 | name += "_nothreads" 83 | copts.append("-DNO_THREADS") 84 | native.cc_library( 85 | name = name, 86 | hdrs = hdrs, 87 | srcs = srcs, 88 | includes = ["include/"], 89 | copts = copts, 90 | linkopts = linkopts, 91 | visibility = ["//visibility:public"] 92 | ) 93 | -------------------------------------------------------------------------------- /gflags/cmake/README_runtime.txt: -------------------------------------------------------------------------------- 1 | This package contains runtime libraries only which are required 2 | by applications that use these libraries for the commandline flags 3 | processing. If you want to develop such application, download 4 | and install the development package instead. 5 | -------------------------------------------------------------------------------- /gflags/cmake/config.cmake.in: -------------------------------------------------------------------------------- 1 | ## gflags CMake configuration file 2 | 3 | # library version information 4 | set (@PACKAGE_PREFIX@_VERSION_STRING "@PACKAGE_VERSION@") 5 | set (@PACKAGE_PREFIX@_VERSION_MAJOR @PACKAGE_VERSION_MAJOR@) 6 | set (@PACKAGE_PREFIX@_VERSION_MINOR @PACKAGE_VERSION_MINOR@) 7 | set (@PACKAGE_PREFIX@_VERSION_PATCH @PACKAGE_VERSION_PATCH@) 8 | 9 | # import targets 10 | include ("${CMAKE_CURRENT_LIST_DIR}/@EXPORT_NAME@.cmake") 11 | 12 | # installation prefix 13 | get_filename_component (CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) 14 | get_filename_component (_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_PREFIX_REL2CONFIG_DIR@" ABSOLUTE) 15 | 16 | # include directory 17 | # 18 | # Newer versions of CMake set the INTERFACE_INCLUDE_DIRECTORIES property 19 | # of the imported targets. It is hence not necessary to add this path 20 | # manually to the include search path for targets which link to gflags. 21 | set (@PACKAGE_PREFIX@_INCLUDE_DIR "${_INSTALL_PREFIX}/@INCLUDE_INSTALL_DIR@") 22 | 23 | if (@PACKAGE_NAME@_FIND_COMPONENTS) 24 | foreach (@PACKAGE_NAME@_FIND_COMPONENT IN LISTS @PACKAGE_NAME@_FIND_COMPONENTS) 25 | if (@PACKAGE_NAME@_FIND_REQUIRED_${@PACKAGE_NAME@_FIND_COMPONENT} AND NOT TARGET @PACKAGE_NAME@_${@PACKAGE_NAME@_FIND_COMPONENT}) 26 | message (FATAL_ERROR "Package @PACKAGE_NAME@ was installed without required component ${@PACKAGE_NAME@_FIND_COMPONENT}!") 27 | endif () 28 | endforeach () 29 | list (GET @PACKAGE_NAME@_FIND_COMPONENTS 0 @PACKAGE_NAME@_FIND_COMPONENT) 30 | else () 31 | set (@PACKAGE_NAME@_FIND_COMPONENT) 32 | endif () 33 | 34 | # default settings of @PACKAGE_PREFIX@_SHARED and @PACKAGE_PREFIX@_NOTHREADS 35 | # 36 | # It is recommended to use either one of the following find_package commands 37 | # instead of setting the @PACKAGE_PREFIX@_(SHARED|NOTHREADS) variables: 38 | # - find_package(@PACKAGE_NAME@ REQUIRED) 39 | # - find_package(@PACKAGE_NAME@ COMPONENTS nothreads_static) 40 | # - find_package(@PACKAGE_NAME@ COMPONENTS nothreads_shared) 41 | # - find_package(@PACKAGE_NAME@ COMPONENTS static) 42 | # - find_package(@PACKAGE_NAME@ COMPONENTS shared) 43 | if (NOT DEFINED @PACKAGE_PREFIX@_SHARED) 44 | if (DEFINED @PACKAGE_NAME@_SHARED) 45 | set (@PACKAGE_PREFIX@_SHARED ${@PACKAGE_NAME@_SHARED}) 46 | elseif (@PACKAGE_NAME@_FIND_COMPONENT) 47 | if (@PACKAGE_NAME@_FIND_COMPONENT MATCHES "shared") 48 | set (@PACKAGE_PREFIX@_SHARED TRUE) 49 | else () 50 | set (@PACKAGE_PREFIX@_SHARED FALSE) 51 | endif () 52 | elseif (TARGET @PACKAGE_NAME@_shared OR TARGET @PACKAGE_NAME@_nothreads_shared) 53 | set (@PACKAGE_PREFIX@_SHARED TRUE) 54 | else () 55 | set (@PACKAGE_PREFIX@_SHARED FALSE) 56 | endif () 57 | endif () 58 | if (NOT DEFINED @PACKAGE_PREFIX@_NOTHREADS) 59 | if (DEFINED @PACKAGE_NAME@_NOTHREADS) 60 | set (@PACKAGE_PREFIX@_NOTHREADS ${@PACKAGE_NAME@_NOTHREADS}) 61 | elseif (@PACKAGE_NAME@_FIND_COMPONENT) 62 | if (@PACKAGE_NAME@_FIND_COMPONENT MATCHES "nothreads") 63 | set (@PACKAGE_PREFIX@_NOTHREADS TRUE) 64 | else () 65 | set (@PACKAGE_PREFIX@_NOTHREADS FALSE) 66 | endif () 67 | elseif (TARGET @PACKAGE_NAME@_static OR TARGET @PACKAGE_NAME@_shared) 68 | set (@PACKAGE_PREFIX@_NOTHREADS FALSE) 69 | else () 70 | set (@PACKAGE_PREFIX@_NOTHREADS TRUE) 71 | endif () 72 | endif () 73 | 74 | # choose imported library target 75 | if (NOT @PACKAGE_PREFIX@_TARGET) 76 | if (@PACKAGE_NAME@_TARGET) 77 | set (@PACKAGE_PREFIX@_TARGET ${@PACKAGE_NAME@_TARGET}) 78 | elseif (@PACKAGE_PREFIX@_SHARED) 79 | if (@PACKAGE_PREFIX@_NOTHREADS) 80 | set (@PACKAGE_PREFIX@_TARGET @PACKAGE_NAME@_nothreads_shared) 81 | else () 82 | set (@PACKAGE_PREFIX@_TARGET @PACKAGE_NAME@_shared) 83 | endif () 84 | else () 85 | if (@PACKAGE_PREFIX@_NOTHREADS) 86 | set (@PACKAGE_PREFIX@_TARGET @PACKAGE_NAME@_nothreads_static) 87 | else () 88 | set (@PACKAGE_PREFIX@_TARGET @PACKAGE_NAME@_static) 89 | endif () 90 | endif () 91 | endif () 92 | if (NOT TARGET ${@PACKAGE_PREFIX@_TARGET}) 93 | message (FATAL_ERROR "Your @PACKAGE_NAME@ installation does not contain a ${@PACKAGE_PREFIX@_TARGET} library target!" 94 | " Try a different combination of @PACKAGE_PREFIX@_SHARED and @PACKAGE_PREFIX@_NOTHREADS.") 95 | endif () 96 | 97 | # add more convenient "@PACKAGE_NAME@" import target 98 | if (NOT TARGET @PACKAGE_NAME@) 99 | if (@PACKAGE_PREFIX@_SHARED) 100 | add_library (@PACKAGE_NAME@ SHARED IMPORTED) 101 | else () 102 | add_library (@PACKAGE_NAME@ STATIC IMPORTED) 103 | endif () 104 | # copy INTERFACE_* properties 105 | foreach (_@PACKAGE_PREFIX@_PROPERTY_NAME IN ITEMS 106 | COMPILE_DEFINITIONS 107 | COMPILE_FEATURES 108 | COMPILE_OPTIONS 109 | INCLUDE_DIRECTORIES 110 | LINK_LIBRARIES 111 | POSITION_INDEPENDENT_CODE 112 | ) 113 | get_target_property (_@PACKAGE_PREFIX@_PROPERTY_VALUE ${@PACKAGE_PREFIX@_TARGET} INTERFACE_${_@PACKAGE_PREFIX@_PROPERTY_NAME}) 114 | if (_@PACKAGE_PREFIX@_PROPERTY_VALUE) 115 | set_target_properties(@PACKAGE_NAME@ PROPERTIES 116 | INTERFACE_${_@PACKAGE_PREFIX@_PROPERTY_NAME} "${_@PACKAGE_PREFIX@_PROPERTY_VALUE}" 117 | ) 118 | endif () 119 | endforeach () 120 | # copy IMPORTED_*_ properties 121 | get_target_property (_@PACKAGE_PREFIX@_CONFIGURATIONS ${@PACKAGE_PREFIX@_TARGET} IMPORTED_CONFIGURATIONS) 122 | set_target_properties (@PACKAGE_NAME@ PROPERTIES IMPORTED_CONFIGURATIONS "${_@PACKAGE_PREFIX@_CONFIGURATIONS}") 123 | foreach (_@PACKAGE_PREFIX@_PROPERTY_NAME IN ITEMS 124 | IMPLIB 125 | LOCATION 126 | LINK_DEPENDENT_LIBRARIES 127 | LINK_INTERFACE_LIBRARIES 128 | LINK_INTERFACE_LANGUAGES 129 | LINK_INTERFACE_MULTIPLICITY 130 | NO_SONAME 131 | SONAME 132 | ) 133 | foreach (_@PACKAGE_PREFIX@_CONFIG IN LISTS _@PACKAGE_PREFIX@_CONFIGURATIONS) 134 | get_target_property (_@PACKAGE_PREFIX@_PROPERTY_VALUE ${@PACKAGE_PREFIX@_TARGET} IMPORTED_${_@PACKAGE_PREFIX@_PROPERTY_NAME}_${_@PACKAGE_PREFIX@_CONFIG}) 135 | if (_@PACKAGE_PREFIX@_PROPERTY_VALUE) 136 | set_target_properties(@PACKAGE_NAME@ PROPERTIES 137 | IMPORTED_${_@PACKAGE_PREFIX@_PROPERTY_NAME}_${_@PACKAGE_PREFIX@_CONFIG} "${_@PACKAGE_PREFIX@_PROPERTY_VALUE}" 138 | ) 139 | endif () 140 | endforeach () 141 | endforeach () 142 | unset (_@PACKAGE_PREFIX@_CONFIGURATIONS) 143 | unset (_@PACKAGE_PREFIX@_CONFIG) 144 | unset (_@PACKAGE_PREFIX@_PROPERTY_NAME) 145 | unset (_@PACKAGE_PREFIX@_PROPERTY_VALUE) 146 | endif () 147 | 148 | # alias for default import target to be compatible with older CMake package configurations 149 | set (@PACKAGE_PREFIX@_LIBRARIES "${@PACKAGE_PREFIX@_TARGET}") 150 | 151 | # set @PACKAGE_NAME@_* variables for backwards compatibility 152 | if (NOT "^@PACKAGE_NAME@$" STREQUAL "^@PACKAGE_PREFIX@$") 153 | foreach (_@PACKAGE_PREFIX@_VARIABLE IN ITEMS 154 | VERSION_STRING 155 | VERSION_MAJOR 156 | VERSION_MINOR 157 | VERSION_PATCH 158 | INCLUDE_DIR 159 | LIBRARIES 160 | TARGET 161 | ) 162 | set (@PACKAGE_NAME@_${_@PACKAGE_PREFIX@_VARIABLE} "${@PACKAGE_PREFIX@_${_@PACKAGE_PREFIX@_VARIABLE}}") 163 | endforeach () 164 | unset (_@PACKAGE_PREFIX@_VARIABLE) 165 | endif () 166 | 167 | # unset private variables 168 | unset (@PACKAGE_NAME@_FIND_COMPONENT) 169 | unset (_INSTALL_PREFIX) 170 | -------------------------------------------------------------------------------- /gflags/cmake/execute_test.cmake: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # sanitize string stored in variable for use in regular expression. 3 | macro (sanitize_for_regex STRVAR) 4 | string (REGEX REPLACE "([.+*?^$()])" "\\\\\\1" ${STRVAR} "${${STRVAR}}") 5 | endmacro () 6 | 7 | # ---------------------------------------------------------------------------- 8 | # script arguments 9 | if (NOT COMMAND) 10 | message (FATAL_ERROR "Test command not specified!") 11 | endif () 12 | if (NOT DEFINED EXPECTED_RC) 13 | set (EXPECTED_RC 0) 14 | endif () 15 | if (EXPECTED_OUTPUT) 16 | sanitize_for_regex(EXPECTED_OUTPUT) 17 | endif () 18 | if (UNEXPECTED_OUTPUT) 19 | sanitize_for_regex(UNEXPECTED_OUTPUT) 20 | endif () 21 | 22 | # ---------------------------------------------------------------------------- 23 | # set a few environment variables (useful for --tryfromenv) 24 | set (ENV{FLAGS_undefok} "foo,bar") 25 | set (ENV{FLAGS_weirdo} "") 26 | set (ENV{FLAGS_version} "true") 27 | set (ENV{FLAGS_help} "false") 28 | 29 | # ---------------------------------------------------------------------------- 30 | # execute test command 31 | execute_process( 32 | COMMAND ${COMMAND} 33 | RESULT_VARIABLE RC 34 | OUTPUT_VARIABLE OUTPUT 35 | ERROR_VARIABLE OUTPUT 36 | ) 37 | 38 | if (OUTPUT) 39 | message ("${OUTPUT}") 40 | endif () 41 | 42 | # ---------------------------------------------------------------------------- 43 | # check test result 44 | if (NOT RC EQUAL EXPECTED_RC) 45 | string (REPLACE ";" " " COMMAND "${COMMAND}") 46 | message (FATAL_ERROR "Command:\n\t${COMMAND}\nExit status is ${RC}, expected ${EXPECTED_RC}") 47 | endif () 48 | if (EXPECTED_OUTPUT AND NOT OUTPUT MATCHES "${EXPECTED_OUTPUT}") 49 | message (FATAL_ERROR "Test output does not match expected output: ${EXPECTED_OUTPUT}") 50 | endif () 51 | if (UNEXPECTED_OUTPUT AND OUTPUT MATCHES "${UNEXPECTED_OUTPUT}") 52 | message (FATAL_ERROR "Test output matches unexpected output: ${UNEXPECTED_OUTPUT}") 53 | endif () -------------------------------------------------------------------------------- /gflags/cmake/package.cmake.in: -------------------------------------------------------------------------------- 1 | # Per-generator CPack configuration file. See CPACK_PROJECT_CONFIG_FILE documented at 2 | # http://www.cmake.org/cmake/help/v2.8.12/cpack.html#variable:CPACK_PROJECT_CONFIG_FILE 3 | # 4 | # All common CPACK_* variables are set in CMakeLists.txt already. This file only 5 | # overrides some of these to provide package generator specific settings. 6 | 7 | # whether package contains all development files or only runtime files 8 | set (DEVEL @INSTALL_HEADERS@) 9 | 10 | # ------------------------------------------------------------------------------ 11 | # Mac OS X package 12 | if (CPACK_GENERATOR MATCHES "PackageMaker|DragNDrop") 13 | 14 | set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}") 15 | if (DEVEL) 16 | set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-devel") 17 | endif () 18 | set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${CPACK_PACKAGE_VERSION}") 19 | 20 | # ------------------------------------------------------------------------------ 21 | # Debian package 22 | elseif (CPACK_GENERATOR MATCHES "DEB") 23 | 24 | set (CPACK_PACKAGE_FILE_NAME "lib${CPACK_PACKAGE_NAME}") 25 | if (DEVEL) 26 | set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-dev") 27 | else () 28 | set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}0") 29 | endif () 30 | set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}_${CPACK_PACKAGE_VERSION}-1_${CPACK_PACKAGE_ARCHITECTURE}") 31 | 32 | set (CPACK_DEBIAN_PACKAGE_DEPENDS) 33 | set (CPACK_DEBIAN_PACKAGE_SECTION "devel") 34 | set (CPACK_DEBIAN_PACKAGE_PRIORITY "optional") 35 | set (CPACK_DEBIAN_PACKAGE_HOMEPAGE "${CPACK_RPM_PACKAGE_URL}") 36 | set (CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_PACKAGE_VENDOR}") 37 | set (CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${CPACK_PACKAGE_ARCHITECTURE}") 38 | 39 | # ------------------------------------------------------------------------------ 40 | # RPM package 41 | elseif (CPACK_GENERATOR MATCHES "RPM") 42 | 43 | set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}") 44 | if (DEVEL) 45 | set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-devel") 46 | endif () 47 | set (CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${CPACK_PACKAGE_VERSION}-1.${CPACK_PACKAGE_ARCHITECTURE}") 48 | 49 | endif () 50 | -------------------------------------------------------------------------------- /gflags/cmake/package.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=${prefix} 3 | bindir=${prefix}/@RUNTIME_INSTALL_DIR@ 4 | libdir=${prefix}/@LIBRARY_INSTALL_DIR@ 5 | includedir=${prefix}/@INCLUDE_INSTALL_DIR@ 6 | 7 | Name: @PACKAGE_NAME@ 8 | Version: @PACKAGE_VERSION@ 9 | Description: @PACKAGE_DESCRIPTION@ 10 | URL: @PACKAGE_URL@ 11 | Requires: 12 | Libs: -L${libdir} -lgflags 13 | Libs.private: -lpthread 14 | Cflags: -I${includedir} 15 | -------------------------------------------------------------------------------- /gflags/cmake/utils.cmake: -------------------------------------------------------------------------------- 1 | ## Utility CMake functions. 2 | 3 | # ---------------------------------------------------------------------------- 4 | ## Convert boolean value to 0 or 1 5 | macro (bool_to_int VAR) 6 | if (${VAR}) 7 | set (${VAR} 1) 8 | else () 9 | set (${VAR} 0) 10 | endif () 11 | endmacro () 12 | 13 | # ---------------------------------------------------------------------------- 14 | ## Extract version numbers from version string 15 | function (version_numbers version major minor patch) 16 | if (version MATCHES "([0-9]+)(\\.[0-9]+)?(\\.[0-9]+)?(rc[1-9][0-9]*|[a-z]+)?") 17 | if (CMAKE_MATCH_1) 18 | set (_major ${CMAKE_MATCH_1}) 19 | else () 20 | set (_major 0) 21 | endif () 22 | if (CMAKE_MATCH_2) 23 | set (_minor ${CMAKE_MATCH_2}) 24 | string (REGEX REPLACE "^\\." "" _minor "${_minor}") 25 | else () 26 | set (_minor 0) 27 | endif () 28 | if (CMAKE_MATCH_3) 29 | set (_patch ${CMAKE_MATCH_3}) 30 | string (REGEX REPLACE "^\\." "" _patch "${_patch}") 31 | else () 32 | set (_patch 0) 33 | endif () 34 | else () 35 | set (_major 0) 36 | set (_minor 0) 37 | set (_patch 0) 38 | endif () 39 | set ("${major}" "${_major}" PARENT_SCOPE) 40 | set ("${minor}" "${_minor}" PARENT_SCOPE) 41 | set ("${patch}" "${_patch}" PARENT_SCOPE) 42 | endfunction () 43 | 44 | # ---------------------------------------------------------------------------- 45 | ## Determine if cache entry exists 46 | macro (gflags_is_cached retvar varname) 47 | if (DEFINED ${varname}) 48 | get_property (${retvar} CACHE ${varname} PROPERTY TYPE SET) 49 | else () 50 | set (${retvar} FALSE) 51 | endif () 52 | endmacro () 53 | 54 | # ---------------------------------------------------------------------------- 55 | ## Add gflags configuration variable 56 | # 57 | # The default value of the (cached) configuration value can be overridden either 58 | # on the CMake command-line or the super-project by setting the GFLAGS_ 59 | # variable. When gflags is a subproject of another project (GFLAGS_IS_SUBPROJECT), 60 | # the variable is not added to the CMake cache. Otherwise it is cached. 61 | macro (gflags_define type varname docstring default) 62 | # note that ARGC must be expanded here, as it is not a "real" variable 63 | # (see the CMake documentation for the macro command) 64 | if ("${ARGC}" GREATER 5) 65 | message (FATAL_ERROR "gflags_variable: Too many macro arguments") 66 | endif () 67 | if (NOT DEFINED GFLAGS_${varname}) 68 | if (GFLAGS_IS_SUBPROJECT AND "${ARGC}" EQUAL 5) 69 | set (GFLAGS_${varname} "${ARGV4}") 70 | else () 71 | set (GFLAGS_${varname} "${default}") 72 | endif () 73 | endif () 74 | if (GFLAGS_IS_SUBPROJECT) 75 | if (NOT DEFINED ${varname}) 76 | set (${varname} "${GFLAGS_${varname}}") 77 | endif () 78 | else () 79 | set (${varname} "${GFLAGS_${varname}}" CACHE ${type} "${docstring}") 80 | endif () 81 | endmacro () 82 | 83 | # ---------------------------------------------------------------------------- 84 | ## Set property of cached gflags configuration variable 85 | macro (gflags_property varname property value) 86 | gflags_is_cached (_cached ${varname}) 87 | if (_cached) 88 | # note that property must be expanded here, as it is not a "real" variable 89 | # (see the CMake documentation for the macro command) 90 | if ("${property}" STREQUAL "ADVANCED") 91 | if (${value}) 92 | mark_as_advanced (FORCE ${varname}) 93 | else () 94 | mark_as_advanced (CLEAR ${varname}) 95 | endif () 96 | else () 97 | set_property (CACHE ${varname} PROPERTY "${property}" "${value}") 98 | endif () 99 | endif () 100 | unset (_cached) 101 | endmacro () 102 | 103 | # ---------------------------------------------------------------------------- 104 | ## Modify value of gflags configuration variable 105 | macro (gflags_set varname value) 106 | gflags_is_cached (_cached ${varname}) 107 | if (_cached) 108 | set_property (CACHE ${varname} PROPERTY VALUE "${value}") 109 | else () 110 | set (${varname} "${value}") 111 | endif () 112 | unset (_cached) 113 | endmacro () 114 | 115 | # ---------------------------------------------------------------------------- 116 | ## Configure public header files 117 | function (configure_headers out) 118 | set (tmp) 119 | foreach (src IN LISTS ARGN) 120 | if (IS_ABSOLUTE "${src}") 121 | list (APPEND tmp "${src}") 122 | elseif (EXISTS "${PROJECT_SOURCE_DIR}/src/${src}.in") 123 | configure_file ("${PROJECT_SOURCE_DIR}/src/${src}.in" "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}" @ONLY) 124 | list (APPEND tmp "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}") 125 | else () 126 | configure_file ("${PROJECT_SOURCE_DIR}/src/${src}" "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}" COPYONLY) 127 | list (APPEND tmp "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}") 128 | endif () 129 | endforeach () 130 | set (${out} "${tmp}" PARENT_SCOPE) 131 | endfunction () 132 | 133 | # ---------------------------------------------------------------------------- 134 | ## Configure source files with .in suffix 135 | function (configure_sources out) 136 | set (tmp) 137 | foreach (src IN LISTS ARGN) 138 | if (src MATCHES ".h$" AND EXISTS "${PROJECT_SOURCE_DIR}/src/${src}.in") 139 | configure_file ("${PROJECT_SOURCE_DIR}/src/${src}.in" "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}" @ONLY) 140 | list (APPEND tmp "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}") 141 | else () 142 | list (APPEND tmp "${PROJECT_SOURCE_DIR}/src/${src}") 143 | endif () 144 | endforeach () 145 | set (${out} "${tmp}" PARENT_SCOPE) 146 | endfunction () 147 | 148 | # ---------------------------------------------------------------------------- 149 | ## Add usage test 150 | # 151 | # Using PASS_REGULAR_EXPRESSION and FAIL_REGULAR_EXPRESSION would 152 | # do as well, but CMake/CTest does not allow us to specify an 153 | # expected exit status. Moreover, the execute_test.cmake script 154 | # sets environment variables needed by the --fromenv/--tryfromenv tests. 155 | macro (add_gflags_test name expected_rc expected_output unexpected_output cmd) 156 | set (args "--test_tmpdir=${PROJECT_BINARY_DIR}/Testing/Temporary" 157 | "--srcdir=${PROJECT_SOURCE_DIR}/test") 158 | add_test ( 159 | NAME ${name} 160 | COMMAND "${CMAKE_COMMAND}" "-DCOMMAND:STRING=$;${args};${ARGN}" 161 | "-DEXPECTED_RC:STRING=${expected_rc}" 162 | "-DEXPECTED_OUTPUT:STRING=${expected_output}" 163 | "-DUNEXPECTED_OUTPUT:STRING=${unexpected_output}" 164 | -P "${PROJECT_SOURCE_DIR}/cmake/execute_test.cmake" 165 | WORKING_DIRECTORY "${GFLAGS_FLAGFILES_DIR}" 166 | ) 167 | endmacro () 168 | 169 | # ------------------------------------------------------------------------------ 170 | ## Register installed package with CMake 171 | # 172 | # This function adds an entry to the CMake registry for packages with the 173 | # path of the directory where the package configuration file of the installed 174 | # package is located in order to help CMake find the package in a custom 175 | # installation prefix. This differs from CMake's export(PACKAGE) command 176 | # which registers the build directory instead. 177 | function (register_gflags_package CONFIG_DIR) 178 | if (NOT IS_ABSOLUTE "${CONFIG_DIR}") 179 | set (CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/${CONFIG_DIR}") 180 | endif () 181 | string (MD5 REGISTRY_ENTRY "${CONFIG_DIR}") 182 | if (WIN32) 183 | install (CODE 184 | "execute_process ( 185 | COMMAND reg add \"HKCU\\\\Software\\\\Kitware\\\\CMake\\\\Packages\\\\${PACKAGE_NAME}\" /v \"${REGISTRY_ENTRY}\" /d \"${CONFIG_DIR}\" /t REG_SZ /f 186 | RESULT_VARIABLE RT 187 | ERROR_VARIABLE ERR 188 | OUTPUT_QUIET 189 | ) 190 | if (RT EQUAL 0) 191 | message (STATUS \"Register: Added HKEY_CURRENT_USER\\\\Software\\\\Kitware\\\\CMake\\\\Packages\\\\${PACKAGE_NAME}\\\\${REGISTRY_ENTRY}\") 192 | else () 193 | string (STRIP \"\${ERR}\" ERR) 194 | message (STATUS \"Register: Failed to add registry entry: \${ERR}\") 195 | endif ()" 196 | ) 197 | elseif (IS_DIRECTORY "$ENV{HOME}") 198 | file (WRITE "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-registry-entry" "${CONFIG_DIR}") 199 | install ( 200 | FILES "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-registry-entry" 201 | DESTINATION "$ENV{HOME}/.cmake/packages/${PACKAGE_NAME}" 202 | RENAME "${REGISTRY_ENTRY}" 203 | ) 204 | endif () 205 | endfunction () 206 | -------------------------------------------------------------------------------- /gflags/cmake/version.cmake.in: -------------------------------------------------------------------------------- 1 | ## gflags CMake configuration version file 2 | 3 | # ----------------------------------------------------------------------------- 4 | # library version 5 | set (PACKAGE_VERSION "@PACKAGE_VERSION@") 6 | 7 | # ----------------------------------------------------------------------------- 8 | # check compatibility 9 | 10 | # Perform compatibility check here using the input CMake variables. 11 | # See example in http://www.cmake.org/Wiki/CMake_2.6_Notes. 12 | 13 | set (PACKAGE_VERSION_COMPATIBLE TRUE) 14 | set (PACKAGE_VERSION_UNSUITABLE FALSE) 15 | 16 | if ("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL "@PACKAGE_VERSION_MAJOR@" AND 17 | "${PACKAGE_FIND_VERSION_MINOR}" EQUAL "@PACKAGE_VERSION_MINOR@") 18 | set (PACKAGE_VERSION_EXACT TRUE) 19 | else () 20 | set (PACKAGE_VERSION_EXACT FALSE) 21 | endif () 22 | -------------------------------------------------------------------------------- /gflags/src/config.h.in: -------------------------------------------------------------------------------- 1 | /* Generated from config.h.in during build configuration using CMake. */ 2 | 3 | // Note: This header file is only used internally. It is not part of public interface! 4 | 5 | #ifndef GFLAGS_CONFIG_H_ 6 | #define GFLAGS_CONFIG_H_ 7 | 8 | 9 | // --------------------------------------------------------------------------- 10 | // System checks 11 | 12 | // Define if you build this library for a MS Windows OS. 13 | #cmakedefine OS_WINDOWS 14 | 15 | // Define if you have the header file. 16 | #cmakedefine HAVE_STDINT_H 17 | 18 | // Define if you have the header file. 19 | #cmakedefine HAVE_SYS_TYPES_H 20 | 21 | // Define if you have the header file. 22 | #cmakedefine HAVE_INTTYPES_H 23 | 24 | // Define if you have the header file. 25 | #cmakedefine HAVE_SYS_STAT_H 26 | 27 | // Define if you have the header file. 28 | #cmakedefine HAVE_UNISTD_H 29 | 30 | // Define if you have the header file. 31 | #cmakedefine HAVE_FNMATCH_H 32 | 33 | // Define if you have the header file (Windows 2000/XP). 34 | #cmakedefine HAVE_SHLWAPI_H 35 | 36 | // Define if you have the strtoll function. 37 | #cmakedefine HAVE_STRTOLL 38 | 39 | // Define if you have the strtoq function. 40 | #cmakedefine HAVE_STRTOQ 41 | 42 | // Define if you have the header file. 43 | #cmakedefine HAVE_PTHREAD 44 | 45 | // Define if your pthread library defines the type pthread_rwlock_t 46 | #cmakedefine HAVE_RWLOCK 47 | 48 | // gcc requires this to get PRId64, etc. 49 | #if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS) 50 | # define __STDC_FORMAT_MACROS 1 51 | #endif 52 | 53 | // --------------------------------------------------------------------------- 54 | // Package information 55 | 56 | // Name of package. 57 | #define PACKAGE @PROJECT_NAME@ 58 | 59 | // Define to the full name of this package. 60 | #define PACKAGE_NAME @PACKAGE_NAME@ 61 | 62 | // Define to the full name and version of this package. 63 | #define PACKAGE_STRING @PACKAGE_STRING@ 64 | 65 | // Define to the one symbol short name of this package. 66 | #define PACKAGE_TARNAME @PACKAGE_TARNAME@ 67 | 68 | // Define to the version of this package. 69 | #define PACKAGE_VERSION @PACKAGE_VERSION@ 70 | 71 | // Version number of package. 72 | #define VERSION PACKAGE_VERSION 73 | 74 | // Define to the address where bug reports for this package should be sent. 75 | #define PACKAGE_BUGREPORT @PACKAGE_BUGREPORT@ 76 | 77 | // --------------------------------------------------------------------------- 78 | // Path separator 79 | #ifndef PATH_SEPARATOR 80 | # ifdef OS_WINDOWS 81 | # define PATH_SEPARATOR '\\' 82 | # else 83 | # define PATH_SEPARATOR '/' 84 | # endif 85 | #endif 86 | 87 | // --------------------------------------------------------------------------- 88 | // Windows 89 | 90 | // Always export symbols when compiling a shared library as this file is only 91 | // included by internal modules when building the gflags library itself. 92 | // The gflags_declare.h header file will set it to import these symbols otherwise. 93 | #ifndef GFLAGS_DLL_DECL 94 | # if GFLAGS_IS_A_DLL && defined(_MSC_VER) 95 | # define GFLAGS_DLL_DECL __declspec(dllexport) 96 | # else 97 | # define GFLAGS_DLL_DECL 98 | # endif 99 | #endif 100 | // Flags defined by the gflags library itself must be exported 101 | #ifndef GFLAGS_DLL_DEFINE_FLAG 102 | # define GFLAGS_DLL_DEFINE_FLAG GFLAGS_DLL_DECL 103 | #endif 104 | 105 | #ifdef OS_WINDOWS 106 | // The unittests import the symbols of the shared gflags library 107 | # if GFLAGS_IS_A_DLL && defined(_MSC_VER) 108 | # define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport) 109 | # endif 110 | # include "windows_port.h" 111 | #endif 112 | 113 | 114 | #endif // GFLAGS_CONFIG_H_ 115 | -------------------------------------------------------------------------------- /gflags/src/gflags_completions.h.in: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // --- 31 | 32 | // 33 | // Implement helpful bash-style command line flag completions 34 | // 35 | // ** Functional API: 36 | // HandleCommandLineCompletions() should be called early during 37 | // program startup, but after command line flag code has been 38 | // initialized, such as the beginning of HandleCommandLineHelpFlags(). 39 | // It checks the value of the flag --tab_completion_word. If this 40 | // flag is empty, nothing happens here. If it contains a string, 41 | // however, then HandleCommandLineCompletions() will hijack the 42 | // process, attempting to identify the intention behind this 43 | // completion. Regardless of the outcome of this deduction, the 44 | // process will be terminated, similar to --helpshort flag 45 | // handling. 46 | // 47 | // ** Overview of Bash completions: 48 | // Bash can be told to programatically determine completions for the 49 | // current 'cursor word'. It does this by (in this case) invoking a 50 | // command with some additional arguments identifying the command 51 | // being executed, the word being completed, and the previous word 52 | // (if any). Bash then expects a sequence of output lines to be 53 | // printed to stdout. If these lines all contain a common prefix 54 | // longer than the cursor word, bash will replace the cursor word 55 | // with that common prefix, and display nothing. If there isn't such 56 | // a common prefix, bash will display the lines in pages using 'more'. 57 | // 58 | // ** Strategy taken for command line completions: 59 | // If we can deduce either the exact flag intended, or a common flag 60 | // prefix, we'll output exactly that. Otherwise, if information 61 | // must be displayed to the user, we'll take the opportunity to add 62 | // some helpful information beyond just the flag name (specifically, 63 | // we'll include the default flag value and as much of the flag's 64 | // description as can fit on a single terminal line width, as specified 65 | // by the flag --tab_completion_columns). Furthermore, we'll try to 66 | // make bash order the output such that the most useful or relevent 67 | // flags are the most likely to be shown at the top. 68 | // 69 | // ** Additional features: 70 | // To assist in finding that one really useful flag, substring matching 71 | // was implemented. Before pressing a to get completion for the 72 | // current word, you can append one or more '?' to the flag to do 73 | // substring matching. Here's the semantics: 74 | // --foo Show me all flags with names prefixed by 'foo' 75 | // --foo? Show me all flags with 'foo' somewhere in the name 76 | // --foo?? Same as prior case, but also search in module 77 | // definition path for 'foo' 78 | // --foo??? Same as prior case, but also search in flag 79 | // descriptions for 'foo' 80 | // Finally, we'll trim the output to a relatively small number of 81 | // flags to keep bash quiet about the verbosity of output. If one 82 | // really wanted to see all possible matches, appending a '+' to the 83 | // search word will force the exhaustive list of matches to be printed. 84 | // 85 | // ** How to have bash accept completions from a binary: 86 | // Bash requires that it be informed about each command that programmatic 87 | // completion should be enabled for. Example addition to a .bashrc 88 | // file would be (your path to gflags_completions.sh file may differ): 89 | 90 | /* 91 | $ complete -o bashdefault -o default -o nospace -C \ 92 | '/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \ 93 | time env binary_name another_binary [...] 94 | */ 95 | 96 | // This would allow the following to work: 97 | // $ /path/to/binary_name --vmodule 98 | // Or: 99 | // $ ./bin/path/another_binary --gfs_u 100 | // (etc) 101 | // 102 | // Sadly, it appears that bash gives no easy way to force this behavior for 103 | // all commands. That's where the "time" in the above example comes in. 104 | // If you haven't specifically added a command to the list of completion 105 | // supported commands, you can still get completions by prefixing the 106 | // entire command with "env". 107 | // $ env /some/brand/new/binary --vmod 108 | // Assuming that "binary" is a newly compiled binary, this should still 109 | // produce the expected completion output. 110 | 111 | 112 | #ifndef GFLAGS_COMPLETIONS_H_ 113 | #define GFLAGS_COMPLETIONS_H_ 114 | 115 | namespace @GFLAGS_NAMESPACE@ { 116 | 117 | extern void HandleCommandLineCompletions(void); 118 | 119 | } 120 | 121 | #endif // GFLAGS_COMPLETIONS_H_ 122 | -------------------------------------------------------------------------------- /gflags/src/gflags_completions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2008, Google Inc. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are 8 | # met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following disclaimer 14 | # in the documentation and/or other materials provided with the 15 | # distribution. 16 | # * Neither the name of Google Inc. nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | # 32 | # --- 33 | # Author: Dave Nicponski 34 | # 35 | # This script is invoked by bash in response to a matching compspec. When 36 | # this happens, bash calls this script using the command shown in the -C 37 | # block of the complete entry, but also appends 3 arguments. They are: 38 | # - The command being used for completion 39 | # - The word being completed 40 | # - The word preceding the completion word. 41 | # 42 | # Here's an example of how you might use this script: 43 | # $ complete -o bashdefault -o default -o nospace -C \ 44 | # '/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \ 45 | # time env binary_name another_binary [...] 46 | 47 | # completion_word_index gets the index of the (N-1)th argument for 48 | # this command line. completion_word gets the actual argument from 49 | # this command line at the (N-1)th position 50 | completion_word_index="$(($# - 1))" 51 | completion_word="${!completion_word_index}" 52 | 53 | # TODO(user): Replace this once gflags_completions.cc has 54 | # a bool parameter indicating unambiguously to hijack the process for 55 | # completion purposes. 56 | if [ -z "$completion_word" ]; then 57 | # Until an empty value for the completion word stops being misunderstood 58 | # by binaries, don't actually execute the binary or the process 59 | # won't be hijacked! 60 | exit 0 61 | fi 62 | 63 | # binary_index gets the index of the command being completed (which bash 64 | # places in the (N-2)nd position. binary gets the actual command from 65 | # this command line at that (N-2)nd position 66 | binary_index="$(($# - 2))" 67 | binary="${!binary_index}" 68 | 69 | # For completions to be universal, we may have setup the compspec to 70 | # trigger on 'harmless pass-through' commands, like 'time' or 'env'. 71 | # If the command being completed is one of those two, we'll need to 72 | # identify the actual command being executed. To do this, we need 73 | # the actual command line that the was pressed on. Bash helpfully 74 | # places this in the $COMP_LINE variable. 75 | if [ "$binary" == "time" ] || [ "$binary" == "env" ]; then 76 | # we'll assume that the first 'argument' is actually the 77 | # binary 78 | 79 | 80 | # TODO(user): This is not perfect - the 'env' command, for instance, 81 | # is allowed to have options between the 'env' and 'the command to 82 | # be executed'. For example, consider: 83 | # $ env FOO="bar" bin/do_something --help 84 | # In this case, we'll mistake the FOO="bar" portion as the binary. 85 | # Perhaps we should continuing consuming leading words until we 86 | # either run out of words, or find a word that is a valid file 87 | # marked as executable. I can't think of any reason this wouldn't 88 | # work. 89 | 90 | # Break up the 'original command line' (not this script's command line, 91 | # rather the one the was pressed on) and find the second word. 92 | parts=( ${COMP_LINE} ) 93 | binary=${parts[1]} 94 | fi 95 | 96 | # Build the command line to use for completion. Basically it involves 97 | # passing through all the arguments given to this script (except the 3 98 | # that bash added), and appending a '--tab_completion_word "WORD"' to 99 | # the arguments. 100 | params="" 101 | for ((i=1; i<=$(($# - 3)); ++i)); do 102 | params="$params \"${!i}\""; 103 | done 104 | params="$params --tab_completion_word \"$completion_word\"" 105 | 106 | # TODO(user): Perhaps stash the output in a temporary file somewhere 107 | # in /tmp, and only cat it to stdout if the command returned a success 108 | # code, to prevent false positives 109 | 110 | # If we think we have a reasonable command to execute, then execute it 111 | # and hope for the best. 112 | candidate=$(type -p "$binary") 113 | if [ ! -z "$candidate" ]; then 114 | eval "$candidate 2>/dev/null $params" 115 | elif [ -f "$binary" ] && [ -x "$binary" ]; then 116 | eval "$binary 2>/dev/null $params" 117 | fi 118 | -------------------------------------------------------------------------------- /gflags/src/gflags_declare.h.in: -------------------------------------------------------------------------------- 1 | // Copyright (c) 1999, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // --- 31 | // 32 | // Revamped and reorganized by Craig Silverstein 33 | // 34 | // This is the file that should be included by any file which declares 35 | // command line flag. 36 | 37 | #ifndef GFLAGS_DECLARE_H_ 38 | #define GFLAGS_DECLARE_H_ 39 | 40 | 41 | // --------------------------------------------------------------------------- 42 | // Namespace of gflags library symbols. 43 | #define GFLAGS_NAMESPACE @GFLAGS_NAMESPACE@ 44 | 45 | // --------------------------------------------------------------------------- 46 | // Windows DLL import/export. 47 | 48 | // Whether gflags library is a DLL. 49 | // 50 | // Set to 1 by default when the shared gflags library was built on Windows. 51 | // Must be overwritten when this header file is used with the optionally also 52 | // built static library instead; set by CMake's INTERFACE_COMPILE_DEFINITIONS. 53 | #ifndef GFLAGS_IS_A_DLL 54 | # define GFLAGS_IS_A_DLL @GFLAGS_IS_A_DLL@ 55 | #endif 56 | 57 | // We always want to import the symbols of the gflags library. 58 | #ifndef GFLAGS_DLL_DECL 59 | # if GFLAGS_IS_A_DLL && defined(_MSC_VER) 60 | # define GFLAGS_DLL_DECL __declspec(dllimport) 61 | # else 62 | # define GFLAGS_DLL_DECL 63 | # endif 64 | #endif 65 | 66 | // We always want to import variables declared in user code. 67 | #ifndef GFLAGS_DLL_DECLARE_FLAG 68 | # if GFLAGS_IS_A_DLL && defined(_MSC_VER) 69 | # define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport) 70 | # else 71 | # define GFLAGS_DLL_DECLARE_FLAG 72 | # endif 73 | #endif 74 | 75 | // --------------------------------------------------------------------------- 76 | // Flag types 77 | #include 78 | #if @HAVE_STDINT_H@ 79 | # include // the normal place uint32_t is defined 80 | #elif @HAVE_SYS_TYPES_H@ 81 | # include // the normal place u_int32_t is defined 82 | #elif @HAVE_INTTYPES_H@ 83 | # include // a third place for uint32_t or u_int32_t 84 | #endif 85 | 86 | namespace GFLAGS_NAMESPACE { 87 | 88 | #if @GFLAGS_INTTYPES_FORMAT_C99@ // C99 89 | typedef int32_t int32; 90 | typedef uint32_t uint32; 91 | typedef int64_t int64; 92 | typedef uint64_t uint64; 93 | #elif @GFLAGS_INTTYPES_FORMAT_BSD@ // BSD 94 | typedef int32_t int32; 95 | typedef u_int32_t uint32; 96 | typedef int64_t int64; 97 | typedef u_int64_t uint64; 98 | #elif @GFLAGS_INTTYPES_FORMAT_VC7@ // Windows 99 | typedef __int32 int32; 100 | typedef unsigned __int32 uint32; 101 | typedef __int64 int64; 102 | typedef unsigned __int64 uint64; 103 | #else 104 | # error Do not know how to define a 32-bit integer quantity on your system 105 | #endif 106 | 107 | } // namespace GFLAGS_NAMESPACE 108 | 109 | 110 | namespace fLS { 111 | 112 | // The meaning of "string" might be different between now and when the 113 | // macros below get invoked (e.g., if someone is experimenting with 114 | // other string implementations that get defined after this file is 115 | // included). Save the current meaning now and use it in the macros. 116 | typedef std::string clstring; 117 | 118 | } // namespace fLS 119 | 120 | 121 | #define DECLARE_VARIABLE(type, shorttype, name) \ 122 | /* We always want to import declared variables, dll or no */ \ 123 | namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \ 124 | using fL##shorttype::FLAGS_##name 125 | 126 | #define DECLARE_bool(name) \ 127 | DECLARE_VARIABLE(bool, B, name) 128 | 129 | #define DECLARE_int32(name) \ 130 | DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int32, I, name) 131 | 132 | #define DECLARE_uint32(name) \ 133 | DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint32, U, name) 134 | 135 | #define DECLARE_int64(name) \ 136 | DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int64, I64, name) 137 | 138 | #define DECLARE_uint64(name) \ 139 | DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint64, U64, name) 140 | 141 | #define DECLARE_double(name) \ 142 | DECLARE_VARIABLE(double, D, name) 143 | 144 | #define DECLARE_string(name) \ 145 | /* We always want to import declared variables, dll or no */ \ 146 | namespace fLS { \ 147 | using ::fLS::clstring; \ 148 | extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \ 149 | } \ 150 | using fLS::FLAGS_##name 151 | 152 | 153 | #endif // GFLAGS_DECLARE_H_ 154 | -------------------------------------------------------------------------------- /gflags/src/gflags_ns.h.in: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Andreas Schuh 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // ----------------------------------------------------------------------------- 31 | // Imports the gflags library symbols into an alternative/deprecated namespace. 32 | 33 | #ifndef GFLAGS_GFLAGS_H_ 34 | # error The internal header gflags_@ns@.h may only be included by gflags.h 35 | #endif 36 | 37 | #ifndef GFLAGS_NS_@NS@_H_ 38 | #define GFLAGS_NS_@NS@_H_ 39 | 40 | 41 | namespace @ns@ { 42 | 43 | 44 | using GFLAGS_NAMESPACE::int32; 45 | using GFLAGS_NAMESPACE::uint32; 46 | using GFLAGS_NAMESPACE::int64; 47 | using GFLAGS_NAMESPACE::uint64; 48 | 49 | using GFLAGS_NAMESPACE::RegisterFlagValidator; 50 | using GFLAGS_NAMESPACE::CommandLineFlagInfo; 51 | using GFLAGS_NAMESPACE::GetAllFlags; 52 | using GFLAGS_NAMESPACE::ShowUsageWithFlags; 53 | using GFLAGS_NAMESPACE::ShowUsageWithFlagsRestrict; 54 | using GFLAGS_NAMESPACE::DescribeOneFlag; 55 | using GFLAGS_NAMESPACE::SetArgv; 56 | using GFLAGS_NAMESPACE::GetArgvs; 57 | using GFLAGS_NAMESPACE::GetArgv; 58 | using GFLAGS_NAMESPACE::GetArgv0; 59 | using GFLAGS_NAMESPACE::GetArgvSum; 60 | using GFLAGS_NAMESPACE::ProgramInvocationName; 61 | using GFLAGS_NAMESPACE::ProgramInvocationShortName; 62 | using GFLAGS_NAMESPACE::ProgramUsage; 63 | using GFLAGS_NAMESPACE::VersionString; 64 | using GFLAGS_NAMESPACE::GetCommandLineOption; 65 | using GFLAGS_NAMESPACE::GetCommandLineFlagInfo; 66 | using GFLAGS_NAMESPACE::GetCommandLineFlagInfoOrDie; 67 | using GFLAGS_NAMESPACE::FlagSettingMode; 68 | using GFLAGS_NAMESPACE::SET_FLAGS_VALUE; 69 | using GFLAGS_NAMESPACE::SET_FLAG_IF_DEFAULT; 70 | using GFLAGS_NAMESPACE::SET_FLAGS_DEFAULT; 71 | using GFLAGS_NAMESPACE::SetCommandLineOption; 72 | using GFLAGS_NAMESPACE::SetCommandLineOptionWithMode; 73 | using GFLAGS_NAMESPACE::FlagSaver; 74 | using GFLAGS_NAMESPACE::CommandlineFlagsIntoString; 75 | using GFLAGS_NAMESPACE::ReadFlagsFromString; 76 | using GFLAGS_NAMESPACE::AppendFlagsIntoFile; 77 | using GFLAGS_NAMESPACE::ReadFromFlagsFile; 78 | using GFLAGS_NAMESPACE::BoolFromEnv; 79 | using GFLAGS_NAMESPACE::Int32FromEnv; 80 | using GFLAGS_NAMESPACE::Uint32FromEnv; 81 | using GFLAGS_NAMESPACE::Int64FromEnv; 82 | using GFLAGS_NAMESPACE::Uint64FromEnv; 83 | using GFLAGS_NAMESPACE::DoubleFromEnv; 84 | using GFLAGS_NAMESPACE::StringFromEnv; 85 | using GFLAGS_NAMESPACE::SetUsageMessage; 86 | using GFLAGS_NAMESPACE::SetVersionString; 87 | using GFLAGS_NAMESPACE::ParseCommandLineNonHelpFlags; 88 | using GFLAGS_NAMESPACE::HandleCommandLineHelpFlags; 89 | using GFLAGS_NAMESPACE::AllowCommandLineReparsing; 90 | using GFLAGS_NAMESPACE::ReparseCommandLineNonHelpFlags; 91 | using GFLAGS_NAMESPACE::ShutDownCommandLineFlags; 92 | using GFLAGS_NAMESPACE::FlagRegisterer; 93 | 94 | #ifndef SWIG 95 | using GFLAGS_NAMESPACE::ParseCommandLineFlags; 96 | #endif 97 | 98 | 99 | } // namespace @ns@ 100 | 101 | 102 | #endif // GFLAGS_NS_@NS@_H_ 103 | -------------------------------------------------------------------------------- /gflags/src/windows_port.cc: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2009, Google Inc. 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above 11 | * copyright notice, this list of conditions and the following disclaimer 12 | * in the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Google Inc. nor the names of its 15 | * contributors may be used to endorse or promote products derived from 16 | * this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | * --- 31 | * Author: Craig Silverstein 32 | */ 33 | 34 | #ifndef _WIN32 35 | # error You should only be including windows/port.cc in a windows environment! 36 | #endif 37 | 38 | #include // for strlen(), memset(), memcmp() 39 | #include 40 | #include // for va_list, va_start, va_end 41 | #include 42 | 43 | #include "windows_port.h" 44 | 45 | // These call the windows _vsnprintf, but always NUL-terminate. 46 | #if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */ 47 | #if !(defined(_MSC_VER) && _MSC_VER >= 1900) /* msvc 2015 already defines */ 48 | 49 | #ifdef _MSC_VER 50 | # pragma warning(push) 51 | # pragma warning(disable: 4996) // ignore _vsnprintf security warning 52 | #endif 53 | int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) { 54 | if (size == 0) // not even room for a \0? 55 | return -1; // not what C99 says to do, but what windows does 56 | str[size-1] = '\0'; 57 | return _vsnprintf(str, size-1, format, ap); 58 | } 59 | #ifdef _MSC_VER 60 | # pragma warning(pop) 61 | #endif 62 | 63 | int snprintf(char *str, size_t size, const char *format, ...) { 64 | int r; 65 | va_list ap; 66 | va_start(ap, format); 67 | r = vsnprintf(str, size, format, ap); 68 | va_end(ap); 69 | return r; 70 | } 71 | 72 | #endif /* if !(defined(_MSC_VER) && _MSC_VER >= 1900) */ 73 | #endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */ 74 | -------------------------------------------------------------------------------- /gflags/src/windows_port.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2009, Google Inc. 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above 11 | * copyright notice, this list of conditions and the following disclaimer 12 | * in the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Google Inc. nor the names of its 15 | * contributors may be used to endorse or promote products derived from 16 | * this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | * --- 31 | * Author: Craig Silverstein 32 | * 33 | * These are some portability typedefs and defines to make it a bit 34 | * easier to compile this code under VC++. 35 | * 36 | * Several of these are taken from glib: 37 | * http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html 38 | */ 39 | 40 | #ifndef GFLAGS_WINDOWS_PORT_H_ 41 | #define GFLAGS_WINDOWS_PORT_H_ 42 | 43 | #include "config.h" 44 | 45 | // This must be defined before the windows.h is included. 46 | // It's needed for mutex.h, to give access to the TryLock method. 47 | # if !defined(_WIN32_WINNT) && !(defined( __MINGW32__) || defined(__MINGW64__)) 48 | # define _WIN32_WINNT 0x0400 49 | # endif 50 | // We always want minimal includes 51 | #ifndef WIN32_LEAN_AND_MEAN 52 | # define WIN32_LEAN_AND_MEAN 53 | #endif 54 | #include 55 | #include /* for mkdir */ 56 | #include /* for _putenv, getenv */ 57 | #include /* need this to override stdio's snprintf, also defines _unlink used by unit tests */ 58 | #include /* util.h uses va_copy */ 59 | #include /* for _stricmp and _strdup */ 60 | 61 | /* We can't just use _vsnprintf and _snprintf as drop-in-replacements, 62 | * because they don't always NUL-terminate. :-( We also can't use the 63 | * name vsnprintf, since windows defines that (but not snprintf (!)). 64 | */ 65 | #if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */ 66 | #if !(defined(_MSC_VER) && _MSC_VER >= 1900) /* msvc 2015 already defines */ 67 | extern GFLAGS_DLL_DECL int snprintf(char *str, size_t size, 68 | const char *format, ...); 69 | extern int GFLAGS_DLL_DECL safe_vsnprintf(char *str, size_t size, 70 | const char *format, va_list ap); 71 | #define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap) 72 | #define va_copy(dst, src) (dst) = (src) 73 | #endif 74 | #endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */ 75 | 76 | #ifdef _MSC_VER 77 | # pragma warning(push) 78 | # pragma warning(disable: 4996) // ignore getenv security warning 79 | #endif 80 | inline void setenv(const char* name, const char* value, int) { 81 | // In windows, it's impossible to set a variable to the empty string. 82 | // We handle this by setting it to "0" and the NUL-ing out the \0. 83 | // That is, we putenv("FOO=0") and then find out where in memory the 84 | // putenv wrote "FOO=0", and change it in-place to "FOO=\0". 85 | // c.f. http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/environ.cpp?r1=611451&r2=637508&pathrev=637508 86 | static const char* const kFakeZero = "0"; 87 | if (*value == '\0') 88 | value = kFakeZero; 89 | // Apparently the semantics of putenv() is that the input 90 | // must live forever, so we leak memory here. :-( 91 | const size_t nameval_len = strlen(name) + 1 + strlen(value) + 1; 92 | char* nameval = reinterpret_cast(malloc(nameval_len)); 93 | snprintf(nameval, nameval_len, "%s=%s", name, value); 94 | _putenv(nameval); 95 | if (value == kFakeZero) { 96 | nameval[nameval_len - 2] = '\0'; // works when putenv() makes no copy 97 | if (*getenv(name) != '\0') 98 | *getenv(name) = '\0'; // works when putenv() copies nameval 99 | } 100 | } 101 | #ifdef _MSC_VER 102 | # pragma warning(pop) 103 | #endif 104 | 105 | #define strcasecmp _stricmp 106 | 107 | #if defined(_MSC_VER) && _MSC_VER >= 1400 108 | #define strdup _strdup 109 | #define unlink _unlink 110 | #endif 111 | 112 | #if defined(_MSC_VER) && _MSC_VER >= 1800 113 | #include 114 | #else 115 | #define PRId32 "d" 116 | #define PRIu32 "u" 117 | #define PRId64 "I64d" 118 | #define PRIu64 "I64u" 119 | #endif 120 | 121 | #if !defined(__MINGW32__) && !defined(__MINGW64__) 122 | #define strtoq _strtoi64 123 | #define strtouq _strtoui64 124 | #define strtoll _strtoi64 125 | #define strtoull _strtoui64 126 | #define atoll _atoi64 127 | #endif 128 | 129 | #ifndef PATH_MAX 130 | #define PATH_MAX 1024 131 | #endif 132 | 133 | #endif /* GFLAGS_WINDOWS_PORT_H_ */ 134 | -------------------------------------------------------------------------------- /gflags/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## gflags tests 2 | 3 | # ---------------------------------------------------------------------------- 4 | # output directories 5 | set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") 6 | set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") 7 | set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") 8 | 9 | # set working directory of test commands 10 | set (GFLAGS_FLAGFILES_DIR "${CMAKE_CURRENT_SOURCE_DIR}") 11 | 12 | # ---------------------------------------------------------------------------- 13 | # common include directories and link libraries 14 | include_directories ("${CMAKE_CURRENT_SOURCE_DIR}") 15 | include_directories ("${gflags_SOURCE_DIR}/src") 16 | include_directories ("${gflags_BINARY_DIR}/include") 17 | include_directories ("${gflags_BINARY_DIR}/include/gflags") 18 | 19 | if (BUILD_SHARED_LIBS) 20 | set (type shared) 21 | if (GFLAGS_IS_A_DLL) 22 | add_definitions(-DGFLAGS_IS_A_DLL) 23 | endif () 24 | else () 25 | set (type static) 26 | endif () 27 | if (BUILD_gflags_LIB) 28 | link_libraries (gflags_${type}) 29 | else () 30 | link_libraries (gflags_nothreads_${type}) 31 | endif () 32 | 33 | # ---------------------------------------------------------------------------- 34 | # STRIP_FLAG_HELP 35 | add_executable (gflags_strip_flags_test gflags_strip_flags_test.cc) 36 | # Make sure the --help output doesn't print the stripped text. 37 | add_gflags_test (strip_flags_help 1 "" "This text should be stripped out" gflags_strip_flags_test --help) 38 | # Make sure the stripped text isn't in the binary at all. 39 | add_test ( 40 | NAME strip_flags_binary 41 | COMMAND "${CMAKE_COMMAND}" "-DBINARY=$" 42 | -P "${CMAKE_CURRENT_SOURCE_DIR}/gflags_strip_flags_test.cmake" 43 | CONFIGURATIONS Release MinSizeRel 44 | ) 45 | 46 | # ---------------------------------------------------------------------------- 47 | # unit tests 48 | configure_file (gflags_unittest.cc gflags_unittest-main.cc COPYONLY) 49 | configure_file (gflags_unittest.cc gflags_unittest_main.cc COPYONLY) 50 | 51 | add_executable (gflags_unittest gflags_unittest.cc) 52 | add_executable (gflags_unittest-main gflags_unittest-main.cc) 53 | add_executable (gflags_unittest_main gflags_unittest_main.cc) 54 | 55 | if (OS_WINDOWS) 56 | set (SLASH "\\\\") 57 | else () 58 | set (SLASH "/") 59 | endif () 60 | 61 | # First, just make sure the gflags_unittest works as-is 62 | add_gflags_test(unittest 0 "" "" gflags_unittest) 63 | 64 | # --help should show all flags, including flags from gflags_reporting 65 | add_gflags_test(help-reporting 1 "${SLASH}gflags_reporting.cc:" "" gflags_unittest --help) 66 | 67 | # Make sure that --help prints even very long helpstrings. 68 | add_gflags_test(long-helpstring 1 "end of a long helpstring" "" gflags_unittest --help) 69 | 70 | # Make sure --help reflects flag changes made before flag-parsing 71 | add_gflags_test(changed_bool1 1 "-changed_bool1 (changed) type: bool default: true" "" gflags_unittest --help) 72 | add_gflags_test(changed_bool2 1 "-changed_bool2 (changed) type: bool default: false currently: true" "" gflags_unittest --help) 73 | # And on the command-line, too 74 | add_gflags_test(changeable_string_var 1 "-changeable_string_var () type: string default: \"1\" currently: \"2\"" "" gflags_unittest --changeable_string_var 2 --help) 75 | 76 | # --nohelp and --help=false should be as if we didn't say anything 77 | add_gflags_test(nohelp 0 "PASS" "" gflags_unittest --nohelp) 78 | add_gflags_test(help=false 0 "PASS" "" gflags_unittest --help=false) 79 | 80 | # --helpfull is the same as help 81 | add_gflags_test(helpfull 1 "${SLASH}gflags_reporting.cc:" "" gflags_unittest --helpfull) 82 | 83 | # --helpshort should show only flags from the gflags_unittest itself 84 | add_gflags_test(helpshort 1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags_reporting.cc:" gflags_unittest --helpshort) 85 | 86 | # --helpshort should show the tldflag we created in the gflags_unittest dir 87 | add_gflags_test(helpshort-tldflag1 1 "tldflag1" "${SLASH}google.cc:" gflags_unittest --helpshort) 88 | add_gflags_test(helpshort-tldflag2 1 "tldflag2" "${SLASH}google.cc:" gflags_unittest --helpshort) 89 | 90 | # --helpshort should work if the main source file is suffixed with [_-]main 91 | add_gflags_test(helpshort-main 1 "${SLASH}gflags_unittest-main.cc:" "${SLASH}gflags_reporting.cc:" gflags_unittest-main --helpshort) 92 | add_gflags_test(helpshort_main 1 "${SLASH}gflags_unittest_main.cc:" "${SLASH}gflags_reporting.cc:" gflags_unittest_main --helpshort) 93 | 94 | # --helpon needs an argument 95 | add_gflags_test(helpon 1 "'--helpon' is missing its argument; flag description: show help on" "" gflags_unittest --helpon) 96 | # --helpon argument indicates what file we'll show args from 97 | add_gflags_test(helpon=gflags 1 "${SLASH}gflags.cc:" "${SLASH}gflags_unittest.cc:" gflags_unittest --helpon=gflags) 98 | # another way of specifying the argument 99 | add_gflags_test(helpon_gflags 1 "${SLASH}gflags.cc:" "${SLASH}gflags_unittest.cc:" gflags_unittest --helpon gflags) 100 | # test another argument 101 | add_gflags_test(helpon=gflags_unittest 1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags.cc:" gflags_unittest --helpon=gflags_unittest) 102 | 103 | # helpmatch is like helpon but takes substrings 104 | add_gflags_test(helpmatch_reporting 1 "${SLASH}gflags_reporting.cc:" "${SLASH}gflags_unittest.cc:" gflags_unittest -helpmatch reporting) 105 | add_gflags_test(helpmatch=unittest 1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags.cc:" gflags_unittest -helpmatch=unittest) 106 | 107 | # if no flags are found with helpmatch or helpon, suggest --help 108 | add_gflags_test(helpmatch=nosuchsubstring 1 "No modules matched" "${SLASH}gflags_unittest.cc:" gflags_unittest -helpmatch=nosuchsubstring) 109 | add_gflags_test(helpon=nosuchmodule 1 "No modules matched" "${SLASH}gflags_unittest.cc:" gflags_unittest -helpon=nosuchmodule) 110 | 111 | # helppackage shows all the flags in the same dir as this unittest 112 | # --help should show all flags, including flags from google.cc 113 | add_gflags_test(helppackage 1 "${SLASH}gflags_reporting.cc:" "" gflags_unittest --helppackage) 114 | 115 | # xml! 116 | add_gflags_test(helpxml 1 "${SLASH}gflags_unittest.cc" "${SLASH}gflags_unittest.cc:" gflags_unittest --helpxml) 117 | 118 | # just print the version info and exit 119 | add_gflags_test(version-1 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --version) 120 | add_gflags_test(version-2 0 "version test_version" "${SLASH}gflags_unittest.cc:" gflags_unittest --version) 121 | 122 | # --undefok is a fun flag... 123 | add_gflags_test(undefok-1 1 "unknown command line flag 'foo'" "" gflags_unittest --undefok= --foo --unused_bool) 124 | add_gflags_test(undefok-2 0 "PASS" "" gflags_unittest --undefok=foo --foo --unused_bool) 125 | # If you say foo is ok to be undefined, we'll accept --nofoo as well 126 | add_gflags_test(undefok-3 0 "PASS" "" gflags_unittest --undefok=foo --nofoo --unused_bool) 127 | # It's ok if the foo is in the middle 128 | add_gflags_test(undefok-4 0 "PASS" "" gflags_unittest --undefok=fee,fi,foo,fum --foo --unused_bool) 129 | # But the spelling has to be just right... 130 | add_gflags_test(undefok-5 1 "unknown command line flag 'foo'" "" gflags_unittest --undefok=fo --foo --unused_bool) 131 | add_gflags_test(undefok-6 1 "unknown command line flag 'foo'" "" gflags_unittest --undefok=foot --foo --unused_bool) 132 | 133 | # See if we can successfully load our flags from the flagfile 134 | add_gflags_test(flagfile.1 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest "--flagfile=flagfile.1") 135 | add_gflags_test(flagfile.2 0 "PASS" "" gflags_unittest "--flagfile=flagfile.2") 136 | add_gflags_test(flagfile.3 0 "PASS" "" gflags_unittest "--flagfile=flagfile.3") 137 | 138 | # Also try to load flags from the environment 139 | add_gflags_test(fromenv=version 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --fromenv=version) 140 | add_gflags_test(tryfromenv=version 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --tryfromenv=version) 141 | add_gflags_test(fromenv=help 0 "PASS" "" gflags_unittest --fromenv=help) 142 | add_gflags_test(tryfromenv=help 0 "PASS" "" gflags_unittest --tryfromenv=help) 143 | add_gflags_test(fromenv=helpfull 1 "helpfull not found in environment" "" gflags_unittest --fromenv=helpfull) 144 | add_gflags_test(tryfromenv=helpfull 0 "PASS" "" gflags_unittest --tryfromenv=helpfull) 145 | add_gflags_test(tryfromenv=undefok 0 "PASS" "" gflags_unittest --tryfromenv=undefok --foo) 146 | add_gflags_test(tryfromenv=weirdo 1 "unknown command line flag" "" gflags_unittest --tryfromenv=weirdo) 147 | add_gflags_test(tryfromenv-multiple 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --tryfromenv=test_bool,version,unused_bool) 148 | add_gflags_test(fromenv=test_bool 1 "not found in environment" "" gflags_unittest --fromenv=test_bool) 149 | add_gflags_test(fromenv=test_bool-ok 1 "unknown command line flag" "" gflags_unittest --fromenv=test_bool,ok) 150 | # Here, the --version overrides the fromenv 151 | add_gflags_test(version-overrides-fromenv 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --fromenv=test_bool,version,ok) 152 | 153 | # Make sure -- by itself stops argv processing 154 | add_gflags_test(dashdash 0 "PASS" "" gflags_unittest -- --help) 155 | 156 | # And we should die if the flag value doesn't pass the validator 157 | add_gflags_test(always_fail 1 "ERROR: failed validation of new value 'true' for flag 'always_fail'" "" gflags_unittest --always_fail) 158 | 159 | # And if locking in validators fails 160 | # TODO(andreas): Worked on Windows 7 Release configuration, but causes 161 | # debugger abort() intervention in case of Debug configuration. 162 | #add_gflags_test(deadlock_if_cant_lock 0 "PASS" "" gflags_unittest --deadlock_if_cant_lock) 163 | 164 | # ---------------------------------------------------------------------------- 165 | # use gflags_declare.h 166 | add_executable (gflags_declare_test gflags_declare_test.cc gflags_declare_flags.cc) 167 | 168 | add_test(NAME gflags_declare COMMAND gflags_declare_test --message "Hello gflags!") 169 | set_tests_properties(gflags_declare PROPERTIES PASS_REGULAR_EXPRESSION "Hello gflags!") 170 | 171 | # ---------------------------------------------------------------------------- 172 | # configure Python script which configures and builds a test project 173 | if (BUILD_NC_TESTS OR BUILD_CONFIG_TESTS) 174 | find_package (PythonInterp) 175 | if (NOT PYTHON_EXECUTABLE) 176 | message (FATAL_ERROR "No Python installation found! It is required by the (negative) compilation tests." 177 | " Either install Python or set BUILD_NC_TESTS and BUILD_CONFIG_TESTS to FALSE.") 178 | endif () 179 | set (TMPDIR "${PROJECT_BINARY_DIR}/Testing/Temporary") 180 | configure_file (gflags_build.py.in "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/build.py" @ONLY) 181 | function (add_gflags_build_test name srcdir expect_fail) 182 | set (srcdir "${CMAKE_CURRENT_SOURCE_DIR}/${srcdir}") 183 | add_test ( 184 | NAME "${name}" 185 | COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/build.py" 186 | ${name} ${srcdir} ${expect_fail} 187 | ) 188 | endfunction () 189 | endif () 190 | 191 | # ---------------------------------------------------------------------------- 192 | # negative compilation tests 193 | option (BUILD_NC_TESTS "Request addition of negative compilation tests." OFF) 194 | mark_as_advanced (BUILD_NC_TESTS) 195 | if (BUILD_NC_TESTS) 196 | add_gflags_build_test (nc_sanity nc 0) 197 | add_gflags_build_test (nc_swapped_args nc 1) 198 | add_gflags_build_test (nc_int_instead_of_bool nc 1) 199 | add_gflags_build_test (nc_bool_in_quotes nc 1) 200 | add_gflags_build_test (nc_define_string_with_0 nc 1) 201 | endif () 202 | 203 | # ---------------------------------------------------------------------------- 204 | # build configuration test 205 | option (BUILD_CONFIG_TESTS "Request addition of package configuration tests." OFF) 206 | mark_as_advanced (BUILD_CONFIG_TESTS) 207 | if (BUILD_CONFIG_TESTS) 208 | add_gflags_build_test (cmake_config config 0) 209 | endif () 210 | -------------------------------------------------------------------------------- /gflags/test/config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## gflags package configuration tests 2 | 3 | cmake_minimum_required (VERSION 2.8.12 FATAL_ERROR) 4 | 5 | project (gflags_${TEST_NAME}) 6 | 7 | find_package (gflags REQUIRED) 8 | 9 | add_executable (foo main.cc) 10 | target_link_libraries (foo gflags) 11 | -------------------------------------------------------------------------------- /gflags/test/config/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | DEFINE_string(message, "Hello World!", "The message to print"); 5 | 6 | static bool ValidateMessage(const char* flagname, const std::string &message) 7 | { 8 | return !message.empty(); 9 | } 10 | DEFINE_validator(message, ValidateMessage); 11 | 12 | int main(int argc, char **argv) 13 | { 14 | gflags::SetUsageMessage("Test CMake configuration of gflags library (gflags-config.cmake)"); 15 | gflags::SetVersionString("0.1"); 16 | gflags::ParseCommandLineFlags(&argc, &argv, true); 17 | std::cout << FLAGS_message << std::endl; 18 | gflags::ShutDownCommandLineFlags(); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /gflags/test/flagfile.1: -------------------------------------------------------------------------------- 1 | --version -------------------------------------------------------------------------------- /gflags/test/flagfile.2: -------------------------------------------------------------------------------- 1 | --foo=bar 2 | --nounused_bool -------------------------------------------------------------------------------- /gflags/test/flagfile.3: -------------------------------------------------------------------------------- 1 | --flagfile=flagfile.2 -------------------------------------------------------------------------------- /gflags/test/gflags_build.py.in: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import sys 5 | import subprocess 6 | import shutil 7 | 8 | CMAKE = '@CMAKE_COMMAND@' 9 | CMAKE_BUILD_TYPE = '@CMAKE_BUILD_TYPE@' 10 | TMPDIR = '@TMPDIR@' 11 | SRCDIR = '@SRCDIR@' 12 | GFLAGS_DIR = '@gflags_BINARY_DIR@' 13 | 14 | if __name__ == "__main__": 15 | if len(sys.argv) != 4: 16 | sys.stderr.write(' '.join(['usage:', sys.argv[0], ' \n'])) 17 | sys.exit(1) 18 | test_name = sys.argv[1] 19 | srcdir = sys.argv[2] 20 | expect_fail = (sys.argv[3].lower() in ['true', 'yes', 'on', '1']) 21 | bindir = os.path.join(TMPDIR, test_name) 22 | if TMPDIR == '': 23 | sys.stderr.write('Temporary directory not set!\n') 24 | sys.exit(1) 25 | # create build directory 26 | if os.path.isdir(bindir): shutil.rmtree(bindir) 27 | os.makedirs(bindir) 28 | # configure the build tree 29 | if subprocess.call([CMAKE, '-DCMAKE_BUILD_TYPE:STRING='+CMAKE_BUILD_TYPE, 30 | '-Dgflags_DIR:PATH='+GFLAGS_DIR, 31 | '-DTEST_NAME:STRING='+test_name, srcdir], cwd=bindir) != 0: 32 | sys.stderr.write('Failed to configure the build tree!\n') 33 | sys.exit(1) 34 | # build the test project 35 | exit_code = subprocess.call([CMAKE, '--build', bindir, '--config', CMAKE_BUILD_TYPE], cwd=bindir) 36 | if expect_fail == True: 37 | if exit_code == 0: 38 | sys.stderr.write('Build expected to fail, but it succeeded!\n') 39 | sys.exit(1) 40 | else: 41 | sys.stderr.write('Build failed as expected\n') 42 | exit_code = 0 43 | sys.exit(exit_code) 44 | -------------------------------------------------------------------------------- /gflags/test/gflags_declare_flags.cc: -------------------------------------------------------------------------------- 1 | #define GFLAGS_DLL_DECLARE_FLAG 2 | 3 | #include 4 | #include 5 | 6 | DECLARE_string(message); // in gflags_delcare_test.cc 7 | 8 | void print_message(); 9 | void print_message() 10 | { 11 | std::cout << FLAGS_message << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /gflags/test/gflags_declare_test.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | DEFINE_string(message, "", "The message to print"); 4 | void print_message(); // in gflags_declare_flags.cc 5 | 6 | int main(int argc, char **argv) 7 | { 8 | gflags::SetUsageMessage("Test compilation and use of gflags_declare.h"); 9 | gflags::ParseCommandLineFlags(&argc, &argv, true); 10 | print_message(); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /gflags/test/gflags_strip_flags_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // --- 31 | // Author: csilvers@google.com (Craig Silverstein) 32 | // 33 | // A simple program that uses STRIP_FLAG_HELP. We'll have a shell 34 | // script that runs 'strings' over this program and makes sure 35 | // that the help string is not in there. 36 | 37 | #define STRIP_FLAG_HELP 1 38 | #include 39 | 40 | #include 41 | 42 | using GFLAGS_NAMESPACE::SetUsageMessage; 43 | using GFLAGS_NAMESPACE::ParseCommandLineFlags; 44 | 45 | 46 | DEFINE_bool(test, true, "This text should be stripped out"); 47 | 48 | int main(int argc, char** argv) { 49 | SetUsageMessage("Usage message"); 50 | ParseCommandLineFlags(&argc, &argv, false); 51 | 52 | // Unfortunately, for us, libtool can replace executables with a shell 53 | // script that does some work before calling the 'real' executable 54 | // under a different name. We need the 'real' executable name to run 55 | // 'strings' on it, so we construct this binary to print the real 56 | // name (argv[0]) on stdout when run. 57 | puts(argv[0]); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /gflags/test/gflags_strip_flags_test.cmake: -------------------------------------------------------------------------------- 1 | if (NOT BINARY) 2 | message (FATAL_ERROR "BINARY file to check not specified!") 3 | endif () 4 | file (STRINGS "${BINARY}" strings REGEX "This text should be stripped out") 5 | if (strings) 6 | message (FATAL_ERROR "Text not stripped from binary like it should be: ${BINARY}") 7 | endif () 8 | -------------------------------------------------------------------------------- /gflags/test/gflags_unittest_flagfile: -------------------------------------------------------------------------------- 1 | --test_flag=1 2 | --test_flag=2 3 | -------------------------------------------------------------------------------- /gflags/test/nc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## gflags negative compilation tests 2 | 3 | cmake_minimum_required (VERSION 2.8.12 FATAL_ERROR) 4 | 5 | if (NOT TEST_NAME) 6 | message (FATAL_ERROR "Missing TEST_NAME CMake flag") 7 | endif () 8 | string (TOUPPER ${TEST_NAME} TEST_NAME_UPPER) 9 | 10 | project (gflags_${TEST_NAME}) 11 | 12 | find_package (gflags REQUIRED) 13 | include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/..") 14 | add_definitions (-DTEST_${TEST_NAME_UPPER}) 15 | add_executable (gflags_${TEST_NAME} gflags_nc.cc) 16 | target_link_libraries(gflags_${TEST_NAME} gflags) 17 | -------------------------------------------------------------------------------- /gflags/test/nc/gflags_nc.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // --- 31 | // 32 | // A negative comiple test for gflags. 33 | 34 | #include 35 | 36 | #if defined(TEST_NC_SWAPPED_ARGS) 37 | 38 | DEFINE_bool(some_bool_flag, 39 | "the default value should go here, not the description", 40 | false); 41 | 42 | 43 | #elif defined(TEST_NC_INT_INSTEAD_OF_BOOL) 44 | 45 | DEFINE_bool(some_bool_flag_2, 46 | 0, 47 | "should have been an int32 flag but mistakenly used bool instead"); 48 | 49 | #elif defined(TEST_NC_BOOL_IN_QUOTES) 50 | 51 | 52 | DEFINE_bool(some_bool_flag_3, 53 | "false", 54 | "false in in quotes, which is wrong"); 55 | 56 | #elif defined(TEST_NC_SANITY) 57 | 58 | DEFINE_bool(some_bool_flag_4, 59 | true, 60 | "this is the correct usage of DEFINE_bool"); 61 | 62 | #elif defined(TEST_NC_DEFINE_STRING_WITH_0) 63 | 64 | DEFINE_string(some_string_flag, 65 | 0, 66 | "Trying to construct a string by passing 0 would cause a crash."); 67 | 68 | #endif 69 | 70 | int main(int, char **) 71 | { 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /include/cnn.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | 17 | /** 18 | * @brief Base class of config for network 19 | */ 20 | struct CnnConfig { 21 | explicit CnnConfig(const std::string& path_to_model) 22 | : path_to_model(path_to_model) {} 23 | 24 | /** @brief Path to model description */ 25 | std::string path_to_model; 26 | /** @brief Maximal size of batch */ 27 | int max_batch_size{1}; 28 | }; 29 | 30 | /** 31 | * @brief Base class of network 32 | */ 33 | class CnnBase { 34 | public: 35 | using Config = CnnConfig; 36 | 37 | /** 38 | * @brief Constructor 39 | */ 40 | CnnBase(const Config& config, 41 | const InferenceEngine::Core & ie, 42 | const std::string & deviceName); 43 | 44 | /** 45 | * @brief Descructor 46 | */ 47 | virtual ~CnnBase() {} 48 | 49 | /** 50 | * @brief Loads network 51 | */ 52 | void Load(); 53 | 54 | /** 55 | * @brief Prints performance report 56 | */ 57 | void PrintPerformanceCounts(std::string fullDeviceName) const; 58 | 59 | protected: 60 | /** 61 | * @brief Run network 62 | * 63 | * @param frame Input image 64 | * @param results_fetcher Callback to fetch inference results 65 | */ 66 | void Infer(const cv::Mat& frame, 67 | const std::function& results_fetcher) const; 68 | 69 | /** 70 | * @brief Run network in batch mode 71 | * 72 | * @param frames Vector of input images 73 | * @param results_fetcher Callback to fetch inference results 74 | */ 75 | void InferBatch(const std::vector& frames, 76 | const std::function& results_fetcher) const; 77 | 78 | /** @brief Config */ 79 | Config config_; 80 | /** @brief Inference Engine instance */ 81 | InferenceEngine::Core ie_; 82 | /** @brief Inference Engine device */ 83 | std::string deviceName_; 84 | /** @brief Net outputs info */ 85 | InferenceEngine::OutputsDataMap outInfo_; 86 | /** @brief IE network */ 87 | InferenceEngine::ExecutableNetwork executable_network_; 88 | /** @brief IE InferRequest */ 89 | mutable InferenceEngine::InferRequest infer_request_; 90 | /** @brief Pointer to the pre-allocated input blob */ 91 | mutable InferenceEngine::Blob::Ptr input_blob_; 92 | /** @brief Map of output blobs */ 93 | InferenceEngine::BlobMap outputs_; 94 | }; 95 | 96 | class VectorCNN : public CnnBase { 97 | public: 98 | VectorCNN(const CnnConfig& config, 99 | const InferenceEngine::Core & ie, 100 | const std::string & deviceName); 101 | 102 | void Compute(const cv::Mat& image, 103 | cv::Mat* vector, cv::Size outp_shape = cv::Size()) const; 104 | void Compute(const std::vector& images, 105 | std::vector* vectors, cv::Size outp_shape = cv::Size()) const; 106 | 107 | int size() const { return result_size_; } 108 | 109 | private: 110 | int result_size_; ///< Length of result 111 | }; 112 | 113 | -------------------------------------------------------------------------------- /include/core.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | /// 15 | /// \brief The TrackedObject struct defines properties of detected object. 16 | /// 17 | struct TrackedObject { 18 | cv::Rect rect; ///< Detected object ROI (zero area if N/A). 19 | double confidence; ///< Detection confidence level (-1 if N/A). 20 | int frame_idx; ///< Frame index where object was detected (-1 if N/A). 21 | int object_id; ///< Unique object identifier (-1 if N/A). 22 | uint64_t timestamp; ///< Timestamp in milliseconds. 23 | 24 | /// 25 | /// \brief Default constructor. 26 | /// 27 | TrackedObject() 28 | : confidence(-1), 29 | frame_idx(-1), 30 | object_id(-1), 31 | timestamp(0) {} 32 | 33 | /// 34 | /// \brief Constructor with parameters. 35 | /// \param rect Bounding box of detected object. 36 | /// \param confidence Confidence of detection. 37 | /// \param frame_idx Index of frame. 38 | /// \param object_id Object ID. 39 | /// 40 | TrackedObject(const cv::Rect &rect, float confidence, int frame_idx, 41 | int object_id) 42 | : rect(rect), 43 | confidence(confidence), 44 | frame_idx(frame_idx), 45 | object_id(object_id), 46 | timestamp(0) {} 47 | }; 48 | 49 | using TrackedObjects = std::deque; 50 | 51 | /// (object id, detected objects) pairs collection. 52 | using ObjectTracks = std::unordered_map; 53 | 54 | -------------------------------------------------------------------------------- /include/descriptor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "opencv2/core/core.hpp" 14 | #include "opencv2/imgproc.hpp" 15 | 16 | 17 | #include "core.hpp" 18 | #include "cnn.hpp" 19 | 20 | /// 21 | /// \brief The IImageDescriptor class declares base class for image 22 | /// descriptor. 23 | /// 24 | class IImageDescriptor { 25 | public: 26 | /// 27 | /// \brief Descriptor size getter. 28 | /// \return Descriptor size. 29 | /// 30 | virtual cv::Size size() const = 0; 31 | 32 | /// 33 | /// \brief Computes image descriptor. 34 | /// \param[in] mat Color image. 35 | /// \param[out] descr Computed descriptor. 36 | /// 37 | virtual void Compute(const cv::Mat &mat, cv::Mat *descr) = 0; 38 | 39 | /// 40 | /// \brief Computes image descriptors in batches. 41 | /// \param[in] mats Images of interest. 42 | /// \param[out] descrs Matrices to store the computed descriptors. 43 | /// 44 | virtual void Compute(const std::vector &mats, 45 | std::vector *descrs) = 0; 46 | 47 | /// 48 | /// \brief Prints performance counts for CNN-based descriptors 49 | /// 50 | virtual void PrintPerformanceCounts(std::string fullDeviceName) const {} 51 | 52 | virtual ~IImageDescriptor() {} 53 | }; 54 | 55 | 56 | /// 57 | /// \brief Uses resized image as descriptor. 58 | /// 59 | class ResizedImageDescriptor : public IImageDescriptor { 60 | public: 61 | /// 62 | /// \brief Constructor. 63 | /// \param[in] descr_size Size of the descriptor (resized image). 64 | /// \param[in] interpolation Interpolation algorithm. 65 | /// 66 | explicit ResizedImageDescriptor(const cv::Size &descr_size, 67 | const cv::InterpolationFlags interpolation) 68 | : descr_size_(descr_size), interpolation_(interpolation) { 69 | PT_CHECK_GT(descr_size.width, 0); 70 | PT_CHECK_GT(descr_size.height, 0); 71 | } 72 | 73 | /// 74 | /// \brief Returns descriptor size. 75 | /// \return Number of elements in the descriptor. 76 | /// 77 | cv::Size size() const override { return descr_size_; } 78 | 79 | /// 80 | /// \brief Computes image descriptor. 81 | /// \param[in] mat Frame containing the image of interest. 82 | /// \param[out] descr Matrix to store the computed descriptor. 83 | /// 84 | void Compute(const cv::Mat &mat, cv::Mat *descr) override { 85 | PT_CHECK(descr != nullptr); 86 | PT_CHECK(!mat.empty()); 87 | cv::resize(mat, *descr, descr_size_, 0, 0, interpolation_); 88 | } 89 | 90 | /// 91 | /// \brief Computes images descriptors. 92 | /// \param[in] mats Frames containing images of interest. 93 | /// \param[out] descrs Matrices to store the computed descriptors. 94 | // 95 | void Compute(const std::vector &mats, 96 | std::vector *descrs) override { 97 | PT_CHECK(descrs != nullptr); 98 | descrs->resize(mats.size()); 99 | for (size_t i = 0; i < mats.size(); i++) { 100 | Compute(mats[i], &(descrs[i])); 101 | } 102 | } 103 | 104 | private: 105 | cv::Size descr_size_; 106 | 107 | cv::InterpolationFlags interpolation_; 108 | }; 109 | 110 | 111 | class DescriptorIE : public IImageDescriptor { 112 | private: 113 | VectorCNN handler; 114 | 115 | public: 116 | DescriptorIE(const CnnConfig& config, 117 | const InferenceEngine::Core& ie, 118 | const std::string & deviceName): 119 | handler(config, ie, deviceName) {} 120 | 121 | /// 122 | /// \brief Descriptor size getter. 123 | /// \return Descriptor size. 124 | /// 125 | virtual cv::Size size() const { 126 | return cv::Size(1, handler.size()); 127 | } 128 | 129 | /// 130 | /// \brief Computes image descriptor. 131 | /// \param[in] mat Color image. 132 | /// \param[out] descr Computed descriptor. 133 | /// 134 | virtual void Compute(const cv::Mat &mat, cv::Mat *descr) { 135 | handler.Compute(mat, descr); 136 | } 137 | 138 | /// 139 | /// \brief Computes image descriptors in batches. 140 | /// \param[in] mats Images of interest. 141 | /// \param[out] descrs Matrices to store the computed descriptors. 142 | /// 143 | virtual void Compute(const std::vector &mats, 144 | std::vector *descrs) { 145 | handler.Compute(mats, descrs); 146 | } 147 | 148 | virtual void PrintPerformanceCounts(std::string fullDeviceName) const { 149 | handler.PrintPerformanceCounts(fullDeviceName); 150 | } 151 | }; 152 | 153 | -------------------------------------------------------------------------------- /include/detector.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "core.hpp" 14 | #include "cnn.hpp" 15 | 16 | 17 | struct DetectorConfig : public CnnConfig { 18 | explicit DetectorConfig(const std::string& path_to_model) 19 | : CnnConfig(path_to_model) {} 20 | 21 | float confidence_threshold{0.5f}; 22 | float increase_scale_x{1.f}; 23 | float increase_scale_y{1.f}; 24 | bool is_async = false; 25 | }; 26 | 27 | class ObjectDetector { 28 | private: 29 | InferenceEngine::InferRequest::Ptr request; 30 | DetectorConfig config_; 31 | InferenceEngine::Core ie_; 32 | std::string deviceName_; 33 | 34 | InferenceEngine::ExecutableNetwork net_; 35 | std::string input_name_; 36 | std::string im_info_name_; 37 | std::string output_name_; 38 | int max_detections_count_; 39 | int object_size_; 40 | int enqueued_frames_ = 0; 41 | float width_ = 0; 42 | float height_ = 0; 43 | bool results_fetched_ = false; 44 | int frame_idx_ = -1; 45 | 46 | TrackedObjects results_; 47 | 48 | void enqueue(const cv::Mat &frame); 49 | void submitRequest(); 50 | void wait(); 51 | void fetchResults(); 52 | 53 | public: 54 | ObjectDetector(const DetectorConfig& config, 55 | const InferenceEngine::Core& ie, 56 | const std::string & deviceName); 57 | 58 | void submitFrame(const cv::Mat &frame, int frame_idx); 59 | void waitAndFetchResults(); 60 | 61 | const TrackedObjects& getResults() const; 62 | 63 | void PrintPerformanceCounts(std::string fullDeviceName); 64 | }; 65 | -------------------------------------------------------------------------------- /include/distance.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | 14 | #include 15 | #include 16 | 17 | 18 | 19 | /// 20 | /// \brief The IDescriptorDistance class declares an interface for distance 21 | /// computation between reidentification descriptors. 22 | /// 23 | class IDescriptorDistance { 24 | public: 25 | /// 26 | /// \brief Computes distance between two descriptors. 27 | /// \param[in] descr1 First descriptor. 28 | /// \param[in] descr2 Second descriptor. 29 | /// \return Distance between two descriptors. 30 | /// 31 | virtual float Compute(const cv::Mat &descr1, const cv::Mat &descr2) = 0; 32 | 33 | /// 34 | /// \brief Computes distances between two descriptors in batches. 35 | /// \param[in] descrs1 Batch of first descriptors. 36 | /// \param[in] descrs2 Batch of second descriptors. 37 | /// \return Distances between descriptors. 38 | /// 39 | virtual std::vector Compute(const std::vector &descrs1, 40 | const std::vector &descrs2) = 0; 41 | 42 | virtual ~IDescriptorDistance() {} 43 | }; 44 | 45 | /// 46 | /// \brief The CosDistance class allows computing cosine distance between two 47 | /// reidentification descriptors. 48 | /// 49 | class CosDistance : public IDescriptorDistance { 50 | public: 51 | /// 52 | /// \brief CosDistance constructor. 53 | /// \param[in] descriptor_size Descriptor size. 54 | /// 55 | explicit CosDistance(const cv::Size &descriptor_size); 56 | 57 | /// 58 | /// \brief Computes distance between two descriptors. 59 | /// \param descr1 First descriptor. 60 | /// \param descr2 Second descriptor. 61 | /// \return Distance between two descriptors. 62 | /// 63 | float Compute(const cv::Mat &descr1, const cv::Mat &descr2) override; 64 | 65 | /// 66 | /// \brief Computes distances between two descriptors in batches. 67 | /// \param[in] descrs1 Batch of first descriptors. 68 | /// \param[in] descrs2 Batch of second descriptors. 69 | /// \return Distances between descriptors. 70 | /// 71 | std::vector Compute( 72 | const std::vector &descrs1, 73 | const std::vector &descrs2) override; 74 | 75 | private: 76 | cv::Size descriptor_size_; 77 | }; 78 | 79 | 80 | 81 | /// 82 | /// \brief Computes distance between images 83 | /// using MatchTemplate function from OpenCV library 84 | /// and its cross-correlation computation method in particular. 85 | /// 86 | class MatchTemplateDistance : public IDescriptorDistance { 87 | public: 88 | /// 89 | /// \brief Constructs the distance object. 90 | /// 91 | /// \param[in] type Method of MatchTemplate function computation. 92 | /// \param[in] scale Scale parameter for the distance. 93 | /// Final distance is computed as: 94 | /// scale * distance + offset. 95 | /// \param[in] offset Offset parameter for the distance. 96 | /// Final distance is computed as: 97 | /// scale * distance + offset. 98 | /// 99 | MatchTemplateDistance(int type = cv::TemplateMatchModes::TM_CCORR_NORMED, 100 | float scale = -1, float offset = 1) 101 | : type_(type), scale_(scale), offset_(offset) {} 102 | /// 103 | /// \brief Computes distance between image descriptors. 104 | /// \param[in] descr1 First image descriptor. 105 | /// \param[in] descr2 Second image descriptor. 106 | /// \return Distance between image descriptors. 107 | /// 108 | float Compute(const cv::Mat &descr1, const cv::Mat &descr2) override; 109 | /// 110 | /// \brief Computes distances between two descriptors in batches. 111 | /// \param[in] descrs1 Batch of first descriptors. 112 | /// \param[in] descrs2 Batch of second descriptors. 113 | /// \return Distances between descriptors. 114 | /// 115 | std::vector Compute(const std::vector &descrs1, 116 | const std::vector &descrs2) override; 117 | virtual ~MatchTemplateDistance() {} 118 | 119 | private: 120 | int type_; ///< Method of MatchTemplate function computation. 121 | float scale_; ///< Scale parameter for the distance. Final distance is 122 | /// computed as: scale * distance + offset. 123 | float offset_; ///< Offset parameter for the distance. Final distance is 124 | /// computed as: scale * distance + offset. 125 | }; 126 | 127 | -------------------------------------------------------------------------------- /include/kuhn_munkres.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #include "core.hpp" 8 | 9 | #include 10 | #include 11 | 12 | 13 | /// 14 | /// \brief The KuhnMunkres class 15 | /// 16 | /// Solves the assignment problem. 17 | /// 18 | class KuhnMunkres { 19 | public: 20 | KuhnMunkres(); 21 | 22 | /// 23 | /// \brief Solves the assignment problem for given dissimilarity matrix. 24 | /// It returns a vector that where each element is a column index for 25 | /// corresponding row (e.g. result[0] stores optimal column index for very 26 | /// first row in the dissimilarity matrix). 27 | /// \param dissimilarity_matrix CV_32F dissimilarity matrix. 28 | /// \return Optimal column index for each row. -1 means that there is no 29 | /// column for row. 30 | /// 31 | std::vector Solve(const cv::Mat &dissimilarity_matrix); 32 | 33 | private: 34 | static constexpr int kStar = 1; 35 | static constexpr int kPrime = 2; 36 | 37 | cv::Mat dm_; 38 | cv::Mat marked_; 39 | std::vector points_; 40 | 41 | std::vector is_row_visited_; 42 | std::vector is_col_visited_; 43 | 44 | int n_; 45 | 46 | void TrySimpleCase(); 47 | bool CheckIfOptimumIsFound(); 48 | cv::Point FindUncoveredMinValPos(); 49 | void UpdateDissimilarityMatrix(float val); 50 | int FindInRow(int row, int what); 51 | int FindInCol(int col, int what); 52 | void Run(); 53 | }; 54 | 55 | -------------------------------------------------------------------------------- /include/logging.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #include
8 | 9 | #define PT_CHECK(cond) IE_ASSERT(cond) << " " 10 | 11 | #define PT_CHECK_BINARY(actual, expected, op) \ 12 | IE_ASSERT(actual op expected) << ". " \ 13 | << actual << " vs " << expected << ". " 14 | 15 | #define PT_CHECK_EQ(actual, expected) PT_CHECK_BINARY(actual, expected, ==) 16 | #define PT_CHECK_NE(actual, expected) PT_CHECK_BINARY(actual, expected, !=) 17 | #define PT_CHECK_LT(actual, expected) PT_CHECK_BINARY(actual, expected, <) 18 | #define PT_CHECK_GT(actual, expected) PT_CHECK_BINARY(actual, expected, >) 19 | #define PT_CHECK_LE(actual, expected) PT_CHECK_BINARY(actual, expected, <=) 20 | #define PT_CHECK_GE(actual, expected) PT_CHECK_BINARY(actual, expected, >=) 21 | 22 | -------------------------------------------------------------------------------- /include/pedestrian_tracker_demo.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | /////////////////////////////////////////////////////////////////////////////////////////////////// 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | static const char help_message[] = "Print a usage message."; 13 | static const char video_message[] = "Required. Video sequence to process."; 14 | static const char pedestrian_detection_model_message[] = "Required. Path to the Pedestrian Detection Retail model (.xml) file."; 15 | static const char pedestrian_reid_model_message[] = "Required. Path to the Pedestrian Reidentification Retail model (.xml) file."; 16 | static const char target_device_detection_message[] = "Optional. Specify the target device for pedestrian detection " 17 | "(the list of available devices is shown below). Default value is CPU. " 18 | "Use \"-d HETERO:\" format to specify HETERO plugin."; 19 | static const char target_device_reid_message[] = "Optional. Specify the target device for pedestrian reidentification " 20 | "(the list of available devices is shown below). Default value is CPU. " 21 | "Use \"-d HETERO:\" format to specify HETERO plugin."; 22 | static const char performance_counter_message[] = "Optional. Enable per-layer performance statistics."; 23 | static const char custom_cldnn_message[] = "Optional. For GPU custom kernels, if any. " 24 | "Absolute path to the .xml file with the kernels description."; 25 | static const char custom_cpu_library_message[] = "Optional. For CPU custom layers, if any. " 26 | "Absolute path to a shared library with the kernels implementation."; 27 | static const char raw_output_message[] = "Optional. Output pedestrian tracking results in a raw format " 28 | "(compatible with MOTChallenge format)."; 29 | static const char no_show_processed_video[] = "Optional. Do not show processed video."; 30 | static const char delay_message[] = "Optional. Delay between frames used for visualization. " 31 | "If negative, the visualization is turned off (like with the option 'no_show'). " 32 | "If zero, the visualization is made frame-by-frame."; 33 | static const char output_log_message[] = "Optional. The file name to write output log file with results of pedestrian tracking. " 34 | "The format of the log file is compatible with MOTChallenge format."; 35 | static const char first_frame_message[] = "Optional. The index of the first frame of video sequence to process. " 36 | "This has effect only if it is positive. The actual first frame captured " 37 | "depends on cv::VideoCapture implementation and may have slightly different " 38 | "number."; 39 | static const char last_frame_message[] = "Optional. The index of the last frame of video sequence to process. " 40 | "This has effect only if it is positive."; 41 | 42 | /// @brief Message list of monitors to show 43 | static const char utilization_monitors_message[] = "Optional. List of monitors to show initially."; 44 | 45 | 46 | DEFINE_bool(h, false, help_message); 47 | DEFINE_string(i, "", video_message); 48 | DEFINE_string(m_det, "", pedestrian_detection_model_message); 49 | DEFINE_string(m_reid, "", pedestrian_reid_model_message); 50 | DEFINE_string(d_det, "CPU", target_device_detection_message); 51 | DEFINE_string(d_reid, "CPU", target_device_reid_message); 52 | DEFINE_bool(pc, false, performance_counter_message); 53 | DEFINE_string(c, "", custom_cldnn_message); 54 | DEFINE_string(l, "", custom_cpu_library_message); 55 | DEFINE_bool(r, false, raw_output_message); 56 | DEFINE_bool(no_show, false, no_show_processed_video); 57 | DEFINE_int32(delay, 3, delay_message); 58 | DEFINE_string(out, "", output_log_message); 59 | DEFINE_int32(first, -1, first_frame_message); 60 | DEFINE_int32(last, -1, last_frame_message); 61 | 62 | /// \brief Define a flag to show monitors
63 | /// It is an optional parameter 64 | DEFINE_string(u, "", utilization_monitors_message); 65 | 66 | 67 | /** 68 | * @brief This function show a help message 69 | */ 70 | static void showUsage() { 71 | std::cout << std::endl; 72 | std::cout << "pedestrian_tracker_demo [OPTION]" << std::endl; 73 | std::cout << "Options:" << std::endl; 74 | std::cout << std::endl; 75 | std::cout << " -h " << help_message << std::endl; 76 | std::cout << " -i \"\" " << video_message << std::endl; 77 | std::cout << " -m_det \"\" " << pedestrian_detection_model_message << std::endl; 78 | std::cout << " -m_reid \"\" " << pedestrian_reid_model_message << std::endl; 79 | std::cout << " -l \"\" " << custom_cpu_library_message << std::endl; 80 | std::cout << " Or" << std::endl; 81 | std::cout << " -c \"\" " << custom_cldnn_message << std::endl; 82 | std::cout << " -d_det \"\" " << target_device_detection_message << std::endl; 83 | std::cout << " -d_reid \"\" " << target_device_reid_message << std::endl; 84 | std::cout << " -r " << raw_output_message << std::endl; 85 | std::cout << " -pc " << performance_counter_message << std::endl; 86 | std::cout << " -no_show " << no_show_processed_video << std::endl; 87 | std::cout << " -delay " << delay_message << std::endl; 88 | std::cout << " -out \"\" " << output_log_message << std::endl; 89 | std::cout << " -first " << first_frame_message << std::endl; 90 | std::cout << " -last " << last_frame_message << std::endl; 91 | std::cout << " -u " << utilization_monitors_message << std::endl; 92 | } 93 | -------------------------------------------------------------------------------- /include/utils.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #pragma once 6 | 7 | #include "core.hpp" 8 | #include "logging.hpp" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | /// 21 | /// \brief The DetectionLogEntry struct 22 | /// 23 | /// An entry describing detected objects on a frame. 24 | /// 25 | struct DetectionLogEntry { 26 | TrackedObjects objects; ///< Detected objects. 27 | int frame_idx; ///< Processed frame index (-1 if N/A). 28 | double time_ms; ///< Frame processing time in ms (-1 if N/A). 29 | 30 | /// 31 | /// \brief DetectionLogEntry default constructor. 32 | /// 33 | DetectionLogEntry() : frame_idx(-1), time_ms(-1) {} 34 | 35 | /// 36 | /// \brief DetectionLogEntry copy constructor. 37 | /// \param other Detection entry. 38 | /// 39 | DetectionLogEntry(const DetectionLogEntry &other) 40 | : objects(other.objects), 41 | frame_idx(other.frame_idx), 42 | time_ms(other.time_ms) {} 43 | 44 | /// 45 | /// \brief DetectionLogEntry move constructor. 46 | /// \param other Detection entry. 47 | /// 48 | DetectionLogEntry(DetectionLogEntry &&other) 49 | : objects(std::move(other.objects)), 50 | frame_idx(other.frame_idx), 51 | time_ms(other.time_ms) {} 52 | 53 | /// 54 | /// \brief Assignment operator. 55 | /// \param other Detection entry. 56 | /// \return Detection entry. 57 | /// 58 | DetectionLogEntry &operator=(const DetectionLogEntry &other) = default; 59 | 60 | /// 61 | /// \brief Move assignment operator. 62 | /// \param other Detection entry. 63 | /// \return Detection entry. 64 | /// 65 | DetectionLogEntry &operator=(DetectionLogEntry &&other) { 66 | if (this != &other) { 67 | objects = std::move(other.objects); 68 | frame_idx = other.frame_idx; 69 | time_ms = other.time_ms; 70 | } 71 | return *this; 72 | } 73 | }; 74 | 75 | /// Detection log is a vector of detection entries. 76 | using DetectionLog = std::vector; 77 | 78 | /// 79 | /// \brief Save DetectionLog to a txt file in the format 80 | /// compatible with the format of MOTChallenge 81 | /// evaluation tool. 82 | /// \param[in] path -- path to a file to store 83 | /// \param[in] log -- detection log to store 84 | /// 85 | void SaveDetectionLogToTrajFile(const std::string& path, 86 | const DetectionLog& log); 87 | 88 | /// 89 | /// \brief Print DetectionLog to stdout in the format 90 | /// compatible with the format of MOTChallenge 91 | /// evaluation tool. 92 | /// \param[in] log -- detection log to print 93 | /// 94 | void PrintDetectionLog(const DetectionLog& log); 95 | 96 | /// 97 | /// \brief Draws a polyline on a frame. 98 | /// \param[in] polyline Vector of points (polyline). 99 | /// \param[in] color Color (BGR). 100 | /// \param[in,out] image Frame. 101 | /// \param[in] lwd Line width. 102 | /// 103 | void DrawPolyline(const std::vector& polyline, 104 | const cv::Scalar& color, cv::Mat* image, 105 | int lwd = 5); 106 | 107 | /// 108 | /// \brief Stream output operator for deque of elements. 109 | /// \param[in,out] os Output stream. 110 | /// \param[in] v Vector of elements. 111 | /// 112 | template 113 | std::ostream &operator<<(std::ostream &os, const std::deque &v) { 114 | os << "[\n"; 115 | if (!v.empty()) { 116 | auto itr = v.begin(); 117 | os << *itr; 118 | for (++itr; itr != v.end(); ++itr) os << ",\n" << *itr; 119 | } 120 | os << "\n]"; 121 | return os; 122 | } 123 | 124 | /// 125 | /// \brief Stream output operator for vector of elements. 126 | /// \param[in,out] os Output stream. 127 | /// \param[in] v Vector of elements. 128 | /// 129 | template 130 | std::ostream &operator<<(std::ostream &os, const std::vector &v) { 131 | os << "[\n"; 132 | if (!v.empty()) { 133 | auto itr = v.begin(); 134 | os << *itr; 135 | for (++itr; itr != v.end(); ++itr) os << ",\n" << *itr; 136 | } 137 | os << "\n]"; 138 | return os; 139 | } 140 | 141 | InferenceEngine::Core 142 | LoadInferenceEngine(const std::vector& devices, 143 | const std::string& custom_cpu_library, 144 | const std::string& custom_cldnn_kernels, 145 | bool should_use_perf_counter); 146 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #include "core.hpp" 6 | #include "utils.hpp" 7 | #include "tracker.hpp" 8 | #include "descriptor.hpp" 9 | #include "distance.hpp" 10 | #include "detector.hpp" 11 | #include "pedestrian_tracker_demo.hpp" 12 | 13 | #include 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | using namespace InferenceEngine; 26 | using ImageWithFrameIndex = std::pair; 27 | 28 | std::unique_ptr 29 | CreatePedestrianTracker(const std::string& reid_model, 30 | const InferenceEngine::Core & ie, 31 | const std::string & deviceName, 32 | bool should_keep_tracking_info) { 33 | TrackerParams params; 34 | 35 | if (should_keep_tracking_info) { 36 | params.drop_forgotten_tracks = false; 37 | params.max_num_objects_in_track = -1; 38 | } 39 | 40 | std::unique_ptr tracker(new PedestrianTracker(params)); 41 | 42 | // Load reid-model. 43 | std::shared_ptr descriptor_fast = 44 | std::make_shared( 45 | cv::Size(16, 32), cv::InterpolationFlags::INTER_LINEAR); 46 | std::shared_ptr distance_fast = 47 | std::make_shared(); 48 | 49 | tracker->set_descriptor_fast(descriptor_fast); 50 | tracker->set_distance_fast(distance_fast); 51 | 52 | if (!reid_model.empty()) { 53 | CnnConfig reid_config(reid_model); 54 | reid_config.max_batch_size = 16; // defaulting to 16 55 | 56 | std::shared_ptr descriptor_strong = 57 | std::make_shared(reid_config, ie, deviceName); 58 | 59 | if (descriptor_strong == nullptr) { 60 | THROW_IE_EXCEPTION << "[SAMPLES] internal error - invalid descriptor"; 61 | } 62 | std::shared_ptr distance_strong = 63 | std::make_shared(descriptor_strong->size()); 64 | 65 | tracker->set_descriptor_strong(descriptor_strong); 66 | tracker->set_distance_strong(distance_strong); 67 | } else { 68 | std::cout << "WARNING: Reid model " 69 | << "was not specified. " 70 | << "Only fast reidentification approach will be used." << std::endl; 71 | } 72 | 73 | return tracker; 74 | } 75 | 76 | bool ParseAndCheckCommandLine(int argc, char *argv[]) { 77 | // ---------------------------Parsing and validation of input args-------------------------------------- 78 | 79 | gflags::ParseCommandLineNonHelpFlags(&argc, &argv, true); 80 | if (FLAGS_h) { 81 | showUsage(); 82 | showAvailableDevices(); 83 | return false; 84 | } 85 | 86 | if (FLAGS_i.empty()) { 87 | throw std::logic_error("Parameter -i is not set"); 88 | } 89 | 90 | if (FLAGS_m_det.empty()) { 91 | throw std::logic_error("Parameter -m_det is not set"); 92 | } 93 | 94 | if (FLAGS_m_reid.empty()) { 95 | throw std::logic_error("Parameter -m_reid is not set"); 96 | } 97 | 98 | return true; 99 | } 100 | 101 | int main_work(int argc, char **argv) { 102 | std::cout << "InferenceEngine: " << GetInferenceEngineVersion() << std::endl; 103 | 104 | if (!ParseAndCheckCommandLine(argc, argv)) { 105 | return 0; 106 | } 107 | 108 | 109 | // Reading command line parameters. 110 | auto det_model = FLAGS_m_det; 111 | auto reid_model = FLAGS_m_reid; 112 | 113 | auto detlog_out = FLAGS_out; 114 | 115 | auto detector_mode = FLAGS_d_det; 116 | auto reid_mode = FLAGS_d_reid; 117 | 118 | auto custom_cpu_library = FLAGS_l; 119 | auto path_to_custom_layers = FLAGS_c; 120 | bool should_use_perf_counter = FLAGS_pc; 121 | 122 | bool should_print_out = FLAGS_r; 123 | 124 | bool should_show = !FLAGS_no_show; 125 | int delay = FLAGS_delay; 126 | if (!should_show) 127 | delay = -1; 128 | should_show = (delay >= 0); 129 | 130 | bool should_save_det_log = !detlog_out.empty(); 131 | 132 | if ((FLAGS_last >= 0) && (FLAGS_first > FLAGS_last)) { 133 | throw std::runtime_error("The first frame index (" + std::to_string(FLAGS_first) + ") must be greater than the " 134 | "last frame index (" + std::to_string(FLAGS_last) + ')'); 135 | } 136 | 137 | std::vector devices{detector_mode, reid_mode}; 138 | InferenceEngine::Core ie = 139 | LoadInferenceEngine( 140 | devices, custom_cpu_library, path_to_custom_layers, 141 | should_use_perf_counter); 142 | 143 | DetectorConfig detector_confid(det_model); 144 | ObjectDetector pedestrian_detector(detector_confid, ie, detector_mode); 145 | 146 | bool should_keep_tracking_info = should_save_det_log || should_print_out; 147 | std::unique_ptr tracker = 148 | CreatePedestrianTracker(reid_model, ie, reid_mode, 149 | should_keep_tracking_info); 150 | 151 | cv::VideoCapture cap; 152 | try { 153 | int intInput = std::stoi(FLAGS_i); 154 | if (!cap.open(intInput)) { 155 | throw std::runtime_error("Can't open " + std::to_string(intInput)); 156 | } 157 | } catch (const std::invalid_argument&) { 158 | if (!cap.open(FLAGS_i)) { 159 | throw std::runtime_error("Can't open " + FLAGS_i); 160 | } 161 | } catch (const std::out_of_range&) { 162 | if (!cap.open(FLAGS_i)) { 163 | throw std::runtime_error("Can't open " + FLAGS_i); 164 | } 165 | } 166 | double video_fps = cap.get(cv::CAP_PROP_FPS); 167 | if (0.0 == video_fps) { 168 | // the default frame rate for DukeMTMC dataset 169 | video_fps = 60.0; 170 | } 171 | if (0 >= FLAGS_first && !cap.set(cv::CAP_PROP_POS_FRAMES, FLAGS_first)) { 172 | throw std::runtime_error("Can't set the frame to begin with"); 173 | } 174 | 175 | std::cout << "To close the application, press 'CTRL+C' here"; 176 | if (!FLAGS_no_show) { 177 | std::cout << " or switch to the output window and press ESC key"; 178 | } 179 | std::cout << std::endl; 180 | 181 | cv::Size graphSize{static_cast(cap.get(cv::CAP_PROP_FRAME_WIDTH) / 4), 60}; 182 | Presenter presenter(FLAGS_u, 10, graphSize); 183 | 184 | for (int32_t frame_idx = std::max(0, FLAGS_first); 0 > FLAGS_last || frame_idx <= FLAGS_last; ++frame_idx) { 185 | cv::Mat frame; 186 | if (!cap.read(frame)) { 187 | break; 188 | } 189 | 190 | pedestrian_detector.submitFrame(frame, frame_idx); 191 | pedestrian_detector.waitAndFetchResults(); 192 | 193 | TrackedObjects detections = pedestrian_detector.getResults(); 194 | 195 | // timestamp in milliseconds 196 | uint64_t cur_timestamp = static_cast(1000.0 / video_fps * frame_idx); 197 | tracker->Process(frame, detections, cur_timestamp); 198 | 199 | presenter.drawGraphs(frame); 200 | 201 | if (should_show) { 202 | // Drawing colored "worms" (tracks). 203 | frame = tracker->DrawActiveTracks(frame); 204 | 205 | // Drawing all detected objects on a frame by BLUE COLOR 206 | for (const auto &detection : detections) { 207 | cv::rectangle(frame, detection.rect, cv::Scalar(255, 0, 0), 3); 208 | } 209 | 210 | // Drawing tracked detections only by RED color and print ID and detection 211 | // confidence level. 212 | for (const auto &detection : tracker->TrackedDetections()) { 213 | cv::rectangle(frame, detection.rect, cv::Scalar(0, 0, 255), 3); 214 | std::string text = std::to_string(detection.object_id) + 215 | " conf: " + std::to_string(detection.confidence); 216 | cv::putText(frame, text, detection.rect.tl(), cv::FONT_HERSHEY_COMPLEX, 217 | 1.0, cv::Scalar(0, 0, 255), 3); 218 | } 219 | 220 | cv::resize(frame, frame, cv::Size(), 0.5, 0.5); 221 | cv::imshow("dbg", frame); 222 | char k = cv::waitKey(delay); 223 | if (k == 27) 224 | break; 225 | presenter.handleKey(k); 226 | } 227 | 228 | if (should_save_det_log && (frame_idx % 100 == 0)) { 229 | DetectionLog log = tracker->GetDetectionLog(true); 230 | SaveDetectionLogToTrajFile(detlog_out, log); 231 | } 232 | } 233 | 234 | if (should_keep_tracking_info) { 235 | DetectionLog log = tracker->GetDetectionLog(true); 236 | 237 | if (should_save_det_log) 238 | SaveDetectionLogToTrajFile(detlog_out, log); 239 | if (should_print_out) 240 | PrintDetectionLog(log); 241 | } 242 | if (should_use_perf_counter) { 243 | pedestrian_detector.PrintPerformanceCounts(getFullDeviceName(ie, FLAGS_d_det)); 244 | tracker->PrintReidPerformanceCounts(getFullDeviceName(ie, FLAGS_d_reid)); 245 | } 246 | 247 | std::cout << presenter.reportMeans() << '\n'; 248 | return 0; 249 | } 250 | 251 | int main(int argc, char **argv) { 252 | try { 253 | main_work(argc, argv); 254 | } 255 | catch (const std::exception& error) { 256 | std::cout << "[ ERROR ] " << error.what() << std::endl; 257 | return 1; 258 | } 259 | catch (...) { 260 | std::cout << "[ ERROR ] Unknown/internal exception happened." << std::endl; 261 | return 1; 262 | } 263 | 264 | std::cout << "Execution successful" << std::endl; 265 | 266 | return 0; 267 | } 268 | -------------------------------------------------------------------------------- /models/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /models/person-detection-retail-0013/FP16-INT8/person-detection-retail-0013.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Smorodov/openvino_pedestrian_tracker/74fdcc7a557369cf2697c73196c1fb4a3b8463de/models/person-detection-retail-0013/FP16-INT8/person-detection-retail-0013.bin -------------------------------------------------------------------------------- /models/person-detection-retail-0013/FP16/person-detection-retail-0013.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Smorodov/openvino_pedestrian_tracker/74fdcc7a557369cf2697c73196c1fb4a3b8463de/models/person-detection-retail-0013/FP16/person-detection-retail-0013.bin -------------------------------------------------------------------------------- /models/person-detection-retail-0013/FP32/person-detection-retail-0013.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Smorodov/openvino_pedestrian_tracker/74fdcc7a557369cf2697c73196c1fb4a3b8463de/models/person-detection-retail-0013/FP32/person-detection-retail-0013.bin -------------------------------------------------------------------------------- /models/person-reidentification-retail-0031/FP16-INT8/person-reidentification-retail-0031.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Smorodov/openvino_pedestrian_tracker/74fdcc7a557369cf2697c73196c1fb4a3b8463de/models/person-reidentification-retail-0031/FP16-INT8/person-reidentification-retail-0031.bin -------------------------------------------------------------------------------- /models/person-reidentification-retail-0031/FP16/person-reidentification-retail-0031.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Smorodov/openvino_pedestrian_tracker/74fdcc7a557369cf2697c73196c1fb4a3b8463de/models/person-reidentification-retail-0031/FP16/person-reidentification-retail-0031.bin -------------------------------------------------------------------------------- /models/person-reidentification-retail-0031/FP32/person-reidentification-retail-0031.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Smorodov/openvino_pedestrian_tracker/74fdcc7a557369cf2697c73196c1fb4a3b8463de/models/person-reidentification-retail-0031/FP32/person-reidentification-retail-0031.bin -------------------------------------------------------------------------------- /src/cnn.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #include "cnn.hpp" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | using namespace InferenceEngine; 19 | 20 | CnnBase::CnnBase(const Config& config, 21 | const InferenceEngine::Core & ie, 22 | const std::string & deviceName) : 23 | config_(config), ie_(ie), deviceName_(deviceName) {} 24 | 25 | void CnnBase::Load() { 26 | auto cnnNetwork = ie_.ReadNetwork(config_.path_to_model); 27 | 28 | const int currentBatchSize = cnnNetwork.getBatchSize(); 29 | if (currentBatchSize != config_.max_batch_size) 30 | cnnNetwork.setBatchSize(config_.max_batch_size); 31 | 32 | InferenceEngine::InputsDataMap in; 33 | in = cnnNetwork.getInputsInfo(); 34 | if (in.size() != 1) { 35 | THROW_IE_EXCEPTION << "Network should have only one input"; 36 | } 37 | 38 | SizeVector inputDims = in.begin()->second->getTensorDesc().getDims(); 39 | in.begin()->second->setPrecision(Precision::U8); 40 | input_blob_ = make_shared_blob(TensorDesc(Precision::U8, inputDims, Layout::NCHW)); 41 | input_blob_->allocate(); 42 | BlobMap inputs; 43 | inputs[in.begin()->first] = input_blob_; 44 | outInfo_ = cnnNetwork.getOutputsInfo(); 45 | 46 | for (auto&& item : outInfo_) { 47 | SizeVector outputDims = item.second->getTensorDesc().getDims(); 48 | auto outputLayout = item.second->getTensorDesc().getLayout(); 49 | item.second->setPrecision(Precision::FP32); 50 | TBlob::Ptr output = 51 | make_shared_blob(TensorDesc(Precision::FP32, outputDims, outputLayout)); 52 | output->allocate(); 53 | outputs_[item.first] = output; 54 | } 55 | 56 | executable_network_ = ie_.LoadNetwork(cnnNetwork, deviceName_); 57 | infer_request_ = executable_network_.CreateInferRequest(); 58 | infer_request_.SetInput(inputs); 59 | infer_request_.SetOutput(outputs_); 60 | } 61 | 62 | void CnnBase::InferBatch( 63 | const std::vector& frames, 64 | const std::function& fetch_results) const { 65 | const size_t batch_size = input_blob_->getTensorDesc().getDims()[0]; 66 | 67 | size_t num_imgs = frames.size(); 68 | for (size_t batch_i = 0; batch_i < num_imgs; batch_i += batch_size) { 69 | const size_t current_batch_size = std::min(batch_size, num_imgs - batch_i); 70 | for (size_t b = 0; b < current_batch_size; b++) { 71 | matU8ToBlob(frames[batch_i + b], input_blob_, b); 72 | } 73 | 74 | infer_request_.Infer(); 75 | 76 | fetch_results(outputs_, current_batch_size); 77 | } 78 | } 79 | 80 | void CnnBase::PrintPerformanceCounts(std::string fullDeviceName) const { 81 | std::cout << "Performance counts for " << config_.path_to_model << std::endl << std::endl; 82 | ::printPerformanceCounts(infer_request_, std::cout, fullDeviceName, false); 83 | } 84 | 85 | void CnnBase::Infer(const cv::Mat& frame, 86 | const std::function& fetch_results) const { 87 | InferBatch({frame}, fetch_results); 88 | } 89 | 90 | VectorCNN::VectorCNN(const Config& config, 91 | const InferenceEngine::Core& ie, 92 | const std::string & deviceName) 93 | : CnnBase(config, ie, deviceName) { 94 | Load(); 95 | 96 | if (outputs_.size() != 1) { 97 | THROW_IE_EXCEPTION << "Demo supports topologies only with 1 output"; 98 | } 99 | 100 | InferenceEngine::SizeVector dims = outInfo_.begin()->second->getTensorDesc().getDims(); 101 | result_size_ = std::accumulate(std::next(dims.begin(), 1), dims.end(), 1, std::multiplies()); 102 | } 103 | 104 | void VectorCNN::Compute(const cv::Mat& frame, 105 | cv::Mat* vector, cv::Size outp_shape) const { 106 | std::vector output; 107 | Compute({frame}, &output, outp_shape); 108 | *vector = output[0]; 109 | } 110 | 111 | void VectorCNN::Compute(const std::vector& images, std::vector* vectors, 112 | cv::Size outp_shape) const { 113 | if (images.empty()) { 114 | return; 115 | } 116 | vectors->clear(); 117 | auto results_fetcher = [vectors, outp_shape](const InferenceEngine::BlobMap& outputs, size_t batch_size) { 118 | for (auto&& item : outputs) { 119 | InferenceEngine::Blob::Ptr blob = item.second; 120 | if (blob == nullptr) { 121 | THROW_IE_EXCEPTION << "VectorCNN::Compute() Invalid blob '" << item.first << "'"; 122 | } 123 | InferenceEngine::SizeVector ie_output_dims = blob->getTensorDesc().getDims(); 124 | std::vector blob_sizes(ie_output_dims.size(), 0); 125 | for (size_t i = 0; i < blob_sizes.size(); ++i) { 126 | blob_sizes[i] = ie_output_dims[i]; 127 | } 128 | cv::Mat out_blob(blob_sizes, CV_32F, blob->buffer()); 129 | for (size_t b = 0; b < batch_size; b++) { 130 | cv::Mat blob_wrapper(out_blob.size[1], 1, CV_32F, 131 | reinterpret_cast((out_blob.ptr(0) + b * out_blob.size[1]))); 132 | vectors->emplace_back(); 133 | if (outp_shape != cv::Size()) 134 | blob_wrapper = blob_wrapper.reshape(1, {outp_shape.height, outp_shape.width}); 135 | blob_wrapper.copyTo(vectors->back()); 136 | } 137 | } 138 | }; 139 | InferBatch(images, results_fetcher); 140 | } 141 | -------------------------------------------------------------------------------- /src/detector.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #include "detector.hpp" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | using namespace InferenceEngine; 16 | 17 | #define SSD_EMPTY_DETECTIONS_INDICATOR -1.0 18 | 19 | namespace { 20 | cv::Rect TruncateToValidRect(const cv::Rect& rect, 21 | const cv::Size& size) { 22 | auto tl = rect.tl(), br = rect.br(); 23 | tl.x = std::max(0, std::min(size.width - 1, tl.x)); 24 | tl.y = std::max(0, std::min(size.height - 1, tl.y)); 25 | br.x = std::max(0, std::min(size.width, br.x)); 26 | br.y = std::max(0, std::min(size.height, br.y)); 27 | int w = std::max(0, br.x - tl.x); 28 | int h = std::max(0, br.y - tl.y); 29 | return cv::Rect(tl.x, tl.y, w, h); 30 | } 31 | 32 | cv::Rect IncreaseRect(const cv::Rect& r, float coeff_x, 33 | float coeff_y) { 34 | cv::Point2f tl = r.tl(); 35 | cv::Point2f br = r.br(); 36 | cv::Point2f c = (tl * 0.5f) + (br * 0.5f); 37 | cv::Point2f diff = c - tl; 38 | cv::Point2f new_diff{diff.x * coeff_x, diff.y * coeff_y}; 39 | cv::Point2f new_tl = c - new_diff; 40 | cv::Point2f new_br = c + new_diff; 41 | 42 | cv::Point new_tl_int {static_cast(std::floor(new_tl.x)), static_cast(std::floor(new_tl.y))}; 43 | cv::Point new_br_int {static_cast(std::ceil(new_br.x)), static_cast(std::ceil(new_br.y))}; 44 | 45 | return cv::Rect(new_tl_int, new_br_int); 46 | } 47 | } // namespace 48 | 49 | void ObjectDetector::submitRequest() { 50 | if (request == nullptr) return; 51 | if (!enqueued_frames_) return; 52 | enqueued_frames_ = 0; 53 | results_fetched_ = false; 54 | results_.clear(); 55 | 56 | if (config_.is_async) { 57 | request->StartAsync(); 58 | } else { 59 | request->Infer(); 60 | } 61 | } 62 | 63 | const TrackedObjects& ObjectDetector::getResults() const { 64 | return results_; 65 | } 66 | 67 | void ObjectDetector::enqueue(const cv::Mat &frame) { 68 | if (!request) { 69 | request = net_.CreateInferRequestPtr(); 70 | } 71 | 72 | width_ = static_cast(frame.cols); 73 | height_ = static_cast(frame.rows); 74 | 75 | Blob::Ptr inputBlob = request->GetBlob(input_name_); 76 | 77 | matU8ToBlob(frame, inputBlob); 78 | 79 | if (!im_info_name_.empty()) { 80 | float* buffer = request->GetBlob(im_info_name_)->buffer().as(); 81 | buffer[0] = static_cast(inputBlob->getTensorDesc().getDims()[2]); 82 | buffer[1] = static_cast(inputBlob->getTensorDesc().getDims()[3]); 83 | buffer[2] = buffer[4] = static_cast(inputBlob->getTensorDesc().getDims()[3]) / width_; 84 | buffer[3] = buffer[5] = static_cast(inputBlob->getTensorDesc().getDims()[2]) / height_; 85 | } 86 | 87 | enqueued_frames_ = 1; 88 | } 89 | 90 | void ObjectDetector::submitFrame(const cv::Mat &frame, int frame_idx) { 91 | frame_idx_ = frame_idx; 92 | enqueue(frame); 93 | submitRequest(); 94 | } 95 | 96 | ObjectDetector::ObjectDetector( 97 | const DetectorConfig& config, 98 | const InferenceEngine::Core & ie, 99 | const std::string & deviceName) : 100 | config_(config), 101 | ie_(ie), 102 | deviceName_(deviceName) { 103 | auto cnnNetwork = ie_.ReadNetwork(config.path_to_model); 104 | 105 | InputsDataMap inputInfo(cnnNetwork.getInputsInfo()); 106 | if (1 == inputInfo.size() || 2 == inputInfo.size()) { 107 | for (const std::pair& input : inputInfo) { 108 | InputInfo::Ptr inputInfo = input.second; 109 | if (4 == inputInfo->getTensorDesc().getDims().size()) { 110 | inputInfo->setPrecision(Precision::U8); 111 | inputInfo->getInputData()->setLayout(Layout::NCHW); 112 | input_name_ = input.first; 113 | } else if (SizeVector{1, 6} == inputInfo->getTensorDesc().getDims()) { 114 | inputInfo->setPrecision(Precision::FP32); 115 | im_info_name_ = input.first; 116 | } else { 117 | THROW_IE_EXCEPTION << "Unknown input for Person Detection network"; 118 | } 119 | } 120 | if (input_name_.empty()) { 121 | THROW_IE_EXCEPTION << "No image input for Person Detection network found"; 122 | } 123 | } else { 124 | THROW_IE_EXCEPTION << "Person Detection network should have one or two inputs"; 125 | } 126 | InputInfo::Ptr inputInfoFirst = inputInfo.begin()->second; 127 | inputInfoFirst->setPrecision(Precision::U8); 128 | inputInfoFirst->getInputData()->setLayout(Layout::NCHW); 129 | 130 | OutputsDataMap outputInfo(cnnNetwork.getOutputsInfo()); 131 | if (outputInfo.size() != 1) { 132 | THROW_IE_EXCEPTION << "Person Detection network should have only one output"; 133 | } 134 | DataPtr& _output = outputInfo.begin()->second; 135 | output_name_ = outputInfo.begin()->first; 136 | 137 | const SizeVector outputDims = _output->getTensorDesc().getDims(); 138 | if (outputDims.size() != 4) { 139 | THROW_IE_EXCEPTION << "Person Detection network output dimensions not compatible shoulld be 4, but was " + 140 | std::to_string(outputDims.size()); 141 | } 142 | max_detections_count_ = outputDims[2]; 143 | object_size_ = outputDims[3]; 144 | if (object_size_ != 7) { 145 | THROW_IE_EXCEPTION << "Person Detection network output layer should have 7 as a last dimension"; 146 | } 147 | _output->setPrecision(Precision::FP32); 148 | _output->setLayout(TensorDesc::getLayoutByDims(_output->getDims())); 149 | 150 | net_ = ie_.LoadNetwork(cnnNetwork, deviceName_); 151 | } 152 | 153 | void ObjectDetector::wait() { 154 | if (!request || !config_.is_async) return; 155 | request->Wait(InferenceEngine::IInferRequest::WaitMode::RESULT_READY); 156 | } 157 | 158 | void ObjectDetector::fetchResults() { 159 | results_.clear(); 160 | if (results_fetched_) return; 161 | results_fetched_ = true; 162 | const float *data = request->GetBlob(output_name_)->buffer().as(); 163 | 164 | for (int det_id = 0; det_id < max_detections_count_; ++det_id) { 165 | const int start_pos = det_id * object_size_; 166 | 167 | const float batchID = data[start_pos]; 168 | if (batchID == SSD_EMPTY_DETECTIONS_INDICATOR) { 169 | break; 170 | } 171 | 172 | const float score = std::min(std::max(0.0f, data[start_pos + 2]), 1.0f); 173 | const float x0 = 174 | std::min(std::max(0.0f, data[start_pos + 3]), 1.0f) * width_; 175 | const float y0 = 176 | std::min(std::max(0.0f, data[start_pos + 4]), 1.0f) * height_; 177 | const float x1 = 178 | std::min(std::max(0.0f, data[start_pos + 5]), 1.0f) * width_; 179 | const float y1 = 180 | std::min(std::max(0.0f, data[start_pos + 6]), 1.0f) * height_; 181 | 182 | TrackedObject object; 183 | object.confidence = score; 184 | object.rect = cv::Rect(cv::Point(static_cast(round(static_cast(x0))), 185 | static_cast(round(static_cast(y0)))), 186 | cv::Point(static_cast(round(static_cast(x1))), 187 | static_cast(round(static_cast(y1))))); 188 | 189 | object.rect = TruncateToValidRect(IncreaseRect(object.rect, 190 | config_.increase_scale_x, 191 | config_.increase_scale_y), 192 | cv::Size(static_cast(width_), static_cast(height_))); 193 | object.frame_idx = frame_idx_; 194 | 195 | if (object.confidence > config_.confidence_threshold && object.rect.area() > 0) { 196 | results_.emplace_back(object); 197 | } 198 | } 199 | } 200 | 201 | void ObjectDetector::waitAndFetchResults() { 202 | wait(); 203 | fetchResults(); 204 | } 205 | 206 | void ObjectDetector::PrintPerformanceCounts(std::string fullDeviceName) { 207 | std::cout << "Performance counts for object detector" << std::endl << std::endl; 208 | ::printPerformanceCounts(*request, std::cout, fullDeviceName, false); 209 | } 210 | -------------------------------------------------------------------------------- /src/distance.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #include "distance.hpp" 6 | #include "logging.hpp" 7 | 8 | #include 9 | 10 | CosDistance::CosDistance(const cv::Size &descriptor_size) 11 | : descriptor_size_(descriptor_size) { 12 | PT_CHECK(descriptor_size.area() != 0); 13 | } 14 | 15 | float CosDistance::Compute(const cv::Mat &descr1, const cv::Mat &descr2) { 16 | PT_CHECK(!descr1.empty()); 17 | PT_CHECK(!descr2.empty()); 18 | PT_CHECK(descr1.size() == descriptor_size_); 19 | PT_CHECK(descr2.size() == descriptor_size_); 20 | 21 | double xy = descr1.dot(descr2); 22 | double xx = descr1.dot(descr1); 23 | double yy = descr2.dot(descr2); 24 | double norm = sqrt(xx * yy) + 1e-6; 25 | return 0.5f * static_cast(1.0 - xy / norm); 26 | } 27 | 28 | std::vector CosDistance::Compute(const std::vector &descrs1, 29 | const std::vector &descrs2) { 30 | PT_CHECK(descrs1.size() != 0); 31 | PT_CHECK(descrs1.size() == descrs2.size()); 32 | 33 | std::vector distances(descrs1.size(), 1.f); 34 | for (size_t i = 0; i < descrs1.size(); i++) { 35 | distances.at(i) = Compute(descrs1.at(i), descrs2.at(i)); 36 | } 37 | 38 | return distances; 39 | } 40 | 41 | 42 | float MatchTemplateDistance::Compute(const cv::Mat &descr1, 43 | const cv::Mat &descr2) { 44 | PT_CHECK(!descr1.empty() && !descr2.empty()); 45 | PT_CHECK_EQ(descr1.size(), descr2.size()); 46 | PT_CHECK_EQ(descr1.type(), descr2.type()); 47 | cv::Mat res; 48 | cv::matchTemplate(descr1, descr2, res, type_); 49 | PT_CHECK(res.size() == cv::Size(1, 1)); 50 | float dist = res.at(0, 0); 51 | return scale_ * dist + offset_; 52 | } 53 | 54 | std::vector MatchTemplateDistance::Compute(const std::vector &descrs1, 55 | const std::vector &descrs2) { 56 | std::vector result; 57 | for (size_t i = 0; i < descrs1.size(); i++) { 58 | result.push_back(Compute(descrs1[i], descrs2[i])); 59 | } 60 | return result; 61 | } 62 | -------------------------------------------------------------------------------- /src/kuhn_munkres.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #include "kuhn_munkres.hpp" 6 | #include "logging.hpp" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | KuhnMunkres::KuhnMunkres() : n_() {} 13 | 14 | std::vector KuhnMunkres::Solve(const cv::Mat& dissimilarity_matrix) { 15 | PT_CHECK(dissimilarity_matrix.type() == CV_32F); 16 | double min_val; 17 | cv::minMaxLoc(dissimilarity_matrix, &min_val); 18 | PT_CHECK(min_val >= 0); 19 | 20 | n_ = std::max(dissimilarity_matrix.rows, dissimilarity_matrix.cols); 21 | dm_ = cv::Mat(n_, n_, CV_32F, cv::Scalar(0)); 22 | marked_ = cv::Mat(n_, n_, CV_8S, cv::Scalar(0)); 23 | points_ = std::vector(n_ * 2); 24 | 25 | dissimilarity_matrix.copyTo(dm_( 26 | cv::Rect(0, 0, dissimilarity_matrix.cols, dissimilarity_matrix.rows))); 27 | 28 | is_row_visited_ = std::vector(n_, 0); 29 | is_col_visited_ = std::vector(n_, 0); 30 | 31 | Run(); 32 | 33 | std::vector results(dissimilarity_matrix.rows, -1); 34 | for (int i = 0; i < dissimilarity_matrix.rows; i++) { 35 | const auto ptr = marked_.ptr(i); 36 | for (int j = 0; j < dissimilarity_matrix.cols; j++) { 37 | if (ptr[j] == kStar) { 38 | results[i] = j; 39 | } 40 | } 41 | } 42 | return results; 43 | } 44 | 45 | void KuhnMunkres::TrySimpleCase() { 46 | auto is_row_visited = std::vector(n_, 0); 47 | auto is_col_visited = std::vector(n_, 0); 48 | 49 | for (int row = 0; row < n_; row++) { 50 | auto ptr = dm_.ptr(row); 51 | auto marked_ptr = marked_.ptr(row); 52 | auto min_val = *std::min_element(ptr, ptr + n_); 53 | for (int col = 0; col < n_; col++) { 54 | ptr[col] -= min_val; 55 | if (ptr[col] == 0 && !is_col_visited[col] && !is_row_visited[row]) { 56 | marked_ptr[col] = kStar; 57 | is_col_visited[col] = 1; 58 | is_row_visited[row] = 1; 59 | } 60 | } 61 | } 62 | } 63 | 64 | bool KuhnMunkres::CheckIfOptimumIsFound() { 65 | int count = 0; 66 | for (int i = 0; i < n_; i++) { 67 | const auto marked_ptr = marked_.ptr(i); 68 | for (int j = 0; j < n_; j++) { 69 | if (marked_ptr[j] == kStar) { 70 | is_col_visited_[j] = 1; 71 | count++; 72 | } 73 | } 74 | } 75 | 76 | return count >= n_; 77 | } 78 | 79 | cv::Point KuhnMunkres::FindUncoveredMinValPos() { 80 | auto min_val = std::numeric_limits::max(); 81 | cv::Point min_val_pos(-1, -1); 82 | for (int i = 0; i < n_; i++) { 83 | if (!is_row_visited_[i]) { 84 | auto dm_ptr = dm_.ptr(i); 85 | for (int j = 0; j < n_; j++) { 86 | if (!is_col_visited_[j] && dm_ptr[j] < min_val) { 87 | min_val = dm_ptr[j]; 88 | min_val_pos = cv::Point(j, i); 89 | } 90 | } 91 | } 92 | } 93 | return min_val_pos; 94 | } 95 | 96 | void KuhnMunkres::UpdateDissimilarityMatrix(float val) { 97 | for (int i = 0; i < n_; i++) { 98 | auto dm_ptr = dm_.ptr(i); 99 | for (int j = 0; j < n_; j++) { 100 | if (is_row_visited_[i]) dm_ptr[j] += val; 101 | if (!is_col_visited_[j]) dm_ptr[j] -= val; 102 | } 103 | } 104 | } 105 | 106 | int KuhnMunkres::FindInRow(int row, int what) { 107 | for (int j = 0; j < n_; j++) { 108 | if (marked_.at(row, j) == what) { 109 | return j; 110 | } 111 | } 112 | return -1; 113 | } 114 | 115 | int KuhnMunkres::FindInCol(int col, int what) { 116 | for (int i = 0; i < n_; i++) { 117 | if (marked_.at(i, col) == what) { 118 | return i; 119 | } 120 | } 121 | return -1; 122 | } 123 | 124 | void KuhnMunkres::Run() { 125 | TrySimpleCase(); 126 | while (!CheckIfOptimumIsFound()) { 127 | while (true) { 128 | auto point = FindUncoveredMinValPos(); 129 | auto min_val = dm_.at(point.y, point.x); 130 | if (min_val > 0) { 131 | UpdateDissimilarityMatrix(min_val); 132 | } else { 133 | marked_.at(point.y, point.x) = kPrime; 134 | int col = FindInRow(point.y, kStar); 135 | if (col >= 0) { 136 | is_row_visited_[point.y] = 1; 137 | is_col_visited_[col] = 0; 138 | } else { 139 | int count = 0; 140 | points_[count] = point; 141 | 142 | while (true) { 143 | int row = FindInCol(points_[count].x, kStar); 144 | if (row >= 0) { 145 | count++; 146 | points_[count] = cv::Point(points_[count - 1].x, row); 147 | int col = FindInRow(points_[count].y, kPrime); 148 | count++; 149 | points_[count] = cv::Point(col, points_[count - 1].y); 150 | } else { 151 | break; 152 | } 153 | } 154 | 155 | for (int i = 0; i < count + 1; i++) { 156 | auto& mark = marked_.at(points_[i].y, points_[i].x); 157 | mark = mark == kStar ? 0 : kStar; 158 | } 159 | 160 | is_row_visited_ = std::vector(n_, 0); 161 | is_col_visited_ = std::vector(n_, 0); 162 | 163 | marked_.setTo(0, marked_ == kPrime); 164 | break; 165 | } 166 | } 167 | } 168 | } 169 | } 170 | 171 | -------------------------------------------------------------------------------- /src/utils.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2018-2019 Intel Corporation 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | 5 | #include "utils.hpp" 6 | 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace InferenceEngine; 19 | 20 | namespace { 21 | template 22 | void SaveDetectionLogToStream(StreamType& stream, 23 | const DetectionLog& log) { 24 | for (const auto& entry : log) { 25 | std::vector objects(entry.objects.begin(), 26 | entry.objects.end()); 27 | std::sort(objects.begin(), objects.end(), 28 | [](const TrackedObject& a, 29 | const TrackedObject& b) 30 | { return a.object_id < b.object_id; }); 31 | for (const auto& object : objects) { 32 | auto frame_idx_to_save = entry.frame_idx; 33 | stream << frame_idx_to_save << ','; 34 | stream << object.object_id << ',' 35 | << object.rect.x << ',' << object.rect.y << ',' 36 | << object.rect.width << ',' << object.rect.height; 37 | stream << '\n'; 38 | } 39 | } 40 | } 41 | } // anonymous namespace 42 | 43 | void DrawPolyline(const std::vector& polyline, 44 | const cv::Scalar& color, cv::Mat* image, int lwd) { 45 | PT_CHECK(image); 46 | PT_CHECK(!image->empty()); 47 | PT_CHECK_EQ(image->type(), CV_8UC3); 48 | PT_CHECK_GT(lwd, 0); 49 | PT_CHECK_LT(lwd, 20); 50 | 51 | for (size_t i = 1; i < polyline.size(); i++) { 52 | cv::line(*image, polyline[i - 1], polyline[i], color, lwd); 53 | } 54 | } 55 | 56 | void SaveDetectionLogToTrajFile(const std::string& path, 57 | const DetectionLog& log) { 58 | std::ofstream file(path.c_str()); 59 | PT_CHECK(file.is_open()); 60 | SaveDetectionLogToStream(file, log); 61 | } 62 | 63 | void PrintDetectionLog(const DetectionLog& log) { 64 | SaveDetectionLogToStream(std::cout, log); 65 | } 66 | 67 | InferenceEngine::Core 68 | LoadInferenceEngine(const std::vector& devices, 69 | const std::string& custom_cpu_library, 70 | const std::string& custom_cldnn_kernels, 71 | bool should_use_perf_counter) { 72 | std::set loadedDevices; 73 | Core ie; 74 | 75 | for (const auto &device : devices) { 76 | if (loadedDevices.find(device) != loadedDevices.end()) { 77 | continue; 78 | } 79 | 80 | std::cout << "Loading device " << device << std::endl; 81 | std::cout << ie.GetVersions(device) << std::endl; 82 | 83 | /** Load extensions for the CPU device **/ 84 | if ((device.find("CPU") != std::string::npos)) { 85 | if (!custom_cpu_library.empty()) { 86 | // CPU(MKLDNN) extensions are loaded as a shared library and passed as a pointer to base extension 87 | auto extension_ptr = make_so_pointer(custom_cpu_library); 88 | ie.AddExtension(std::static_pointer_cast(extension_ptr), "CPU"); 89 | } 90 | } else if (!custom_cldnn_kernels.empty()) { 91 | // Load Extensions for other plugins not CPU 92 | ie.SetConfig({{PluginConfigParams::KEY_CONFIG_FILE, custom_cldnn_kernels}}, "GPU"); 93 | } 94 | 95 | if (should_use_perf_counter) 96 | ie.SetConfig({{PluginConfigParams::KEY_PERF_COUNT, PluginConfigParams::YES}}); 97 | 98 | loadedDevices.insert(device); 99 | } 100 | 101 | return ie; 102 | } 103 | -------------------------------------------------------------------------------- /test_videos/people-detection.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Smorodov/openvino_pedestrian_tracker/74fdcc7a557369cf2697c73196c1fb4a3b8463de/test_videos/people-detection.mp4 --------------------------------------------------------------------------------