├── version.txt ├── src-tool ├── DarkHelp.rc ├── DarkHelp.ico ├── DarkHelpCombine.cpp └── CMakeLists.txt ├── .gitignore ├── src-doc ├── DarkHelp.png ├── mailboxes.png ├── xkcd_bike.png ├── mailbox_13.png ├── shade_0pcnt.png ├── tile_edge_0.png ├── tile_edge_1.png ├── tile_edge_2.png ├── tile_rect_0.png ├── tile_rect_1.png ├── tile_rect_2.png ├── darkhelp_cam.jpg ├── pixelate_off.png ├── shade_100pcnt.png ├── shade_25pcnt.png ├── shade_50pcnt.png ├── shade_75pcnt.png ├── tile_combine_1.png ├── tile_combine_2.png ├── tile_combine_3.png ├── tile_combine_4.png ├── tracking_cars.jpg ├── tracking_pigs.jpg ├── pixelate_size_05.png ├── pixelate_size_15.png ├── pixelate_size_25.png ├── snapping_enabled.png ├── snapping_h01_v01.png ├── snapping_h02_v01.png ├── snapping_h03_v01.png ├── snapping_h07_v01.png ├── snapping_h07_v03.png ├── snapping_h07_v15.png ├── swirl_75x75_red.jpg ├── barcode_100_percent.png ├── driving_annotations.png ├── mailboxes_2x2_tiles.png ├── mailboxes_detection.png ├── mailboxes_suppress.png ├── snapping_disabled.png ├── auto_hide_labels_true.png ├── mailbox_13_annotated.png ├── auto_hide_labels_false.png ├── barcode_with_timestamp.png ├── darkmark_build_thumbnail.png ├── include_percentage_false.png ├── include_percentage_true.png ├── red_swirl_darknet_75x75.png ├── tile_combine_similar_0.png ├── tile_combine_similar_1.png ├── tile_combine_similar_2.png ├── tile_combine_similar_3.png ├── tile_combine_similar_4.png ├── tile_combine_similar_5.png ├── mailboxes_2x2_tiles_detection.png ├── mailbox_13_invalid_coordinates.png ├── mailboxes_1024x768_and_416x320.png ├── 03_license.dox ├── CMakeLists.txt ├── footer_doxygen.html ├── 05_darkhelp_c_api.dox ├── footer_ccoderun.html ├── 05_darkhelp_python_api.dox ├── 08_darkhelp_webcam.dox ├── header_ccoderun.html ├── 04_building_darkhelp.dox ├── 06_darkhelp_tool.dox ├── 01_mainpage.dox ├── 09_tiling.dox ├── 07_parms.dox ├── 03_changelist.dox ├── 05_darkhelp_api.dox ├── 02_summary.dox ├── 08_shell_script.dox └── 08_darkhelp_server.dox ├── .editorconfig ├── CM_source.cmake ├── src-cam ├── CMakeLists.txt ├── CamOptions.hpp └── Cam.cpp ├── src-apps ├── CMakeLists.txt ├── process_single_image.cpp ├── display_using_bundle.cpp ├── display_single_image.cpp ├── process_using_bundle_and_dhthreads.cpp ├── display_single_image_snapping.cpp ├── display_single_image_custom_settings.cpp ├── process_video_webcam.cpp ├── process_many_images_on_threads.cpp ├── using_c_api.cpp ├── save_webcam_to_video.cpp ├── video_display_realtime.cpp ├── readme.md ├── rotate_images.cpp └── video_object_counter.cpp ├── CM_version.cmake ├── .github └── FUNDING.yml ├── example_project ├── CMakeLists.txt ├── readme.txt └── example.cpp ├── CM_definitions.cmake ├── CMakeLists.txt ├── src-lib ├── CMakeLists.txt ├── DarkHelpPredictionResult.cpp ├── DarkHelpConfig.cpp ├── DarkHelp.hpp ├── DarkHelpPositionTracker.cpp ├── DarkHelpPredictionResult.hpp └── DarkHelpThreads.cpp ├── license.txt ├── CM_dependencies.cmake ├── readme_windows.txt ├── src-python ├── example.py └── DarkHelp.py ├── CM_package.cmake ├── readme_linux.txt └── readme.md /version.txt: -------------------------------------------------------------------------------- 1 | 1.9.7-1 2 | -------------------------------------------------------------------------------- /src-tool/DarkHelp.rc: -------------------------------------------------------------------------------- 1 | 1 ICON "DarkHelp.ico" 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.kdev4 2 | build 3 | build_and_upload.sh 4 | /.vs 5 | /.vscode 6 | -------------------------------------------------------------------------------- /src-doc/DarkHelp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/DarkHelp.png -------------------------------------------------------------------------------- /src-doc/mailboxes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/mailboxes.png -------------------------------------------------------------------------------- /src-doc/xkcd_bike.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/xkcd_bike.png -------------------------------------------------------------------------------- /src-tool/DarkHelp.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-tool/DarkHelp.ico -------------------------------------------------------------------------------- /src-doc/mailbox_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/mailbox_13.png -------------------------------------------------------------------------------- /src-doc/shade_0pcnt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/shade_0pcnt.png -------------------------------------------------------------------------------- /src-doc/tile_edge_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_edge_0.png -------------------------------------------------------------------------------- /src-doc/tile_edge_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_edge_1.png -------------------------------------------------------------------------------- /src-doc/tile_edge_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_edge_2.png -------------------------------------------------------------------------------- /src-doc/tile_rect_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_rect_0.png -------------------------------------------------------------------------------- /src-doc/tile_rect_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_rect_1.png -------------------------------------------------------------------------------- /src-doc/tile_rect_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_rect_2.png -------------------------------------------------------------------------------- /src-doc/darkhelp_cam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/darkhelp_cam.jpg -------------------------------------------------------------------------------- /src-doc/pixelate_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/pixelate_off.png -------------------------------------------------------------------------------- /src-doc/shade_100pcnt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/shade_100pcnt.png -------------------------------------------------------------------------------- /src-doc/shade_25pcnt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/shade_25pcnt.png -------------------------------------------------------------------------------- /src-doc/shade_50pcnt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/shade_50pcnt.png -------------------------------------------------------------------------------- /src-doc/shade_75pcnt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/shade_75pcnt.png -------------------------------------------------------------------------------- /src-doc/tile_combine_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_combine_1.png -------------------------------------------------------------------------------- /src-doc/tile_combine_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_combine_2.png -------------------------------------------------------------------------------- /src-doc/tile_combine_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_combine_3.png -------------------------------------------------------------------------------- /src-doc/tile_combine_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_combine_4.png -------------------------------------------------------------------------------- /src-doc/tracking_cars.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tracking_cars.jpg -------------------------------------------------------------------------------- /src-doc/tracking_pigs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tracking_pigs.jpg -------------------------------------------------------------------------------- /src-doc/pixelate_size_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/pixelate_size_05.png -------------------------------------------------------------------------------- /src-doc/pixelate_size_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/pixelate_size_15.png -------------------------------------------------------------------------------- /src-doc/pixelate_size_25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/pixelate_size_25.png -------------------------------------------------------------------------------- /src-doc/snapping_enabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/snapping_enabled.png -------------------------------------------------------------------------------- /src-doc/snapping_h01_v01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/snapping_h01_v01.png -------------------------------------------------------------------------------- /src-doc/snapping_h02_v01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/snapping_h02_v01.png -------------------------------------------------------------------------------- /src-doc/snapping_h03_v01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/snapping_h03_v01.png -------------------------------------------------------------------------------- /src-doc/snapping_h07_v01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/snapping_h07_v01.png -------------------------------------------------------------------------------- /src-doc/snapping_h07_v03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/snapping_h07_v03.png -------------------------------------------------------------------------------- /src-doc/snapping_h07_v15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/snapping_h07_v15.png -------------------------------------------------------------------------------- /src-doc/swirl_75x75_red.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/swirl_75x75_red.jpg -------------------------------------------------------------------------------- /src-doc/barcode_100_percent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/barcode_100_percent.png -------------------------------------------------------------------------------- /src-doc/driving_annotations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/driving_annotations.png -------------------------------------------------------------------------------- /src-doc/mailboxes_2x2_tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/mailboxes_2x2_tiles.png -------------------------------------------------------------------------------- /src-doc/mailboxes_detection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/mailboxes_detection.png -------------------------------------------------------------------------------- /src-doc/mailboxes_suppress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/mailboxes_suppress.png -------------------------------------------------------------------------------- /src-doc/snapping_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/snapping_disabled.png -------------------------------------------------------------------------------- /src-doc/auto_hide_labels_true.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/auto_hide_labels_true.png -------------------------------------------------------------------------------- /src-doc/mailbox_13_annotated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/mailbox_13_annotated.png -------------------------------------------------------------------------------- /src-doc/auto_hide_labels_false.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/auto_hide_labels_false.png -------------------------------------------------------------------------------- /src-doc/barcode_with_timestamp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/barcode_with_timestamp.png -------------------------------------------------------------------------------- /src-doc/darkmark_build_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/darkmark_build_thumbnail.png -------------------------------------------------------------------------------- /src-doc/include_percentage_false.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/include_percentage_false.png -------------------------------------------------------------------------------- /src-doc/include_percentage_true.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/include_percentage_true.png -------------------------------------------------------------------------------- /src-doc/red_swirl_darknet_75x75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/red_swirl_darknet_75x75.png -------------------------------------------------------------------------------- /src-doc/tile_combine_similar_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_combine_similar_0.png -------------------------------------------------------------------------------- /src-doc/tile_combine_similar_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_combine_similar_1.png -------------------------------------------------------------------------------- /src-doc/tile_combine_similar_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_combine_similar_2.png -------------------------------------------------------------------------------- /src-doc/tile_combine_similar_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_combine_similar_3.png -------------------------------------------------------------------------------- /src-doc/tile_combine_similar_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_combine_similar_4.png -------------------------------------------------------------------------------- /src-doc/tile_combine_similar_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/tile_combine_similar_5.png -------------------------------------------------------------------------------- /src-doc/mailboxes_2x2_tiles_detection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/mailboxes_2x2_tiles_detection.png -------------------------------------------------------------------------------- /src-doc/mailbox_13_invalid_coordinates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/mailbox_13_invalid_coordinates.png -------------------------------------------------------------------------------- /src-doc/mailboxes_1024x768_and_416x320.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanecharette/DarkHelp/HEAD/src-doc/mailboxes_1024x768_and_416x320.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | charset = utf-8 10 | indent_style = tab 11 | indent_size = 4 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | 15 | -------------------------------------------------------------------------------- /src-doc/03_license.dox: -------------------------------------------------------------------------------- 1 | /** @page License License 2 | 3 | A copy of the license file (MIT) is included with the @p %DarkHelp source code. The license is reproduced in its entirety here: 4 | 5 |
6 | @htmlinclude "../license.txt" 7 |
8 | 9 | */ 10 | -------------------------------------------------------------------------------- /CM_source.cmake: -------------------------------------------------------------------------------- 1 | # DarkHelp - C++ helper class for Darknet's C API. 2 | # Copyright 2019-2024 Stephane Charette 3 | # MIT license applies. See "license.txt" for details. 4 | 5 | 6 | INCLUDE_DIRECTORIES (src-lib) 7 | INCLUDE_DIRECTORIES (src-tool) 8 | 9 | ADD_SUBDIRECTORY (src-lib) 10 | ADD_SUBDIRECTORY (src-tool) 11 | ADD_SUBDIRECTORY (src-apps) 12 | ADD_SUBDIRECTORY (src-cam) 13 | ADD_SUBDIRECTORY (src-doc) 14 | -------------------------------------------------------------------------------- /src-cam/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # DarkHelp - C++ helper class for Darknet's C API. 2 | # Copyright 2019-2024 Stephane Charette 3 | # MIT license applies. See "license.txt" for details. 4 | 5 | 6 | FILE (GLOB SRC_CAM *.cpp) 7 | LIST (SORT SRC_CAM) 8 | 9 | ADD_EXECUTABLE (DarkHelp_cam ${SRC_CAM}) 10 | TARGET_LINK_LIBRARIES (DarkHelp_cam PRIVATE Threads::Threads dh ${Darknet} ${OpenCV_LIBS}) 11 | INSTALL (TARGETS DarkHelp_cam DESTINATION bin) 12 | -------------------------------------------------------------------------------- /src-doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # DarkHelp - C++ helper class for Darknet's C API. 2 | # Copyright 2019-2024 Stephane Charette 3 | # MIT license applies. See "license.txt" for details. 4 | 5 | 6 | FIND_PACKAGE ( Doxygen QUIET ) 7 | 8 | IF ( Doxygen_FOUND ) 9 | 10 | CONFIGURE_FILE ( ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile ) 11 | 12 | ADD_CUSTOM_TARGET ( 13 | doc 14 | ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 15 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 16 | COMMENT "Generating documentation with Doxygen" VERBATIM ) 17 | 18 | ENDIF ( Doxygen_FOUND ) 19 | -------------------------------------------------------------------------------- /src-apps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # DarkHelp - C++ helper class for Darknet's C API. 2 | # Copyright 2019-2024 Stephane Charette 3 | # MIT license applies. See "license.txt" for details. 4 | 5 | 6 | IF ( WIN32 ) 7 | ADD_COMPILE_DEFINITIONS ( _USE_MATH_DEFINES ) 8 | ADD_COMPILE_OPTIONS ( /wd4244 ) # conversion between types 9 | ENDIF () 10 | 11 | 12 | FILE ( GLOB SRC_APPS *.cpp ) 13 | LIST ( SORT SRC_APPS ) 14 | 15 | 16 | FOREACH ( filename IN LISTS SRC_APPS ) 17 | CMAKE_PATH ( GET filename STEM stem ) 18 | ADD_EXECUTABLE ( ${stem} ${filename} ) 19 | TARGET_LINK_LIBRARIES ( ${stem} PRIVATE Threads::Threads dh ${Darknet} ${OpenCV_LIBS} ) 20 | ENDFOREACH () 21 | -------------------------------------------------------------------------------- /CM_version.cmake: -------------------------------------------------------------------------------- 1 | # DarkHelp - C++ helper class for Darknet's C API. 2 | # Copyright 2019-2024 Stephane Charette 3 | # MIT license applies. See "license.txt" for details. 4 | 5 | 6 | FILE ( READ version.txt VERSION_TXT ) 7 | STRING ( STRIP "${VERSION_TXT}" VERSION_TXT ) 8 | STRING ( REGEX MATCHALL "^([0-9]+)\\.([0-9]+)\\.([0-9]+)-([0-9]+)$" OUTPUT ${VERSION_TXT} ) 9 | 10 | SET ( DH_VER_MAJOR ${CMAKE_MATCH_1} ) 11 | SET ( DH_VER_MINOR ${CMAKE_MATCH_2} ) 12 | SET ( DH_VER_PATCH ${CMAKE_MATCH_3} ) 13 | SET ( DH_VER_COMMIT ${CMAKE_MATCH_4} ) 14 | 15 | SET ( DH_VERSION ${DH_VER_MAJOR}.${DH_VER_MINOR}.${DH_VER_PATCH}-${DH_VER_COMMIT} ) 16 | MESSAGE ( "Building ver: ${DH_VERSION}" ) 17 | 18 | ADD_DEFINITIONS ( -DDH_VERSION="${DH_VERSION}" ) 19 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: stephanecharette # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['paypal.me/ccoderun'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /src-doc/footer_doxygen.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /example_project/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED (VERSION 3.0) 2 | 3 | PROJECT (ExampleProject C CXX) 4 | 5 | SET (CMAKE_BUILD_TYPE Release) 6 | SET (CMAKE_CXX_STANDARD 17) 7 | SET (CMAKE_CXX_STANDARD_REQUIRED ON) 8 | 9 | IF (WIN32) 10 | ADD_COMPILE_OPTIONS ( /permissive- ) # stick to C++ standards (turn off Microsoft-specific extensions) 11 | ELSE () 12 | ADD_COMPILE_OPTIONS ( -Wall -Wextra -Werror -Wno-unused-parameter ) 13 | ENDIF () 14 | 15 | FIND_PACKAGE (Threads REQUIRED) 16 | FIND_PACKAGE (OpenCV REQUIRED) 17 | FIND_LIBRARY (DARKHELP darkhelp) 18 | FIND_LIBRARY (DARKNET darknet ) 19 | 20 | INCLUDE_DIRECTORIES (${OpenCV_INCLUDE_DIRS}) 21 | 22 | FILE (GLOB SOURCE *.cpp) 23 | LIST (SORT SOURCE) 24 | 25 | ADD_EXECUTABLE (example ${SOURCE}) 26 | TARGET_LINK_LIBRARIES (example Threads::Threads ${DARKHELP} ${DARKNET} ${OpenCV_LIBS}) 27 | -------------------------------------------------------------------------------- /CM_definitions.cmake: -------------------------------------------------------------------------------- 1 | # DarkHelp - C++ helper class for Darknet's C API. 2 | # Copyright 2019-2024 Stephane Charette 3 | # MIT license applies. See "license.txt" for details. 4 | 5 | 6 | IF (WIN32) 7 | ADD_COMPILE_OPTIONS ( /W4 ) # warning level (high) 8 | ADD_COMPILE_OPTIONS ( /WX ) # treat warnings as errors 9 | ADD_COMPILE_OPTIONS ( /permissive- ) # stick to C++ standards (turn off Microsoft-specific extensions) 10 | ADD_COMPILE_OPTIONS ( /wd4100 ) # disable "unreferenced formal parameter" 11 | ADD_COMPILE_OPTIONS ( /wd4127 ) # disable "conditional expression is constant" 12 | ADD_COMPILE_DEFINITIONS ( _CRT_SECURE_NO_WARNINGS ) # don't complain about localtime() 13 | SET ( CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" ) 14 | ELSE () 15 | ADD_COMPILE_OPTIONS ( -Wall -Wextra -Werror -Wno-unused-parameter ) 16 | ENDIF () 17 | -------------------------------------------------------------------------------- /example_project/readme.txt: -------------------------------------------------------------------------------- 1 | This is an example of how to create a CMake-based C++ project that uses the 2 | DarkHelp library. 3 | 4 | The CMakeLists.txt file will pull in darknet, OpenCV, and DarkHelp. 5 | 6 | The example.cpp file loads a neural network, sets several example options, 7 | annotates a single image file, and displays the results. 8 | 9 | To build on Linux: 10 | 11 | mkdir build 12 | cd build 13 | cmake .. 14 | make 15 | 16 | To build on Windows (you may need to adjust, similar commands as the ones you used to build Darknet and DarkHelp): 17 | 18 | mkdir build 19 | cd build 20 | cmake -DCMAKE_TOOLCHAIN_FILE=C:/src/vcpkg/scripts/buildsystems/vcpkg.cmake -DDARKNET="C:/Program Files/Darknet/lib/darknet.lib" -DDARKHELP="C:/Program Files/DarkHelp/lib/darkhelp.lib" .. 21 | msbuild.exe ...etc... or use Visual Studio 22 | 23 | IMPORTANT! See the other source code examples in ../src-apps/. 24 | 25 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # DarkHelp - C++ helper class for Darknet's C API. 2 | # Copyright 2019-2024 Stephane Charette 3 | # MIT license applies. See "license.txt" for details. 4 | 5 | 6 | # for anyone trying to build this in Ubuntu 18.04, if the minimum version 7 | # is causing you problems, please use the cmake from vcpkg or snap 8 | CMAKE_MINIMUM_REQUIRED ( VERSION 3.20 ) 9 | 10 | PROJECT ( DarkHelp C CXX ) 11 | 12 | IF ( NOT CMAKE_BUILD_TYPE ) 13 | SET ( CMAKE_BUILD_TYPE Release ) 14 | ENDIF () 15 | 16 | SET ( CMAKE_CXX_STANDARD 17 ) 17 | SET ( CMAKE_CXX_STANDARD_REQUIRED ON ) 18 | 19 | 20 | INCLUDE ( CM_version.cmake ) # get the version number 21 | INCLUDE ( CM_definitions.cmake ) # compiler definitions 22 | INCLUDE ( CM_dependencies.cmake ) # find all required dependencies 23 | INCLUDE ( CM_source.cmake ) # source code that needs to be built 24 | INCLUDE ( CM_package.cmake ) # create .exe or .deb packages 25 | -------------------------------------------------------------------------------- /src-lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # DarkHelp - C++ helper class for Darknet's C API. 2 | # Copyright 2019-2024 Stephane Charette 3 | # MIT license applies. See "license.txt" for details. 4 | 5 | 6 | SET ( CMAKE_POSITION_INDEPENDENT_CODE ON ) 7 | SET ( CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON ) 8 | SET ( BUILD_SHARED_LIBS TRUE ) 9 | 10 | FILE ( GLOB SRC_LIB *.cpp ) 11 | LIST ( SORT SRC_LIB ) 12 | 13 | FILE ( GLOB HEADERS *.hpp *.h) 14 | LIST ( SORT HEADERS ) 15 | 16 | ADD_LIBRARY ( dh SHARED ${SRC_LIB} ) 17 | SET_TARGET_PROPERTIES ( dh PROPERTIES OUTPUT_NAME "darkhelp" ) 18 | TARGET_LINK_LIBRARIES ( dh PRIVATE Threads::Threads ${Darknet} ${OpenCV_LIBS} ) 19 | 20 | INSTALL ( FILES ${HEADERS} DESTINATION include ) 21 | INSTALL ( TARGETS dh DESTINATION lib ) 22 | 23 | IF (WIN32) 24 | # Windows assumes the DLLs are installed with the executables, 25 | # so put a copy of it here as well 26 | INSTALL (TARGETS dh DESTINATION bin) 27 | ENDIF () 28 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2019-2024 Stephane Charette 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /src-doc/05_darkhelp_c_api.dox: -------------------------------------------------------------------------------- 1 | /** @page CAPI %DarkHelp C API 2 | 3 | The %DarkHelp @p C API is a simplified wrapper API for the C++ API. 4 | 5 | To use the %DarkHelp C API, you must include the project header file within your application: 6 | 7 | ~~~~{.c} 8 | #include 9 | ~~~~ 10 | 11 | The C API requires that a @p void* object be allocated to represent the %DarkHelp object in C++. That @p void* pointer is then passed in to all the function calls. 12 | 13 | ~~~~{.c} 14 | DarkHelpPtr dh = CreateDarkHelpNN("cars.cfg", "cars.names", "cars_best.weights"); 15 | 16 | PredictFN(dh, "test.jpg"); 17 | results = GetPredictionResults(dh); 18 | Annotate(dh, "output.jpg"); 19 | 20 | DestroyDarkHelpNN(dh); 21 | ~~~~ 22 | 23 | See the example application @p src-apps/using_c_api.cpp for sample code which shows how to use the @p C API. 24 | 25 | Convenient links to some of the API call documentation to get started: 26 | 27 | @li @ref DarkHelpVersion() 28 | @li @ref CreateDarkHelpNN() 29 | @li @ref SetThreshold() 30 | @li @ref EnableTiles() 31 | @li @ref EnableSnapping() 32 | @li @ref SetAnnotationLineThickness() 33 | @li @ref PredictFN() 34 | @li @ref Annotate() 35 | @li @ref GetPredictionResults() 36 | 37 | */ 38 | -------------------------------------------------------------------------------- /src-doc/footer_ccoderun.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 19 | 20 | 21 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src-apps/process_single_image.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | #include "DarkHelp.hpp" 7 | 8 | int main(int argc, char * argv[]) 9 | { 10 | int rc = 0; 11 | 12 | try 13 | { 14 | if (argc != 5) 15 | { 16 | std::cout 17 | << "Usage:" << std::endl 18 | << argv[0] << " " << std::endl; 19 | throw std::invalid_argument("wrong number of arguments"); 20 | } 21 | 22 | std::string fn1 = argv[1]; 23 | std::string fn2 = argv[2]; 24 | std::string fn3 = argv[3]; 25 | std::string image = argv[4]; 26 | 27 | // Load the neural network. The order of the 3 files does not matter, DarkHelp should figure out which file is which. 28 | DarkHelp::NN nn(fn1, fn2, fn3); 29 | 30 | // Call on the neural network to process the given filename 31 | const auto results = nn.predict(image); 32 | 33 | // Display the results on the console. 34 | std::cout << image << " " << results << std::endl; 35 | } 36 | catch (const std::exception & e) 37 | { 38 | std::cout << e.what() << std::endl; 39 | rc = 1; 40 | } 41 | 42 | return rc; 43 | } 44 | -------------------------------------------------------------------------------- /src-tool/DarkHelpCombine.cpp: -------------------------------------------------------------------------------- 1 | #include "DarkHelp.hpp" 2 | 3 | 4 | int main(int argc, char * argv[]) 5 | { 6 | int rc = 1; 7 | 8 | try 9 | { 10 | if (argc != 5) 11 | { 12 | std::cout 13 | << std::endl 14 | << "Usage:" << std::endl 15 | << "\t" << argv[0] << " " << std::endl 16 | << std::endl 17 | << "The key phrase must come first, but the order of the 3 filenames does not matter." << std::endl 18 | << "To disable obfuscation, use \"\" as the key phrase." << std::endl; 19 | 20 | throw std::invalid_argument("expected 4 parameters but found " + std::to_string(argc - 1)); 21 | } 22 | 23 | const std::string phrase = argv[1]; 24 | std::filesystem::path cfg = std::filesystem::canonical(argv[2]); 25 | std::filesystem::path names = std::filesystem::canonical(argv[3]); 26 | std::filesystem::path weights = std::filesystem::canonical(argv[4]); 27 | 28 | std::cout << "Combining neural network files into 1 file:" << std::endl; 29 | 30 | const auto output = DarkHelp::combine(phrase, cfg, names, weights); 31 | 32 | std::cout << "Results saved to: " << output.string() << std::endl; 33 | 34 | rc = 0; 35 | } 36 | catch (const std::exception & e) 37 | { 38 | std::cout << std::endl << "ERROR: " << e.what() << std::endl; 39 | } 40 | 41 | return rc; 42 | } 43 | -------------------------------------------------------------------------------- /src-apps/display_using_bundle.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | #include "DarkHelp.hpp" 7 | 8 | int main(int argc, char * argv[]) 9 | { 10 | int rc = 0; 11 | 12 | try 13 | { 14 | if (argc != 4) 15 | { 16 | std::cout 17 | << "Usage:" << std::endl 18 | << argv[0] << " " << std::endl; 19 | throw std::invalid_argument("wrong number of arguments"); 20 | } 21 | 22 | std::string dh = argv[1]; 23 | std::string key = argv[2]; 24 | std::string image = argv[3]; 25 | 26 | // Load the neural network. The .dh filename must have been created with the DarkHelpCombine CLI tool. 27 | DarkHelp::NN nn(false, dh, key); 28 | 29 | // Use OpenCV to load the image. 30 | cv::Mat original_image = cv::imread(image); 31 | 32 | // Call on the neural network to process the given filename 33 | nn.predict(original_image); 34 | 35 | // Annotate the image using the results. 36 | cv::Mat annotated_image = nn.annotate(); 37 | 38 | // Display the results using OpenCV. 39 | cv::imshow("original", original_image); 40 | cv::imshow("annotated", annotated_image); 41 | cv::waitKey(); 42 | } 43 | catch (const std::exception & e) 44 | { 45 | std::cout << e.what() << std::endl; 46 | rc = 1; 47 | } 48 | 49 | return rc; 50 | } 51 | -------------------------------------------------------------------------------- /src-apps/display_single_image.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | #include "DarkHelp.hpp" 7 | 8 | int main(int argc, char * argv[]) 9 | { 10 | int rc = 0; 11 | 12 | try 13 | { 14 | if (argc != 5) 15 | { 16 | std::cout 17 | << "Usage:" << std::endl 18 | << argv[0] << " " << std::endl; 19 | throw std::invalid_argument("wrong number of arguments"); 20 | } 21 | 22 | std::string fn1 = argv[1]; 23 | std::string fn2 = argv[2]; 24 | std::string fn3 = argv[3]; 25 | std::string image = argv[4]; 26 | 27 | // Load the neural network. The order of the 3 files does not matter, DarkHelp should figure out which file is which. 28 | DarkHelp::NN nn(fn1, fn2, fn3); 29 | 30 | // Use OpenCV to load the image. 31 | cv::Mat original_image = cv::imread(image); 32 | 33 | // Call on the neural network to process the given filename 34 | nn.predict(original_image); 35 | 36 | // Annotate the image using the results. 37 | cv::Mat annotated_image = nn.annotate(); 38 | 39 | // Display the results using OpenCV. 40 | cv::imshow("original", original_image); 41 | cv::imshow("annotated", annotated_image); 42 | cv::waitKey(); 43 | } 44 | catch (const std::exception & e) 45 | { 46 | std::cout << e.what() << std::endl; 47 | rc = 1; 48 | } 49 | 50 | return rc; 51 | } 52 | -------------------------------------------------------------------------------- /src-lib/DarkHelpPredictionResult.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | #include "DarkHelp.hpp" 7 | 8 | 9 | std::ostream & DarkHelp::operator<<(std::ostream & os, const DarkHelp::PredictionResult & pred) 10 | { 11 | os << "\"" << pred.name << "\"" 12 | << " #" << pred.best_class 13 | << " prob=" << pred.best_probability 14 | << " x=" << pred.rect.x 15 | << " y=" << pred.rect.y 16 | << " w=" << pred.rect.width 17 | << " h=" << pred.rect.height 18 | << " oid=" << pred.object_id 19 | << " tile=" << pred.tile 20 | << " entries=" << pred.all_probabilities.size() 21 | ; 22 | 23 | if (pred.all_probabilities.size() > 1) 24 | { 25 | os << " ["; 26 | for (auto iter : pred.all_probabilities) 27 | { 28 | const auto & key = iter.first; 29 | const auto & val = iter.second; 30 | os << " " << key << "=" << val; 31 | } 32 | os << " ]"; 33 | } 34 | 35 | return os; 36 | } 37 | 38 | 39 | std::ostream & DarkHelp::operator<<(std::ostream & os, const DarkHelp::PredictionResults & results) 40 | { 41 | const size_t number_of_results = results.size(); 42 | os << "prediction results: " << number_of_results; 43 | 44 | for (size_t idx = 0; idx < number_of_results; idx ++) 45 | { 46 | os << std::endl << "-> " << (idx+1) << "/" << number_of_results << ": "; 47 | operator<<(os, results.at(idx)); 48 | } 49 | 50 | return os; 51 | } 52 | -------------------------------------------------------------------------------- /CM_dependencies.cmake: -------------------------------------------------------------------------------- 1 | # DarkHelp - C++ helper class for Darknet's C API. 2 | # Copyright 2019-2024 Stephane Charette 3 | # MIT license applies. See "license.txt" for details. 4 | 5 | 6 | IF (WIN32) 7 | SET (CMAKE_HAVE_THREADS_LIBRARY 1) 8 | SET (CMAKE_USE_WIN32_THREADS_INIT 1) 9 | SET (CMAKE_USE_PTHREADS_INIT 0) 10 | SET (THREADS_PREFER_PTHREAD_FLAG ON) 11 | ENDIF () 12 | 13 | FIND_PACKAGE (Threads REQUIRED ) 14 | FIND_PACKAGE (OpenCV CONFIG REQUIRED ) 15 | INCLUDE_DIRECTORIES (${OpenCV_INCLUDE_DIRS} ) 16 | 17 | # On Linux, Darknet should be installed as /usr/lib/libdarknet.so. 18 | # On Windows, it is user-defined but probably is C:/Program Files/Darknet/lib/darknet.lib. 19 | # If that is not the case, be prepared to manually edit the CMake cache file. 20 | FIND_LIBRARY (Darknet darknet) 21 | IF (WIN32) 22 | GET_FILENAME_COMPONENT(DARKNET_PARENT_DIR "${Darknet}" DIRECTORY) 23 | INCLUDE_DIRECTORIES (${DARKNET_PARENT_DIR}/../include/) 24 | ENDIF () 25 | 26 | SET (StdCppFS "") 27 | 28 | IF (NOT WIN32) 29 | FIND_LIBRARY (Magic magic) # sudo apt-get install libmagic-dev 30 | 31 | # On older 18.04, we need to use "experimental/filesystem" instead of "filesystem" 32 | # and we need to pass in the -lstdc++fs flag when linking. This seems to have no 33 | # impact even when using newer versions of g++ which technically doesn't need this 34 | # to link. (Does this need to be fixed in a different manner?) 35 | SET ( StdCppFS stdc++fs ) 36 | ENDIF () 37 | 38 | FIND_PATH (TCLAP_INCLUDE_DIRS "tclap/Arg.h") # sudo apt-get install libtclap-dev 39 | INCLUDE_DIRECTORIES (${TCLAP_INCLUDE_DIRS}) 40 | -------------------------------------------------------------------------------- /src-doc/05_darkhelp_python_api.dox: -------------------------------------------------------------------------------- 1 | /** @page PythonAPI %DarkHelp Python API 2 | 3 | The %DarkHelp @p Python API uses the simplified @ref CAPI. 4 | 5 | @note The Python API does not expose 100% of what is available in the @ref API. 6 | 7 | Calls such as @p DarkHelp.EnableNamesIncludePercentage() map to the @p C API @ref EnableNamesIncludePercentage() which is documented as @ref DarkHelp::Config::names_include_percentage. Using this API, %DarkHelp can be used with advanced features such as tiling and snapping. 8 | 9 | Example code: 10 | 11 | ~~~~{.python} 12 | import DarkHelp 13 | 14 | dh = DarkHelp.CreateDarkHelpNN("cars.cfg".encode("utf-8"), "cars.names".encode("utf-8"), "cars.weights".encode("utf-8")) 15 | 16 | DarkHelp.SetThreshold(dh, 0.35) 17 | DarkHelp.SetAnnotationLineThickness(dh, 1) 18 | DarkHelp.EnableTiles(dh, True) 19 | DarkHelp.EnableCombineTilePredictions(dh, True) 20 | DarkHelp.EnableOnlyCombineSimilarPredictions(dh, False) 21 | DarkHelp.SetTileEdgeFactor(dh, 0.18f) 22 | DarkHelp.SetTileRectFactor(dh, 1.22f) 23 | 24 | DarkHelp.PredictFN(dh, "car_01.jpg".encode("utf-8")) 25 | DarkHelp.Annotate(dh, "output.jpg".encode("utf-8")) 26 | json = DarkHelp.GetPredictionResults(dh) 27 | 28 | DarkHelp.DestroyDarkHelpNN(dh) 29 | 30 | print(json.decode()) 31 | ~~~~ 32 | 33 | See the sample file @p src-python/example.py which shows how to use the @p Python API. 34 | 35 | Convenient links to some of the API call documentation to get started: 36 | 37 | @li @ref DarkHelpVersion() 38 | @li @ref CreateDarkHelpNN() 39 | @li @ref SetThreshold() 40 | @li @ref EnableTiles() 41 | @li @ref EnableSnapping() 42 | @li @ref SetAnnotationLineThickness() 43 | @li @ref PredictFN() 44 | @li @ref Annotate() 45 | @li @ref GetPredictionResults() 46 | 47 | */ 48 | -------------------------------------------------------------------------------- /src-tool/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # DarkHelp - C++ helper class for Darknet's C API. 2 | # Copyright 2019-2024 Stephane Charette 3 | # MIT license applies. See "license.txt" for details. 4 | 5 | 6 | ADD_EXECUTABLE ( cli DarkHelpCli.cpp DarkHelp.rc ) 7 | SET_TARGET_PROPERTIES ( cli PROPERTIES OUTPUT_NAME "DarkHelp" ) 8 | TARGET_LINK_LIBRARIES ( cli PRIVATE Threads::Threads dh ${Darknet} ${OpenCV_LIBS} ${Magic} ${StdCppFS} ) 9 | 10 | 11 | ADD_EXECUTABLE ( server DarkHelpServer.cpp DarkHelp.rc ) 12 | SET_TARGET_PROPERTIES ( server PROPERTIES OUTPUT_NAME "DarkHelpServer" ) 13 | TARGET_LINK_LIBRARIES ( server PRIVATE Threads::Threads dh ${Darknet} ${OpenCV_LIBS} ${Magic} ${StdCppFS} ) 14 | 15 | 16 | ADD_EXECUTABLE ( combine DarkHelpCombine.cpp DarkHelp.rc ) 17 | SET_TARGET_PROPERTIES ( combine PROPERTIES OUTPUT_NAME "DarkHelpCombine" ) 18 | TARGET_LINK_LIBRARIES ( combine PRIVATE Threads::Threads dh ${Darknet} ${OpenCV_LIBS} ${StdCppFS} ) 19 | 20 | 21 | IF (UNIX) 22 | # non-Windows installation is very simple 23 | INSTALL (TARGETS cli server combine DESTINATION bin) 24 | ELSE () 25 | INSTALL ( FILES DarkHelp.ico DESTINATION bin ) 26 | # more complicated install for Windows so we also get the .DLL files copied over from vcpkg 27 | # https://stackoverflow.com/a/72088102/13022 28 | # note you may also need to manually copy over darknet.dll! 29 | INSTALL (TARGETS cli server combine DESTINATION bin 30 | RUNTIME_DEPENDENCIES 31 | PRE_EXCLUDE_REGEXES "api-ms-" "ext-ms-" "wpaxholder" "HvsiFileTrust" "PdmUtilities" 32 | POST_EXCLUDE_REGEXES ".*system32/.*\\.dll" 33 | DIRECTORIES ${CMAKE_BINARY_DIR}/bin ${CMAKE_BINARY_DIR}/src-lib/Release/ ${CMAKE_BINARY_DIR}/src-lib/Debug/ 34 | RUNTIME DESTINATION bin 35 | ) 36 | ENDIF () 37 | -------------------------------------------------------------------------------- /example_project/example.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // ----------------------------------------------------------------------------- 4 | // Please also see the other source code examples in the ../src-apps/ directory. 5 | // ----------------------------------------------------------------------------- 6 | 7 | int main() 8 | { 9 | int rc = 0; 10 | 11 | try 12 | { 13 | DarkHelp::Config cfg("example.cfg", "example_best.weights", "example.names"); 14 | cfg.enable_tiles = false; 15 | cfg.annotation_auto_hide_labels = false; 16 | cfg.annotation_include_duration = true; 17 | cfg.annotation_include_timestamp = false; 18 | cfg.threshold = 0.2f; 19 | // lots of other options, scroll down this page to see what can be done: https://www.ccoderun.ca/darkhelp/api/classDarkHelp_1_1Config.html#details 20 | 21 | DarkHelp::NN nn(cfg); 22 | 23 | // you can further modify the configuration even after the neural network has been created 24 | nn.config.annotation_line_thickness = 1; 25 | nn.config.annotation_shade_predictions = 0.36f; 26 | 27 | // apply the neural network to an image on disk 28 | const auto results = nn.predict("example.jpg"); 29 | 30 | // print the neural network results on the console 31 | std::cout << results << std::endl; 32 | 33 | // display both the original image and the annotated image using OpenCV HighGUI 34 | cv::Mat img1 = nn.original_image; 35 | cv::Mat img2 = nn.annotate(); 36 | 37 | const cv::Size size(1024, 768); 38 | cv::imshow("original", DarkHelp::resize_keeping_aspect_ratio(img1, size)); 39 | cv::imshow("detected", DarkHelp::resize_keeping_aspect_ratio(img2, size)); 40 | cv::waitKey(); 41 | } 42 | catch (const std::exception & e) 43 | { 44 | std::cout << e.what() << std::endl; 45 | rc = 1; 46 | } 47 | 48 | return rc; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src-apps/process_using_bundle_and_dhthreads.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | #include "DarkHelp.hpp" 7 | #include "DarkHelpThreads.hpp" 8 | 9 | 10 | int main(int argc, char * argv[]) 11 | { 12 | int rc = 0; 13 | 14 | try 15 | { 16 | if (argc < 4) 17 | { 18 | std::cout 19 | << "Usage:" << std::endl 20 | << argv[0] << " [ ...]" << std::endl; 21 | throw std::invalid_argument("wrong number of arguments"); 22 | } 23 | 24 | std::string dh = argv[1]; 25 | std::string key = argv[2]; 26 | const size_t number_of_threads_to_start = 10; 27 | 28 | DarkHelp::DHThreads dht(dh, key, number_of_threads_to_start); 29 | 30 | // if you want to change some of the configuration settings, you'll need to do it *after* the network has been loaded 31 | for (size_t i = 0; i < number_of_threads_to_start; i++) 32 | { 33 | DarkHelp::NN * nn = dht.get_nn(i); 34 | if (nn) 35 | { 36 | nn->config.threshold = 0.2f; 37 | nn->config.enable_tiles = false; 38 | nn->config.snapping_enabled = false; 39 | } 40 | } 41 | 42 | // add the images and immediately start processing them on different threads 43 | for (int i = 3; i < argc; i++) 44 | { 45 | dht.add_images(argv[i]); 46 | } 47 | 48 | const auto results = dht.wait_for_results(); 49 | 50 | // display all of the filenames and the results for each one 51 | for (const auto & [fn, predictions] : results) 52 | { 53 | std::cout << fn << ": " << predictions << std::endl; 54 | } 55 | 56 | } 57 | catch (const std::exception & e) 58 | { 59 | std::cout << e.what() << std::endl; 60 | rc = 1; 61 | } 62 | 63 | return rc; 64 | } 65 | -------------------------------------------------------------------------------- /src-apps/display_single_image_snapping.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | #include "DarkHelp.hpp" 7 | 8 | int main(int argc, char * argv[]) 9 | { 10 | int rc = 0; 11 | 12 | try 13 | { 14 | if (argc != 5) 15 | { 16 | std::cout 17 | << "Usage:" << std::endl 18 | << argv[0] << " " << std::endl; 19 | throw std::invalid_argument("wrong number of arguments"); 20 | } 21 | 22 | std::string fn1 = argv[1]; 23 | std::string fn2 = argv[2]; 24 | std::string fn3 = argv[3]; 25 | std::string image = argv[4]; 26 | 27 | // Load the neural network. The order of the 3 files does not matter, DarkHelp should figure out which file is which. 28 | DarkHelp::NN nn(fn1, fn2, fn3); 29 | 30 | /* Turn on snapping. This will try to grow and/or shrink the bounding boxes in cases where Darknet/YOLO doesn't 31 | * provide perfect results. This is also impacted by the black-and-white threshold values, and may not apply to 32 | * all image types. 33 | */ 34 | nn.config.snapping_enabled = true; 35 | 36 | // Use OpenCV to load the image. 37 | cv::Mat original_image = cv::imread(image); 38 | 39 | // Call on the neural network to process the given filename 40 | nn.predict(original_image); 41 | 42 | // Annotate the image using the results. 43 | cv::Mat annotated_image = nn.annotate(); 44 | 45 | // Display the results using OpenCV. 46 | cv::imshow("original", original_image); 47 | cv::imshow("annotated", annotated_image); 48 | cv::waitKey(); 49 | } 50 | catch (const std::exception & e) 51 | { 52 | std::cout << e.what() << std::endl; 53 | rc = 1; 54 | } 55 | 56 | return rc; 57 | } 58 | -------------------------------------------------------------------------------- /src-doc/08_darkhelp_webcam.dox: -------------------------------------------------------------------------------- 1 | /** @page Cam %DarkHelp Camera 2 | 3 | The %DarkHelp Camera is a command-line tool that loads a neural network and applies it to every frame read from a webcam. The output is then shown on the screen and saved to disk as a video. 4 | 5 | Similar functionality is available in the example applications. See the code in @p process_video_webcam.cpp and @p save_webcam_to_video.cpp. But the %DarkHelp Cam tool contains many additional and advanced features, such as tiling, snapping, threshold, and font settings. It is meant to be a useful command-line tool, while the code in the @p src-apps directory is meant to be example source code. 6 | 7 | To get a full list of parameters with a brief explanation of each one, run @p "DarkHelp_cam --help". Most of the parameters are very similar to the %DarkHelp CLI. 8 | 9 | Here is an example showing how the @p DarkHelp_cam tool can be used to load the MSCOCO pre-trained weights: 10 | 11 | ~~~~{.sh} 12 | DarkHelp_cam \ 13 | --camera 2 \ 14 | --autohide off \ 15 | --duration off \ 16 | --redirection on \ 17 | --threshold 0.25 \ 18 | --size 800x600 \ 19 | --fps 30 \ 20 | --pixelate on \ 21 | mscoco.names \ 22 | mscoco-yolov4-tiny.cfg \ 23 | mscoco-yolov4-tiny.weights 24 | ~~~~ 25 | 26 | This opens the @p /dev/video2 device, configures the webcam to use 800x600 @ 30 FPS, uses a Darknet threshold of 0.25, and pixelates all of the detected objects. With those example parameters, the @p .mp4 video that is generated as output might look similar to this frame: 27 | 28 | @image html darkhelp_cam.jpg 29 | 30 | To test the @p DarkHelp_cam command, you'll need some neural network files -- the @p .cfg, @p .names, and @p .weights files. 31 | 32 | @note If you've not yet trained a custom network, you can download the MSCOCO pre-trained weights from the repo: https://github.com/hank-ai/darknet#mscoco-pre-trained-weights 33 | 34 | */ 35 | -------------------------------------------------------------------------------- /src-cam/CamOptions.hpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | 7 | #include "DarkHelp.hpp" 8 | 9 | 10 | namespace DarkHelp 11 | { 12 | class CamOptions final 13 | { 14 | public: 15 | 16 | bool show_gui; ///< Set to @p true if OpenCV HighGUI can be used, set to @p false to run in a console window. 17 | std::string device_filename; ///< A specific filename to use such as @p /dev/video0 when @ref device_index is set to @p -1. 18 | int device_index; ///< The OpenCV device index to use, unless it is set to @p -1 in which case @ref device_filename is used instead. 19 | int device_backend; ///< Which backend OpenCV should be using (CAP_ANY, CAP_V4L2, CAP_FFMPEG, ...). 20 | double fps_request; ///< Frames per second requested by the user. 21 | double fps_actual; ///< Frames per second as determined by OpenCV, which is not necessarily the same as what was requested. 22 | cv::Size size_request; ///< The video dimensions the user want to be using. 23 | cv::Size size_actual; ///< The video dimensions as determined by OpenCV, which is not necessarily the same as what was requested. 24 | cv::Size resize_before; ///< If set, images will be resized to this dimension prior to calling Darknet. 25 | cv::Size resize_after; ///< If set, images will be resized to this dimension after annotating by DarkHelp. 26 | int capture_seconds; ///< The length of time (in seconds) to run before exiting. 27 | 28 | /// Constructor. 29 | CamOptions(); 30 | 31 | /// Destructor 32 | ~CamOptions(); 33 | 34 | /// Reset all of the options to their default values. This is automatically called by the constructor. 35 | CamOptions & reset(); 36 | }; 37 | 38 | void parse(CamOptions & cam_options, DarkHelp::Config & config, int argc, char * argv[]); 39 | } 40 | -------------------------------------------------------------------------------- /src-apps/display_single_image_custom_settings.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | #include "DarkHelp.hpp" 7 | 8 | int main(int argc, char * argv[]) 9 | { 10 | int rc = 0; 11 | 12 | try 13 | { 14 | if (argc != 5) 15 | { 16 | std::cout 17 | << "Usage:" << std::endl 18 | << argv[0] << " " << std::endl; 19 | throw std::invalid_argument("wrong number of arguments"); 20 | } 21 | 22 | std::string fn1 = argv[1]; 23 | std::string fn2 = argv[2]; 24 | std::string fn3 = argv[3]; 25 | std::string image = argv[4]; 26 | 27 | // You can customize settings before you load the network, or after you load the network. Or both, like we do in this example. 28 | DarkHelp::Config config(fn1, fn2, fn3); 29 | config.annotation_auto_hide_labels = false; 30 | config.annotation_include_duration = true; 31 | config.annotation_include_timestamp = false; 32 | config.threshold = 0.25; 33 | 34 | // Load the neural network using the configuration object. 35 | DarkHelp::NN nn(config); 36 | 37 | /* At this point the "config" object above is no longer used. The DarkHelp::NN object made a copy of it. When you 38 | * want to alter additional config settings after this point, you'll need to do so via that copy in nn.config. 39 | */ 40 | nn.config.enable_tiles = false; 41 | nn.config.annotation_line_thickness = 1; 42 | nn.config.annotation_font_scale = 0.75; 43 | 44 | // Call on the neural network to process the given filename 45 | nn.predict(image); 46 | 47 | // Display the annotated image. 48 | cv::imshow("annotated", nn.annotate()); 49 | cv::waitKey(); 50 | } 51 | catch (const std::exception & e) 52 | { 53 | std::cout << e.what() << std::endl; 54 | rc = 1; 55 | } 56 | 57 | return rc; 58 | } 59 | -------------------------------------------------------------------------------- /src-apps/process_video_webcam.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | #include "DarkHelp.hpp" 7 | 8 | int main(int argc, char * argv[]) 9 | { 10 | int rc = 0; 11 | 12 | try 13 | { 14 | if (argc != 4) 15 | { 16 | std::cout 17 | << "Usage:" << std::endl 18 | << argv[0] << " " << std::endl; 19 | throw std::invalid_argument("wrong number of arguments"); 20 | } 21 | 22 | // Load the neural network. The order of the 3 files does not matter, DarkHelp should figure out which file is which. 23 | DarkHelp::NN nn(argv[1], argv[2], argv[3]); 24 | 25 | // Use OpenCV to open the webcam. Index zero is the first webcam. Attemp to set a few camera properties. 26 | cv::VideoCapture cap(0); 27 | if (not cap.isOpened()) 28 | { 29 | throw std::runtime_error("failed to open the webcam"); 30 | } 31 | cap.set(cv::CAP_PROP_FRAME_WIDTH, 640.0); 32 | cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480.0); 33 | cap.set(cv::CAP_PROP_FPS, 30.0); 34 | 35 | while (cap.isOpened()) 36 | { 37 | cv::Mat frame; 38 | cap >> frame; 39 | if (frame.empty()) 40 | { 41 | break; 42 | } 43 | 44 | nn.predict(frame); 45 | frame = nn.annotate(); 46 | 47 | /* This is an over-simplistic example, where the waitKey() timeout is hard-coded. You want the timeout to be short 48 | * enough for the OpenCV HighGUI event loop to have time to process events, but not too long that the code doesn't 49 | * have time to keep up with new incoming video frames. 50 | * 51 | * An assumption is made that most webcams might default to 30 FPS, meaning 33.33333 milliseconds per frame. Sleep 52 | * just half of that time to process HighGUI events, and instead spend the extra remaining time waiting for the next 53 | * frame to be extracted. 54 | */ 55 | cv::imshow("video", frame); 56 | const auto key = cv::waitKey(15); 57 | if (key == 27) 58 | { 59 | break; 60 | } 61 | } 62 | } 63 | catch (const std::exception & e) 64 | { 65 | std::cout << e.what() << std::endl; 66 | rc = 1; 67 | } 68 | 69 | return rc; 70 | } 71 | -------------------------------------------------------------------------------- /src-apps/process_many_images_on_threads.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | #include "DarkHelpThreads.hpp" 7 | 8 | 9 | int main(int argc, char * argv[]) 10 | { 11 | int rc = 1; 12 | 13 | try 14 | { 15 | if (argc < 5) 16 | { 17 | std::cout 18 | << "Usage:" << std::endl 19 | << argv[0] << " []" << std::endl; 20 | throw std::invalid_argument("wrong number of arguments"); 21 | } 22 | 23 | // these are just a few of the DarkHelp settings that can be set 24 | // for additional examples, see https://www.ccoderun.ca/darkhelp/api/classDarkHelp_1_1Config.html#details 25 | DarkHelp::Config cfg(argv[1], argv[2], argv[3]); 26 | cfg.threshold = 0.2f; 27 | cfg.enable_tiles = false; 28 | cfg.snapping_enabled = false; 29 | cfg.annotation_auto_hide_labels = false; 30 | cfg.annotation_include_duration = false; 31 | cfg.annotation_include_timestamp = false; 32 | cfg.annotation_pixelate_enabled = false; 33 | cfg.annotation_line_thickness = 1; 34 | 35 | const size_t number_of_threads_to_start = 10; 36 | 37 | DarkHelp::DHThreads dht(cfg, number_of_threads_to_start, "/tmp/output/"); 38 | 39 | #if 0 40 | // test adding a bunch of image filenames 41 | for (int i = 4; i < argc; i ++) 42 | { 43 | // call this as many times as necessary, with either a subdirectory name or a specific image filename 44 | dht.add_images(argv[i]); 45 | } 46 | #else 47 | // test adding a bunch of *images* (not filenames) 48 | for (int i = 4 ; i < argc; i ++) 49 | { 50 | // hopefully for this example all of the these are image files and not directory names 51 | cv::Mat mat = cv::imread(argv[i]); 52 | dht.add_image(mat); 53 | } 54 | #endif 55 | 56 | const auto results = dht.wait_for_results(); 57 | 58 | // display all of the filenames and the results for each one 59 | for (const auto & [key, val] : results) 60 | { 61 | std::cout << key << ": " << val << std::endl; 62 | } 63 | 64 | rc = 0; 65 | } 66 | catch (const std::exception & e) 67 | { 68 | std::cout << "Exception: " << e.what() << std::endl; 69 | } 70 | 71 | return rc; 72 | } 73 | -------------------------------------------------------------------------------- /readme_windows.txt: -------------------------------------------------------------------------------- 1 | # DarkHelp - C++ helper class for Darknet's C API. 2 | # Copyright 2019-2024 Stephane Charette 3 | # MIT license applies. See "license.txt" for details. 4 | 5 | 6 | Most recent documentation for DarkHelp: https://github.com/stephanecharette/DarkHelp/ 7 | 8 | # -------- 9 | # WARNING! 10 | # -------- 11 | 12 | These instructions are no longer up-to-date. I strongly recommend you do NOT 13 | install things this way. See the build instructions on the DarkHelp project 14 | page instead (readme.md) for the installation steps. 15 | 16 | 17 | # ------------------------- 18 | # SETTING UP PRE-REQUISITES 19 | # ------------------------- 20 | 21 | Install Visual Studio 2019 from https://visualstudio.microsoft.com/vs/ 22 | During installation, select "Desktop development with C++". 23 | 24 | Download and install WinGet from https://github.com/microsoft/winget-cli/releases 25 | Run the following commands: 26 | 27 | winget install git.git 28 | winget install kitware.cmake 29 | winget install nsis 30 | 31 | 32 | # ------------------------- 33 | # BUILDING OPENCV & DARKNET 34 | # ------------------------- 35 | 36 | Run the following commands: 37 | 38 | mkdir c:\src 39 | cd c:\src 40 | git clone https://github.com/microsoft/vcpkg 41 | cd vcpkg 42 | bootstrap-vcpkg.bat 43 | vcpkg.exe integrate install 44 | vcpkg.exe integrate powershell 45 | vcpkg.exe install opencv[contrib,core,dnn,ffmpeg,jpeg,png,quirc,tiff,webp]:x64-windows darknet[opencv-base]:x64-windows 46 | 47 | 48 | # ----------------- 49 | # BUILDING DARKHELP 50 | # ----------------- 51 | 52 | Assuming you already followed the steps above which included installing vcpkg, run the following commands: 53 | 54 | cd c:\src\vcpkg 55 | vcpkg.exe install tclap:x64-windows 56 | cd c:\src 57 | git clone https://github.com/stephanecharette/DarkHelp.git 58 | cd darkhelp 59 | mkdir build 60 | cd build 61 | cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=C:/src/vcpkg/scripts/buildsystems/vcpkg.cmake .. 62 | 63 | You should now have a Visual Studio project file. You can build using Visual Studio, or from the command line: 64 | 65 | msbuild.exe /property:Platform=x64;Configuration=Release /target:Build -maxCpuCount -verbosity:normal -detailedSummary DarkHelp.sln 66 | 67 | This will build a static library named "darkhelp.lib", and the "DarkHelp.exe" example command-line tool. 68 | 69 | Create the installation package: 70 | 71 | msbuild.exe /property:Platform=x64;Configuration=Release PACKAGE.vcxproj 72 | 73 | Also see the script build_windows.cmd. 74 | -------------------------------------------------------------------------------- /src-python/example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import DarkHelp 4 | 5 | # Sample code to show how to use the DarkHelp C API in Python. 6 | 7 | print("DarkHelp v" + DarkHelp.DarkHelpVersion().decode("utf-8")) 8 | print("Darknet v" + DarkHelp.DarknetVersion().decode("utf-8")) 9 | 10 | # The "Rolodex" example dataset can be downloaded from https://www.ccoderun.ca/programming/2023-11-06_Rolodex/ 11 | cfg_filename = "Rolodex.cfg".encode("utf-8") 12 | names_filename = "Rolodex.names".encode("utf-8") 13 | weights_filename = "Rolodex_best.weights".encode("utf-8") 14 | 15 | # By default CreateDarknetNN() will toggle the output redirection to hide the 16 | # output from Darknet, so call ToggleOutputRediretion() just prior to that if 17 | # you do want to see the neural network being loaded. 18 | #DarkHelp.ToggleOutputRedirection() 19 | 20 | # The order in which the .cfg, .names, and .weights file are specified does 21 | # not matter. DarkHelp will automatically figure out which file is which. 22 | dh = DarkHelp.CreateDarkHelpNN(cfg_filename, names_filename, weights_filename) 23 | if not dh: 24 | print(""" 25 | Failed to allocate a DarkHelp object. Possible problems include: 26 | 27 | 1) missing neural network files, or files are in a different directory 28 | 2) libraries needed by DarkHelp or Darknet have not been installed 29 | 3) errors in DarkHelp or Darknet libraries 30 | """) 31 | quit(1) 32 | 33 | # If you toggled the output redirection above, remember to restore it once the 34 | # network has been loaded, otherwise all your output will go to /dev/null. 35 | #DarkHelp.ToggleOutputRedirection() 36 | 37 | # Configure DarkHelp to ensure it behaves like we want. 38 | DarkHelp.SetThreshold(dh, 0.35) 39 | DarkHelp.EnableTiles(dh, False) 40 | DarkHelp.EnableSnapping(dh, True) 41 | DarkHelp.EnableUseFastImageResize(dh, False) 42 | DarkHelp.EnableNamesIncludePercentage(dh, True) 43 | DarkHelp.EnableAnnotationAutoHideLabels(dh, False) 44 | DarkHelp.EnableAnnotationIncludeDuration(dh, False) 45 | DarkHelp.EnableAnnotationIncludeTimestamp(dh, False) 46 | DarkHelp.SetAnnotationLineThickness(dh, 1) 47 | 48 | # Now we run all our images through DarkHelp, generating both an 49 | # output image and the JSON string with all of the predicitions. 50 | # This is the code you'd run in a loop if you have many images. 51 | DarkHelp.PredictFN(dh, "page_1.png".encode("utf-8")) 52 | DarkHelp.Annotate(dh, "output.jpg".encode("utf-8")) 53 | json = DarkHelp.GetPredictionResults(dh) 54 | print(json.decode()) 55 | 56 | # When done with DarkHelp, destroy the object to release memory. 57 | DarkHelp.DestroyDarkHelpNN(dh) 58 | -------------------------------------------------------------------------------- /src-apps/using_c_api.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | 7 | // This source file is written in C++ so we can use OpenCV easily, 8 | // but the calls demonstrated are from the "C" DarkHelp API. 9 | #include "DarkHelp_C_API.h" 10 | #include 11 | #include 12 | 13 | 14 | int main(int argc, char * argv[]) 15 | { 16 | int rc = 0; 17 | 18 | try 19 | { 20 | if (argc != 5) 21 | { 22 | std::cout 23 | << "Usage:" << std::endl 24 | << argv[0] << " " << std::endl; 25 | throw std::invalid_argument("wrong number of arguments"); 26 | } 27 | 28 | const std::string fn1 = argv[1]; 29 | const std::string fn2 = argv[2]; 30 | const std::string fn3 = argv[3]; 31 | const std::string image = argv[4]; 32 | 33 | std::cout 34 | << "Darknet v" << DarknetVersion() << std::endl 35 | << "DarkHelp v" << DarkHelpVersion() << std::endl; 36 | 37 | DarkHelpPtr ptr = CreateDarkHelpNN(fn1.c_str(), fn2.c_str(), fn3.c_str()); 38 | 39 | /* All of the DarkHelp settings have default values described in the documentation. Calling these here 40 | * just for demonstration. You don't have to call all of these if the default value works for you. 41 | */ 42 | SetThreshold(ptr, 0.25); 43 | EnableNamesIncludePercentage(ptr, true); 44 | EnableAnnotationAutoHideLabels(ptr, false); 45 | SetAnnotationShadePredictions(ptr, 0.15f); 46 | SetAnnotationFontScale(ptr, 0.5); 47 | SetAnnotationFontThickness(ptr, 1); 48 | SetAnnotationLineThickness(ptr, 1); 49 | EnableAnnotationIncludeDuration(ptr, false); 50 | EnableAnnotationIncludeTimestamp(ptr, false); 51 | EnableTiles(ptr, false); 52 | EnableSnapping(ptr, true); 53 | 54 | PredictFN(ptr, image.c_str()); 55 | 56 | const char * json = GetPredictionResults(ptr); 57 | std::cout << "results=" << json << std::endl; 58 | 59 | Annotate(ptr, "testing.jpg"); 60 | 61 | /* Once the DarkHelp object has been destroyed, make sure you don't make any further 62 | * DarkHelp "C" calls other than CreateDarkHelpNN() to create a new instance. 63 | */ 64 | DestroyDarkHelpNN(ptr); 65 | 66 | // see what the output image looks like 67 | cv::Mat mat = cv::imread("testing.jpg"); 68 | cv::imshow("annotated", mat); 69 | cv::waitKey(); 70 | } 71 | catch (const std::exception & e) 72 | { 73 | std::cout << e.what() << std::endl; 74 | rc = 1; 75 | } 76 | 77 | return rc; 78 | } 79 | -------------------------------------------------------------------------------- /src-doc/header_ccoderun.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | $projectname: $title 10 | $title 11 | 12 | 13 | 14 | $treeview 15 | $search 16 | $mathjax 17 | 18 | $extrastylesheet 19 | 20 | 21 |
22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 38 | 39 | 40 | 41 | 44 | 45 | 46 | 47 | 48 | 53 | 54 | 55 | 56 | 57 | 58 |
33 |
$projectname 34 |  $projectnumber 35 |
36 |
$projectbrief
37 |
42 |
$projectbrief
43 |
49 |
50 | Looking for a C++ dev who knows OpenCV?
I'm looking for work. Hire me! 51 |
52 |
$searchbox
59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /src-doc/04_building_darkhelp.dox: -------------------------------------------------------------------------------- 1 | /** @page Building Building %DarkHelp 2 | 3 | @section Windows 4 | 5 | The most up-to-date build instructions are the ones in @p readme.md. You can find this easily on the github repo: https://github.com/stephanecharette/DarkHelp#building-darknet-windows 6 | 7 | The Windows build uses a combination of @p winget, @p vcpkg, and @p cmake to get everything built and installed, including 3rd party dependencies like OpenCV. 8 | 9 | Once all the dependencies are installed, the %DarkHelp portion is like this: 10 | 11 | ~~~~{.sh} 12 | cd c:\src 13 | git clone https://github.com/stephanecharette/DarkHelp.git 14 | cd darkhelp 15 | mkdir build 16 | cd build 17 | cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=C:/src/vcpkg/scripts/buildsystems/vcpkg.cmake .. 18 | msbuild.exe /property:Platform=x64;Configuration=Release /target:Build -maxCpuCount -verbosity:normal -detailedSummary DarkHelp.sln 19 | msbuild.exe /property:Platform=x64;Configuration=Release PACKAGE.vcxproj 20 | ~~~~ 21 | 22 | @section Linux 23 | 24 | Extremely simple tutorial on how to build Darknet, %DarkHelp, and DarkMark: 25 | 26 | @htmlonly[block] 27 | 28 | @endhtmlonly 29 | 30 | Building both Darknet and %DarkHelp on Linux should not take more than 5 minutes combined. See the instructions in @p readme.md: https://github.com/stephanecharette/DarkHelp#building-darknet-linux 31 | 32 | Once Darknet is built @em and installed, download the source code to %DarkHelp and build like this: 33 | 34 | ~~~~{.sh} 35 | sudo apt-get install build-essential libtclap-dev libmagic-dev libopencv-dev 36 | cd ~/src/ 37 | git clone https://github.com/stephanecharette/DarkHelp.git 38 | cd DarkHelp 39 | mkdir build 40 | cd build 41 | cmake -DCMAKE_BUILD_TYPE=Release .. 42 | make 43 | make package 44 | sudo dpkg -i darkhelp*.deb 45 | ~~~~ 46 | 47 | @section BuildingDoxygen Doxygen 48 | 49 | If desired, the doxygen documentation can be created with @p "make doc". Of course, Doxygen must be installed. 50 | 51 | @section BuildingPackages Packages and the DarkHelp API 52 | 53 | To install %DarkHelp so the API can be used within your own C++ application, run @p "sudo dpkg -i darkhelp-*.deb" after having run @p "make package". 54 | 55 | Now from within your application, you must @p "#include " and link against @p libdarkhelp.so, @p libdarknet.so, and the OpenCV libraries. 56 | 57 | An example showing how to do this is available in the github repo: https://github.com/stephanecharette/DarkHelp/tree/master/example_project 58 | 59 | */ 60 | -------------------------------------------------------------------------------- /src-apps/save_webcam_to_video.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | #include "DarkHelp.hpp" 7 | 8 | int main(int argc, char * argv[]) 9 | { 10 | int rc = 0; 11 | 12 | try 13 | { 14 | if (argc != 4) 15 | { 16 | std::cout 17 | << "Usage:" << std::endl 18 | << argv[0] << " " << std::endl; 19 | throw std::invalid_argument("wrong number of arguments"); 20 | } 21 | 22 | // Load the neural network. The order of the 3 files does not matter, DarkHelp should figure out which file is which. 23 | DarkHelp::NN nn(argv[1], argv[2], argv[3]); 24 | 25 | // Use OpenCV to open the webcam. Index zero is the first webcam. Attemp to set a few camera properties. 26 | cv::VideoCapture cap(0); 27 | if (not cap.isOpened()) 28 | { 29 | throw std::runtime_error("failed to open the webcam"); 30 | } 31 | cap.set(cv::CAP_PROP_FPS, 30.0); 32 | cap.set(cv::CAP_PROP_FRAME_WIDTH, 640.0); 33 | cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480.0); 34 | 35 | /* Be careful here. Just because we requested a certain size and FPS doesn't mean the camera supports that mode, 36 | * or that OpenCV was successful in setting those values. You should check to see if the values we think we set are 37 | * the values that OpenCV and the webcam are using. 38 | */ 39 | cv::Mat frame; 40 | cap >> frame; 41 | const double fps = cap.get(cv::CAP_PROP_FPS); 42 | cv::VideoWriter out("out.mp4", cv::VideoWriter::fourcc('m', 'p', '4', 'v'), fps, frame.size()); 43 | 44 | /* The length of time we wait should be 1000 milliseconds divided by the FPS. So for 30 FPS video, we might wait 45 | * 33.333 milliseconds between each frame. But this example is very simple, and we're not getting the current time 46 | * to calibrate against to ensure each frame is shown for the right duration. Plus we make no attempt in the code 47 | * below to take into account the time it takes to run nn.predict() and nn.annotate(). 48 | * 49 | * So as a simple solution for a simple app, let's divide the wait time in half. This should give the HighGUI event 50 | * loop time to run, but shouldn't be too much where we introduce lag. 51 | */ 52 | const int milliseconds_to_wait = std::round(1000.0 / 2.0 / fps); 53 | while (cap.isOpened()) 54 | { 55 | cap >> frame; 56 | if (frame.empty()) 57 | { 58 | // something went wrong -- for example, webcam may have been disconnected 59 | break; 60 | } 61 | 62 | nn.predict(frame); 63 | auto annotated_frame = nn.annotate(); 64 | out.write(annotated_frame); 65 | 66 | cv::imshow("video", annotated_frame); 67 | const auto key = cv::waitKey(milliseconds_to_wait); 68 | if (key == 27) 69 | { 70 | break; 71 | } 72 | } 73 | } 74 | catch (const std::exception & e) 75 | { 76 | std::cout << e.what() << std::endl; 77 | rc = 1; 78 | } 79 | 80 | return rc; 81 | } 82 | -------------------------------------------------------------------------------- /src-lib/DarkHelpConfig.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | #include "DarkHelp.hpp" 7 | 8 | #ifdef WIN32 9 | #pragma warning(disable: 4305) 10 | #endif 11 | 12 | 13 | DarkHelp::Config::~Config() 14 | { 15 | return; 16 | } 17 | 18 | DarkHelp::Config::Config() 19 | { 20 | reset(); 21 | 22 | return; 23 | } 24 | 25 | 26 | DarkHelp::Config::Config(const std::string & cfg_fn, const std::string & weights_fn, const std::string & names_fn, const bool verify_files_first, const EDriver d) : 27 | DarkHelp::Config::Config() 28 | { 29 | cfg_filename = cfg_fn; 30 | weights_filename = weights_fn; 31 | names_filename = names_fn; 32 | 33 | if (verify_files_first) 34 | { 35 | DarkHelp::verify_cfg_and_weights(cfg_filename, weights_filename, names_filename); 36 | } 37 | 38 | #ifndef HAVE_OPENCV_DNN_OBJDETECT 39 | // with old versions of OpenCV, we don't have a DNN module 40 | driver = DarkHelp::EDriver::kDarknet; 41 | #else 42 | driver = d; 43 | #endif 44 | 45 | return; 46 | } 47 | 48 | 49 | DarkHelp::Config & DarkHelp::Config::reset() 50 | { 51 | // pick some reasonable default values 52 | 53 | cfg_filename .clear(); 54 | weights_filename .clear(); 55 | names_filename .clear(); 56 | threshold = 0.5f; 57 | hierarchy_threshold = 0.5f; 58 | non_maximal_suppression_threshold = 0.45f; 59 | annotation_font_face = cv::HersheyFonts::FONT_HERSHEY_SIMPLEX; 60 | annotation_font_scale = 0.5; 61 | annotation_font_thickness = 1; 62 | annotation_line_thickness = 2; 63 | annotation_include_duration = true; 64 | annotation_include_timestamp = false; 65 | annotation_pixelate_enabled = false; 66 | annotation_pixelate_size = 15; 67 | annotation_pixelate_classes .clear(); 68 | names_include_percentage = true; 69 | include_all_names = true; 70 | fix_out_of_bound_values = true; 71 | annotation_colours = DarkHelp::get_default_annotation_colours(); 72 | sort_predictions = ESort::kAscending; 73 | annotation_auto_hide_labels = true; 74 | annotation_suppress_all_labels = false; 75 | annotation_shade_predictions = 0.25; 76 | enable_debug = false; 77 | enable_tiles = false; 78 | combine_tile_predictions = true; 79 | only_combine_similar_predictions = true; 80 | tile_edge_factor = 0.25f; 81 | tile_rect_factor = 1.20f; 82 | modify_batch_and_subdivisions = true; 83 | driver = EDriver::kInvalid; 84 | annotation_suppress_classes .clear(); 85 | snapping_enabled = false; 86 | binary_threshold_block_size = 25; 87 | binary_threshold_constant = 25; 88 | snapping_horizontal_tolerance = 5; 89 | snapping_vertical_tolerance = 5; 90 | snapping_limit_shrink = 0.4; 91 | snapping_limit_grow = 1.25; 92 | redirect_darknet_output = false; // don't default this to TRUE, it becomes too easy to hide errors! 93 | use_fast_image_resize = true; 94 | 95 | return *this; 96 | } 97 | -------------------------------------------------------------------------------- /src-doc/06_darkhelp_tool.dox: -------------------------------------------------------------------------------- 1 | /** @page Tool %DarkHelp CLI Tool 2 | 3 | The %DarkHelp library also comes with a command-line tool that uses the @ref API to show the results on the screen, or outputs the findings in JSON format. 4 | 5 | @image html DarkHelp.png 6 | 7 | @note The CLI tool can also be used in a non-interactive mode, where it returns results as a JSON structure. This can be useful in bash scripts, and is explained in @ref ShellScripting. 8 | 9 | You can load a neural network and browse through a large set of images as you examine the results of calling @ref DarkHelp::NN::predict() and @ref DarkHelp::NN::annotate() on each image. Images can be resized, apply different thresholds to the predictions, and get details on the predicted results. 10 | 11 | Here is an example of how to use it: 12 | 13 | ~~~~{.sh} 14 | DarkHelp barcodetest.cfg barcodetest_final.weights barcodetest.names test_image_1.jpg test_image_2.jpg 15 | ~~~~ 16 | 17 | Note the parameters: 18 | 19 | @li The `.cfg` file used to originally train the neural network. 20 | @li The `.weights` file that was created as part of the neural network training. 21 | @li The `.names` file which contains the names of the various classes in the network. 22 | @li One or more image file (typically `.jpg`, but could be any type of image) against which you want to run the network. This can be left out if you instead use the @p -l parameter to read in a list of image filenames from a text file. 23 | 24 | There are at least a dozen possible command-line arguments. run `%DarkHelp --help` for the full list or see @ref Parameters. Some examples: 25 | 26 | ~~~~{.sh} 27 | # -b means resize the "before" input image prior to calling DarkHelp::predict() 28 | # -t sets the new lower bound threshold to 25% 29 | DarkHelp -b 800x800 -t 0.25 barcodetest.cfg barcodetest_best.weights barcodetest.names *.jpg 30 | 31 | # -a resizes the "after" output image once DarkHelp::annotate() has been called 32 | # -s starts the viewer in slideshow mode, where a new image is loaded every second 33 | DarkHelp -a 640x480 -s barcodetest.cfg barcodetest_final.weights barcodetest.names *.jpg 34 | 35 | # -j outputs the results as JSON text instead of showing an annotated image. 36 | DarkHelp -j -t 0.5 barcodetest.cfg barcodetest_best.weights barcodetest.names *.jpg 37 | ~~~~ 38 | 39 | In addition to command-line arguments, there are several keys you can use in the viewer. Some of which are: 40 | 41 | @li @p q or @p ESC to exit from the viewer. 42 | @li @p t to toggle image tiling (see @ref Tiling) 43 | @li @p w to write the current image to disk in the current working directory (see @p "output.png") 44 | @li @p HOME to return to the first image in the data set 45 | @li @p END to skip to the last image in the data set 46 | @li @p LEFT go to the previous image 47 | @li @p UP increase the rate at which images are processed during the slideshow 48 | @li @p DOWN decrease the rate at which images are processed during the slideshow 49 | @li @p PAGE-UP increase the threshold 50 | @li @p PAGE-DOWN decrease the threshold 51 | @li @p g to toggle greyscale images 52 | @li @p p to pause or play the slideshow 53 | 54 | Press @p h in %DarkHelp to show the help page with all the keyboard shortcuts. 55 | 56 | Also see: 57 | - @subpage Parameters 58 | - @subpage ShellScripting 59 | 60 | */ 61 | -------------------------------------------------------------------------------- /CM_package.cmake: -------------------------------------------------------------------------------- 1 | # DarkHelp - C++ helper class for Darknet's C API. 2 | # Copyright 2019-2024 Stephane Charette 3 | # MIT license applies. See "license.txt" for details. 4 | 5 | 6 | SET ( CPACK_PACKAGE_VENDOR "Stephane Charette" ) 7 | SET ( CPACK_PACKAGE_CONTACT "stephanecharette@gmail.com" ) 8 | SET ( CPACK_PACKAGE_VERSION ${DH_VERSION} ) 9 | SET ( CPACK_PACKAGE_VERSION_MAJOR ${DH_VER_MAJOR} ) 10 | SET ( CPACK_PACKAGE_VERSION_MINOR ${DH_VER_MINOR} ) 11 | SET ( CPACK_PACKAGE_VERSION_PATCH ${DH_VER_PATCH} ) 12 | SET ( CPACK_PACKAGE_INSTALL_DIRECTORY "DarkHelp" ) 13 | SET ( CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/license.txt ) 14 | SET ( CPACK_PACKAGE_NAME "darkhelp" ) 15 | SET ( CPACK_PACKAGE_DESCRIPTION_SUMMARY "DarkHelp C++ library" ) 16 | SET ( CPACK_PACKAGE_DESCRIPTION "DarkHelp C++ library" ) 17 | SET ( CPACK_PACKAGE_HOMEPAGE_URL "https://www.ccoderun.ca/DarkHelp/" ) 18 | 19 | IF ( WIN32 ) 20 | SET ( CPACK_PACKAGE_FILE_NAME "darkhelp-${DH_VERSION}-Windows-64" ) 21 | SET ( CPACK_NSIS_PACKAGE_NAME "DarkHelp" ) 22 | SET ( CPACK_NSIS_DISPLAY_NAME "DarkHelp v${DH_VERSION}" ) 23 | SET ( CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\src-tool\\\\DarkHelp.ico" ) 24 | SET ( CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\src-tool\\\\DarkHelp.ico" ) 25 | SET ( CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\src-tool\\\\DarkHelp.ico" ) 26 | SET ( CPACK_NSIS_CONTACT "stephanecharette@gmail.com" ) 27 | SET ( CPACK_NSIS_URL_INFO_ABOUT "https://www.ccoderun.ca/DarkHelp/" ) 28 | SET ( CPACK_NSIS_HELP_LINK "https://www.ccoderun.ca/DarkHelp/" ) 29 | SET ( CPACK_NSIS_MODIFY_PATH "ON" ) 30 | SET ( CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL "ON" ) 31 | SET ( CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\DarkHelp.ico" ) 32 | SET ( CPACK_GENERATOR "NSIS" ) 33 | ELSE () 34 | # Get the kernel name. This should give us a string such as "Linux". 35 | EXECUTE_PROCESS ( 36 | COMMAND uname -s 37 | OUTPUT_VARIABLE DH_UNAME_S 38 | OUTPUT_STRIP_TRAILING_WHITESPACE ) 39 | 40 | # Get the machine hardware name. This should give us a string such as "x86_64" or "aarch64" (Jetson Nano for example). 41 | EXECUTE_PROCESS ( 42 | COMMAND uname -m 43 | OUTPUT_VARIABLE DH_UNAME_M 44 | OUTPUT_STRIP_TRAILING_WHITESPACE ) 45 | 46 | # Get the name "Ubuntu". 47 | EXECUTE_PROCESS ( 48 | COMMAND lsb_release --id 49 | COMMAND cut -d\t -f2 50 | OUTPUT_VARIABLE DH_LSB_ID 51 | OUTPUT_STRIP_TRAILING_WHITESPACE ) 52 | 53 | # Get the version number "20.04". 54 | EXECUTE_PROCESS ( 55 | COMMAND lsb_release --release 56 | COMMAND cut -d\t -f2 57 | OUTPUT_VARIABLE DH_LSB_REL 58 | OUTPUT_STRIP_TRAILING_WHITESPACE ) 59 | 60 | SET ( CPACK_PACKAGE_FILE_NAME "darkhelp-${DH_VERSION}-${DH_UNAME_S}-${DH_UNAME_M}-${DH_LSB_ID}-${DH_LSB_REL}" ) 61 | SET ( CPACK_DEBIAN_PACKAGE_SECTION "other" ) 62 | SET ( CPACK_DEBIAN_PACKAGE_PRIORITY "optional" ) 63 | SET ( CPACK_DEBIAN_PACKAGE_MAINTAINER "Stephane Charette " ) 64 | SET ( CPACK_DEBIAN_PACKAGE_SHLIBDEPS "ON" ) 65 | SET ( CPACK_GENERATOR "DEB" ) 66 | SET ( CPACK_SOURCE_IGNORE_FILES ".svn" ".git" ".kdev4" "build/" "build_and_upload.sh" ) 67 | SET ( CPACK_SOURCE_GENERATOR "TGZ;ZIP" ) 68 | ENDIF () 69 | 70 | INCLUDE( CPack ) 71 | -------------------------------------------------------------------------------- /src-apps/video_display_realtime.cpp: -------------------------------------------------------------------------------- 1 | /* DarkHelp - C++ helper class for Darknet's C API. 2 | * Copyright 2019-2024 Stephane Charette 3 | * MIT license applies. See "license.txt" for details. 4 | */ 5 | 6 | #include "DarkHelp.hpp" 7 | 8 | int main(int argc, char * argv[]) 9 | { 10 | int rc = 0; 11 | 12 | try 13 | { 14 | if (argc != 5) 15 | { 16 | std::cout 17 | << "Usage:" << std::endl 18 | << argv[0] << "