Skip to content

Commit a7a328f

Browse files
committed
feat: make detectors work on windows
1 parent 8a9415d commit a7a328f

File tree

5 files changed

+75
-21
lines changed

5 files changed

+75
-21
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@
1111
!/samples/game-1.jpg
1212
!/samples/game-2.jpg
1313
!/samples/game-3.jpg
14+
15+
/externals/onnxruntime-win-x64-1.12.1

CMakeLists.txt

+30-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cmake_minimum_required(VERSION 3.23)
1+
cmake_minimum_required(VERSION 3.21) # use the lower version requirement
22

33
set(APP_NAME yolo_opencv)
44
project(${APP_NAME})
@@ -10,10 +10,17 @@ add_executable(${APP_NAME} src/main.cpp src/YOLODetector.h src/YOLOSegmentor.h)
1010
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
1111

1212
# OpenCV
13-
find_package(OpenCV REQUIRED)
14-
target_link_libraries(${APP_NAME} PUBLIC "-framework Carbon")
15-
target_link_libraries(${APP_NAME} PUBLIC ${OpenCV_LIBS})
13+
if(APPLE)
14+
find_package(OpenCV REQUIRED)
15+
target_link_libraries(${APP_NAME} PUBLIC "-framework Carbon")
16+
target_link_libraries(${APP_NAME} PUBLIC ${OpenCV_LIBS})
17+
elseif(WIN32)
18+
set(OpenCV_DIR "C:/tools/opencv/build/x64/vc15/lib")
19+
find_package(OpenCV REQUIRED)
20+
target_link_libraries(${APP_NAME} PUBLIC ${OpenCV_LIBS})
21+
endif()
1622

23+
# Link Tesseract and Leptonica
1724
target_link_libraries(${APP_NAME} PUBLIC
1825
${tesseract_lib}
1926
${leptonica_lib}
@@ -23,15 +30,29 @@ target_link_libraries(${APP_NAME} PUBLIC
2330

2431
target_include_directories(${APP_NAME} PUBLIC
2532
${tesseract_include}
26-
${leptonica_include})
33+
${leptonica_include}
34+
)
2735

2836
# OnnxRuntime
29-
if(DEFINED ENV{ONNXRUNTIME_ROOT})
30-
set(ONNXRUNTIME_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/externals/$ENV{ONNXRUNTIME_ROOT}")
31-
else()
32-
set(ONNXRUNTIME_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/externals/onnxruntime-osx-arm64-1.12.1")
37+
if(APPLE)
38+
if(DEFINED ENV{ONNXRUNTIME_ROOT})
39+
set(ONNXRUNTIME_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/externals/$ENV{ONNXRUNTIME_ROOT}")
40+
else()
41+
set(ONNXRUNTIME_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/externals/onnxruntime-osx-arm64-1.12.1")
42+
endif()
43+
elseif(WIN32)
44+
set(ONNXRUNTIME_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/externals/onnxruntime-win-x64-1.12.1")
3345
endif()
3446

3547
find_package(ONNXRUNTIME REQUIRED)
3648
target_link_libraries(${APP_NAME} PUBLIC ${ONNXRUNTIME_LIBRARY})
3749
target_include_directories(${APP_NAME} PUBLIC ${ONNXRUNTIME_INCLUDE_DIR})
50+
51+
# Copy onnxruntime.dll on Windows
52+
if(WIN32)
53+
add_custom_command(TARGET ${APP_NAME} POST_BUILD
54+
COMMAND ${CMAKE_COMMAND} -E copy
55+
"${CMAKE_CURRENT_SOURCE_DIR}/externals/onnxruntime-win-x64-1.12.1/lib/onnxruntime.dll"
56+
"${CMAKE_CURRENT_BINARY_DIR}/onnxruntime.dll"
57+
)
58+
endif()

README.md

+15-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ by [hpc203/yolov7-opencv-onnxrun-cpp-py](https://github.com/hpc203/yolov7-opencv
88
This repository serves mostly as documentation for my personal use, demonstrating how to use ONNX and OpenCV with CMake
99
on MacOS.
1010

11-
## How to run
11+
## MacOS installation
1212

1313
1) Install dependencies:
1414

@@ -18,27 +18,33 @@ $ brew install onnxruntime
1818
$ brew install opencv
1919
```
2020

21-
2) If you are on M1 then you are good to go 🎉
21+
2) If you are on ARM then you are good to go 🎉
2222

23+
3) **If you are not using an ARM processor**, [download correct runtime 1.12.1 header files from the official GitHub repository](https://github.com/microsoft/onnxruntime/releases/tag/v1.12.1).
2324

24-
3) **If you are not using an M1 processor**, download ONNX Runtime.
25+
4) Put onnxruntime files to `external/`
2526

26-
- Either select the correct version from the releases available [here](github.com/microsoft/onnxruntime/releases)
27-
- If you are unsure which version to download, you can use the official optimize inferencing
28-
picker [here](https://onnxruntime.ai)
27+
5) Set `ONNXRUNTIME_ROOT` env variable to your onnxruntime folder name
2928

30-
4) Put ONNX runtime files to `external/`
29+
## Windows installation
3130

31+
1) Install dependencies:
32+
33+
```bash
34+
$ choco install cmake --pre
35+
$ choco install opencv
36+
```
3237

33-
5) Set `ONNXRUNTIME_ROOT` .env variable to your onnxruntime folder name
38+
2) Download [ONNX Runtime 1.12.1](https://github.com/microsoft/onnxruntime/releases/download/v1.12.1/onnxruntime-win-x64-1.12.1.zip)
39+
3) Extract and put onnxruntime folder to `external/onnxruntime-win-x64-1.12.1`
3440

3541
## Model
3642

3743
- This example utilizes a custom-trained model. If you wish to train your own model, you can create a dataset
3844
using [Roboflow](https://roboflow.com/#annotate) and then use one of
3945
their [official notebooks](https://github.com/roboflow/notebooks) to perform the training. There are also many
4046
comprehensive tutorials in the official [ultralytics/yolov5 repository](https://github.com/ultralytics/yolov5)
41-
- You are free to use any model you prefer, but be sure to update the `class.names` file accordingly. Additionally, for instance segmentation, it is important to pass `SegNetConfig` with proper parameters.
47+
- You are free to use any model you prefer, but be sure to update the `class.names` file accordingly. Additionally, for instance segmentation, it is important to pass `SegNetConfig` with proper parameters.
4248

4349
## Preview
4450

src/YOLODetector.h

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#pragma once
22

3+
#ifdef _WIN32
4+
#include <Windows.h>
5+
#endif
6+
37
#include <fstream>
48
#include <iostream>
59
#include <opencv2/highgui.hpp>
@@ -38,9 +42,17 @@ class YOLODetector {
3842
// OrtStatus* status =
3943
// OrtSessionOptionsAppendExecutionProvider_CUDA(sessionOptions, 0);
4044
sessionOptions.SetGraphOptimizationLevel(ORT_ENABLE_ALL);
41-
ortSession =
42-
Ort::Session(ortEnv, config.pathToModel.c_str(), sessionOptions);
4345

46+
#ifdef _WIN32
47+
int size_needed = MultiByteToWideChar(CP_UTF8, 0, config.pathToModel.c_str(), (int)config.pathToModel.size(), NULL, 0);
48+
std::wstring wstrPathToModel(size_needed, 0);
49+
MultiByteToWideChar(CP_UTF8, 0, config.pathToModel.c_str(), (int)config.pathToModel.size(), &wstrPathToModel[0], size_needed);
50+
ORTCHAR_T* path = const_cast<ORTCHAR_T*>(wstrPathToModel.c_str());
51+
#else
52+
ORTCHAR_T* path = const_cast<ORTCHAR_T*>(config.pathToModel.c_str());
53+
#endif
54+
55+
ortSession = Ort::Session(ortEnv, path, sessionOptions);
4456
LoadTypeInfo();
4557
LoadClasses(config.pathToClasses);
4658
}

src/YOLOSegmentor.h

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#pragma once
22

3+
#ifdef _WIN32
4+
#include <Windows.h>
5+
#endif
6+
37
#include <fstream>
48
#include <iostream>
59
#include <memory>
@@ -51,7 +55,16 @@ class YOLOSegmentor {
5155
GraphOptimizationLevel::ORT_ENABLE_EXTENDED
5256
);
5357

54-
session = Ort::Session(env, config.pathToModel.c_str(), sessionOptions);
58+
#ifdef _WIN32
59+
int size_needed = MultiByteToWideChar(CP_UTF8, 0, config.pathToModel.c_str(), (int)config.pathToModel.size(), NULL, 0);
60+
std::wstring wstrPathToModel(size_needed, 0);
61+
MultiByteToWideChar(CP_UTF8, 0, config.pathToModel.c_str(), (int)config.pathToModel.size(), &wstrPathToModel[0], size_needed);
62+
ORTCHAR_T* path = const_cast<ORTCHAR_T*>(wstrPathToModel.c_str());
63+
#else
64+
ORTCHAR_T* path = const_cast<ORTCHAR_T*>(config.pathToModel.c_str());
65+
#endif
66+
67+
session = Ort::Session(env, path, sessionOptions);
5568

5669
LoadTypeInfo();
5770
LoadClasses(config.pathToClasses);

0 commit comments

Comments
 (0)