qc903113684 commited on
Commit
d39709e
·
verified ·
1 Parent(s): f4212f5

Upload 45 files

Browse files
Files changed (46) hide show
  1. .gitattributes +10 -0
  2. model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/README.md +56 -0
  3. model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/cpp/CMakeLists.txt +32 -0
  4. model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/cpp/dog.jpg +3 -0
  5. model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/cpp/run_test.cpp +392 -0
  6. model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/models/midas_v2_w8a8.qnn216.ctx.bin +3 -0
  7. model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/python/dog.jpg +3 -0
  8. model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/python/run_test.py +111 -0
  9. model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/python/transforms.py +234 -0
  10. model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/python/utils.py +104 -0
  11. model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/README.md +56 -0
  12. model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/cpp/CMakeLists.txt +32 -0
  13. model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/cpp/dog.jpg +3 -0
  14. model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/cpp/run_test.cpp +392 -0
  15. model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/models/midas_v2_w8a16.qnn216.ctx.bin +3 -0
  16. model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/python/dog.jpg +3 -0
  17. model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/python/run_test.py +111 -0
  18. model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/python/transforms.py +234 -0
  19. model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/python/utils.py +104 -0
  20. model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/README.md +56 -0
  21. model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/cpp/CMakeLists.txt +32 -0
  22. model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/cpp/dog.jpg +3 -0
  23. model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/cpp/run_test.cpp +392 -0
  24. model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/models/midas_v2_fp16.qnn216.ctx.bin +3 -0
  25. model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/python/dog.jpg +3 -0
  26. model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/python/run_test.py +111 -0
  27. model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/python/transforms.py +234 -0
  28. model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/python/utils.py +104 -0
  29. model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/README.md +56 -0
  30. model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/cpp/CMakeLists.txt +32 -0
  31. model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/cpp/dog.jpg +3 -0
  32. model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/cpp/run_test.cpp +392 -0
  33. model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/models/midas_v2_w8a8.qnn216.ctx.bin +3 -0
  34. model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/python/dog.jpg +3 -0
  35. model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/python/run_test.py +111 -0
  36. model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/python/transforms.py +234 -0
  37. model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/python/utils.py +104 -0
  38. model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/README.md +57 -0
  39. model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/cpp/CMakeLists.txt +32 -0
  40. model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/cpp/dog.jpg +3 -0
  41. model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/cpp/run_test.cpp +392 -0
  42. model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/models/midas_v2_w8a16.qnn216.ctx.bin +3 -0
  43. model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/python/dog.jpg +3 -0
  44. model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/python/run_test.py +111 -0
  45. model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/python/transforms.py +234 -0
  46. model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/python/utils.py +104 -0
.gitattributes CHANGED
@@ -33,3 +33,13 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/cpp/dog.jpg filter=lfs diff=lfs merge=lfs -text
37
+ model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/python/dog.jpg filter=lfs diff=lfs merge=lfs -text
38
+ model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/cpp/dog.jpg filter=lfs diff=lfs merge=lfs -text
39
+ model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/python/dog.jpg filter=lfs diff=lfs merge=lfs -text
40
+ model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/cpp/dog.jpg filter=lfs diff=lfs merge=lfs -text
41
+ model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/python/dog.jpg filter=lfs diff=lfs merge=lfs -text
42
+ model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/cpp/dog.jpg filter=lfs diff=lfs merge=lfs -text
43
+ model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/python/dog.jpg filter=lfs diff=lfs merge=lfs -text
44
+ model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/cpp/dog.jpg filter=lfs diff=lfs merge=lfs -text
45
+ model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/python/dog.jpg filter=lfs diff=lfs merge=lfs -text
model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/README.md ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Model Information
2
+
3
+ ### Source model
4
+ - Input shape: 1x3x256x256
5
+ - Number of parameters: 20.33M
6
+ - Model size: 82.17M
7
+ - Output shape: 1x1x256x256
8
+
9
+ Source model repository: [midas](https://github.com/isl-org/MiDaS/tree/master)
10
+
11
+ ### Converted model
12
+
13
+ - Precision: INT8
14
+ - Backend: QNN2.16
15
+ - Target Device: FV01 QCS6490
16
+
17
+ ## Inference with AidLite SDK
18
+
19
+ ### SDK installation
20
+ Model Farm uses AidLite SDK as the model inference SDK. For details, please refer to the [AidLite Developer Documentation](https://v2.docs.aidlux.com/en/sdk-api/aidlite-sdk/)
21
+
22
+ - Install AidLite SDK
23
+
24
+ ```bash
25
+ # Install the appropriate version of the aidlite sdk
26
+ sudo aid-pkg update
27
+ sudo aid-pkg install aidlite-sdk
28
+ # Download the qnn version that matches the above backend. Eg Install QNN2.23 Aidlite: sudo aid-pkg install aidlite-qnn223
29
+ sudo aid-pkg install aidlite-{QNN VERSION}
30
+ ```
31
+
32
+ - Verify AidLite SDK
33
+
34
+ ```bash
35
+ # aidlite sdk c++ check
36
+ python3 -c "import aidlite ; print(aidlite.get_library_version())"
37
+
38
+ # aidlite sdk python check
39
+ python3 -c "import aidlite ; print(aidlite.get_py_library_version())"
40
+ ```
41
+
42
+ ### Run Demo
43
+ #### python
44
+ ```bash
45
+ cd model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite
46
+ python3 python/run_test.py --target_model ./models/midas_v2_w8a8.qnn216.ctx.bin --imgs ./python/dog.jpg --invoke_nums 10
47
+ ```
48
+
49
+ #### c++
50
+ ```bash
51
+ cd midas_v2/model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/cpp
52
+ mkdir build && cd build
53
+ cmake ..
54
+ make
55
+ ./run_test
56
+ ```
model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/cpp/CMakeLists.txt ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required (VERSION 3.5)
2
+ project("run_test")
3
+
4
+ find_package(OpenCV REQUIRED)
5
+
6
+ message(STATUS "oPENCV Library status:")
7
+ message(STATUS ">version:${OpenCV_VERSION}")
8
+ message(STATUS "Include:${OpenCV_INCLUDE_DIRS}")
9
+
10
+ set(CMAKE_CXX_FLAGS "-Wno-error=deprecated-declarations -Wno-deprecated-declarations")
11
+
12
+ include_directories(
13
+ /usr/local/include
14
+ /usr/include/opencv4
15
+ )
16
+
17
+ link_directories(
18
+ /usr/local/lib/
19
+ )
20
+
21
+ file(GLOB SRC_LISTS
22
+ ${CMAKE_CURRENT_SOURCE_DIR}/run_test.cpp
23
+ )
24
+
25
+ add_executable(run_test ${SRC_LISTS})
26
+
27
+ target_link_libraries(run_test
28
+ aidlite
29
+ ${OpenCV_LIBS}
30
+ pthread
31
+ jsoncpp
32
+ )
model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/cpp/dog.jpg ADDED

Git LFS Details

  • SHA256: f3f87bb8ab3c26c7ecfd3ac60421d7f32b0503d1d6c5baf8bac42ed93d86351a
  • Pointer size: 131 Bytes
  • Size of remote file: 661 kB
model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/cpp/run_test.cpp ADDED
@@ -0,0 +1,392 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <fstream>
3
+ #include <opencv2/opencv.hpp>
4
+ #include <aidlux/aidlite/aidlite.hpp>
5
+ #include <vector>
6
+ #include <numeric>
7
+ #include <cmath>
8
+ #include <jsoncpp/json/json.h>
9
+
10
+ using namespace cv;
11
+ using namespace std;
12
+ using namespace Aidlux::Aidlite;
13
+
14
+ const int net_w = 256;
15
+ const int net_h = 256;
16
+
17
+ const std::vector<float> mean_vals = {0.485f, 0.456f, 0.406f};
18
+ const std::vector<float> std_vals = {0.229f, 0.224f, 0.225f};
19
+
20
+
21
+ struct Args {
22
+ std::string target_model = "../../models/midas_v2_w8a8.qnn216.ctx.bin";
23
+ std::string imgs = "../dog.jpg";
24
+ int invoke_nums = 10;
25
+ std::string model_type = "QNN";
26
+ };
27
+
28
+
29
+ Args parse_args(int argc, char* argv[]) {
30
+ Args args;
31
+ for (int i = 1; i < argc; ++i) {
32
+ std::string arg = argv[i];
33
+ if (arg == "--target_model" && i + 1 < argc) {
34
+ args.target_model = argv[++i];
35
+ } else if (arg == "--imgs" && i + 1 < argc) {
36
+ args.imgs = argv[++i];
37
+ } else if (arg == "--invoke_nums" && i + 1 < argc) {
38
+ args.invoke_nums = std::stoi(argv[++i]);
39
+ } else if (arg == "--model_type" && i + 1 < argc) {
40
+ args.model_type = argv[++i];
41
+ }
42
+ }
43
+ return args;
44
+ }
45
+
46
+ std::string to_lower(const std::string& str) {
47
+ std::string lower_str = str;
48
+ std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(), [](unsigned char c) {
49
+ return std::tolower(c);
50
+ });
51
+ return lower_str;
52
+ }
53
+
54
+
55
+ int transpose(float* src, unsigned int* src_dims, unsigned int* tsp_dims, float* dest){
56
+
57
+ int current_coordinate[4] = {0, 0, 0, 0};
58
+ for(int a = 0; a < src_dims[0]; ++a){
59
+ current_coordinate[0] = a;
60
+ for(int b = 0; b < src_dims[1]; ++b){
61
+ current_coordinate[1] = b;
62
+ for(int c = 0; c < src_dims[2]; ++c){
63
+ current_coordinate[2] = c;
64
+ for(int d = 0; d < src_dims[3]; ++d){
65
+ current_coordinate[3] = d;
66
+
67
+ int old_index = current_coordinate[0]*src_dims[1]*src_dims[2]*src_dims[3] +
68
+ current_coordinate[1]*src_dims[2]*src_dims[3] +
69
+ current_coordinate[2]*src_dims[3] +
70
+ current_coordinate[3];
71
+
72
+ int new_index = current_coordinate[tsp_dims[0]]*src_dims[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
73
+ current_coordinate[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
74
+ current_coordinate[tsp_dims[2]]*src_dims[tsp_dims[3]] +
75
+ current_coordinate[tsp_dims[3]];
76
+
77
+ dest[new_index] = src[old_index];
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ return EXIT_SUCCESS;
84
+ }
85
+
86
+
87
+ // 替代 np.nan_to_num
88
+ void sanitizeDepthMap(cv::Mat& depth) {
89
+ for (int y = 0; y < depth.rows; ++y) {
90
+ float* row = depth.ptr<float>(y);
91
+ for (int x = 0; x < depth.cols; ++x) {
92
+ float val = row[x];
93
+ if (!std::isfinite(val)) {
94
+ row[x] = 0.0f;
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ // 等效于 Python write_depth
101
+ void write_depth(const std::string& path, const cv::Mat& input_depth, bool grayscale = false, int bits = 1) {
102
+ CV_Assert(input_depth.type() == CV_32FC1);
103
+
104
+ // 拷贝 + 处理非法值
105
+ cv::Mat depth = input_depth.clone();
106
+ sanitizeDepthMap(depth);
107
+
108
+ double minVal, maxVal;
109
+ cv::minMaxLoc(depth, &minVal, &maxVal);
110
+
111
+ double max_val = (1 << (8 * bits)) - 1;
112
+ cv::Mat out;
113
+
114
+ if (maxVal - minVal > std::numeric_limits<float>::epsilon()) {
115
+ // 归一化并映射到位深范围
116
+ out = (depth - minVal) * (max_val / (maxVal - minVal));
117
+ } else {
118
+ out = cv::Mat::zeros(depth.size(), CV_32F);
119
+ }
120
+
121
+ if (!grayscale) {
122
+ out.convertTo(out, CV_8UC1);
123
+ cv::applyColorMap(out, out, cv::COLORMAP_INFERNO);
124
+ }
125
+
126
+ if (bits == 1) {
127
+ out.convertTo(out, CV_8U);
128
+ } else if (bits == 2) {
129
+ out.convertTo(out, CV_16U);
130
+ }
131
+
132
+ cv::imwrite(path, out);
133
+ }
134
+
135
+ // 等效于 Python write_pfm
136
+ void write_pfm(const std::string& path, const cv::Mat& image, float scale = 1.0f) {
137
+ CV_Assert(image.type() == CV_32FC1 || image.type() == CV_32FC3);
138
+
139
+ std::ofstream file(path, std::ios::binary);
140
+ if (!file.is_open()) {
141
+ std::cerr << "Failed to open file for writing PFM: " << path << std::endl;
142
+ return;
143
+ }
144
+
145
+ int width = image.cols;
146
+ int height = image.rows;
147
+ int channels = image.channels();
148
+ bool color = (channels == 3);
149
+
150
+ file << (color ? "PF" : "Pf") << "\n";
151
+ file << width << " " << height << "\n";
152
+
153
+ // Endianness: negative = little-endian
154
+ uint16_t endian_test = 0x1;
155
+ bool is_little_endian = *(reinterpret_cast<uint8_t*>(&endian_test)) == 0x1;
156
+ if (is_little_endian) {
157
+ scale = -scale;
158
+ }
159
+
160
+ file << scale << "\n";
161
+
162
+ // Flip vertically (OpenCV top-left origin -> PFM bottom-left origin)
163
+ cv::Mat flipped;
164
+ cv::flip(image, flipped, 0);
165
+
166
+ // Write raw data
167
+ file.write(reinterpret_cast<const char*>(flipped.data), flipped.total() * channels * sizeof(float));
168
+ file.close();
169
+ }
170
+
171
+
172
+ // ======================= Normalize =======================
173
+ void normalize(cv::Mat& image) {
174
+ CV_Assert(image.type() == CV_32FC3);
175
+ int rows = image.rows;
176
+ int cols = image.cols;
177
+
178
+ for (int y = 0; y < rows; ++y) {
179
+ cv::Vec3f* row = image.ptr<cv::Vec3f>(y);
180
+ for (int x = 0; x < cols; ++x) {
181
+ for (int c = 0; c < 3; ++c) {
182
+ row[x][c] = (row[x][c] - mean_vals[c]) / std_vals[c];
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ cv::Mat hwc_to_chw(const cv::Mat& image) {
189
+ std::vector<cv::Mat> channels(3);
190
+ cv::split(image, channels);
191
+
192
+ cv::Mat chw(3, image.rows * image.cols, CV_32F);
193
+ for (int c = 0; c < 3; ++c) {
194
+ memcpy(chw.ptr(c), channels[c].data, image.rows * image.cols * sizeof(float));
195
+ }
196
+
197
+ return chw;
198
+ }
199
+
200
+
201
+ bool first_execution = true;
202
+ cv::Mat img_process(const cv::Mat image_bgr, cv::Size& org_size_out) {
203
+ first_execution = false;
204
+
205
+ cv::Mat image_rgb;
206
+ cv::cvtColor(image_bgr, image_rgb, cv::COLOR_BGR2RGB);
207
+ image_rgb.convertTo(image_rgb, CV_32FC3, 1.0 / 255.0);
208
+
209
+ // 2. Save original size
210
+ org_size_out = image_rgb.size(); // H x W
211
+
212
+ // 3. Resize to 256x256 using cubic interpolation
213
+ cv::resize(image_rgb, image_rgb, cv::Size(net_w, net_h), 0, 0, cv::INTER_CUBIC);
214
+
215
+ // 4. Normalize using mean/std
216
+ normalize(image_rgb);
217
+
218
+ // 5. Convert HWC to CHW
219
+ cv::Mat chw = hwc_to_chw(image_rgb);
220
+
221
+ // 6. Add batch dimension: [1, C, H, W] → reshape to 1x3xHxW style float array
222
+ cv::Mat input_tensor(1, 3 * net_h * net_w, CV_32F);
223
+ memcpy(input_tensor.ptr<float>(), chw.data, 3 * net_h * net_w * sizeof(float));
224
+
225
+ std::cout << "Input resized to " << net_w << "x" << net_h << " before entering the encoder" << std::endl;
226
+
227
+ return input_tensor;
228
+ }
229
+
230
+
231
+ float* matToFloatPtr(const cv::Mat& input_mat, bool normalize = true) {
232
+ // 检查连续性
233
+ cv::Mat mat = input_mat;
234
+ if (!mat.isContinuous()) {
235
+ mat = mat.clone();
236
+ }
237
+
238
+ // 分配内存
239
+ int total_pixels = mat.rows * mat.cols;
240
+ int channels = mat.channels();
241
+ float* float_data = new float[total_pixels * channels];
242
+
243
+ // 根据数据类型转换
244
+ if (mat.type() == CV_8UC1 || mat.type() == CV_8UC3) {
245
+ uchar* ptr = mat.ptr<uchar>(0);
246
+ for (int i = 0; i < total_pixels * channels; ++i) {
247
+ float_data[i] = normalize ? (static_cast<float>(ptr[i]) / 255.0f) : ptr[i];
248
+ }
249
+ } else if (mat.type() == CV_32FC1 || mat.type() == CV_32FC3) {
250
+ float* ptr = mat.ptr<float>(0);
251
+ std::memcpy(float_data, ptr, total_pixels * channels * sizeof(float));
252
+ } else {
253
+ delete[] float_data;
254
+ return nullptr; // 不支持的类型
255
+ }
256
+
257
+ return float_data;
258
+ }
259
+
260
+
261
+ int invoke(const Args& args) {
262
+ std::cout << "Start main ... ... Model Path: " << args.target_model << "\n"
263
+ << "Image Path: " << args.imgs << "\n"
264
+ << "Inference Nums: " << args.invoke_nums << "\n"
265
+ << "Model Type: " << args.model_type << "\n";
266
+ Model* model = Model::create_instance(args.target_model);
267
+ if(model == nullptr){
268
+ printf("Create model failed !\n");
269
+ return EXIT_FAILURE;
270
+ }
271
+ Config* config = Config::create_instance();
272
+ if(config == nullptr){
273
+ printf("Create config failed !\n");
274
+ return EXIT_FAILURE;
275
+ }
276
+ config->implement_type = ImplementType::TYPE_LOCAL;
277
+ std::string model_type_lower = to_lower(args.model_type);
278
+ if (model_type_lower == "qnn"){
279
+ config->framework_type = FrameworkType::TYPE_QNN;
280
+ } else if (model_type_lower == "snpe2" || model_type_lower == "snpe") {
281
+ config->framework_type = FrameworkType::TYPE_SNPE2;
282
+ }
283
+ config->accelerate_type = AccelerateType::TYPE_DSP;
284
+ config->is_quantify_model = 1;
285
+
286
+ unsigned int model_h = 256;
287
+ unsigned int model_w = 256;
288
+ std::vector<std::vector<uint32_t>> input_shapes = {{1,model_h,model_w,3}};
289
+ std::vector<std::vector<uint32_t>> output_shapes = {{1,model_h,model_w,1}};
290
+ model->set_model_properties(input_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32, output_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32);
291
+ std::unique_ptr<Interpreter> fast_interpreter = InterpreterBuilder::build_interpretper_from_model_and_config(model, config);
292
+ if(fast_interpreter == nullptr){
293
+ printf("build_interpretper_from_model_and_config failed !\n");
294
+ return EXIT_FAILURE;
295
+ }
296
+ int result = fast_interpreter->init();
297
+ if(result != EXIT_SUCCESS){
298
+ printf("interpreter->init() failed !\n");
299
+ return EXIT_FAILURE;
300
+ }
301
+ // load model
302
+ fast_interpreter->load_model();
303
+ if(result != EXIT_SUCCESS){
304
+ printf("interpreter->load_model() failed !\n");
305
+ return EXIT_FAILURE;
306
+ }
307
+ printf("detect model load success!\n");
308
+
309
+ cv::Mat frame = cv::imread(args.imgs);
310
+ if (frame.empty()) {
311
+ printf("detect image load failed!\n");
312
+ return 1;
313
+ }
314
+ printf("img_src cols: %d, img_src rows: %d\n", frame.cols, frame.rows);
315
+ cv::Mat input_data;
316
+ cv::Mat frame_clone = frame.clone();
317
+ int h = frame_clone.rows;
318
+ int w = frame_clone.cols;
319
+ cv::Size org_size(w, h);
320
+ cv::Size org_size0(256, 256);
321
+
322
+ cv::Mat input_tensor = img_process(frame_clone, org_size0);
323
+ float* float_data = matToFloatPtr(input_tensor);
324
+ unsigned int src_dims[4] = {1, 3, 256, 256};
325
+ unsigned int tsp_dims[4] = {0,2,3,1};
326
+ unsigned int stride_data_num = 1*256*256*3;
327
+ float* format_data = new float[stride_data_num];
328
+ transpose(float_data, src_dims, tsp_dims, format_data);
329
+ cv::Mat origin_buffer(3,256*256, CV_32F, format_data);
330
+
331
+ float *outdata0 = nullptr;
332
+ std::vector<float> invoke_time;
333
+ for (int i = 0; i < args.invoke_nums; ++i) {
334
+ result = fast_interpreter->set_input_tensor(0, origin_buffer.data);
335
+ if(result != EXIT_SUCCESS){
336
+ printf("interpreter->set_input_tensor() failed !\n");
337
+ return EXIT_FAILURE;
338
+ }
339
+ auto t1 = std::chrono::high_resolution_clock::now();
340
+ result = fast_interpreter->invoke();
341
+ auto t2 = std::chrono::high_resolution_clock::now();
342
+ std::chrono::duration<double> cost_time = t2 - t1;
343
+ invoke_time.push_back(cost_time.count() * 1000);
344
+ if(result != EXIT_SUCCESS){
345
+ printf("interpreter->invoke() failed !\n");
346
+ return EXIT_FAILURE;
347
+ }
348
+ uint32_t out_data_0 = 0;
349
+ result = fast_interpreter->get_output_tensor(0, (void**)&outdata0, &out_data_0);
350
+ if(result != EXIT_SUCCESS){
351
+ printf("interpreter->get_output_tensor() 1 failed !\n");
352
+ return EXIT_FAILURE;
353
+ }
354
+
355
+ }
356
+
357
+ float max_invoke_time = *std::max_element(invoke_time.begin(), invoke_time.end());
358
+ float min_invoke_time = *std::min_element(invoke_time.begin(), invoke_time.end());
359
+ float mean_invoke_time = std::accumulate(invoke_time.begin(), invoke_time.end(), 0.0f) / args.invoke_nums;
360
+ float var_invoketime = 0.0f;
361
+ for (auto time : invoke_time) {
362
+ var_invoketime += (time - mean_invoke_time) * (time - mean_invoke_time);
363
+ }
364
+ var_invoketime /= args.invoke_nums;
365
+ printf("=======================================\n");
366
+ printf("QNN inference %d times :\n --mean_invoke_time is %f \n --max_invoke_time is %f \n --min_invoke_time is %f \n --var_invoketime is %f\n",
367
+ args.invoke_nums, mean_invoke_time, max_invoke_time, min_invoke_time, var_invoketime);
368
+ printf("=======================================\n");
369
+
370
+ // post process
371
+ cv::Mat out_buffer(1,256*256, CV_32F, outdata0);
372
+ cv::Mat prediction_2d(256, 256, CV_32F, (void*)out_buffer.ptr<float>());
373
+ cv::Mat resized;
374
+ cv::resize(prediction_2d, resized, org_size, 0, 0, cv::INTER_CUBIC);
375
+
376
+ // 保存为图像
377
+ write_depth("depth_output.jpg", resized, false, 1);
378
+
379
+ // 保存为 PFM
380
+ write_pfm("depth_output.pfm", resized);
381
+
382
+
383
+
384
+ fast_interpreter->destory();
385
+ return 0;
386
+ }
387
+
388
+
389
+ int main(int argc, char* argv[]) {
390
+ Args args = parse_args(argc, argv);
391
+ return invoke(args);
392
+ }
model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/models/midas_v2_w8a8.qnn216.ctx.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1abbd2fc95f87af48b1b609368d9dbaac7136a3aeb8a9c791ea3907da79550f8
3
+ size 27611136
model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/python/dog.jpg ADDED

Git LFS Details

  • SHA256: f3f87bb8ab3c26c7ecfd3ac60421d7f32b0503d1d6c5baf8bac42ed93d86351a
  • Pointer size: 131 Bytes
  • Size of remote file: 661 kB
model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/python/run_test.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import torch
3
+ import cv2
4
+ import os
5
+ from utils import write_pfm,write_depth,img_process
6
+ import aidlite
7
+ import time
8
+ import argparse
9
+
10
+ def out_process(prediction,target_size):
11
+ prediction = torch.nn.functional.interpolate(
12
+ prediction,
13
+ size=target_size,
14
+ mode="bicubic",
15
+ align_corners=False,
16
+ )
17
+ prediction = prediction.squeeze().detach().numpy()
18
+ return prediction
19
+
20
+ class run_qnn:
21
+ def __init__(self,qnn_path):
22
+ super().__init__()
23
+ self.model = aidlite.Model.create_instance(qnn_path)
24
+ if self.model is None:
25
+ print("Create model failed !")
26
+ return
27
+
28
+ self.config = aidlite.Config.create_instance()
29
+ if self.config is None:
30
+ print("build_interpretper_from_model_and_config failed !")
31
+ return
32
+
33
+ self.config.implement_type = aidlite.ImplementType.TYPE_LOCAL
34
+ self.config.framework_type = aidlite.FrameworkType.TYPE_QNN
35
+ self.config.accelerate_type = aidlite.AccelerateType.TYPE_DSP
36
+ # self.config.accelerate_type = aidlite.AccelerateType.TYPE_CPU
37
+ self.config.is_quantify_model = 1
38
+
39
+ self.interpreter = aidlite.InterpreterBuilder.build_interpretper_from_model_and_config(self.model, self.config)
40
+ if self.interpreter is None:
41
+ print("build_interpretper_from_model_and_config failed !")
42
+ return
43
+ input_shapes = [[1,256,256,3]]
44
+ output_shapes = [[1,256,256,1]]
45
+ self.model.set_model_properties(input_shapes, aidlite.DataType.TYPE_FLOAT32,
46
+ output_shapes, aidlite.DataType.TYPE_FLOAT32)
47
+
48
+ if self.interpreter is None:
49
+ print("build_interpretper_from_model_and_config failed !")
50
+ result = self.interpreter.init()
51
+ if result != 0:
52
+ print(f"interpreter init failed !")
53
+ result = self.interpreter.load_model()
54
+ if result != 0:
55
+ print("interpreter load model failed !")
56
+
57
+ print(" model load success!")
58
+
59
+ def __call__(self, input,invoke_nums):
60
+ self.interpreter.set_input_tensor(0,input)
61
+ invoke_time=[]
62
+ for i in range(invoke_nums):
63
+ result = self.interpreter.set_input_tensor(0, input.data)
64
+ if result != 0:
65
+ print("interpreter set_input_tensor() failed")
66
+ t1=time.time()
67
+ result = self.interpreter.invoke()
68
+ cost_time = (time.time()-t1)*1000
69
+ invoke_time.append(cost_time)
70
+
71
+ max_invoke_time = max(invoke_time)
72
+ min_invoke_time = min(invoke_time)
73
+ mean_invoke_time = sum(invoke_time)/invoke_nums
74
+ var_invoketime=np.var(invoke_time)
75
+ print("====================================")
76
+ print(f"QNN invoke time:\n --mean_invoke_time is {mean_invoke_time} \n --max_invoke_time is {max_invoke_time} \n --min_invoke_time is {min_invoke_time} \n --var_invoketime is {var_invoketime}")
77
+ print("====================================")
78
+ features_0 = self.interpreter.get_output_tensor(0).reshape(1,256,256,1).transpose(0,3,1,2)
79
+ return features_0
80
+
81
+
82
+
83
+ def run(args):
84
+ img_path = args.imgs
85
+ qnn_path = args.target_model
86
+ invoke_num=args.invoke_nums
87
+ print("Start processing...")
88
+ img_input,org_size = img_process(img_path)
89
+
90
+ qnn_model =run_qnn(qnn_path)
91
+ prediction_qnn = qnn_model(img_input.numpy().transpose(0,2,3,1),invoke_num)
92
+ prediction_qnn = torch.tensor(prediction_qnn)
93
+ qnn_process = out_process(prediction_qnn,org_size)
94
+
95
+ write_depth("./python/results.jpg", qnn_process, grayscale=False, bits=1)
96
+ write_pfm("./python/results.pfm", qnn_process.astype(np.float32))
97
+ print("Finished")
98
+
99
+ def parser_args():
100
+ parser = argparse.ArgumentParser(description="Run model benchmarks")
101
+ parser.add_argument('--target_model',type=str,default='./models/midas_v2_w8a8.qnn216.ctx.bin',help="Inference model path")
102
+ parser.add_argument('--imgs',type=str,default='./python/dog.jpg',help="Predict images path")
103
+ parser.add_argument('--invoke_nums',type=int,default=10,help="Inference nums")
104
+ parser.add_argument('--model_type',type=str,default='QNN',help="Run backend")
105
+ args = parser.parse_args()
106
+ return args
107
+
108
+
109
+ if __name__ =="__main__":
110
+ args = parser_args()
111
+ run(args)
model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/python/transforms.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import cv2
3
+ import math
4
+
5
+
6
+ def apply_min_size(sample, size, image_interpolation_method=cv2.INTER_AREA):
7
+ """Rezise the sample to ensure the given size. Keeps aspect ratio.
8
+
9
+ Args:
10
+ sample (dict): sample
11
+ size (tuple): image size
12
+
13
+ Returns:
14
+ tuple: new size
15
+ """
16
+ shape = list(sample["disparity"].shape)
17
+
18
+ if shape[0] >= size[0] and shape[1] >= size[1]:
19
+ return sample
20
+
21
+ scale = [0, 0]
22
+ scale[0] = size[0] / shape[0]
23
+ scale[1] = size[1] / shape[1]
24
+
25
+ scale = max(scale)
26
+
27
+ shape[0] = math.ceil(scale * shape[0])
28
+ shape[1] = math.ceil(scale * shape[1])
29
+
30
+ # resize
31
+ sample["image"] = cv2.resize(
32
+ sample["image"], tuple(shape[::-1]), interpolation=image_interpolation_method
33
+ )
34
+
35
+ sample["disparity"] = cv2.resize(
36
+ sample["disparity"], tuple(shape[::-1]), interpolation=cv2.INTER_NEAREST
37
+ )
38
+ sample["mask"] = cv2.resize(
39
+ sample["mask"].astype(np.float32),
40
+ tuple(shape[::-1]),
41
+ interpolation=cv2.INTER_NEAREST,
42
+ )
43
+ sample["mask"] = sample["mask"].astype(bool)
44
+
45
+ return tuple(shape)
46
+
47
+
48
+ class Resize(object):
49
+ """Resize sample to given size (width, height).
50
+ """
51
+
52
+ def __init__(
53
+ self,
54
+ width,
55
+ height,
56
+ resize_target=True,
57
+ keep_aspect_ratio=False,
58
+ ensure_multiple_of=1,
59
+ resize_method="lower_bound",
60
+ image_interpolation_method=cv2.INTER_AREA,
61
+ ):
62
+ """Init.
63
+
64
+ Args:
65
+ width (int): desired output width
66
+ height (int): desired output height
67
+ resize_target (bool, optional):
68
+ True: Resize the full sample (image, mask, target).
69
+ False: Resize image only.
70
+ Defaults to True.
71
+ keep_aspect_ratio (bool, optional):
72
+ True: Keep the aspect ratio of the input sample.
73
+ Output sample might not have the given width and height, and
74
+ resize behaviour depends on the parameter 'resize_method'.
75
+ Defaults to False.
76
+ ensure_multiple_of (int, optional):
77
+ Output width and height is constrained to be multiple of this parameter.
78
+ Defaults to 1.
79
+ resize_method (str, optional):
80
+ "lower_bound": Output will be at least as large as the given size.
81
+ "upper_bound": Output will be at max as large as the given size. (Output size might be smaller than given size.)
82
+ "minimal": Scale as least as possible. (Output size might be smaller than given size.)
83
+ Defaults to "lower_bound".
84
+ """
85
+ self.__width = width
86
+ self.__height = height
87
+
88
+ self.__resize_target = resize_target
89
+ self.__keep_aspect_ratio = keep_aspect_ratio
90
+ self.__multiple_of = ensure_multiple_of
91
+ self.__resize_method = resize_method
92
+ self.__image_interpolation_method = image_interpolation_method
93
+
94
+ def constrain_to_multiple_of(self, x, min_val=0, max_val=None):
95
+ y = (np.round(x / self.__multiple_of) * self.__multiple_of).astype(int)
96
+
97
+ if max_val is not None and y > max_val:
98
+ y = (np.floor(x / self.__multiple_of) * self.__multiple_of).astype(int)
99
+
100
+ if y < min_val:
101
+ y = (np.ceil(x / self.__multiple_of) * self.__multiple_of).astype(int)
102
+
103
+ return y
104
+
105
+ def get_size(self, width, height):
106
+ # determine new height and width
107
+ scale_height = self.__height / height
108
+ scale_width = self.__width / width
109
+
110
+ if self.__keep_aspect_ratio:
111
+ if self.__resize_method == "lower_bound":
112
+ # scale such that output size is lower bound
113
+ if scale_width > scale_height:
114
+ # fit width
115
+ scale_height = scale_width
116
+ else:
117
+ # fit height
118
+ scale_width = scale_height
119
+ elif self.__resize_method == "upper_bound":
120
+ # scale such that output size is upper bound
121
+ if scale_width < scale_height:
122
+ # fit width
123
+ scale_height = scale_width
124
+ else:
125
+ # fit height
126
+ scale_width = scale_height
127
+ elif self.__resize_method == "minimal":
128
+ # scale as least as possbile
129
+ if abs(1 - scale_width) < abs(1 - scale_height):
130
+ # fit width
131
+ scale_height = scale_width
132
+ else:
133
+ # fit height
134
+ scale_width = scale_height
135
+ else:
136
+ raise ValueError(
137
+ f"resize_method {self.__resize_method} not implemented"
138
+ )
139
+
140
+ if self.__resize_method == "lower_bound":
141
+ new_height = self.constrain_to_multiple_of(
142
+ scale_height * height, min_val=self.__height
143
+ )
144
+ new_width = self.constrain_to_multiple_of(
145
+ scale_width * width, min_val=self.__width
146
+ )
147
+ elif self.__resize_method == "upper_bound":
148
+ new_height = self.constrain_to_multiple_of(
149
+ scale_height * height, max_val=self.__height
150
+ )
151
+ new_width = self.constrain_to_multiple_of(
152
+ scale_width * width, max_val=self.__width
153
+ )
154
+ elif self.__resize_method == "minimal":
155
+ new_height = self.constrain_to_multiple_of(scale_height * height)
156
+ new_width = self.constrain_to_multiple_of(scale_width * width)
157
+ else:
158
+ raise ValueError(f"resize_method {self.__resize_method} not implemented")
159
+
160
+ return (new_width, new_height)
161
+
162
+ def __call__(self, sample):
163
+ width, height = self.get_size(
164
+ sample["image"].shape[1], sample["image"].shape[0]
165
+ )
166
+
167
+ # resize sample
168
+ sample["image"] = cv2.resize(
169
+ sample["image"],
170
+ (width, height),
171
+ interpolation=self.__image_interpolation_method,
172
+ )
173
+
174
+ if self.__resize_target:
175
+ if "disparity" in sample:
176
+ sample["disparity"] = cv2.resize(
177
+ sample["disparity"],
178
+ (width, height),
179
+ interpolation=cv2.INTER_NEAREST,
180
+ )
181
+
182
+ if "depth" in sample:
183
+ sample["depth"] = cv2.resize(
184
+ sample["depth"], (width, height), interpolation=cv2.INTER_NEAREST
185
+ )
186
+
187
+ sample["mask"] = cv2.resize(
188
+ sample["mask"].astype(np.float32),
189
+ (width, height),
190
+ interpolation=cv2.INTER_NEAREST,
191
+ )
192
+ sample["mask"] = sample["mask"].astype(bool)
193
+
194
+ return sample
195
+
196
+
197
+ class NormalizeImage(object):
198
+ """Normlize image by given mean and std.
199
+ """
200
+
201
+ def __init__(self, mean, std):
202
+ self.__mean = mean
203
+ self.__std = std
204
+
205
+ def __call__(self, sample):
206
+ sample["image"] = (sample["image"] - self.__mean) / self.__std
207
+
208
+ return sample
209
+
210
+
211
+ class PrepareForNet(object):
212
+ """Prepare sample for usage as network input.
213
+ """
214
+
215
+ def __init__(self):
216
+ pass
217
+
218
+ def __call__(self, sample):
219
+ image = np.transpose(sample["image"], (2, 0, 1))
220
+ sample["image"] = np.ascontiguousarray(image).astype(np.float32)
221
+
222
+ if "mask" in sample:
223
+ sample["mask"] = sample["mask"].astype(np.float32)
224
+ sample["mask"] = np.ascontiguousarray(sample["mask"])
225
+
226
+ if "disparity" in sample:
227
+ disparity = sample["disparity"].astype(np.float32)
228
+ sample["disparity"] = np.ascontiguousarray(disparity)
229
+
230
+ if "depth" in sample:
231
+ depth = sample["depth"].astype(np.float32)
232
+ sample["depth"] = np.ascontiguousarray(depth)
233
+
234
+ return sample
model_farm_midas_v2_qcs6490_qnn2.16_int8_aidlite/python/utils.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import torch
3
+ import cv2
4
+ import os
5
+
6
+ from transforms import Resize, NormalizeImage, PrepareForNet
7
+
8
+ from torchvision.transforms import Compose
9
+ import sys
10
+ first_execution = True
11
+ def img_process(img_path):
12
+ global first_execution
13
+ first_execution = False
14
+ net_w, net_h = 256, 256
15
+ resize_mode = "upper_bound"
16
+ normalization = NormalizeImage(
17
+ mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]
18
+ )
19
+ transform = Compose(
20
+ [
21
+ Resize(
22
+ net_w,
23
+ net_h,
24
+ resize_target=None,
25
+ keep_aspect_ratio=False,
26
+ ensure_multiple_of=32,
27
+ resize_method=resize_mode,
28
+ image_interpolation_method=cv2.INTER_CUBIC,
29
+ ),
30
+ normalization,
31
+ PrepareForNet(),
32
+ ]
33
+ )
34
+ # image = utils.read_image(img_path) # in [0, 1]
35
+ image = cv2.imread(img_path)
36
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) / 255.0
37
+ org_size= image.shape[:2]
38
+ image = transform({"image": image})["image"]
39
+ sample = torch.from_numpy(image).to("cpu").unsqueeze(0)
40
+ height, width = sample.shape[2:]
41
+ print(f"Input resized to {width}x{height} before entering the encoder")
42
+
43
+ return sample,org_size
44
+
45
+
46
+
47
+ def write_depth(path, depth, grayscale=False, bits=1):
48
+ if not grayscale:
49
+ bits = 1
50
+
51
+ if not np.isfinite(depth).all():
52
+ depth=np.nan_to_num(depth, nan=0.0, posinf=0.0, neginf=0.0)
53
+ print("WARNING: Non-finite depth values present")
54
+
55
+ depth_min = depth.min()
56
+ depth_max = depth.max()
57
+
58
+ max_val = (2**(8*bits))-1
59
+
60
+ if depth_max - depth_min > np.finfo("float").eps:
61
+ out = max_val * (depth - depth_min) / (depth_max - depth_min)
62
+ else:
63
+ out = np.zeros(depth.shape, dtype=depth.dtype)
64
+
65
+ # print("out :",out.shape,out)
66
+ if not grayscale:
67
+ out = cv2.applyColorMap(np.uint8(out), cv2.COLORMAP_INFERNO)
68
+
69
+ if bits == 1:
70
+ cv2.imwrite(path , out.astype("uint8"))
71
+ elif bits == 2:
72
+ cv2.imwrite(path , out.astype("uint16"))
73
+
74
+ return
75
+
76
+ def write_pfm(path, image, scale=1):
77
+ with open(path, "wb") as file:
78
+ color = None
79
+
80
+ if image.dtype.name != "float32":
81
+ raise Exception("Image dtype must be float32.")
82
+
83
+ image = np.flipud(image)
84
+
85
+ if len(image.shape) == 3 and image.shape[2] == 3: # color image
86
+ color = True
87
+ elif (
88
+ len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1
89
+ ): # greyscale
90
+ color = False
91
+ else:
92
+ raise Exception("Image must have H x W x 3, H x W x 1 or H x W dimensions.")
93
+
94
+ file.write("PF\n" if color else "Pf\n".encode())
95
+ file.write("%d %d\n".encode() % (image.shape[1], image.shape[0]))
96
+
97
+ endian = image.dtype.byteorder
98
+
99
+ if endian == "<" or endian == "=" and sys.byteorder == "little":
100
+ scale = -scale
101
+
102
+ file.write("%f\n".encode() % scale)
103
+
104
+ image.tofile(file)
model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/README.md ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Model Information
2
+
3
+ ### Source model
4
+ - Input shape: 1x3x256x256
5
+ - Number of parameters: 20.33M
6
+ - Model size: 82.17M
7
+ - Output shape: 1x1x256x256
8
+
9
+ Source model repository: [midas](https://github.com/isl-org/MiDaS/tree/master)
10
+
11
+ ### Converted model
12
+
13
+ - Precision: INT8
14
+ - Backend: QNN2.16
15
+ - Target Device: FV01 QCS6490
16
+
17
+ ## Inference with AidLite SDK
18
+
19
+ ### SDK installation
20
+ Model Farm uses AidLite SDK as the model inference SDK. For details, please refer to the [AidLite Developer Documentation](https://v2.docs.aidlux.com/en/sdk-api/aidlite-sdk/)
21
+
22
+ - Install AidLite SDK
23
+
24
+ ```bash
25
+ # Install the appropriate version of the aidlite sdk
26
+ sudo aid-pkg update
27
+ sudo aid-pkg install aidlite-sdk
28
+ # Download the qnn version that matches the above backend. Eg Install QNN2.23 Aidlite: sudo aid-pkg install aidlite-qnn223
29
+ sudo aid-pkg install aidlite-{QNN VERSION}
30
+ ```
31
+
32
+ - Verify AidLite SDK
33
+
34
+ ```bash
35
+ # aidlite sdk c++ check
36
+ python3 -c "import aidlite ; print(aidlite.get_library_version())"
37
+
38
+ # aidlite sdk python check
39
+ python3 -c "import aidlite ; print(aidlite.get_py_library_version())"
40
+ ```
41
+
42
+ ### Run Demo
43
+ #### python
44
+ ```bash
45
+ cd model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite
46
+ python3 python/run_test.py --target_model ./models/midas_v2_w8a16.qnn216.ctx.bin --imgs ./python/dog.jpg --invoke_nums 10
47
+ ```
48
+
49
+ #### c++
50
+ ```bash
51
+ cd midas_v2/model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/cpp
52
+ mkdir build && cd build
53
+ cmake ..
54
+ make
55
+ ./run_test
56
+ ```
model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/cpp/CMakeLists.txt ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required (VERSION 3.5)
2
+ project("run_test")
3
+
4
+ find_package(OpenCV REQUIRED)
5
+
6
+ message(STATUS "oPENCV Library status:")
7
+ message(STATUS ">version:${OpenCV_VERSION}")
8
+ message(STATUS "Include:${OpenCV_INCLUDE_DIRS}")
9
+
10
+ set(CMAKE_CXX_FLAGS "-Wno-error=deprecated-declarations -Wno-deprecated-declarations")
11
+
12
+ include_directories(
13
+ /usr/local/include
14
+ /usr/include/opencv4
15
+ )
16
+
17
+ link_directories(
18
+ /usr/local/lib/
19
+ )
20
+
21
+ file(GLOB SRC_LISTS
22
+ ${CMAKE_CURRENT_SOURCE_DIR}/run_test.cpp
23
+ )
24
+
25
+ add_executable(run_test ${SRC_LISTS})
26
+
27
+ target_link_libraries(run_test
28
+ aidlite
29
+ ${OpenCV_LIBS}
30
+ pthread
31
+ jsoncpp
32
+ )
model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/cpp/dog.jpg ADDED

Git LFS Details

  • SHA256: f3f87bb8ab3c26c7ecfd3ac60421d7f32b0503d1d6c5baf8bac42ed93d86351a
  • Pointer size: 131 Bytes
  • Size of remote file: 661 kB
model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/cpp/run_test.cpp ADDED
@@ -0,0 +1,392 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <fstream>
3
+ #include <opencv2/opencv.hpp>
4
+ #include <aidlux/aidlite/aidlite.hpp>
5
+ #include <vector>
6
+ #include <numeric>
7
+ #include <cmath>
8
+ #include <jsoncpp/json/json.h>
9
+
10
+ using namespace cv;
11
+ using namespace std;
12
+ using namespace Aidlux::Aidlite;
13
+
14
+ const int net_w = 256;
15
+ const int net_h = 256;
16
+
17
+ const std::vector<float> mean_vals = {0.485f, 0.456f, 0.406f};
18
+ const std::vector<float> std_vals = {0.229f, 0.224f, 0.225f};
19
+
20
+
21
+ struct Args {
22
+ std::string target_model = "../../models/midas_v2_w8a16.qnn216.ctx.bin";
23
+ std::string imgs = "../dog.jpg";
24
+ int invoke_nums = 10;
25
+ std::string model_type = "QNN";
26
+ };
27
+
28
+
29
+ Args parse_args(int argc, char* argv[]) {
30
+ Args args;
31
+ for (int i = 1; i < argc; ++i) {
32
+ std::string arg = argv[i];
33
+ if (arg == "--target_model" && i + 1 < argc) {
34
+ args.target_model = argv[++i];
35
+ } else if (arg == "--imgs" && i + 1 < argc) {
36
+ args.imgs = argv[++i];
37
+ } else if (arg == "--invoke_nums" && i + 1 < argc) {
38
+ args.invoke_nums = std::stoi(argv[++i]);
39
+ } else if (arg == "--model_type" && i + 1 < argc) {
40
+ args.model_type = argv[++i];
41
+ }
42
+ }
43
+ return args;
44
+ }
45
+
46
+ std::string to_lower(const std::string& str) {
47
+ std::string lower_str = str;
48
+ std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(), [](unsigned char c) {
49
+ return std::tolower(c);
50
+ });
51
+ return lower_str;
52
+ }
53
+
54
+
55
+ int transpose(float* src, unsigned int* src_dims, unsigned int* tsp_dims, float* dest){
56
+
57
+ int current_coordinate[4] = {0, 0, 0, 0};
58
+ for(int a = 0; a < src_dims[0]; ++a){
59
+ current_coordinate[0] = a;
60
+ for(int b = 0; b < src_dims[1]; ++b){
61
+ current_coordinate[1] = b;
62
+ for(int c = 0; c < src_dims[2]; ++c){
63
+ current_coordinate[2] = c;
64
+ for(int d = 0; d < src_dims[3]; ++d){
65
+ current_coordinate[3] = d;
66
+
67
+ int old_index = current_coordinate[0]*src_dims[1]*src_dims[2]*src_dims[3] +
68
+ current_coordinate[1]*src_dims[2]*src_dims[3] +
69
+ current_coordinate[2]*src_dims[3] +
70
+ current_coordinate[3];
71
+
72
+ int new_index = current_coordinate[tsp_dims[0]]*src_dims[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
73
+ current_coordinate[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
74
+ current_coordinate[tsp_dims[2]]*src_dims[tsp_dims[3]] +
75
+ current_coordinate[tsp_dims[3]];
76
+
77
+ dest[new_index] = src[old_index];
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ return EXIT_SUCCESS;
84
+ }
85
+
86
+
87
+ // 替代 np.nan_to_num
88
+ void sanitizeDepthMap(cv::Mat& depth) {
89
+ for (int y = 0; y < depth.rows; ++y) {
90
+ float* row = depth.ptr<float>(y);
91
+ for (int x = 0; x < depth.cols; ++x) {
92
+ float val = row[x];
93
+ if (!std::isfinite(val)) {
94
+ row[x] = 0.0f;
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ // 等效于 Python write_depth
101
+ void write_depth(const std::string& path, const cv::Mat& input_depth, bool grayscale = false, int bits = 1) {
102
+ CV_Assert(input_depth.type() == CV_32FC1);
103
+
104
+ // 拷贝 + 处理非法值
105
+ cv::Mat depth = input_depth.clone();
106
+ sanitizeDepthMap(depth);
107
+
108
+ double minVal, maxVal;
109
+ cv::minMaxLoc(depth, &minVal, &maxVal);
110
+
111
+ double max_val = (1 << (8 * bits)) - 1;
112
+ cv::Mat out;
113
+
114
+ if (maxVal - minVal > std::numeric_limits<float>::epsilon()) {
115
+ // 归一化并映射到位深范围
116
+ out = (depth - minVal) * (max_val / (maxVal - minVal));
117
+ } else {
118
+ out = cv::Mat::zeros(depth.size(), CV_32F);
119
+ }
120
+
121
+ if (!grayscale) {
122
+ out.convertTo(out, CV_8UC1);
123
+ cv::applyColorMap(out, out, cv::COLORMAP_INFERNO);
124
+ }
125
+
126
+ if (bits == 1) {
127
+ out.convertTo(out, CV_8U);
128
+ } else if (bits == 2) {
129
+ out.convertTo(out, CV_16U);
130
+ }
131
+
132
+ cv::imwrite(path, out);
133
+ }
134
+
135
+ // 等效于 Python write_pfm
136
+ void write_pfm(const std::string& path, const cv::Mat& image, float scale = 1.0f) {
137
+ CV_Assert(image.type() == CV_32FC1 || image.type() == CV_32FC3);
138
+
139
+ std::ofstream file(path, std::ios::binary);
140
+ if (!file.is_open()) {
141
+ std::cerr << "Failed to open file for writing PFM: " << path << std::endl;
142
+ return;
143
+ }
144
+
145
+ int width = image.cols;
146
+ int height = image.rows;
147
+ int channels = image.channels();
148
+ bool color = (channels == 3);
149
+
150
+ file << (color ? "PF" : "Pf") << "\n";
151
+ file << width << " " << height << "\n";
152
+
153
+ // Endianness: negative = little-endian
154
+ uint16_t endian_test = 0x1;
155
+ bool is_little_endian = *(reinterpret_cast<uint8_t*>(&endian_test)) == 0x1;
156
+ if (is_little_endian) {
157
+ scale = -scale;
158
+ }
159
+
160
+ file << scale << "\n";
161
+
162
+ // Flip vertically (OpenCV top-left origin -> PFM bottom-left origin)
163
+ cv::Mat flipped;
164
+ cv::flip(image, flipped, 0);
165
+
166
+ // Write raw data
167
+ file.write(reinterpret_cast<const char*>(flipped.data), flipped.total() * channels * sizeof(float));
168
+ file.close();
169
+ }
170
+
171
+
172
+ // ======================= Normalize =======================
173
+ void normalize(cv::Mat& image) {
174
+ CV_Assert(image.type() == CV_32FC3);
175
+ int rows = image.rows;
176
+ int cols = image.cols;
177
+
178
+ for (int y = 0; y < rows; ++y) {
179
+ cv::Vec3f* row = image.ptr<cv::Vec3f>(y);
180
+ for (int x = 0; x < cols; ++x) {
181
+ for (int c = 0; c < 3; ++c) {
182
+ row[x][c] = (row[x][c] - mean_vals[c]) / std_vals[c];
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ cv::Mat hwc_to_chw(const cv::Mat& image) {
189
+ std::vector<cv::Mat> channels(3);
190
+ cv::split(image, channels);
191
+
192
+ cv::Mat chw(3, image.rows * image.cols, CV_32F);
193
+ for (int c = 0; c < 3; ++c) {
194
+ memcpy(chw.ptr(c), channels[c].data, image.rows * image.cols * sizeof(float));
195
+ }
196
+
197
+ return chw;
198
+ }
199
+
200
+
201
+ bool first_execution = true;
202
+ cv::Mat img_process(const cv::Mat image_bgr, cv::Size& org_size_out) {
203
+ first_execution = false;
204
+
205
+ cv::Mat image_rgb;
206
+ cv::cvtColor(image_bgr, image_rgb, cv::COLOR_BGR2RGB);
207
+ image_rgb.convertTo(image_rgb, CV_32FC3, 1.0 / 255.0);
208
+
209
+ // 2. Save original size
210
+ org_size_out = image_rgb.size(); // H x W
211
+
212
+ // 3. Resize to 256x256 using cubic interpolation
213
+ cv::resize(image_rgb, image_rgb, cv::Size(net_w, net_h), 0, 0, cv::INTER_CUBIC);
214
+
215
+ // 4. Normalize using mean/std
216
+ normalize(image_rgb);
217
+
218
+ // 5. Convert HWC to CHW
219
+ cv::Mat chw = hwc_to_chw(image_rgb);
220
+
221
+ // 6. Add batch dimension: [1, C, H, W] → reshape to 1x3xHxW style float array
222
+ cv::Mat input_tensor(1, 3 * net_h * net_w, CV_32F);
223
+ memcpy(input_tensor.ptr<float>(), chw.data, 3 * net_h * net_w * sizeof(float));
224
+
225
+ std::cout << "Input resized to " << net_w << "x" << net_h << " before entering the encoder" << std::endl;
226
+
227
+ return input_tensor;
228
+ }
229
+
230
+
231
+ float* matToFloatPtr(const cv::Mat& input_mat, bool normalize = true) {
232
+ // 检查连续性
233
+ cv::Mat mat = input_mat;
234
+ if (!mat.isContinuous()) {
235
+ mat = mat.clone();
236
+ }
237
+
238
+ // 分配内存
239
+ int total_pixels = mat.rows * mat.cols;
240
+ int channels = mat.channels();
241
+ float* float_data = new float[total_pixels * channels];
242
+
243
+ // 根据数据类型转换
244
+ if (mat.type() == CV_8UC1 || mat.type() == CV_8UC3) {
245
+ uchar* ptr = mat.ptr<uchar>(0);
246
+ for (int i = 0; i < total_pixels * channels; ++i) {
247
+ float_data[i] = normalize ? (static_cast<float>(ptr[i]) / 255.0f) : ptr[i];
248
+ }
249
+ } else if (mat.type() == CV_32FC1 || mat.type() == CV_32FC3) {
250
+ float* ptr = mat.ptr<float>(0);
251
+ std::memcpy(float_data, ptr, total_pixels * channels * sizeof(float));
252
+ } else {
253
+ delete[] float_data;
254
+ return nullptr; // 不支持的类型
255
+ }
256
+
257
+ return float_data;
258
+ }
259
+
260
+
261
+ int invoke(const Args& args) {
262
+ std::cout << "Start main ... ... Model Path: " << args.target_model << "\n"
263
+ << "Image Path: " << args.imgs << "\n"
264
+ << "Inference Nums: " << args.invoke_nums << "\n"
265
+ << "Model Type: " << args.model_type << "\n";
266
+ Model* model = Model::create_instance(args.target_model);
267
+ if(model == nullptr){
268
+ printf("Create model failed !\n");
269
+ return EXIT_FAILURE;
270
+ }
271
+ Config* config = Config::create_instance();
272
+ if(config == nullptr){
273
+ printf("Create config failed !\n");
274
+ return EXIT_FAILURE;
275
+ }
276
+ config->implement_type = ImplementType::TYPE_LOCAL;
277
+ std::string model_type_lower = to_lower(args.model_type);
278
+ if (model_type_lower == "qnn"){
279
+ config->framework_type = FrameworkType::TYPE_QNN;
280
+ } else if (model_type_lower == "snpe2" || model_type_lower == "snpe") {
281
+ config->framework_type = FrameworkType::TYPE_SNPE2;
282
+ }
283
+ config->accelerate_type = AccelerateType::TYPE_DSP;
284
+ config->is_quantify_model = 1;
285
+
286
+ unsigned int model_h = 256;
287
+ unsigned int model_w = 256;
288
+ std::vector<std::vector<uint32_t>> input_shapes = {{1,model_h,model_w,3}};
289
+ std::vector<std::vector<uint32_t>> output_shapes = {{1,model_h,model_w,1}};
290
+ model->set_model_properties(input_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32, output_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32);
291
+ std::unique_ptr<Interpreter> fast_interpreter = InterpreterBuilder::build_interpretper_from_model_and_config(model, config);
292
+ if(fast_interpreter == nullptr){
293
+ printf("build_interpretper_from_model_and_config failed !\n");
294
+ return EXIT_FAILURE;
295
+ }
296
+ int result = fast_interpreter->init();
297
+ if(result != EXIT_SUCCESS){
298
+ printf("interpreter->init() failed !\n");
299
+ return EXIT_FAILURE;
300
+ }
301
+ // load model
302
+ fast_interpreter->load_model();
303
+ if(result != EXIT_SUCCESS){
304
+ printf("interpreter->load_model() failed !\n");
305
+ return EXIT_FAILURE;
306
+ }
307
+ printf("detect model load success!\n");
308
+
309
+ cv::Mat frame = cv::imread(args.imgs);
310
+ if (frame.empty()) {
311
+ printf("detect image load failed!\n");
312
+ return 1;
313
+ }
314
+ printf("img_src cols: %d, img_src rows: %d\n", frame.cols, frame.rows);
315
+ cv::Mat input_data;
316
+ cv::Mat frame_clone = frame.clone();
317
+ int h = frame_clone.rows;
318
+ int w = frame_clone.cols;
319
+ cv::Size org_size(w, h);
320
+ cv::Size org_size0(256, 256);
321
+
322
+ cv::Mat input_tensor = img_process(frame_clone, org_size0);
323
+ float* float_data = matToFloatPtr(input_tensor);
324
+ unsigned int src_dims[4] = {1, 3, 256, 256};
325
+ unsigned int tsp_dims[4] = {0,2,3,1};
326
+ unsigned int stride_data_num = 1*256*256*3;
327
+ float* format_data = new float[stride_data_num];
328
+ transpose(float_data, src_dims, tsp_dims, format_data);
329
+ cv::Mat origin_buffer(3,256*256, CV_32F, format_data);
330
+
331
+ float *outdata0 = nullptr;
332
+ std::vector<float> invoke_time;
333
+ for (int i = 0; i < args.invoke_nums; ++i) {
334
+ result = fast_interpreter->set_input_tensor(0, origin_buffer.data);
335
+ if(result != EXIT_SUCCESS){
336
+ printf("interpreter->set_input_tensor() failed !\n");
337
+ return EXIT_FAILURE;
338
+ }
339
+ auto t1 = std::chrono::high_resolution_clock::now();
340
+ result = fast_interpreter->invoke();
341
+ auto t2 = std::chrono::high_resolution_clock::now();
342
+ std::chrono::duration<double> cost_time = t2 - t1;
343
+ invoke_time.push_back(cost_time.count() * 1000);
344
+ if(result != EXIT_SUCCESS){
345
+ printf("interpreter->invoke() failed !\n");
346
+ return EXIT_FAILURE;
347
+ }
348
+ uint32_t out_data_0 = 0;
349
+ result = fast_interpreter->get_output_tensor(0, (void**)&outdata0, &out_data_0);
350
+ if(result != EXIT_SUCCESS){
351
+ printf("interpreter->get_output_tensor() 1 failed !\n");
352
+ return EXIT_FAILURE;
353
+ }
354
+
355
+ }
356
+
357
+ float max_invoke_time = *std::max_element(invoke_time.begin(), invoke_time.end());
358
+ float min_invoke_time = *std::min_element(invoke_time.begin(), invoke_time.end());
359
+ float mean_invoke_time = std::accumulate(invoke_time.begin(), invoke_time.end(), 0.0f) / args.invoke_nums;
360
+ float var_invoketime = 0.0f;
361
+ for (auto time : invoke_time) {
362
+ var_invoketime += (time - mean_invoke_time) * (time - mean_invoke_time);
363
+ }
364
+ var_invoketime /= args.invoke_nums;
365
+ printf("=======================================\n");
366
+ printf("QNN inference %d times :\n --mean_invoke_time is %f \n --max_invoke_time is %f \n --min_invoke_time is %f \n --var_invoketime is %f\n",
367
+ args.invoke_nums, mean_invoke_time, max_invoke_time, min_invoke_time, var_invoketime);
368
+ printf("=======================================\n");
369
+
370
+ // post process
371
+ cv::Mat out_buffer(1,256*256, CV_32F, outdata0);
372
+ cv::Mat prediction_2d(256, 256, CV_32F, (void*)out_buffer.ptr<float>());
373
+ cv::Mat resized;
374
+ cv::resize(prediction_2d, resized, org_size, 0, 0, cv::INTER_CUBIC);
375
+
376
+ // 保存为图像
377
+ write_depth("depth_output.jpg", resized, false, 1);
378
+
379
+ // 保存为 PFM
380
+ write_pfm("depth_output.pfm", resized);
381
+
382
+
383
+
384
+ fast_interpreter->destory();
385
+ return 0;
386
+ }
387
+
388
+
389
+ int main(int argc, char* argv[]) {
390
+ Args args = parse_args(argc, argv);
391
+ return invoke(args);
392
+ }
model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/models/midas_v2_w8a16.qnn216.ctx.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cc4f6a5cdfb55ede7cfde5298734fc33221d440fe410b726bc9fdaca2ff6a667
3
+ size 27836416
model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/python/dog.jpg ADDED

Git LFS Details

  • SHA256: f3f87bb8ab3c26c7ecfd3ac60421d7f32b0503d1d6c5baf8bac42ed93d86351a
  • Pointer size: 131 Bytes
  • Size of remote file: 661 kB
model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/python/run_test.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import torch
3
+ import cv2
4
+ import os
5
+ from utils import write_pfm,write_depth,img_process
6
+ import aidlite
7
+ import time
8
+ import argparse
9
+
10
+ def out_process(prediction,target_size):
11
+ prediction = torch.nn.functional.interpolate(
12
+ prediction,
13
+ size=target_size,
14
+ mode="bicubic",
15
+ align_corners=False,
16
+ )
17
+ prediction = prediction.squeeze().detach().numpy()
18
+ return prediction
19
+
20
+ class run_qnn:
21
+ def __init__(self,qnn_path):
22
+ super().__init__()
23
+ self.model = aidlite.Model.create_instance(qnn_path)
24
+ if self.model is None:
25
+ print("Create model failed !")
26
+ return
27
+
28
+ self.config = aidlite.Config.create_instance()
29
+ if self.config is None:
30
+ print("build_interpretper_from_model_and_config failed !")
31
+ return
32
+
33
+ self.config.implement_type = aidlite.ImplementType.TYPE_LOCAL
34
+ self.config.framework_type = aidlite.FrameworkType.TYPE_QNN
35
+ self.config.accelerate_type = aidlite.AccelerateType.TYPE_DSP
36
+ # self.config.accelerate_type = aidlite.AccelerateType.TYPE_CPU
37
+ self.config.is_quantify_model = 1
38
+
39
+ self.interpreter = aidlite.InterpreterBuilder.build_interpretper_from_model_and_config(self.model, self.config)
40
+ if self.interpreter is None:
41
+ print("build_interpretper_from_model_and_config failed !")
42
+ return
43
+ input_shapes = [[1,256,256,3]]
44
+ output_shapes = [[1,256,256,1]]
45
+ self.model.set_model_properties(input_shapes, aidlite.DataType.TYPE_FLOAT32,
46
+ output_shapes, aidlite.DataType.TYPE_FLOAT32)
47
+
48
+ if self.interpreter is None:
49
+ print("build_interpretper_from_model_and_config failed !")
50
+ result = self.interpreter.init()
51
+ if result != 0:
52
+ print(f"interpreter init failed !")
53
+ result = self.interpreter.load_model()
54
+ if result != 0:
55
+ print("interpreter load model failed !")
56
+
57
+ print(" model load success!")
58
+
59
+ def __call__(self, input,invoke_nums):
60
+ self.interpreter.set_input_tensor(0,input)
61
+ invoke_time=[]
62
+ for i in range(invoke_nums):
63
+ result = self.interpreter.set_input_tensor(0, input.data)
64
+ if result != 0:
65
+ print("interpreter set_input_tensor() failed")
66
+ t1=time.time()
67
+ result = self.interpreter.invoke()
68
+ cost_time = (time.time()-t1)*1000
69
+ invoke_time.append(cost_time)
70
+
71
+ max_invoke_time = max(invoke_time)
72
+ min_invoke_time = min(invoke_time)
73
+ mean_invoke_time = sum(invoke_time)/invoke_nums
74
+ var_invoketime=np.var(invoke_time)
75
+ print("====================================")
76
+ print(f"QNN invoke time:\n --mean_invoke_time is {mean_invoke_time} \n --max_invoke_time is {max_invoke_time} \n --min_invoke_time is {min_invoke_time} \n --var_invoketime is {var_invoketime}")
77
+ print("====================================")
78
+ features_0 = self.interpreter.get_output_tensor(0).reshape(1,256,256,1).transpose(0,3,1,2)
79
+ return features_0
80
+
81
+
82
+
83
+ def run(args):
84
+ img_path = args.imgs
85
+ qnn_path = args.target_model
86
+ invoke_num=args.invoke_nums
87
+ print("Start processing...")
88
+ img_input,org_size = img_process(img_path)
89
+
90
+ qnn_model =run_qnn(qnn_path)
91
+ prediction_qnn = qnn_model(img_input.numpy().transpose(0,2,3,1),invoke_num)
92
+ prediction_qnn = torch.tensor(prediction_qnn)
93
+ qnn_process = out_process(prediction_qnn,org_size)
94
+
95
+ write_depth("./python/results.jpg", qnn_process, grayscale=False, bits=1)
96
+ write_pfm("./python/results.pfm", qnn_process.astype(np.float32))
97
+ print("Finished")
98
+
99
+ def parser_args():
100
+ parser = argparse.ArgumentParser(description="Run model benchmarks")
101
+ parser.add_argument('--target_model',type=str,default='./models/midas_v2_w8a16.qnn216.ctx.bin',help="Inference model path")
102
+ parser.add_argument('--imgs',type=str,default='./python/dog.jpg',help="Predict images path")
103
+ parser.add_argument('--invoke_nums',type=int,default=10,help="Inference nums")
104
+ parser.add_argument('--model_type',type=str,default='QNN',help="Run backend")
105
+ args = parser.parse_args()
106
+ return args
107
+
108
+
109
+ if __name__ =="__main__":
110
+ args = parser_args()
111
+ run(args)
model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/python/transforms.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import cv2
3
+ import math
4
+
5
+
6
+ def apply_min_size(sample, size, image_interpolation_method=cv2.INTER_AREA):
7
+ """Rezise the sample to ensure the given size. Keeps aspect ratio.
8
+
9
+ Args:
10
+ sample (dict): sample
11
+ size (tuple): image size
12
+
13
+ Returns:
14
+ tuple: new size
15
+ """
16
+ shape = list(sample["disparity"].shape)
17
+
18
+ if shape[0] >= size[0] and shape[1] >= size[1]:
19
+ return sample
20
+
21
+ scale = [0, 0]
22
+ scale[0] = size[0] / shape[0]
23
+ scale[1] = size[1] / shape[1]
24
+
25
+ scale = max(scale)
26
+
27
+ shape[0] = math.ceil(scale * shape[0])
28
+ shape[1] = math.ceil(scale * shape[1])
29
+
30
+ # resize
31
+ sample["image"] = cv2.resize(
32
+ sample["image"], tuple(shape[::-1]), interpolation=image_interpolation_method
33
+ )
34
+
35
+ sample["disparity"] = cv2.resize(
36
+ sample["disparity"], tuple(shape[::-1]), interpolation=cv2.INTER_NEAREST
37
+ )
38
+ sample["mask"] = cv2.resize(
39
+ sample["mask"].astype(np.float32),
40
+ tuple(shape[::-1]),
41
+ interpolation=cv2.INTER_NEAREST,
42
+ )
43
+ sample["mask"] = sample["mask"].astype(bool)
44
+
45
+ return tuple(shape)
46
+
47
+
48
+ class Resize(object):
49
+ """Resize sample to given size (width, height).
50
+ """
51
+
52
+ def __init__(
53
+ self,
54
+ width,
55
+ height,
56
+ resize_target=True,
57
+ keep_aspect_ratio=False,
58
+ ensure_multiple_of=1,
59
+ resize_method="lower_bound",
60
+ image_interpolation_method=cv2.INTER_AREA,
61
+ ):
62
+ """Init.
63
+
64
+ Args:
65
+ width (int): desired output width
66
+ height (int): desired output height
67
+ resize_target (bool, optional):
68
+ True: Resize the full sample (image, mask, target).
69
+ False: Resize image only.
70
+ Defaults to True.
71
+ keep_aspect_ratio (bool, optional):
72
+ True: Keep the aspect ratio of the input sample.
73
+ Output sample might not have the given width and height, and
74
+ resize behaviour depends on the parameter 'resize_method'.
75
+ Defaults to False.
76
+ ensure_multiple_of (int, optional):
77
+ Output width and height is constrained to be multiple of this parameter.
78
+ Defaults to 1.
79
+ resize_method (str, optional):
80
+ "lower_bound": Output will be at least as large as the given size.
81
+ "upper_bound": Output will be at max as large as the given size. (Output size might be smaller than given size.)
82
+ "minimal": Scale as least as possible. (Output size might be smaller than given size.)
83
+ Defaults to "lower_bound".
84
+ """
85
+ self.__width = width
86
+ self.__height = height
87
+
88
+ self.__resize_target = resize_target
89
+ self.__keep_aspect_ratio = keep_aspect_ratio
90
+ self.__multiple_of = ensure_multiple_of
91
+ self.__resize_method = resize_method
92
+ self.__image_interpolation_method = image_interpolation_method
93
+
94
+ def constrain_to_multiple_of(self, x, min_val=0, max_val=None):
95
+ y = (np.round(x / self.__multiple_of) * self.__multiple_of).astype(int)
96
+
97
+ if max_val is not None and y > max_val:
98
+ y = (np.floor(x / self.__multiple_of) * self.__multiple_of).astype(int)
99
+
100
+ if y < min_val:
101
+ y = (np.ceil(x / self.__multiple_of) * self.__multiple_of).astype(int)
102
+
103
+ return y
104
+
105
+ def get_size(self, width, height):
106
+ # determine new height and width
107
+ scale_height = self.__height / height
108
+ scale_width = self.__width / width
109
+
110
+ if self.__keep_aspect_ratio:
111
+ if self.__resize_method == "lower_bound":
112
+ # scale such that output size is lower bound
113
+ if scale_width > scale_height:
114
+ # fit width
115
+ scale_height = scale_width
116
+ else:
117
+ # fit height
118
+ scale_width = scale_height
119
+ elif self.__resize_method == "upper_bound":
120
+ # scale such that output size is upper bound
121
+ if scale_width < scale_height:
122
+ # fit width
123
+ scale_height = scale_width
124
+ else:
125
+ # fit height
126
+ scale_width = scale_height
127
+ elif self.__resize_method == "minimal":
128
+ # scale as least as possbile
129
+ if abs(1 - scale_width) < abs(1 - scale_height):
130
+ # fit width
131
+ scale_height = scale_width
132
+ else:
133
+ # fit height
134
+ scale_width = scale_height
135
+ else:
136
+ raise ValueError(
137
+ f"resize_method {self.__resize_method} not implemented"
138
+ )
139
+
140
+ if self.__resize_method == "lower_bound":
141
+ new_height = self.constrain_to_multiple_of(
142
+ scale_height * height, min_val=self.__height
143
+ )
144
+ new_width = self.constrain_to_multiple_of(
145
+ scale_width * width, min_val=self.__width
146
+ )
147
+ elif self.__resize_method == "upper_bound":
148
+ new_height = self.constrain_to_multiple_of(
149
+ scale_height * height, max_val=self.__height
150
+ )
151
+ new_width = self.constrain_to_multiple_of(
152
+ scale_width * width, max_val=self.__width
153
+ )
154
+ elif self.__resize_method == "minimal":
155
+ new_height = self.constrain_to_multiple_of(scale_height * height)
156
+ new_width = self.constrain_to_multiple_of(scale_width * width)
157
+ else:
158
+ raise ValueError(f"resize_method {self.__resize_method} not implemented")
159
+
160
+ return (new_width, new_height)
161
+
162
+ def __call__(self, sample):
163
+ width, height = self.get_size(
164
+ sample["image"].shape[1], sample["image"].shape[0]
165
+ )
166
+
167
+ # resize sample
168
+ sample["image"] = cv2.resize(
169
+ sample["image"],
170
+ (width, height),
171
+ interpolation=self.__image_interpolation_method,
172
+ )
173
+
174
+ if self.__resize_target:
175
+ if "disparity" in sample:
176
+ sample["disparity"] = cv2.resize(
177
+ sample["disparity"],
178
+ (width, height),
179
+ interpolation=cv2.INTER_NEAREST,
180
+ )
181
+
182
+ if "depth" in sample:
183
+ sample["depth"] = cv2.resize(
184
+ sample["depth"], (width, height), interpolation=cv2.INTER_NEAREST
185
+ )
186
+
187
+ sample["mask"] = cv2.resize(
188
+ sample["mask"].astype(np.float32),
189
+ (width, height),
190
+ interpolation=cv2.INTER_NEAREST,
191
+ )
192
+ sample["mask"] = sample["mask"].astype(bool)
193
+
194
+ return sample
195
+
196
+
197
+ class NormalizeImage(object):
198
+ """Normlize image by given mean and std.
199
+ """
200
+
201
+ def __init__(self, mean, std):
202
+ self.__mean = mean
203
+ self.__std = std
204
+
205
+ def __call__(self, sample):
206
+ sample["image"] = (sample["image"] - self.__mean) / self.__std
207
+
208
+ return sample
209
+
210
+
211
+ class PrepareForNet(object):
212
+ """Prepare sample for usage as network input.
213
+ """
214
+
215
+ def __init__(self):
216
+ pass
217
+
218
+ def __call__(self, sample):
219
+ image = np.transpose(sample["image"], (2, 0, 1))
220
+ sample["image"] = np.ascontiguousarray(image).astype(np.float32)
221
+
222
+ if "mask" in sample:
223
+ sample["mask"] = sample["mask"].astype(np.float32)
224
+ sample["mask"] = np.ascontiguousarray(sample["mask"])
225
+
226
+ if "disparity" in sample:
227
+ disparity = sample["disparity"].astype(np.float32)
228
+ sample["disparity"] = np.ascontiguousarray(disparity)
229
+
230
+ if "depth" in sample:
231
+ depth = sample["depth"].astype(np.float32)
232
+ sample["depth"] = np.ascontiguousarray(depth)
233
+
234
+ return sample
model_farm_midas_v2_qcs6490_qnn2.16_w8a16_aidlite/python/utils.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import torch
3
+ import cv2
4
+ import os
5
+
6
+ from transforms import Resize, NormalizeImage, PrepareForNet
7
+
8
+ from torchvision.transforms import Compose
9
+ import sys
10
+ first_execution = True
11
+ def img_process(img_path):
12
+ global first_execution
13
+ first_execution = False
14
+ net_w, net_h = 256, 256
15
+ resize_mode = "upper_bound"
16
+ normalization = NormalizeImage(
17
+ mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]
18
+ )
19
+ transform = Compose(
20
+ [
21
+ Resize(
22
+ net_w,
23
+ net_h,
24
+ resize_target=None,
25
+ keep_aspect_ratio=False,
26
+ ensure_multiple_of=32,
27
+ resize_method=resize_mode,
28
+ image_interpolation_method=cv2.INTER_CUBIC,
29
+ ),
30
+ normalization,
31
+ PrepareForNet(),
32
+ ]
33
+ )
34
+ # image = utils.read_image(img_path) # in [0, 1]
35
+ image = cv2.imread(img_path)
36
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) / 255.0
37
+ org_size= image.shape[:2]
38
+ image = transform({"image": image})["image"]
39
+ sample = torch.from_numpy(image).to("cpu").unsqueeze(0)
40
+ height, width = sample.shape[2:]
41
+ print(f"Input resized to {width}x{height} before entering the encoder")
42
+
43
+ return sample,org_size
44
+
45
+
46
+
47
+ def write_depth(path, depth, grayscale=False, bits=1):
48
+ if not grayscale:
49
+ bits = 1
50
+
51
+ if not np.isfinite(depth).all():
52
+ depth=np.nan_to_num(depth, nan=0.0, posinf=0.0, neginf=0.0)
53
+ print("WARNING: Non-finite depth values present")
54
+
55
+ depth_min = depth.min()
56
+ depth_max = depth.max()
57
+
58
+ max_val = (2**(8*bits))-1
59
+
60
+ if depth_max - depth_min > np.finfo("float").eps:
61
+ out = max_val * (depth - depth_min) / (depth_max - depth_min)
62
+ else:
63
+ out = np.zeros(depth.shape, dtype=depth.dtype)
64
+
65
+ # print("out :",out.shape,out)
66
+ if not grayscale:
67
+ out = cv2.applyColorMap(np.uint8(out), cv2.COLORMAP_INFERNO)
68
+
69
+ if bits == 1:
70
+ cv2.imwrite(path , out.astype("uint8"))
71
+ elif bits == 2:
72
+ cv2.imwrite(path , out.astype("uint16"))
73
+
74
+ return
75
+
76
+ def write_pfm(path, image, scale=1):
77
+ with open(path, "wb") as file:
78
+ color = None
79
+
80
+ if image.dtype.name != "float32":
81
+ raise Exception("Image dtype must be float32.")
82
+
83
+ image = np.flipud(image)
84
+
85
+ if len(image.shape) == 3 and image.shape[2] == 3: # color image
86
+ color = True
87
+ elif (
88
+ len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1
89
+ ): # greyscale
90
+ color = False
91
+ else:
92
+ raise Exception("Image must have H x W x 3, H x W x 1 or H x W dimensions.")
93
+
94
+ file.write("PF\n" if color else "Pf\n".encode())
95
+ file.write("%d %d\n".encode() % (image.shape[1], image.shape[0]))
96
+
97
+ endian = image.dtype.byteorder
98
+
99
+ if endian == "<" or endian == "=" and sys.byteorder == "little":
100
+ scale = -scale
101
+
102
+ file.write("%f\n".encode() % scale)
103
+
104
+ image.tofile(file)
model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/README.md ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Model Information
2
+
3
+ ### Source model
4
+ - Input shape: 1x3x256x256
5
+ - Number of parameters: 20.33M
6
+ - Model size: 82.17M
7
+ - Output shape: 1x1x256x256
8
+
9
+ Source model repository: [midas](https://github.com/isl-org/MiDaS/tree/master)
10
+
11
+ ### Converted model
12
+
13
+ - Precision: FP16
14
+ - Backend: QNN2.16
15
+ - Target Device: SNM972 QCS8550
16
+
17
+ ## Inference with AidLite SDK
18
+
19
+ ### SDK installation
20
+ Model Farm uses AidLite SDK as the model inference SDK. For details, please refer to the [AidLite Developer Documentation](https://v2.docs.aidlux.com/en/sdk-api/aidlite-sdk/)
21
+
22
+ - Install AidLite SDK
23
+
24
+ ```bash
25
+ # Install the appropriate version of the aidlite sdk
26
+ sudo aid-pkg update
27
+ sudo aid-pkg install aidlite-sdk
28
+ # Download the qnn version that matches the above backend. Eg Install QNN2.23 Aidlite: sudo aid-pkg install aidlite-qnn223
29
+ sudo aid-pkg install aidlite-{QNN VERSION}
30
+ ```
31
+
32
+ - Verify AidLite SDK
33
+
34
+ ```bash
35
+ # aidlite sdk c++ check
36
+ python3 -c "import aidlite ; print(aidlite.get_library_version())"
37
+
38
+ # aidlite sdk python check
39
+ python3 -c "import aidlite ; print(aidlite.get_py_library_version())"
40
+ ```
41
+
42
+ ### Run Demo
43
+ #### python
44
+ ```bash
45
+ cd model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite
46
+ python3 python/run_test.py --target_model ./models/midas_v2_fp16.qnn216.ctx.bin --imgs ./python/dog.jpg --invoke_nums 10
47
+ ```
48
+
49
+ #### c++
50
+ ```bash
51
+ cd midas_v2/model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/cpp
52
+ mkdir build && cd build
53
+ cmake ..
54
+ make
55
+ ./run_test
56
+ ```
model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/cpp/CMakeLists.txt ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required (VERSION 3.5)
2
+ project("run_test")
3
+
4
+ find_package(OpenCV REQUIRED)
5
+
6
+ message(STATUS "oPENCV Library status:")
7
+ message(STATUS ">version:${OpenCV_VERSION}")
8
+ message(STATUS "Include:${OpenCV_INCLUDE_DIRS}")
9
+
10
+ set(CMAKE_CXX_FLAGS "-Wno-error=deprecated-declarations -Wno-deprecated-declarations")
11
+
12
+ include_directories(
13
+ /usr/local/include
14
+ /usr/include/opencv4
15
+ )
16
+
17
+ link_directories(
18
+ /usr/local/lib/
19
+ )
20
+
21
+ file(GLOB SRC_LISTS
22
+ ${CMAKE_CURRENT_SOURCE_DIR}/run_test.cpp
23
+ )
24
+
25
+ add_executable(run_test ${SRC_LISTS})
26
+
27
+ target_link_libraries(run_test
28
+ aidlite
29
+ ${OpenCV_LIBS}
30
+ pthread
31
+ jsoncpp
32
+ )
model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/cpp/dog.jpg ADDED

Git LFS Details

  • SHA256: f3f87bb8ab3c26c7ecfd3ac60421d7f32b0503d1d6c5baf8bac42ed93d86351a
  • Pointer size: 131 Bytes
  • Size of remote file: 661 kB
model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/cpp/run_test.cpp ADDED
@@ -0,0 +1,392 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <fstream>
3
+ #include <opencv2/opencv.hpp>
4
+ #include <aidlux/aidlite/aidlite.hpp>
5
+ #include <vector>
6
+ #include <numeric>
7
+ #include <cmath>
8
+ #include <jsoncpp/json/json.h>
9
+
10
+ using namespace cv;
11
+ using namespace std;
12
+ using namespace Aidlux::Aidlite;
13
+
14
+ const int net_w = 256;
15
+ const int net_h = 256;
16
+
17
+ const std::vector<float> mean_vals = {0.485f, 0.456f, 0.406f};
18
+ const std::vector<float> std_vals = {0.229f, 0.224f, 0.225f};
19
+
20
+
21
+ struct Args {
22
+ std::string target_model = "../../models/midas_v2_fp16.qnn216.ctx.bin";
23
+ std::string imgs = "../dog.jpg";
24
+ int invoke_nums = 10;
25
+ std::string model_type = "QNN";
26
+ };
27
+
28
+
29
+ Args parse_args(int argc, char* argv[]) {
30
+ Args args;
31
+ for (int i = 1; i < argc; ++i) {
32
+ std::string arg = argv[i];
33
+ if (arg == "--target_model" && i + 1 < argc) {
34
+ args.target_model = argv[++i];
35
+ } else if (arg == "--imgs" && i + 1 < argc) {
36
+ args.imgs = argv[++i];
37
+ } else if (arg == "--invoke_nums" && i + 1 < argc) {
38
+ args.invoke_nums = std::stoi(argv[++i]);
39
+ } else if (arg == "--model_type" && i + 1 < argc) {
40
+ args.model_type = argv[++i];
41
+ }
42
+ }
43
+ return args;
44
+ }
45
+
46
+ std::string to_lower(const std::string& str) {
47
+ std::string lower_str = str;
48
+ std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(), [](unsigned char c) {
49
+ return std::tolower(c);
50
+ });
51
+ return lower_str;
52
+ }
53
+
54
+
55
+ int transpose(float* src, unsigned int* src_dims, unsigned int* tsp_dims, float* dest){
56
+
57
+ int current_coordinate[4] = {0, 0, 0, 0};
58
+ for(int a = 0; a < src_dims[0]; ++a){
59
+ current_coordinate[0] = a;
60
+ for(int b = 0; b < src_dims[1]; ++b){
61
+ current_coordinate[1] = b;
62
+ for(int c = 0; c < src_dims[2]; ++c){
63
+ current_coordinate[2] = c;
64
+ for(int d = 0; d < src_dims[3]; ++d){
65
+ current_coordinate[3] = d;
66
+
67
+ int old_index = current_coordinate[0]*src_dims[1]*src_dims[2]*src_dims[3] +
68
+ current_coordinate[1]*src_dims[2]*src_dims[3] +
69
+ current_coordinate[2]*src_dims[3] +
70
+ current_coordinate[3];
71
+
72
+ int new_index = current_coordinate[tsp_dims[0]]*src_dims[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
73
+ current_coordinate[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
74
+ current_coordinate[tsp_dims[2]]*src_dims[tsp_dims[3]] +
75
+ current_coordinate[tsp_dims[3]];
76
+
77
+ dest[new_index] = src[old_index];
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ return EXIT_SUCCESS;
84
+ }
85
+
86
+
87
+ // 替代 np.nan_to_num
88
+ void sanitizeDepthMap(cv::Mat& depth) {
89
+ for (int y = 0; y < depth.rows; ++y) {
90
+ float* row = depth.ptr<float>(y);
91
+ for (int x = 0; x < depth.cols; ++x) {
92
+ float val = row[x];
93
+ if (!std::isfinite(val)) {
94
+ row[x] = 0.0f;
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ // 等效于 Python write_depth
101
+ void write_depth(const std::string& path, const cv::Mat& input_depth, bool grayscale = false, int bits = 1) {
102
+ CV_Assert(input_depth.type() == CV_32FC1);
103
+
104
+ // 拷贝 + 处理非法值
105
+ cv::Mat depth = input_depth.clone();
106
+ sanitizeDepthMap(depth);
107
+
108
+ double minVal, maxVal;
109
+ cv::minMaxLoc(depth, &minVal, &maxVal);
110
+
111
+ double max_val = (1 << (8 * bits)) - 1;
112
+ cv::Mat out;
113
+
114
+ if (maxVal - minVal > std::numeric_limits<float>::epsilon()) {
115
+ // 归一化并映射到位深范围
116
+ out = (depth - minVal) * (max_val / (maxVal - minVal));
117
+ } else {
118
+ out = cv::Mat::zeros(depth.size(), CV_32F);
119
+ }
120
+
121
+ if (!grayscale) {
122
+ out.convertTo(out, CV_8UC1);
123
+ cv::applyColorMap(out, out, cv::COLORMAP_INFERNO);
124
+ }
125
+
126
+ if (bits == 1) {
127
+ out.convertTo(out, CV_8U);
128
+ } else if (bits == 2) {
129
+ out.convertTo(out, CV_16U);
130
+ }
131
+
132
+ cv::imwrite(path, out);
133
+ }
134
+
135
+ // 等效于 Python write_pfm
136
+ void write_pfm(const std::string& path, const cv::Mat& image, float scale = 1.0f) {
137
+ CV_Assert(image.type() == CV_32FC1 || image.type() == CV_32FC3);
138
+
139
+ std::ofstream file(path, std::ios::binary);
140
+ if (!file.is_open()) {
141
+ std::cerr << "Failed to open file for writing PFM: " << path << std::endl;
142
+ return;
143
+ }
144
+
145
+ int width = image.cols;
146
+ int height = image.rows;
147
+ int channels = image.channels();
148
+ bool color = (channels == 3);
149
+
150
+ file << (color ? "PF" : "Pf") << "\n";
151
+ file << width << " " << height << "\n";
152
+
153
+ // Endianness: negative = little-endian
154
+ uint16_t endian_test = 0x1;
155
+ bool is_little_endian = *(reinterpret_cast<uint8_t*>(&endian_test)) == 0x1;
156
+ if (is_little_endian) {
157
+ scale = -scale;
158
+ }
159
+
160
+ file << scale << "\n";
161
+
162
+ // Flip vertically (OpenCV top-left origin -> PFM bottom-left origin)
163
+ cv::Mat flipped;
164
+ cv::flip(image, flipped, 0);
165
+
166
+ // Write raw data
167
+ file.write(reinterpret_cast<const char*>(flipped.data), flipped.total() * channels * sizeof(float));
168
+ file.close();
169
+ }
170
+
171
+
172
+ // ======================= Normalize =======================
173
+ void normalize(cv::Mat& image) {
174
+ CV_Assert(image.type() == CV_32FC3);
175
+ int rows = image.rows;
176
+ int cols = image.cols;
177
+
178
+ for (int y = 0; y < rows; ++y) {
179
+ cv::Vec3f* row = image.ptr<cv::Vec3f>(y);
180
+ for (int x = 0; x < cols; ++x) {
181
+ for (int c = 0; c < 3; ++c) {
182
+ row[x][c] = (row[x][c] - mean_vals[c]) / std_vals[c];
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ cv::Mat hwc_to_chw(const cv::Mat& image) {
189
+ std::vector<cv::Mat> channels(3);
190
+ cv::split(image, channels);
191
+
192
+ cv::Mat chw(3, image.rows * image.cols, CV_32F);
193
+ for (int c = 0; c < 3; ++c) {
194
+ memcpy(chw.ptr(c), channels[c].data, image.rows * image.cols * sizeof(float));
195
+ }
196
+
197
+ return chw;
198
+ }
199
+
200
+
201
+ bool first_execution = true;
202
+ cv::Mat img_process(const cv::Mat image_bgr, cv::Size& org_size_out) {
203
+ first_execution = false;
204
+
205
+ cv::Mat image_rgb;
206
+ cv::cvtColor(image_bgr, image_rgb, cv::COLOR_BGR2RGB);
207
+ image_rgb.convertTo(image_rgb, CV_32FC3, 1.0 / 255.0);
208
+
209
+ // 2. Save original size
210
+ org_size_out = image_rgb.size(); // H x W
211
+
212
+ // 3. Resize to 256x256 using cubic interpolation
213
+ cv::resize(image_rgb, image_rgb, cv::Size(net_w, net_h), 0, 0, cv::INTER_CUBIC);
214
+
215
+ // 4. Normalize using mean/std
216
+ normalize(image_rgb);
217
+
218
+ // 5. Convert HWC to CHW
219
+ cv::Mat chw = hwc_to_chw(image_rgb);
220
+
221
+ // 6. Add batch dimension: [1, C, H, W] → reshape to 1x3xHxW style float array
222
+ cv::Mat input_tensor(1, 3 * net_h * net_w, CV_32F);
223
+ memcpy(input_tensor.ptr<float>(), chw.data, 3 * net_h * net_w * sizeof(float));
224
+
225
+ std::cout << "Input resized to " << net_w << "x" << net_h << " before entering the encoder" << std::endl;
226
+
227
+ return input_tensor;
228
+ }
229
+
230
+
231
+ float* matToFloatPtr(const cv::Mat& input_mat, bool normalize = true) {
232
+ // 检查连续性
233
+ cv::Mat mat = input_mat;
234
+ if (!mat.isContinuous()) {
235
+ mat = mat.clone();
236
+ }
237
+
238
+ // 分配内存
239
+ int total_pixels = mat.rows * mat.cols;
240
+ int channels = mat.channels();
241
+ float* float_data = new float[total_pixels * channels];
242
+
243
+ // 根据数据类型转换
244
+ if (mat.type() == CV_8UC1 || mat.type() == CV_8UC3) {
245
+ uchar* ptr = mat.ptr<uchar>(0);
246
+ for (int i = 0; i < total_pixels * channels; ++i) {
247
+ float_data[i] = normalize ? (static_cast<float>(ptr[i]) / 255.0f) : ptr[i];
248
+ }
249
+ } else if (mat.type() == CV_32FC1 || mat.type() == CV_32FC3) {
250
+ float* ptr = mat.ptr<float>(0);
251
+ std::memcpy(float_data, ptr, total_pixels * channels * sizeof(float));
252
+ } else {
253
+ delete[] float_data;
254
+ return nullptr; // 不支持的类型
255
+ }
256
+
257
+ return float_data;
258
+ }
259
+
260
+
261
+ int invoke(const Args& args) {
262
+ std::cout << "Start main ... ... Model Path: " << args.target_model << "\n"
263
+ << "Image Path: " << args.imgs << "\n"
264
+ << "Inference Nums: " << args.invoke_nums << "\n"
265
+ << "Model Type: " << args.model_type << "\n";
266
+ Model* model = Model::create_instance(args.target_model);
267
+ if(model == nullptr){
268
+ printf("Create model failed !\n");
269
+ return EXIT_FAILURE;
270
+ }
271
+ Config* config = Config::create_instance();
272
+ if(config == nullptr){
273
+ printf("Create config failed !\n");
274
+ return EXIT_FAILURE;
275
+ }
276
+ config->implement_type = ImplementType::TYPE_LOCAL;
277
+ std::string model_type_lower = to_lower(args.model_type);
278
+ if (model_type_lower == "qnn"){
279
+ config->framework_type = FrameworkType::TYPE_QNN;
280
+ } else if (model_type_lower == "snpe2" || model_type_lower == "snpe") {
281
+ config->framework_type = FrameworkType::TYPE_SNPE2;
282
+ }
283
+ config->accelerate_type = AccelerateType::TYPE_DSP;
284
+ config->is_quantify_model = 1;
285
+
286
+ unsigned int model_h = 256;
287
+ unsigned int model_w = 256;
288
+ std::vector<std::vector<uint32_t>> input_shapes = {{1,model_h,model_w,3}};
289
+ std::vector<std::vector<uint32_t>> output_shapes = {{1,model_h,model_w,1}};
290
+ model->set_model_properties(input_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32, output_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32);
291
+ std::unique_ptr<Interpreter> fast_interpreter = InterpreterBuilder::build_interpretper_from_model_and_config(model, config);
292
+ if(fast_interpreter == nullptr){
293
+ printf("build_interpretper_from_model_and_config failed !\n");
294
+ return EXIT_FAILURE;
295
+ }
296
+ int result = fast_interpreter->init();
297
+ if(result != EXIT_SUCCESS){
298
+ printf("interpreter->init() failed !\n");
299
+ return EXIT_FAILURE;
300
+ }
301
+ // load model
302
+ fast_interpreter->load_model();
303
+ if(result != EXIT_SUCCESS){
304
+ printf("interpreter->load_model() failed !\n");
305
+ return EXIT_FAILURE;
306
+ }
307
+ printf("detect model load success!\n");
308
+
309
+ cv::Mat frame = cv::imread(args.imgs);
310
+ if (frame.empty()) {
311
+ printf("detect image load failed!\n");
312
+ return 1;
313
+ }
314
+ printf("img_src cols: %d, img_src rows: %d\n", frame.cols, frame.rows);
315
+ cv::Mat input_data;
316
+ cv::Mat frame_clone = frame.clone();
317
+ int h = frame_clone.rows;
318
+ int w = frame_clone.cols;
319
+ cv::Size org_size(w, h);
320
+ cv::Size org_size0(256, 256);
321
+
322
+ cv::Mat input_tensor = img_process(frame_clone, org_size0);
323
+ float* float_data = matToFloatPtr(input_tensor);
324
+ unsigned int src_dims[4] = {1, 3, 256, 256};
325
+ unsigned int tsp_dims[4] = {0,2,3,1};
326
+ unsigned int stride_data_num = 1*256*256*3;
327
+ float* format_data = new float[stride_data_num];
328
+ transpose(float_data, src_dims, tsp_dims, format_data);
329
+ cv::Mat origin_buffer(3,256*256, CV_32F, format_data);
330
+
331
+ float *outdata0 = nullptr;
332
+ std::vector<float> invoke_time;
333
+ for (int i = 0; i < args.invoke_nums; ++i) {
334
+ result = fast_interpreter->set_input_tensor(0, origin_buffer.data);
335
+ if(result != EXIT_SUCCESS){
336
+ printf("interpreter->set_input_tensor() failed !\n");
337
+ return EXIT_FAILURE;
338
+ }
339
+ auto t1 = std::chrono::high_resolution_clock::now();
340
+ result = fast_interpreter->invoke();
341
+ auto t2 = std::chrono::high_resolution_clock::now();
342
+ std::chrono::duration<double> cost_time = t2 - t1;
343
+ invoke_time.push_back(cost_time.count() * 1000);
344
+ if(result != EXIT_SUCCESS){
345
+ printf("interpreter->invoke() failed !\n");
346
+ return EXIT_FAILURE;
347
+ }
348
+ uint32_t out_data_0 = 0;
349
+ result = fast_interpreter->get_output_tensor(0, (void**)&outdata0, &out_data_0);
350
+ if(result != EXIT_SUCCESS){
351
+ printf("interpreter->get_output_tensor() 1 failed !\n");
352
+ return EXIT_FAILURE;
353
+ }
354
+
355
+ }
356
+
357
+ float max_invoke_time = *std::max_element(invoke_time.begin(), invoke_time.end());
358
+ float min_invoke_time = *std::min_element(invoke_time.begin(), invoke_time.end());
359
+ float mean_invoke_time = std::accumulate(invoke_time.begin(), invoke_time.end(), 0.0f) / args.invoke_nums;
360
+ float var_invoketime = 0.0f;
361
+ for (auto time : invoke_time) {
362
+ var_invoketime += (time - mean_invoke_time) * (time - mean_invoke_time);
363
+ }
364
+ var_invoketime /= args.invoke_nums;
365
+ printf("=======================================\n");
366
+ printf("QNN inference %d times :\n --mean_invoke_time is %f \n --max_invoke_time is %f \n --min_invoke_time is %f \n --var_invoketime is %f\n",
367
+ args.invoke_nums, mean_invoke_time, max_invoke_time, min_invoke_time, var_invoketime);
368
+ printf("=======================================\n");
369
+
370
+ // post process
371
+ cv::Mat out_buffer(1,256*256, CV_32F, outdata0);
372
+ cv::Mat prediction_2d(256, 256, CV_32F, (void*)out_buffer.ptr<float>());
373
+ cv::Mat resized;
374
+ cv::resize(prediction_2d, resized, org_size, 0, 0, cv::INTER_CUBIC);
375
+
376
+ // 保存为图像
377
+ write_depth("depth_output.jpg", resized, false, 1);
378
+
379
+ // 保存为 PFM
380
+ write_pfm("depth_output.pfm", resized);
381
+
382
+
383
+
384
+ fast_interpreter->destory();
385
+ return 0;
386
+ }
387
+
388
+
389
+ int main(int argc, char* argv[]) {
390
+ Args args = parse_args(argc, argv);
391
+ return invoke(args);
392
+ }
model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/models/midas_v2_fp16.qnn216.ctx.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:02f972176f66995cd0e7e3da5cab3467911acd2ccf0f64612d2755a7884798cc
3
+ size 37268200
model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/python/dog.jpg ADDED

Git LFS Details

  • SHA256: f3f87bb8ab3c26c7ecfd3ac60421d7f32b0503d1d6c5baf8bac42ed93d86351a
  • Pointer size: 131 Bytes
  • Size of remote file: 661 kB
model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/python/run_test.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import torch
3
+ import cv2
4
+ import os
5
+ from utils import write_pfm,write_depth,img_process
6
+ import aidlite
7
+ import time
8
+ import argparse
9
+
10
+ def out_process(prediction,target_size):
11
+ prediction = torch.nn.functional.interpolate(
12
+ prediction,
13
+ size=target_size,
14
+ mode="bicubic",
15
+ align_corners=False,
16
+ )
17
+ prediction = prediction.squeeze().detach().numpy()
18
+ return prediction
19
+
20
+ class run_qnn:
21
+ def __init__(self,qnn_path):
22
+ super().__init__()
23
+ self.model = aidlite.Model.create_instance(qnn_path)
24
+ if self.model is None:
25
+ print("Create model failed !")
26
+ return
27
+
28
+ self.config = aidlite.Config.create_instance()
29
+ if self.config is None:
30
+ print("build_interpretper_from_model_and_config failed !")
31
+ return
32
+
33
+ self.config.implement_type = aidlite.ImplementType.TYPE_LOCAL
34
+ self.config.framework_type = aidlite.FrameworkType.TYPE_QNN
35
+ self.config.accelerate_type = aidlite.AccelerateType.TYPE_DSP
36
+ # self.config.accelerate_type = aidlite.AccelerateType.TYPE_CPU
37
+ self.config.is_quantify_model = 1
38
+
39
+ self.interpreter = aidlite.InterpreterBuilder.build_interpretper_from_model_and_config(self.model, self.config)
40
+ if self.interpreter is None:
41
+ print("build_interpretper_from_model_and_config failed !")
42
+ return
43
+ input_shapes = [[1,256,256,3]]
44
+ output_shapes = [[1,256,256,1]]
45
+ self.model.set_model_properties(input_shapes, aidlite.DataType.TYPE_FLOAT32,
46
+ output_shapes, aidlite.DataType.TYPE_FLOAT32)
47
+
48
+ if self.interpreter is None:
49
+ print("build_interpretper_from_model_and_config failed !")
50
+ result = self.interpreter.init()
51
+ if result != 0:
52
+ print(f"interpreter init failed !")
53
+ result = self.interpreter.load_model()
54
+ if result != 0:
55
+ print("interpreter load model failed !")
56
+
57
+ print(" model load success!")
58
+
59
+ def __call__(self, input,invoke_nums):
60
+ self.interpreter.set_input_tensor(0,input)
61
+ invoke_time=[]
62
+ for i in range(invoke_nums):
63
+ result = self.interpreter.set_input_tensor(0, input.data)
64
+ if result != 0:
65
+ print("interpreter set_input_tensor() failed")
66
+ t1=time.time()
67
+ result = self.interpreter.invoke()
68
+ cost_time = (time.time()-t1)*1000
69
+ invoke_time.append(cost_time)
70
+
71
+ max_invoke_time = max(invoke_time)
72
+ min_invoke_time = min(invoke_time)
73
+ mean_invoke_time = sum(invoke_time)/invoke_nums
74
+ var_invoketime=np.var(invoke_time)
75
+ print("====================================")
76
+ print(f"QNN invoke time:\n --mean_invoke_time is {mean_invoke_time} \n --max_invoke_time is {max_invoke_time} \n --min_invoke_time is {min_invoke_time} \n --var_invoketime is {var_invoketime}")
77
+ print("====================================")
78
+ features_0 = self.interpreter.get_output_tensor(0).reshape(1,256,256,1).transpose(0,3,1,2)
79
+ return features_0
80
+
81
+
82
+
83
+ def run(args):
84
+ img_path = args.imgs
85
+ qnn_path = args.target_model
86
+ invoke_num=args.invoke_nums
87
+ print("Start processing...")
88
+ img_input,org_size = img_process(img_path)
89
+
90
+ qnn_model =run_qnn(qnn_path)
91
+ prediction_qnn = qnn_model(img_input.numpy().transpose(0,2,3,1),invoke_num)
92
+ prediction_qnn = torch.tensor(prediction_qnn)
93
+ qnn_process = out_process(prediction_qnn,org_size)
94
+
95
+ write_depth("./python/results.jpg", qnn_process, grayscale=False, bits=1)
96
+ write_pfm("./python/results.pfm", qnn_process.astype(np.float32))
97
+ print("Finished")
98
+
99
+ def parser_args():
100
+ parser = argparse.ArgumentParser(description="Run model benchmarks")
101
+ parser.add_argument('--target_model',type=str,default='./models/midas_v2_fp16.qnn216.ctx.bin',help="Inference model path")
102
+ parser.add_argument('--imgs',type=str,default='./python/dog.jpg',help="Predict images path")
103
+ parser.add_argument('--invoke_nums',type=int,default=10,help="Inference nums")
104
+ parser.add_argument('--model_type',type=str,default='QNN',help="Run backend")
105
+ args = parser.parse_args()
106
+ return args
107
+
108
+
109
+ if __name__ =="__main__":
110
+ args = parser_args()
111
+ run(args)
model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/python/transforms.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import cv2
3
+ import math
4
+
5
+
6
+ def apply_min_size(sample, size, image_interpolation_method=cv2.INTER_AREA):
7
+ """Rezise the sample to ensure the given size. Keeps aspect ratio.
8
+
9
+ Args:
10
+ sample (dict): sample
11
+ size (tuple): image size
12
+
13
+ Returns:
14
+ tuple: new size
15
+ """
16
+ shape = list(sample["disparity"].shape)
17
+
18
+ if shape[0] >= size[0] and shape[1] >= size[1]:
19
+ return sample
20
+
21
+ scale = [0, 0]
22
+ scale[0] = size[0] / shape[0]
23
+ scale[1] = size[1] / shape[1]
24
+
25
+ scale = max(scale)
26
+
27
+ shape[0] = math.ceil(scale * shape[0])
28
+ shape[1] = math.ceil(scale * shape[1])
29
+
30
+ # resize
31
+ sample["image"] = cv2.resize(
32
+ sample["image"], tuple(shape[::-1]), interpolation=image_interpolation_method
33
+ )
34
+
35
+ sample["disparity"] = cv2.resize(
36
+ sample["disparity"], tuple(shape[::-1]), interpolation=cv2.INTER_NEAREST
37
+ )
38
+ sample["mask"] = cv2.resize(
39
+ sample["mask"].astype(np.float32),
40
+ tuple(shape[::-1]),
41
+ interpolation=cv2.INTER_NEAREST,
42
+ )
43
+ sample["mask"] = sample["mask"].astype(bool)
44
+
45
+ return tuple(shape)
46
+
47
+
48
+ class Resize(object):
49
+ """Resize sample to given size (width, height).
50
+ """
51
+
52
+ def __init__(
53
+ self,
54
+ width,
55
+ height,
56
+ resize_target=True,
57
+ keep_aspect_ratio=False,
58
+ ensure_multiple_of=1,
59
+ resize_method="lower_bound",
60
+ image_interpolation_method=cv2.INTER_AREA,
61
+ ):
62
+ """Init.
63
+
64
+ Args:
65
+ width (int): desired output width
66
+ height (int): desired output height
67
+ resize_target (bool, optional):
68
+ True: Resize the full sample (image, mask, target).
69
+ False: Resize image only.
70
+ Defaults to True.
71
+ keep_aspect_ratio (bool, optional):
72
+ True: Keep the aspect ratio of the input sample.
73
+ Output sample might not have the given width and height, and
74
+ resize behaviour depends on the parameter 'resize_method'.
75
+ Defaults to False.
76
+ ensure_multiple_of (int, optional):
77
+ Output width and height is constrained to be multiple of this parameter.
78
+ Defaults to 1.
79
+ resize_method (str, optional):
80
+ "lower_bound": Output will be at least as large as the given size.
81
+ "upper_bound": Output will be at max as large as the given size. (Output size might be smaller than given size.)
82
+ "minimal": Scale as least as possible. (Output size might be smaller than given size.)
83
+ Defaults to "lower_bound".
84
+ """
85
+ self.__width = width
86
+ self.__height = height
87
+
88
+ self.__resize_target = resize_target
89
+ self.__keep_aspect_ratio = keep_aspect_ratio
90
+ self.__multiple_of = ensure_multiple_of
91
+ self.__resize_method = resize_method
92
+ self.__image_interpolation_method = image_interpolation_method
93
+
94
+ def constrain_to_multiple_of(self, x, min_val=0, max_val=None):
95
+ y = (np.round(x / self.__multiple_of) * self.__multiple_of).astype(int)
96
+
97
+ if max_val is not None and y > max_val:
98
+ y = (np.floor(x / self.__multiple_of) * self.__multiple_of).astype(int)
99
+
100
+ if y < min_val:
101
+ y = (np.ceil(x / self.__multiple_of) * self.__multiple_of).astype(int)
102
+
103
+ return y
104
+
105
+ def get_size(self, width, height):
106
+ # determine new height and width
107
+ scale_height = self.__height / height
108
+ scale_width = self.__width / width
109
+
110
+ if self.__keep_aspect_ratio:
111
+ if self.__resize_method == "lower_bound":
112
+ # scale such that output size is lower bound
113
+ if scale_width > scale_height:
114
+ # fit width
115
+ scale_height = scale_width
116
+ else:
117
+ # fit height
118
+ scale_width = scale_height
119
+ elif self.__resize_method == "upper_bound":
120
+ # scale such that output size is upper bound
121
+ if scale_width < scale_height:
122
+ # fit width
123
+ scale_height = scale_width
124
+ else:
125
+ # fit height
126
+ scale_width = scale_height
127
+ elif self.__resize_method == "minimal":
128
+ # scale as least as possbile
129
+ if abs(1 - scale_width) < abs(1 - scale_height):
130
+ # fit width
131
+ scale_height = scale_width
132
+ else:
133
+ # fit height
134
+ scale_width = scale_height
135
+ else:
136
+ raise ValueError(
137
+ f"resize_method {self.__resize_method} not implemented"
138
+ )
139
+
140
+ if self.__resize_method == "lower_bound":
141
+ new_height = self.constrain_to_multiple_of(
142
+ scale_height * height, min_val=self.__height
143
+ )
144
+ new_width = self.constrain_to_multiple_of(
145
+ scale_width * width, min_val=self.__width
146
+ )
147
+ elif self.__resize_method == "upper_bound":
148
+ new_height = self.constrain_to_multiple_of(
149
+ scale_height * height, max_val=self.__height
150
+ )
151
+ new_width = self.constrain_to_multiple_of(
152
+ scale_width * width, max_val=self.__width
153
+ )
154
+ elif self.__resize_method == "minimal":
155
+ new_height = self.constrain_to_multiple_of(scale_height * height)
156
+ new_width = self.constrain_to_multiple_of(scale_width * width)
157
+ else:
158
+ raise ValueError(f"resize_method {self.__resize_method} not implemented")
159
+
160
+ return (new_width, new_height)
161
+
162
+ def __call__(self, sample):
163
+ width, height = self.get_size(
164
+ sample["image"].shape[1], sample["image"].shape[0]
165
+ )
166
+
167
+ # resize sample
168
+ sample["image"] = cv2.resize(
169
+ sample["image"],
170
+ (width, height),
171
+ interpolation=self.__image_interpolation_method,
172
+ )
173
+
174
+ if self.__resize_target:
175
+ if "disparity" in sample:
176
+ sample["disparity"] = cv2.resize(
177
+ sample["disparity"],
178
+ (width, height),
179
+ interpolation=cv2.INTER_NEAREST,
180
+ )
181
+
182
+ if "depth" in sample:
183
+ sample["depth"] = cv2.resize(
184
+ sample["depth"], (width, height), interpolation=cv2.INTER_NEAREST
185
+ )
186
+
187
+ sample["mask"] = cv2.resize(
188
+ sample["mask"].astype(np.float32),
189
+ (width, height),
190
+ interpolation=cv2.INTER_NEAREST,
191
+ )
192
+ sample["mask"] = sample["mask"].astype(bool)
193
+
194
+ return sample
195
+
196
+
197
+ class NormalizeImage(object):
198
+ """Normlize image by given mean and std.
199
+ """
200
+
201
+ def __init__(self, mean, std):
202
+ self.__mean = mean
203
+ self.__std = std
204
+
205
+ def __call__(self, sample):
206
+ sample["image"] = (sample["image"] - self.__mean) / self.__std
207
+
208
+ return sample
209
+
210
+
211
+ class PrepareForNet(object):
212
+ """Prepare sample for usage as network input.
213
+ """
214
+
215
+ def __init__(self):
216
+ pass
217
+
218
+ def __call__(self, sample):
219
+ image = np.transpose(sample["image"], (2, 0, 1))
220
+ sample["image"] = np.ascontiguousarray(image).astype(np.float32)
221
+
222
+ if "mask" in sample:
223
+ sample["mask"] = sample["mask"].astype(np.float32)
224
+ sample["mask"] = np.ascontiguousarray(sample["mask"])
225
+
226
+ if "disparity" in sample:
227
+ disparity = sample["disparity"].astype(np.float32)
228
+ sample["disparity"] = np.ascontiguousarray(disparity)
229
+
230
+ if "depth" in sample:
231
+ depth = sample["depth"].astype(np.float32)
232
+ sample["depth"] = np.ascontiguousarray(depth)
233
+
234
+ return sample
model_farm_midas_v2_qcs8550_qnn2.16_fp16_aidlite/python/utils.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import torch
3
+ import cv2
4
+ import os
5
+
6
+ from transforms import Resize, NormalizeImage, PrepareForNet
7
+
8
+ from torchvision.transforms import Compose
9
+ import sys
10
+ first_execution = True
11
+ def img_process(img_path):
12
+ global first_execution
13
+ first_execution = False
14
+ net_w, net_h = 256, 256
15
+ resize_mode = "upper_bound"
16
+ normalization = NormalizeImage(
17
+ mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]
18
+ )
19
+ transform = Compose(
20
+ [
21
+ Resize(
22
+ net_w,
23
+ net_h,
24
+ resize_target=None,
25
+ keep_aspect_ratio=False,
26
+ ensure_multiple_of=32,
27
+ resize_method=resize_mode,
28
+ image_interpolation_method=cv2.INTER_CUBIC,
29
+ ),
30
+ normalization,
31
+ PrepareForNet(),
32
+ ]
33
+ )
34
+ # image = utils.read_image(img_path) # in [0, 1]
35
+ image = cv2.imread(img_path)
36
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) / 255.0
37
+ org_size= image.shape[:2]
38
+ image = transform({"image": image})["image"]
39
+ sample = torch.from_numpy(image).to("cpu").unsqueeze(0)
40
+ height, width = sample.shape[2:]
41
+ print(f"Input resized to {width}x{height} before entering the encoder")
42
+
43
+ return sample,org_size
44
+
45
+
46
+
47
+ def write_depth(path, depth, grayscale=False, bits=1):
48
+ if not grayscale:
49
+ bits = 1
50
+
51
+ if not np.isfinite(depth).all():
52
+ depth=np.nan_to_num(depth, nan=0.0, posinf=0.0, neginf=0.0)
53
+ print("WARNING: Non-finite depth values present")
54
+
55
+ depth_min = depth.min()
56
+ depth_max = depth.max()
57
+
58
+ max_val = (2**(8*bits))-1
59
+
60
+ if depth_max - depth_min > np.finfo("float").eps:
61
+ out = max_val * (depth - depth_min) / (depth_max - depth_min)
62
+ else:
63
+ out = np.zeros(depth.shape, dtype=depth.dtype)
64
+
65
+ # print("out :",out.shape,out)
66
+ if not grayscale:
67
+ out = cv2.applyColorMap(np.uint8(out), cv2.COLORMAP_INFERNO)
68
+
69
+ if bits == 1:
70
+ cv2.imwrite(path , out.astype("uint8"))
71
+ elif bits == 2:
72
+ cv2.imwrite(path , out.astype("uint16"))
73
+
74
+ return
75
+
76
+ def write_pfm(path, image, scale=1):
77
+ with open(path, "wb") as file:
78
+ color = None
79
+
80
+ if image.dtype.name != "float32":
81
+ raise Exception("Image dtype must be float32.")
82
+
83
+ image = np.flipud(image)
84
+
85
+ if len(image.shape) == 3 and image.shape[2] == 3: # color image
86
+ color = True
87
+ elif (
88
+ len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1
89
+ ): # greyscale
90
+ color = False
91
+ else:
92
+ raise Exception("Image must have H x W x 3, H x W x 1 or H x W dimensions.")
93
+
94
+ file.write("PF\n" if color else "Pf\n".encode())
95
+ file.write("%d %d\n".encode() % (image.shape[1], image.shape[0]))
96
+
97
+ endian = image.dtype.byteorder
98
+
99
+ if endian == "<" or endian == "=" and sys.byteorder == "little":
100
+ scale = -scale
101
+
102
+ file.write("%f\n".encode() % scale)
103
+
104
+ image.tofile(file)
model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/README.md ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Model Information
2
+
3
+ ### Source model
4
+ - Input shape: 1x3x256x256
5
+ - Number of parameters: 20.33M
6
+ - Model size: 82.17M
7
+ - Output shape: 1x1x256x256
8
+
9
+ Source model repository: [midas](https://github.com/isl-org/MiDaS/tree/master)
10
+
11
+ ### Converted model
12
+
13
+ - Precision: INT8
14
+ - Backend: QNN2.16
15
+ - Target Device: SNM972 QCS8550
16
+
17
+ ## Inference with AidLite SDK
18
+
19
+ ### SDK installation
20
+ Model Farm uses AidLite SDK as the model inference SDK. For details, please refer to the [AidLite Developer Documentation](https://v2.docs.aidlux.com/en/sdk-api/aidlite-sdk/)
21
+
22
+ - Install AidLite SDK
23
+
24
+ ```bash
25
+ # Install the appropriate version of the aidlite sdk
26
+ sudo aid-pkg update
27
+ sudo aid-pkg install aidlite-sdk
28
+ # Download the qnn version that matches the above backend. Eg Install QNN2.23 Aidlite: sudo aid-pkg install aidlite-qnn223
29
+ sudo aid-pkg install aidlite-{QNN VERSION}
30
+ ```
31
+
32
+ - Verify AidLite SDK
33
+
34
+ ```bash
35
+ # aidlite sdk c++ check
36
+ python3 -c "import aidlite ; print(aidlite.get_library_version())"
37
+
38
+ # aidlite sdk python check
39
+ python3 -c "import aidlite ; print(aidlite.get_py_library_version())"
40
+ ```
41
+
42
+ ### Run Demo
43
+ #### python
44
+ ```bash
45
+ cd model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite
46
+ python3 python/run_test.py --target_model ./models/midas_v2_w8a8.qnn216.ctx.bin --imgs ./python/dog.jpg --invoke_nums 10
47
+ ```
48
+
49
+ #### c++
50
+ ```bash
51
+ cd midas_v2/model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/cpp
52
+ mkdir build && cd build
53
+ cmake ..
54
+ make
55
+ ./run_test
56
+ ```
model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/cpp/CMakeLists.txt ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required (VERSION 3.5)
2
+ project("run_test")
3
+
4
+ find_package(OpenCV REQUIRED)
5
+
6
+ message(STATUS "oPENCV Library status:")
7
+ message(STATUS ">version:${OpenCV_VERSION}")
8
+ message(STATUS "Include:${OpenCV_INCLUDE_DIRS}")
9
+
10
+ set(CMAKE_CXX_FLAGS "-Wno-error=deprecated-declarations -Wno-deprecated-declarations")
11
+
12
+ include_directories(
13
+ /usr/local/include
14
+ /usr/include/opencv4
15
+ )
16
+
17
+ link_directories(
18
+ /usr/local/lib/
19
+ )
20
+
21
+ file(GLOB SRC_LISTS
22
+ ${CMAKE_CURRENT_SOURCE_DIR}/run_test.cpp
23
+ )
24
+
25
+ add_executable(run_test ${SRC_LISTS})
26
+
27
+ target_link_libraries(run_test
28
+ aidlite
29
+ ${OpenCV_LIBS}
30
+ pthread
31
+ jsoncpp
32
+ )
model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/cpp/dog.jpg ADDED

Git LFS Details

  • SHA256: f3f87bb8ab3c26c7ecfd3ac60421d7f32b0503d1d6c5baf8bac42ed93d86351a
  • Pointer size: 131 Bytes
  • Size of remote file: 661 kB
model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/cpp/run_test.cpp ADDED
@@ -0,0 +1,392 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <fstream>
3
+ #include <opencv2/opencv.hpp>
4
+ #include <aidlux/aidlite/aidlite.hpp>
5
+ #include <vector>
6
+ #include <numeric>
7
+ #include <cmath>
8
+ #include <jsoncpp/json/json.h>
9
+
10
+ using namespace cv;
11
+ using namespace std;
12
+ using namespace Aidlux::Aidlite;
13
+
14
+ const int net_w = 256;
15
+ const int net_h = 256;
16
+
17
+ const std::vector<float> mean_vals = {0.485f, 0.456f, 0.406f};
18
+ const std::vector<float> std_vals = {0.229f, 0.224f, 0.225f};
19
+
20
+
21
+ struct Args {
22
+ std::string target_model = "../../models/midas_v2_w8a8.qnn216.ctx.bin";
23
+ std::string imgs = "../dog.jpg";
24
+ int invoke_nums = 10;
25
+ std::string model_type = "QNN";
26
+ };
27
+
28
+
29
+ Args parse_args(int argc, char* argv[]) {
30
+ Args args;
31
+ for (int i = 1; i < argc; ++i) {
32
+ std::string arg = argv[i];
33
+ if (arg == "--target_model" && i + 1 < argc) {
34
+ args.target_model = argv[++i];
35
+ } else if (arg == "--imgs" && i + 1 < argc) {
36
+ args.imgs = argv[++i];
37
+ } else if (arg == "--invoke_nums" && i + 1 < argc) {
38
+ args.invoke_nums = std::stoi(argv[++i]);
39
+ } else if (arg == "--model_type" && i + 1 < argc) {
40
+ args.model_type = argv[++i];
41
+ }
42
+ }
43
+ return args;
44
+ }
45
+
46
+ std::string to_lower(const std::string& str) {
47
+ std::string lower_str = str;
48
+ std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(), [](unsigned char c) {
49
+ return std::tolower(c);
50
+ });
51
+ return lower_str;
52
+ }
53
+
54
+
55
+ int transpose(float* src, unsigned int* src_dims, unsigned int* tsp_dims, float* dest){
56
+
57
+ int current_coordinate[4] = {0, 0, 0, 0};
58
+ for(int a = 0; a < src_dims[0]; ++a){
59
+ current_coordinate[0] = a;
60
+ for(int b = 0; b < src_dims[1]; ++b){
61
+ current_coordinate[1] = b;
62
+ for(int c = 0; c < src_dims[2]; ++c){
63
+ current_coordinate[2] = c;
64
+ for(int d = 0; d < src_dims[3]; ++d){
65
+ current_coordinate[3] = d;
66
+
67
+ int old_index = current_coordinate[0]*src_dims[1]*src_dims[2]*src_dims[3] +
68
+ current_coordinate[1]*src_dims[2]*src_dims[3] +
69
+ current_coordinate[2]*src_dims[3] +
70
+ current_coordinate[3];
71
+
72
+ int new_index = current_coordinate[tsp_dims[0]]*src_dims[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
73
+ current_coordinate[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
74
+ current_coordinate[tsp_dims[2]]*src_dims[tsp_dims[3]] +
75
+ current_coordinate[tsp_dims[3]];
76
+
77
+ dest[new_index] = src[old_index];
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ return EXIT_SUCCESS;
84
+ }
85
+
86
+
87
+ // 替代 np.nan_to_num
88
+ void sanitizeDepthMap(cv::Mat& depth) {
89
+ for (int y = 0; y < depth.rows; ++y) {
90
+ float* row = depth.ptr<float>(y);
91
+ for (int x = 0; x < depth.cols; ++x) {
92
+ float val = row[x];
93
+ if (!std::isfinite(val)) {
94
+ row[x] = 0.0f;
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ // 等效于 Python write_depth
101
+ void write_depth(const std::string& path, const cv::Mat& input_depth, bool grayscale = false, int bits = 1) {
102
+ CV_Assert(input_depth.type() == CV_32FC1);
103
+
104
+ // 拷贝 + 处理非法值
105
+ cv::Mat depth = input_depth.clone();
106
+ sanitizeDepthMap(depth);
107
+
108
+ double minVal, maxVal;
109
+ cv::minMaxLoc(depth, &minVal, &maxVal);
110
+
111
+ double max_val = (1 << (8 * bits)) - 1;
112
+ cv::Mat out;
113
+
114
+ if (maxVal - minVal > std::numeric_limits<float>::epsilon()) {
115
+ // 归一化并映射到位深范围
116
+ out = (depth - minVal) * (max_val / (maxVal - minVal));
117
+ } else {
118
+ out = cv::Mat::zeros(depth.size(), CV_32F);
119
+ }
120
+
121
+ if (!grayscale) {
122
+ out.convertTo(out, CV_8UC1);
123
+ cv::applyColorMap(out, out, cv::COLORMAP_INFERNO);
124
+ }
125
+
126
+ if (bits == 1) {
127
+ out.convertTo(out, CV_8U);
128
+ } else if (bits == 2) {
129
+ out.convertTo(out, CV_16U);
130
+ }
131
+
132
+ cv::imwrite(path, out);
133
+ }
134
+
135
+ // 等效于 Python write_pfm
136
+ void write_pfm(const std::string& path, const cv::Mat& image, float scale = 1.0f) {
137
+ CV_Assert(image.type() == CV_32FC1 || image.type() == CV_32FC3);
138
+
139
+ std::ofstream file(path, std::ios::binary);
140
+ if (!file.is_open()) {
141
+ std::cerr << "Failed to open file for writing PFM: " << path << std::endl;
142
+ return;
143
+ }
144
+
145
+ int width = image.cols;
146
+ int height = image.rows;
147
+ int channels = image.channels();
148
+ bool color = (channels == 3);
149
+
150
+ file << (color ? "PF" : "Pf") << "\n";
151
+ file << width << " " << height << "\n";
152
+
153
+ // Endianness: negative = little-endian
154
+ uint16_t endian_test = 0x1;
155
+ bool is_little_endian = *(reinterpret_cast<uint8_t*>(&endian_test)) == 0x1;
156
+ if (is_little_endian) {
157
+ scale = -scale;
158
+ }
159
+
160
+ file << scale << "\n";
161
+
162
+ // Flip vertically (OpenCV top-left origin -> PFM bottom-left origin)
163
+ cv::Mat flipped;
164
+ cv::flip(image, flipped, 0);
165
+
166
+ // Write raw data
167
+ file.write(reinterpret_cast<const char*>(flipped.data), flipped.total() * channels * sizeof(float));
168
+ file.close();
169
+ }
170
+
171
+
172
+ // ======================= Normalize =======================
173
+ void normalize(cv::Mat& image) {
174
+ CV_Assert(image.type() == CV_32FC3);
175
+ int rows = image.rows;
176
+ int cols = image.cols;
177
+
178
+ for (int y = 0; y < rows; ++y) {
179
+ cv::Vec3f* row = image.ptr<cv::Vec3f>(y);
180
+ for (int x = 0; x < cols; ++x) {
181
+ for (int c = 0; c < 3; ++c) {
182
+ row[x][c] = (row[x][c] - mean_vals[c]) / std_vals[c];
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ cv::Mat hwc_to_chw(const cv::Mat& image) {
189
+ std::vector<cv::Mat> channels(3);
190
+ cv::split(image, channels);
191
+
192
+ cv::Mat chw(3, image.rows * image.cols, CV_32F);
193
+ for (int c = 0; c < 3; ++c) {
194
+ memcpy(chw.ptr(c), channels[c].data, image.rows * image.cols * sizeof(float));
195
+ }
196
+
197
+ return chw;
198
+ }
199
+
200
+
201
+ bool first_execution = true;
202
+ cv::Mat img_process(const cv::Mat image_bgr, cv::Size& org_size_out) {
203
+ first_execution = false;
204
+
205
+ cv::Mat image_rgb;
206
+ cv::cvtColor(image_bgr, image_rgb, cv::COLOR_BGR2RGB);
207
+ image_rgb.convertTo(image_rgb, CV_32FC3, 1.0 / 255.0);
208
+
209
+ // 2. Save original size
210
+ org_size_out = image_rgb.size(); // H x W
211
+
212
+ // 3. Resize to 256x256 using cubic interpolation
213
+ cv::resize(image_rgb, image_rgb, cv::Size(net_w, net_h), 0, 0, cv::INTER_CUBIC);
214
+
215
+ // 4. Normalize using mean/std
216
+ normalize(image_rgb);
217
+
218
+ // 5. Convert HWC to CHW
219
+ cv::Mat chw = hwc_to_chw(image_rgb);
220
+
221
+ // 6. Add batch dimension: [1, C, H, W] → reshape to 1x3xHxW style float array
222
+ cv::Mat input_tensor(1, 3 * net_h * net_w, CV_32F);
223
+ memcpy(input_tensor.ptr<float>(), chw.data, 3 * net_h * net_w * sizeof(float));
224
+
225
+ std::cout << "Input resized to " << net_w << "x" << net_h << " before entering the encoder" << std::endl;
226
+
227
+ return input_tensor;
228
+ }
229
+
230
+
231
+ float* matToFloatPtr(const cv::Mat& input_mat, bool normalize = true) {
232
+ // 检查连续性
233
+ cv::Mat mat = input_mat;
234
+ if (!mat.isContinuous()) {
235
+ mat = mat.clone();
236
+ }
237
+
238
+ // 分配内存
239
+ int total_pixels = mat.rows * mat.cols;
240
+ int channels = mat.channels();
241
+ float* float_data = new float[total_pixels * channels];
242
+
243
+ // 根据数据类型转换
244
+ if (mat.type() == CV_8UC1 || mat.type() == CV_8UC3) {
245
+ uchar* ptr = mat.ptr<uchar>(0);
246
+ for (int i = 0; i < total_pixels * channels; ++i) {
247
+ float_data[i] = normalize ? (static_cast<float>(ptr[i]) / 255.0f) : ptr[i];
248
+ }
249
+ } else if (mat.type() == CV_32FC1 || mat.type() == CV_32FC3) {
250
+ float* ptr = mat.ptr<float>(0);
251
+ std::memcpy(float_data, ptr, total_pixels * channels * sizeof(float));
252
+ } else {
253
+ delete[] float_data;
254
+ return nullptr; // 不支持的类型
255
+ }
256
+
257
+ return float_data;
258
+ }
259
+
260
+
261
+ int invoke(const Args& args) {
262
+ std::cout << "Start main ... ... Model Path: " << args.target_model << "\n"
263
+ << "Image Path: " << args.imgs << "\n"
264
+ << "Inference Nums: " << args.invoke_nums << "\n"
265
+ << "Model Type: " << args.model_type << "\n";
266
+ Model* model = Model::create_instance(args.target_model);
267
+ if(model == nullptr){
268
+ printf("Create model failed !\n");
269
+ return EXIT_FAILURE;
270
+ }
271
+ Config* config = Config::create_instance();
272
+ if(config == nullptr){
273
+ printf("Create config failed !\n");
274
+ return EXIT_FAILURE;
275
+ }
276
+ config->implement_type = ImplementType::TYPE_LOCAL;
277
+ std::string model_type_lower = to_lower(args.model_type);
278
+ if (model_type_lower == "qnn"){
279
+ config->framework_type = FrameworkType::TYPE_QNN;
280
+ } else if (model_type_lower == "snpe2" || model_type_lower == "snpe") {
281
+ config->framework_type = FrameworkType::TYPE_SNPE2;
282
+ }
283
+ config->accelerate_type = AccelerateType::TYPE_DSP;
284
+ config->is_quantify_model = 1;
285
+
286
+ unsigned int model_h = 256;
287
+ unsigned int model_w = 256;
288
+ std::vector<std::vector<uint32_t>> input_shapes = {{1,model_h,model_w,3}};
289
+ std::vector<std::vector<uint32_t>> output_shapes = {{1,model_h,model_w,1}};
290
+ model->set_model_properties(input_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32, output_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32);
291
+ std::unique_ptr<Interpreter> fast_interpreter = InterpreterBuilder::build_interpretper_from_model_and_config(model, config);
292
+ if(fast_interpreter == nullptr){
293
+ printf("build_interpretper_from_model_and_config failed !\n");
294
+ return EXIT_FAILURE;
295
+ }
296
+ int result = fast_interpreter->init();
297
+ if(result != EXIT_SUCCESS){
298
+ printf("interpreter->init() failed !\n");
299
+ return EXIT_FAILURE;
300
+ }
301
+ // load model
302
+ fast_interpreter->load_model();
303
+ if(result != EXIT_SUCCESS){
304
+ printf("interpreter->load_model() failed !\n");
305
+ return EXIT_FAILURE;
306
+ }
307
+ printf("detect model load success!\n");
308
+
309
+ cv::Mat frame = cv::imread(args.imgs);
310
+ if (frame.empty()) {
311
+ printf("detect image load failed!\n");
312
+ return 1;
313
+ }
314
+ printf("img_src cols: %d, img_src rows: %d\n", frame.cols, frame.rows);
315
+ cv::Mat input_data;
316
+ cv::Mat frame_clone = frame.clone();
317
+ int h = frame_clone.rows;
318
+ int w = frame_clone.cols;
319
+ cv::Size org_size(w, h);
320
+ cv::Size org_size0(256, 256);
321
+
322
+ cv::Mat input_tensor = img_process(frame_clone, org_size0);
323
+ float* float_data = matToFloatPtr(input_tensor);
324
+ unsigned int src_dims[4] = {1, 3, 256, 256};
325
+ unsigned int tsp_dims[4] = {0,2,3,1};
326
+ unsigned int stride_data_num = 1*256*256*3;
327
+ float* format_data = new float[stride_data_num];
328
+ transpose(float_data, src_dims, tsp_dims, format_data);
329
+ cv::Mat origin_buffer(3,256*256, CV_32F, format_data);
330
+
331
+ float *outdata0 = nullptr;
332
+ std::vector<float> invoke_time;
333
+ for (int i = 0; i < args.invoke_nums; ++i) {
334
+ result = fast_interpreter->set_input_tensor(0, origin_buffer.data);
335
+ if(result != EXIT_SUCCESS){
336
+ printf("interpreter->set_input_tensor() failed !\n");
337
+ return EXIT_FAILURE;
338
+ }
339
+ auto t1 = std::chrono::high_resolution_clock::now();
340
+ result = fast_interpreter->invoke();
341
+ auto t2 = std::chrono::high_resolution_clock::now();
342
+ std::chrono::duration<double> cost_time = t2 - t1;
343
+ invoke_time.push_back(cost_time.count() * 1000);
344
+ if(result != EXIT_SUCCESS){
345
+ printf("interpreter->invoke() failed !\n");
346
+ return EXIT_FAILURE;
347
+ }
348
+ uint32_t out_data_0 = 0;
349
+ result = fast_interpreter->get_output_tensor(0, (void**)&outdata0, &out_data_0);
350
+ if(result != EXIT_SUCCESS){
351
+ printf("interpreter->get_output_tensor() 1 failed !\n");
352
+ return EXIT_FAILURE;
353
+ }
354
+
355
+ }
356
+
357
+ float max_invoke_time = *std::max_element(invoke_time.begin(), invoke_time.end());
358
+ float min_invoke_time = *std::min_element(invoke_time.begin(), invoke_time.end());
359
+ float mean_invoke_time = std::accumulate(invoke_time.begin(), invoke_time.end(), 0.0f) / args.invoke_nums;
360
+ float var_invoketime = 0.0f;
361
+ for (auto time : invoke_time) {
362
+ var_invoketime += (time - mean_invoke_time) * (time - mean_invoke_time);
363
+ }
364
+ var_invoketime /= args.invoke_nums;
365
+ printf("=======================================\n");
366
+ printf("QNN inference %d times :\n --mean_invoke_time is %f \n --max_invoke_time is %f \n --min_invoke_time is %f \n --var_invoketime is %f\n",
367
+ args.invoke_nums, mean_invoke_time, max_invoke_time, min_invoke_time, var_invoketime);
368
+ printf("=======================================\n");
369
+
370
+ // post process
371
+ cv::Mat out_buffer(1,256*256, CV_32F, outdata0);
372
+ cv::Mat prediction_2d(256, 256, CV_32F, (void*)out_buffer.ptr<float>());
373
+ cv::Mat resized;
374
+ cv::resize(prediction_2d, resized, org_size, 0, 0, cv::INTER_CUBIC);
375
+
376
+ // 保存为图像
377
+ write_depth("depth_output.jpg", resized, false, 1);
378
+
379
+ // 保存为 PFM
380
+ write_pfm("depth_output.pfm", resized);
381
+
382
+
383
+
384
+ fast_interpreter->destory();
385
+ return 0;
386
+ }
387
+
388
+
389
+ int main(int argc, char* argv[]) {
390
+ Args args = parse_args(argc, argv);
391
+ return invoke(args);
392
+ }
model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/models/midas_v2_w8a8.qnn216.ctx.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d583ca678b740c8075b7f829e4d01ecbcfccf7fc498d549b365508d686d89982
3
+ size 18853888
model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/python/dog.jpg ADDED

Git LFS Details

  • SHA256: f3f87bb8ab3c26c7ecfd3ac60421d7f32b0503d1d6c5baf8bac42ed93d86351a
  • Pointer size: 131 Bytes
  • Size of remote file: 661 kB
model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/python/run_test.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import torch
3
+ import cv2
4
+ import os
5
+ from utils import write_pfm,write_depth,img_process
6
+ import aidlite
7
+ import time
8
+ import argparse
9
+
10
+ def out_process(prediction,target_size):
11
+ prediction = torch.nn.functional.interpolate(
12
+ prediction,
13
+ size=target_size,
14
+ mode="bicubic",
15
+ align_corners=False,
16
+ )
17
+ prediction = prediction.squeeze().detach().numpy()
18
+ return prediction
19
+
20
+ class run_qnn:
21
+ def __init__(self,qnn_path):
22
+ super().__init__()
23
+ self.model = aidlite.Model.create_instance(qnn_path)
24
+ if self.model is None:
25
+ print("Create model failed !")
26
+ return
27
+
28
+ self.config = aidlite.Config.create_instance()
29
+ if self.config is None:
30
+ print("build_interpretper_from_model_and_config failed !")
31
+ return
32
+
33
+ self.config.implement_type = aidlite.ImplementType.TYPE_LOCAL
34
+ self.config.framework_type = aidlite.FrameworkType.TYPE_QNN
35
+ self.config.accelerate_type = aidlite.AccelerateType.TYPE_DSP
36
+ # self.config.accelerate_type = aidlite.AccelerateType.TYPE_CPU
37
+ self.config.is_quantify_model = 1
38
+
39
+ self.interpreter = aidlite.InterpreterBuilder.build_interpretper_from_model_and_config(self.model, self.config)
40
+ if self.interpreter is None:
41
+ print("build_interpretper_from_model_and_config failed !")
42
+ return
43
+ input_shapes = [[1,256,256,3]]
44
+ output_shapes = [[1,256,256,1]]
45
+ self.model.set_model_properties(input_shapes, aidlite.DataType.TYPE_FLOAT32,
46
+ output_shapes, aidlite.DataType.TYPE_FLOAT32)
47
+
48
+ if self.interpreter is None:
49
+ print("build_interpretper_from_model_and_config failed !")
50
+ result = self.interpreter.init()
51
+ if result != 0:
52
+ print(f"interpreter init failed !")
53
+ result = self.interpreter.load_model()
54
+ if result != 0:
55
+ print("interpreter load model failed !")
56
+
57
+ print(" model load success!")
58
+
59
+ def __call__(self, input,invoke_nums):
60
+ self.interpreter.set_input_tensor(0,input)
61
+ invoke_time=[]
62
+ for i in range(invoke_nums):
63
+ result = self.interpreter.set_input_tensor(0, input.data)
64
+ if result != 0:
65
+ print("interpreter set_input_tensor() failed")
66
+ t1=time.time()
67
+ result = self.interpreter.invoke()
68
+ cost_time = (time.time()-t1)*1000
69
+ invoke_time.append(cost_time)
70
+
71
+ max_invoke_time = max(invoke_time)
72
+ min_invoke_time = min(invoke_time)
73
+ mean_invoke_time = sum(invoke_time)/invoke_nums
74
+ var_invoketime=np.var(invoke_time)
75
+ print("====================================")
76
+ print(f"QNN invoke time:\n --mean_invoke_time is {mean_invoke_time} \n --max_invoke_time is {max_invoke_time} \n --min_invoke_time is {min_invoke_time} \n --var_invoketime is {var_invoketime}")
77
+ print("====================================")
78
+ features_0 = self.interpreter.get_output_tensor(0).reshape(1,256,256,1).transpose(0,3,1,2)
79
+ return features_0
80
+
81
+
82
+
83
+ def run(args):
84
+ img_path = args.imgs
85
+ qnn_path = args.target_model
86
+ invoke_num=args.invoke_nums
87
+ print("Start processing...")
88
+ img_input,org_size = img_process(img_path)
89
+
90
+ qnn_model =run_qnn(qnn_path)
91
+ prediction_qnn = qnn_model(img_input.numpy().transpose(0,2,3,1),invoke_num)
92
+ prediction_qnn = torch.tensor(prediction_qnn)
93
+ qnn_process = out_process(prediction_qnn,org_size)
94
+
95
+ write_depth("./python/results.jpg", qnn_process, grayscale=False, bits=1)
96
+ write_pfm("./python/results.pfm", qnn_process.astype(np.float32))
97
+ print("Finished")
98
+
99
+ def parser_args():
100
+ parser = argparse.ArgumentParser(description="Run model benchmarks")
101
+ parser.add_argument('--target_model',type=str,default='./models/midas_v2_w8a8.qnn216.ctx.bin',help="Inference model path")
102
+ parser.add_argument('--imgs',type=str,default='./python/dog.jpg',help="Predict images path")
103
+ parser.add_argument('--invoke_nums',type=int,default=10,help="Inference nums")
104
+ parser.add_argument('--model_type',type=str,default='QNN',help="Run backend")
105
+ args = parser.parse_args()
106
+ return args
107
+
108
+
109
+ if __name__ =="__main__":
110
+ args = parser_args()
111
+ run(args)
model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/python/transforms.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import cv2
3
+ import math
4
+
5
+
6
+ def apply_min_size(sample, size, image_interpolation_method=cv2.INTER_AREA):
7
+ """Rezise the sample to ensure the given size. Keeps aspect ratio.
8
+
9
+ Args:
10
+ sample (dict): sample
11
+ size (tuple): image size
12
+
13
+ Returns:
14
+ tuple: new size
15
+ """
16
+ shape = list(sample["disparity"].shape)
17
+
18
+ if shape[0] >= size[0] and shape[1] >= size[1]:
19
+ return sample
20
+
21
+ scale = [0, 0]
22
+ scale[0] = size[0] / shape[0]
23
+ scale[1] = size[1] / shape[1]
24
+
25
+ scale = max(scale)
26
+
27
+ shape[0] = math.ceil(scale * shape[0])
28
+ shape[1] = math.ceil(scale * shape[1])
29
+
30
+ # resize
31
+ sample["image"] = cv2.resize(
32
+ sample["image"], tuple(shape[::-1]), interpolation=image_interpolation_method
33
+ )
34
+
35
+ sample["disparity"] = cv2.resize(
36
+ sample["disparity"], tuple(shape[::-1]), interpolation=cv2.INTER_NEAREST
37
+ )
38
+ sample["mask"] = cv2.resize(
39
+ sample["mask"].astype(np.float32),
40
+ tuple(shape[::-1]),
41
+ interpolation=cv2.INTER_NEAREST,
42
+ )
43
+ sample["mask"] = sample["mask"].astype(bool)
44
+
45
+ return tuple(shape)
46
+
47
+
48
+ class Resize(object):
49
+ """Resize sample to given size (width, height).
50
+ """
51
+
52
+ def __init__(
53
+ self,
54
+ width,
55
+ height,
56
+ resize_target=True,
57
+ keep_aspect_ratio=False,
58
+ ensure_multiple_of=1,
59
+ resize_method="lower_bound",
60
+ image_interpolation_method=cv2.INTER_AREA,
61
+ ):
62
+ """Init.
63
+
64
+ Args:
65
+ width (int): desired output width
66
+ height (int): desired output height
67
+ resize_target (bool, optional):
68
+ True: Resize the full sample (image, mask, target).
69
+ False: Resize image only.
70
+ Defaults to True.
71
+ keep_aspect_ratio (bool, optional):
72
+ True: Keep the aspect ratio of the input sample.
73
+ Output sample might not have the given width and height, and
74
+ resize behaviour depends on the parameter 'resize_method'.
75
+ Defaults to False.
76
+ ensure_multiple_of (int, optional):
77
+ Output width and height is constrained to be multiple of this parameter.
78
+ Defaults to 1.
79
+ resize_method (str, optional):
80
+ "lower_bound": Output will be at least as large as the given size.
81
+ "upper_bound": Output will be at max as large as the given size. (Output size might be smaller than given size.)
82
+ "minimal": Scale as least as possible. (Output size might be smaller than given size.)
83
+ Defaults to "lower_bound".
84
+ """
85
+ self.__width = width
86
+ self.__height = height
87
+
88
+ self.__resize_target = resize_target
89
+ self.__keep_aspect_ratio = keep_aspect_ratio
90
+ self.__multiple_of = ensure_multiple_of
91
+ self.__resize_method = resize_method
92
+ self.__image_interpolation_method = image_interpolation_method
93
+
94
+ def constrain_to_multiple_of(self, x, min_val=0, max_val=None):
95
+ y = (np.round(x / self.__multiple_of) * self.__multiple_of).astype(int)
96
+
97
+ if max_val is not None and y > max_val:
98
+ y = (np.floor(x / self.__multiple_of) * self.__multiple_of).astype(int)
99
+
100
+ if y < min_val:
101
+ y = (np.ceil(x / self.__multiple_of) * self.__multiple_of).astype(int)
102
+
103
+ return y
104
+
105
+ def get_size(self, width, height):
106
+ # determine new height and width
107
+ scale_height = self.__height / height
108
+ scale_width = self.__width / width
109
+
110
+ if self.__keep_aspect_ratio:
111
+ if self.__resize_method == "lower_bound":
112
+ # scale such that output size is lower bound
113
+ if scale_width > scale_height:
114
+ # fit width
115
+ scale_height = scale_width
116
+ else:
117
+ # fit height
118
+ scale_width = scale_height
119
+ elif self.__resize_method == "upper_bound":
120
+ # scale such that output size is upper bound
121
+ if scale_width < scale_height:
122
+ # fit width
123
+ scale_height = scale_width
124
+ else:
125
+ # fit height
126
+ scale_width = scale_height
127
+ elif self.__resize_method == "minimal":
128
+ # scale as least as possbile
129
+ if abs(1 - scale_width) < abs(1 - scale_height):
130
+ # fit width
131
+ scale_height = scale_width
132
+ else:
133
+ # fit height
134
+ scale_width = scale_height
135
+ else:
136
+ raise ValueError(
137
+ f"resize_method {self.__resize_method} not implemented"
138
+ )
139
+
140
+ if self.__resize_method == "lower_bound":
141
+ new_height = self.constrain_to_multiple_of(
142
+ scale_height * height, min_val=self.__height
143
+ )
144
+ new_width = self.constrain_to_multiple_of(
145
+ scale_width * width, min_val=self.__width
146
+ )
147
+ elif self.__resize_method == "upper_bound":
148
+ new_height = self.constrain_to_multiple_of(
149
+ scale_height * height, max_val=self.__height
150
+ )
151
+ new_width = self.constrain_to_multiple_of(
152
+ scale_width * width, max_val=self.__width
153
+ )
154
+ elif self.__resize_method == "minimal":
155
+ new_height = self.constrain_to_multiple_of(scale_height * height)
156
+ new_width = self.constrain_to_multiple_of(scale_width * width)
157
+ else:
158
+ raise ValueError(f"resize_method {self.__resize_method} not implemented")
159
+
160
+ return (new_width, new_height)
161
+
162
+ def __call__(self, sample):
163
+ width, height = self.get_size(
164
+ sample["image"].shape[1], sample["image"].shape[0]
165
+ )
166
+
167
+ # resize sample
168
+ sample["image"] = cv2.resize(
169
+ sample["image"],
170
+ (width, height),
171
+ interpolation=self.__image_interpolation_method,
172
+ )
173
+
174
+ if self.__resize_target:
175
+ if "disparity" in sample:
176
+ sample["disparity"] = cv2.resize(
177
+ sample["disparity"],
178
+ (width, height),
179
+ interpolation=cv2.INTER_NEAREST,
180
+ )
181
+
182
+ if "depth" in sample:
183
+ sample["depth"] = cv2.resize(
184
+ sample["depth"], (width, height), interpolation=cv2.INTER_NEAREST
185
+ )
186
+
187
+ sample["mask"] = cv2.resize(
188
+ sample["mask"].astype(np.float32),
189
+ (width, height),
190
+ interpolation=cv2.INTER_NEAREST,
191
+ )
192
+ sample["mask"] = sample["mask"].astype(bool)
193
+
194
+ return sample
195
+
196
+
197
+ class NormalizeImage(object):
198
+ """Normlize image by given mean and std.
199
+ """
200
+
201
+ def __init__(self, mean, std):
202
+ self.__mean = mean
203
+ self.__std = std
204
+
205
+ def __call__(self, sample):
206
+ sample["image"] = (sample["image"] - self.__mean) / self.__std
207
+
208
+ return sample
209
+
210
+
211
+ class PrepareForNet(object):
212
+ """Prepare sample for usage as network input.
213
+ """
214
+
215
+ def __init__(self):
216
+ pass
217
+
218
+ def __call__(self, sample):
219
+ image = np.transpose(sample["image"], (2, 0, 1))
220
+ sample["image"] = np.ascontiguousarray(image).astype(np.float32)
221
+
222
+ if "mask" in sample:
223
+ sample["mask"] = sample["mask"].astype(np.float32)
224
+ sample["mask"] = np.ascontiguousarray(sample["mask"])
225
+
226
+ if "disparity" in sample:
227
+ disparity = sample["disparity"].astype(np.float32)
228
+ sample["disparity"] = np.ascontiguousarray(disparity)
229
+
230
+ if "depth" in sample:
231
+ depth = sample["depth"].astype(np.float32)
232
+ sample["depth"] = np.ascontiguousarray(depth)
233
+
234
+ return sample
model_farm_midas_v2_qcs8550_qnn2.16_int8_aidlite/python/utils.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import torch
3
+ import cv2
4
+ import os
5
+
6
+ from transforms import Resize, NormalizeImage, PrepareForNet
7
+
8
+ from torchvision.transforms import Compose
9
+ import sys
10
+ first_execution = True
11
+ def img_process(img_path):
12
+ global first_execution
13
+ first_execution = False
14
+ net_w, net_h = 256, 256
15
+ resize_mode = "upper_bound"
16
+ normalization = NormalizeImage(
17
+ mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]
18
+ )
19
+ transform = Compose(
20
+ [
21
+ Resize(
22
+ net_w,
23
+ net_h,
24
+ resize_target=None,
25
+ keep_aspect_ratio=False,
26
+ ensure_multiple_of=32,
27
+ resize_method=resize_mode,
28
+ image_interpolation_method=cv2.INTER_CUBIC,
29
+ ),
30
+ normalization,
31
+ PrepareForNet(),
32
+ ]
33
+ )
34
+ # image = utils.read_image(img_path) # in [0, 1]
35
+ image = cv2.imread(img_path)
36
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) / 255.0
37
+ org_size= image.shape[:2]
38
+ image = transform({"image": image})["image"]
39
+ sample = torch.from_numpy(image).to("cpu").unsqueeze(0)
40
+ height, width = sample.shape[2:]
41
+ print(f"Input resized to {width}x{height} before entering the encoder")
42
+
43
+ return sample,org_size
44
+
45
+
46
+
47
+ def write_depth(path, depth, grayscale=False, bits=1):
48
+ if not grayscale:
49
+ bits = 1
50
+
51
+ if not np.isfinite(depth).all():
52
+ depth=np.nan_to_num(depth, nan=0.0, posinf=0.0, neginf=0.0)
53
+ print("WARNING: Non-finite depth values present")
54
+
55
+ depth_min = depth.min()
56
+ depth_max = depth.max()
57
+
58
+ max_val = (2**(8*bits))-1
59
+
60
+ if depth_max - depth_min > np.finfo("float").eps:
61
+ out = max_val * (depth - depth_min) / (depth_max - depth_min)
62
+ else:
63
+ out = np.zeros(depth.shape, dtype=depth.dtype)
64
+
65
+ # print("out :",out.shape,out)
66
+ if not grayscale:
67
+ out = cv2.applyColorMap(np.uint8(out), cv2.COLORMAP_INFERNO)
68
+
69
+ if bits == 1:
70
+ cv2.imwrite(path , out.astype("uint8"))
71
+ elif bits == 2:
72
+ cv2.imwrite(path , out.astype("uint16"))
73
+
74
+ return
75
+
76
+ def write_pfm(path, image, scale=1):
77
+ with open(path, "wb") as file:
78
+ color = None
79
+
80
+ if image.dtype.name != "float32":
81
+ raise Exception("Image dtype must be float32.")
82
+
83
+ image = np.flipud(image)
84
+
85
+ if len(image.shape) == 3 and image.shape[2] == 3: # color image
86
+ color = True
87
+ elif (
88
+ len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1
89
+ ): # greyscale
90
+ color = False
91
+ else:
92
+ raise Exception("Image must have H x W x 3, H x W x 1 or H x W dimensions.")
93
+
94
+ file.write("PF\n" if color else "Pf\n".encode())
95
+ file.write("%d %d\n".encode() % (image.shape[1], image.shape[0]))
96
+
97
+ endian = image.dtype.byteorder
98
+
99
+ if endian == "<" or endian == "=" and sys.byteorder == "little":
100
+ scale = -scale
101
+
102
+ file.write("%f\n".encode() % scale)
103
+
104
+ image.tofile(file)
model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/README.md ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Model Information
2
+
3
+ ### Source model
4
+ - Input shape: 1x3x256x256
5
+ - Number of parameters: 20.33M
6
+ - Model size: 82.17M
7
+ - Output shape: 1x1x256x256
8
+
9
+ Source model repository: [midas](https://github.com/isl-org/MiDaS/tree/master)
10
+
11
+ ### Converted model
12
+
13
+ - Precision: INT8
14
+ - Backend: QNN2.16
15
+ - Target Device: SNM972 QCS8550
16
+
17
+ ## Inference with AidLite SDK
18
+
19
+ ### SDK installation
20
+ Model Farm uses AidLite SDK as the model inference SDK. For details, please refer to the [AidLite Developer Documentation](https://v2.docs.aidlux.com/en/sdk-api/aidlite-sdk/)
21
+
22
+ - Install AidLite SDK
23
+
24
+ ```bash
25
+ # Install the appropriate version of the aidlite sdk
26
+ sudo aid-pkg update
27
+ sudo aid-pkg install aidlite-sdk
28
+ # Download the qnn version that matches the above backend. Eg Install QNN2.23 Aidlite: sudo aid-pkg install aidlite-qnn223
29
+ sudo aid-pkg install aidlite-{QNN VERSION}
30
+ ```
31
+
32
+ - Verify AidLite SDK
33
+
34
+ ```bash
35
+ # aidlite sdk c++ check
36
+ python3 -c "import aidlite ; print(aidlite.get_library_version())"
37
+
38
+ # aidlite sdk python check, Aidlux_Aidlite version <=2.1.0
39
+ python3 -c "import aidlite ; print(aidlite.get_py_library_version())"
40
+ ```
41
+
42
+ ### Run Demo
43
+ #### python
44
+ ```bash
45
+ cd model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite
46
+ python3 python/run_test.py --target_model ./models/midas_v2_w8a16.qnn216.ctx.bin --imgs ./python/dog.jpg --invoke_nums 10
47
+ ```
48
+
49
+
50
+ #### c++
51
+ ```bash
52
+ cd midas_v2/model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/cpp
53
+ mkdir build && cd build
54
+ cmake ..
55
+ make
56
+ ./run_test
57
+ ```
model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/cpp/CMakeLists.txt ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required (VERSION 3.5)
2
+ project("run_test")
3
+
4
+ find_package(OpenCV REQUIRED)
5
+
6
+ message(STATUS "oPENCV Library status:")
7
+ message(STATUS ">version:${OpenCV_VERSION}")
8
+ message(STATUS "Include:${OpenCV_INCLUDE_DIRS}")
9
+
10
+ set(CMAKE_CXX_FLAGS "-Wno-error=deprecated-declarations -Wno-deprecated-declarations")
11
+
12
+ include_directories(
13
+ /usr/local/include
14
+ /usr/include/opencv4
15
+ )
16
+
17
+ link_directories(
18
+ /usr/local/lib/
19
+ )
20
+
21
+ file(GLOB SRC_LISTS
22
+ ${CMAKE_CURRENT_SOURCE_DIR}/run_test.cpp
23
+ )
24
+
25
+ add_executable(run_test ${SRC_LISTS})
26
+
27
+ target_link_libraries(run_test
28
+ aidlite
29
+ ${OpenCV_LIBS}
30
+ pthread
31
+ jsoncpp
32
+ )
model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/cpp/dog.jpg ADDED

Git LFS Details

  • SHA256: f3f87bb8ab3c26c7ecfd3ac60421d7f32b0503d1d6c5baf8bac42ed93d86351a
  • Pointer size: 131 Bytes
  • Size of remote file: 661 kB
model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/cpp/run_test.cpp ADDED
@@ -0,0 +1,392 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <fstream>
3
+ #include <opencv2/opencv.hpp>
4
+ #include <aidlux/aidlite/aidlite.hpp>
5
+ #include <vector>
6
+ #include <numeric>
7
+ #include <cmath>
8
+ #include <jsoncpp/json/json.h>
9
+
10
+ using namespace cv;
11
+ using namespace std;
12
+ using namespace Aidlux::Aidlite;
13
+
14
+ const int net_w = 256;
15
+ const int net_h = 256;
16
+
17
+ const std::vector<float> mean_vals = {0.485f, 0.456f, 0.406f};
18
+ const std::vector<float> std_vals = {0.229f, 0.224f, 0.225f};
19
+
20
+
21
+ struct Args {
22
+ std::string target_model = "../../models/midas_v2_w8a16.qnn216.ctx.bin";
23
+ std::string imgs = "../dog.jpg";
24
+ int invoke_nums = 10;
25
+ std::string model_type = "QNN";
26
+ };
27
+
28
+
29
+ Args parse_args(int argc, char* argv[]) {
30
+ Args args;
31
+ for (int i = 1; i < argc; ++i) {
32
+ std::string arg = argv[i];
33
+ if (arg == "--target_model" && i + 1 < argc) {
34
+ args.target_model = argv[++i];
35
+ } else if (arg == "--imgs" && i + 1 < argc) {
36
+ args.imgs = argv[++i];
37
+ } else if (arg == "--invoke_nums" && i + 1 < argc) {
38
+ args.invoke_nums = std::stoi(argv[++i]);
39
+ } else if (arg == "--model_type" && i + 1 < argc) {
40
+ args.model_type = argv[++i];
41
+ }
42
+ }
43
+ return args;
44
+ }
45
+
46
+ std::string to_lower(const std::string& str) {
47
+ std::string lower_str = str;
48
+ std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(), [](unsigned char c) {
49
+ return std::tolower(c);
50
+ });
51
+ return lower_str;
52
+ }
53
+
54
+
55
+ int transpose(float* src, unsigned int* src_dims, unsigned int* tsp_dims, float* dest){
56
+
57
+ int current_coordinate[4] = {0, 0, 0, 0};
58
+ for(int a = 0; a < src_dims[0]; ++a){
59
+ current_coordinate[0] = a;
60
+ for(int b = 0; b < src_dims[1]; ++b){
61
+ current_coordinate[1] = b;
62
+ for(int c = 0; c < src_dims[2]; ++c){
63
+ current_coordinate[2] = c;
64
+ for(int d = 0; d < src_dims[3]; ++d){
65
+ current_coordinate[3] = d;
66
+
67
+ int old_index = current_coordinate[0]*src_dims[1]*src_dims[2]*src_dims[3] +
68
+ current_coordinate[1]*src_dims[2]*src_dims[3] +
69
+ current_coordinate[2]*src_dims[3] +
70
+ current_coordinate[3];
71
+
72
+ int new_index = current_coordinate[tsp_dims[0]]*src_dims[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
73
+ current_coordinate[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
74
+ current_coordinate[tsp_dims[2]]*src_dims[tsp_dims[3]] +
75
+ current_coordinate[tsp_dims[3]];
76
+
77
+ dest[new_index] = src[old_index];
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ return EXIT_SUCCESS;
84
+ }
85
+
86
+
87
+ // 替代 np.nan_to_num
88
+ void sanitizeDepthMap(cv::Mat& depth) {
89
+ for (int y = 0; y < depth.rows; ++y) {
90
+ float* row = depth.ptr<float>(y);
91
+ for (int x = 0; x < depth.cols; ++x) {
92
+ float val = row[x];
93
+ if (!std::isfinite(val)) {
94
+ row[x] = 0.0f;
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ // 等效于 Python write_depth
101
+ void write_depth(const std::string& path, const cv::Mat& input_depth, bool grayscale = false, int bits = 1) {
102
+ CV_Assert(input_depth.type() == CV_32FC1);
103
+
104
+ // 拷贝 + 处理非法值
105
+ cv::Mat depth = input_depth.clone();
106
+ sanitizeDepthMap(depth);
107
+
108
+ double minVal, maxVal;
109
+ cv::minMaxLoc(depth, &minVal, &maxVal);
110
+
111
+ double max_val = (1 << (8 * bits)) - 1;
112
+ cv::Mat out;
113
+
114
+ if (maxVal - minVal > std::numeric_limits<float>::epsilon()) {
115
+ // 归一化并映射到位深范围
116
+ out = (depth - minVal) * (max_val / (maxVal - minVal));
117
+ } else {
118
+ out = cv::Mat::zeros(depth.size(), CV_32F);
119
+ }
120
+
121
+ if (!grayscale) {
122
+ out.convertTo(out, CV_8UC1);
123
+ cv::applyColorMap(out, out, cv::COLORMAP_INFERNO);
124
+ }
125
+
126
+ if (bits == 1) {
127
+ out.convertTo(out, CV_8U);
128
+ } else if (bits == 2) {
129
+ out.convertTo(out, CV_16U);
130
+ }
131
+
132
+ cv::imwrite(path, out);
133
+ }
134
+
135
+ // 等效于 Python write_pfm
136
+ void write_pfm(const std::string& path, const cv::Mat& image, float scale = 1.0f) {
137
+ CV_Assert(image.type() == CV_32FC1 || image.type() == CV_32FC3);
138
+
139
+ std::ofstream file(path, std::ios::binary);
140
+ if (!file.is_open()) {
141
+ std::cerr << "Failed to open file for writing PFM: " << path << std::endl;
142
+ return;
143
+ }
144
+
145
+ int width = image.cols;
146
+ int height = image.rows;
147
+ int channels = image.channels();
148
+ bool color = (channels == 3);
149
+
150
+ file << (color ? "PF" : "Pf") << "\n";
151
+ file << width << " " << height << "\n";
152
+
153
+ // Endianness: negative = little-endian
154
+ uint16_t endian_test = 0x1;
155
+ bool is_little_endian = *(reinterpret_cast<uint8_t*>(&endian_test)) == 0x1;
156
+ if (is_little_endian) {
157
+ scale = -scale;
158
+ }
159
+
160
+ file << scale << "\n";
161
+
162
+ // Flip vertically (OpenCV top-left origin -> PFM bottom-left origin)
163
+ cv::Mat flipped;
164
+ cv::flip(image, flipped, 0);
165
+
166
+ // Write raw data
167
+ file.write(reinterpret_cast<const char*>(flipped.data), flipped.total() * channels * sizeof(float));
168
+ file.close();
169
+ }
170
+
171
+
172
+ // ======================= Normalize =======================
173
+ void normalize(cv::Mat& image) {
174
+ CV_Assert(image.type() == CV_32FC3);
175
+ int rows = image.rows;
176
+ int cols = image.cols;
177
+
178
+ for (int y = 0; y < rows; ++y) {
179
+ cv::Vec3f* row = image.ptr<cv::Vec3f>(y);
180
+ for (int x = 0; x < cols; ++x) {
181
+ for (int c = 0; c < 3; ++c) {
182
+ row[x][c] = (row[x][c] - mean_vals[c]) / std_vals[c];
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ cv::Mat hwc_to_chw(const cv::Mat& image) {
189
+ std::vector<cv::Mat> channels(3);
190
+ cv::split(image, channels);
191
+
192
+ cv::Mat chw(3, image.rows * image.cols, CV_32F);
193
+ for (int c = 0; c < 3; ++c) {
194
+ memcpy(chw.ptr(c), channels[c].data, image.rows * image.cols * sizeof(float));
195
+ }
196
+
197
+ return chw;
198
+ }
199
+
200
+
201
+ bool first_execution = true;
202
+ cv::Mat img_process(const cv::Mat image_bgr, cv::Size& org_size_out) {
203
+ first_execution = false;
204
+
205
+ cv::Mat image_rgb;
206
+ cv::cvtColor(image_bgr, image_rgb, cv::COLOR_BGR2RGB);
207
+ image_rgb.convertTo(image_rgb, CV_32FC3, 1.0 / 255.0);
208
+
209
+ // 2. Save original size
210
+ org_size_out = image_rgb.size(); // H x W
211
+
212
+ // 3. Resize to 256x256 using cubic interpolation
213
+ cv::resize(image_rgb, image_rgb, cv::Size(net_w, net_h), 0, 0, cv::INTER_CUBIC);
214
+
215
+ // 4. Normalize using mean/std
216
+ normalize(image_rgb);
217
+
218
+ // 5. Convert HWC to CHW
219
+ cv::Mat chw = hwc_to_chw(image_rgb);
220
+
221
+ // 6. Add batch dimension: [1, C, H, W] → reshape to 1x3xHxW style float array
222
+ cv::Mat input_tensor(1, 3 * net_h * net_w, CV_32F);
223
+ memcpy(input_tensor.ptr<float>(), chw.data, 3 * net_h * net_w * sizeof(float));
224
+
225
+ std::cout << "Input resized to " << net_w << "x" << net_h << " before entering the encoder" << std::endl;
226
+
227
+ return input_tensor;
228
+ }
229
+
230
+
231
+ float* matToFloatPtr(const cv::Mat& input_mat, bool normalize = true) {
232
+ // 检查连续性
233
+ cv::Mat mat = input_mat;
234
+ if (!mat.isContinuous()) {
235
+ mat = mat.clone();
236
+ }
237
+
238
+ // 分配内存
239
+ int total_pixels = mat.rows * mat.cols;
240
+ int channels = mat.channels();
241
+ float* float_data = new float[total_pixels * channels];
242
+
243
+ // 根据数据类型转换
244
+ if (mat.type() == CV_8UC1 || mat.type() == CV_8UC3) {
245
+ uchar* ptr = mat.ptr<uchar>(0);
246
+ for (int i = 0; i < total_pixels * channels; ++i) {
247
+ float_data[i] = normalize ? (static_cast<float>(ptr[i]) / 255.0f) : ptr[i];
248
+ }
249
+ } else if (mat.type() == CV_32FC1 || mat.type() == CV_32FC3) {
250
+ float* ptr = mat.ptr<float>(0);
251
+ std::memcpy(float_data, ptr, total_pixels * channels * sizeof(float));
252
+ } else {
253
+ delete[] float_data;
254
+ return nullptr; // 不支持的类型
255
+ }
256
+
257
+ return float_data;
258
+ }
259
+
260
+
261
+ int invoke(const Args& args) {
262
+ std::cout << "Start main ... ... Model Path: " << args.target_model << "\n"
263
+ << "Image Path: " << args.imgs << "\n"
264
+ << "Inference Nums: " << args.invoke_nums << "\n"
265
+ << "Model Type: " << args.model_type << "\n";
266
+ Model* model = Model::create_instance(args.target_model);
267
+ if(model == nullptr){
268
+ printf("Create model failed !\n");
269
+ return EXIT_FAILURE;
270
+ }
271
+ Config* config = Config::create_instance();
272
+ if(config == nullptr){
273
+ printf("Create config failed !\n");
274
+ return EXIT_FAILURE;
275
+ }
276
+ config->implement_type = ImplementType::TYPE_LOCAL;
277
+ std::string model_type_lower = to_lower(args.model_type);
278
+ if (model_type_lower == "qnn"){
279
+ config->framework_type = FrameworkType::TYPE_QNN;
280
+ } else if (model_type_lower == "snpe2" || model_type_lower == "snpe") {
281
+ config->framework_type = FrameworkType::TYPE_SNPE2;
282
+ }
283
+ config->accelerate_type = AccelerateType::TYPE_DSP;
284
+ config->is_quantify_model = 1;
285
+
286
+ unsigned int model_h = 256;
287
+ unsigned int model_w = 256;
288
+ std::vector<std::vector<uint32_t>> input_shapes = {{1,model_h,model_w,3}};
289
+ std::vector<std::vector<uint32_t>> output_shapes = {{1,model_h,model_w,1}};
290
+ model->set_model_properties(input_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32, output_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32);
291
+ std::unique_ptr<Interpreter> fast_interpreter = InterpreterBuilder::build_interpretper_from_model_and_config(model, config);
292
+ if(fast_interpreter == nullptr){
293
+ printf("build_interpretper_from_model_and_config failed !\n");
294
+ return EXIT_FAILURE;
295
+ }
296
+ int result = fast_interpreter->init();
297
+ if(result != EXIT_SUCCESS){
298
+ printf("interpreter->init() failed !\n");
299
+ return EXIT_FAILURE;
300
+ }
301
+ // load model
302
+ fast_interpreter->load_model();
303
+ if(result != EXIT_SUCCESS){
304
+ printf("interpreter->load_model() failed !\n");
305
+ return EXIT_FAILURE;
306
+ }
307
+ printf("detect model load success!\n");
308
+
309
+ cv::Mat frame = cv::imread(args.imgs);
310
+ if (frame.empty()) {
311
+ printf("detect image load failed!\n");
312
+ return 1;
313
+ }
314
+ printf("img_src cols: %d, img_src rows: %d\n", frame.cols, frame.rows);
315
+ cv::Mat input_data;
316
+ cv::Mat frame_clone = frame.clone();
317
+ int h = frame_clone.rows;
318
+ int w = frame_clone.cols;
319
+ cv::Size org_size(w, h);
320
+ cv::Size org_size0(256, 256);
321
+
322
+ cv::Mat input_tensor = img_process(frame_clone, org_size0);
323
+ float* float_data = matToFloatPtr(input_tensor);
324
+ unsigned int src_dims[4] = {1, 3, 256, 256};
325
+ unsigned int tsp_dims[4] = {0,2,3,1};
326
+ unsigned int stride_data_num = 1*256*256*3;
327
+ float* format_data = new float[stride_data_num];
328
+ transpose(float_data, src_dims, tsp_dims, format_data);
329
+ cv::Mat origin_buffer(3,256*256, CV_32F, format_data);
330
+
331
+ float *outdata0 = nullptr;
332
+ std::vector<float> invoke_time;
333
+ for (int i = 0; i < args.invoke_nums; ++i) {
334
+ result = fast_interpreter->set_input_tensor(0, origin_buffer.data);
335
+ if(result != EXIT_SUCCESS){
336
+ printf("interpreter->set_input_tensor() failed !\n");
337
+ return EXIT_FAILURE;
338
+ }
339
+ auto t1 = std::chrono::high_resolution_clock::now();
340
+ result = fast_interpreter->invoke();
341
+ auto t2 = std::chrono::high_resolution_clock::now();
342
+ std::chrono::duration<double> cost_time = t2 - t1;
343
+ invoke_time.push_back(cost_time.count() * 1000);
344
+ if(result != EXIT_SUCCESS){
345
+ printf("interpreter->invoke() failed !\n");
346
+ return EXIT_FAILURE;
347
+ }
348
+ uint32_t out_data_0 = 0;
349
+ result = fast_interpreter->get_output_tensor(0, (void**)&outdata0, &out_data_0);
350
+ if(result != EXIT_SUCCESS){
351
+ printf("interpreter->get_output_tensor() 1 failed !\n");
352
+ return EXIT_FAILURE;
353
+ }
354
+
355
+ }
356
+
357
+ float max_invoke_time = *std::max_element(invoke_time.begin(), invoke_time.end());
358
+ float min_invoke_time = *std::min_element(invoke_time.begin(), invoke_time.end());
359
+ float mean_invoke_time = std::accumulate(invoke_time.begin(), invoke_time.end(), 0.0f) / args.invoke_nums;
360
+ float var_invoketime = 0.0f;
361
+ for (auto time : invoke_time) {
362
+ var_invoketime += (time - mean_invoke_time) * (time - mean_invoke_time);
363
+ }
364
+ var_invoketime /= args.invoke_nums;
365
+ printf("=======================================\n");
366
+ printf("QNN inference %d times :\n --mean_invoke_time is %f \n --max_invoke_time is %f \n --min_invoke_time is %f \n --var_invoketime is %f\n",
367
+ args.invoke_nums, mean_invoke_time, max_invoke_time, min_invoke_time, var_invoketime);
368
+ printf("=======================================\n");
369
+
370
+ // post process
371
+ cv::Mat out_buffer(1,256*256, CV_32F, outdata0);
372
+ cv::Mat prediction_2d(256, 256, CV_32F, (void*)out_buffer.ptr<float>());
373
+ cv::Mat resized;
374
+ cv::resize(prediction_2d, resized, org_size, 0, 0, cv::INTER_CUBIC);
375
+
376
+ // 保存为图像
377
+ write_depth("depth_output.jpg", resized, false, 1);
378
+
379
+ // 保存为 PFM
380
+ write_pfm("depth_output.pfm", resized);
381
+
382
+
383
+
384
+ fast_interpreter->destory();
385
+ return 0;
386
+ }
387
+
388
+
389
+ int main(int argc, char* argv[]) {
390
+ Args args = parse_args(argc, argv);
391
+ return invoke(args);
392
+ }
model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/models/midas_v2_w8a16.qnn216.ctx.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0e26a9e1f7c7879c958086c295514e488ca9ecb7debab782a75158afd76982fd
3
+ size 19263488
model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/python/dog.jpg ADDED

Git LFS Details

  • SHA256: f3f87bb8ab3c26c7ecfd3ac60421d7f32b0503d1d6c5baf8bac42ed93d86351a
  • Pointer size: 131 Bytes
  • Size of remote file: 661 kB
model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/python/run_test.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import torch
3
+ import cv2
4
+ import os
5
+ from utils import write_pfm,write_depth,img_process
6
+ import aidlite
7
+ import time
8
+ import argparse
9
+
10
+ def out_process(prediction,target_size):
11
+ prediction = torch.nn.functional.interpolate(
12
+ prediction,
13
+ size=target_size,
14
+ mode="bicubic",
15
+ align_corners=False,
16
+ )
17
+ prediction = prediction.squeeze().detach().numpy()
18
+ return prediction
19
+
20
+ class run_qnn:
21
+ def __init__(self,qnn_path):
22
+ super().__init__()
23
+ self.model = aidlite.Model.create_instance(qnn_path)
24
+ if self.model is None:
25
+ print("Create model failed !")
26
+ return
27
+
28
+ self.config = aidlite.Config.create_instance()
29
+ if self.config is None:
30
+ print("build_interpretper_from_model_and_config failed !")
31
+ return
32
+
33
+ self.config.implement_type = aidlite.ImplementType.TYPE_LOCAL
34
+ self.config.framework_type = aidlite.FrameworkType.TYPE_QNN
35
+ self.config.accelerate_type = aidlite.AccelerateType.TYPE_DSP
36
+ # self.config.accelerate_type = aidlite.AccelerateType.TYPE_CPU
37
+ self.config.is_quantify_model = 1
38
+
39
+ self.interpreter = aidlite.InterpreterBuilder.build_interpretper_from_model_and_config(self.model, self.config)
40
+ if self.interpreter is None:
41
+ print("build_interpretper_from_model_and_config failed !")
42
+ return
43
+ input_shapes = [[1,256,256,3]]
44
+ output_shapes = [[1,256,256,1]]
45
+ self.model.set_model_properties(input_shapes, aidlite.DataType.TYPE_FLOAT32,
46
+ output_shapes, aidlite.DataType.TYPE_FLOAT32)
47
+
48
+ if self.interpreter is None:
49
+ print("build_interpretper_from_model_and_config failed !")
50
+ result = self.interpreter.init()
51
+ if result != 0:
52
+ print(f"interpreter init failed !")
53
+ result = self.interpreter.load_model()
54
+ if result != 0:
55
+ print("interpreter load model failed !")
56
+
57
+ print(" model load success!")
58
+
59
+ def __call__(self, input,invoke_nums):
60
+ self.interpreter.set_input_tensor(0,input)
61
+ invoke_time=[]
62
+ for i in range(invoke_nums):
63
+ result = self.interpreter.set_input_tensor(0, input.data)
64
+ if result != 0:
65
+ print("interpreter set_input_tensor() failed")
66
+ t1=time.time()
67
+ result = self.interpreter.invoke()
68
+ cost_time = (time.time()-t1)*1000
69
+ invoke_time.append(cost_time)
70
+
71
+ max_invoke_time = max(invoke_time)
72
+ min_invoke_time = min(invoke_time)
73
+ mean_invoke_time = sum(invoke_time)/invoke_nums
74
+ var_invoketime=np.var(invoke_time)
75
+ print("====================================")
76
+ print(f"QNN invoke time:\n --mean_invoke_time is {mean_invoke_time} \n --max_invoke_time is {max_invoke_time} \n --min_invoke_time is {min_invoke_time} \n --var_invoketime is {var_invoketime}")
77
+ print("====================================")
78
+ features_0 = self.interpreter.get_output_tensor(0).reshape(1,256,256,1).transpose(0,3,1,2)
79
+ return features_0
80
+
81
+
82
+
83
+ def run(args):
84
+ img_path = args.imgs
85
+ qnn_path = args.target_model
86
+ invoke_num=args.invoke_nums
87
+ print("Start processing...")
88
+ img_input,org_size = img_process(img_path)
89
+
90
+ qnn_model =run_qnn(qnn_path)
91
+ prediction_qnn = qnn_model(img_input.numpy().transpose(0,2,3,1),invoke_num)
92
+ prediction_qnn = torch.tensor(prediction_qnn)
93
+ qnn_process = out_process(prediction_qnn,org_size)
94
+
95
+ write_depth("./python/results.jpg", qnn_process, grayscale=False, bits=1)
96
+ write_pfm("./python/results.pfm", qnn_process.astype(np.float32))
97
+ print("Finished")
98
+
99
+ def parser_args():
100
+ parser = argparse.ArgumentParser(description="Run model benchmarks")
101
+ parser.add_argument('--target_model',type=str,default='./models/midas_v2_w8a16.qnn216.ctx.bin',help="Inference model path")
102
+ parser.add_argument('--imgs',type=str,default='./python/dog.jpg',help="Predict images path")
103
+ parser.add_argument('--invoke_nums',type=int,default=10,help="Inference nums")
104
+ parser.add_argument('--model_type',type=str,default='QNN',help="Run backend")
105
+ args = parser.parse_args()
106
+ return args
107
+
108
+
109
+ if __name__ =="__main__":
110
+ args = parser_args()
111
+ run(args)
model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/python/transforms.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import cv2
3
+ import math
4
+
5
+
6
+ def apply_min_size(sample, size, image_interpolation_method=cv2.INTER_AREA):
7
+ """Rezise the sample to ensure the given size. Keeps aspect ratio.
8
+
9
+ Args:
10
+ sample (dict): sample
11
+ size (tuple): image size
12
+
13
+ Returns:
14
+ tuple: new size
15
+ """
16
+ shape = list(sample["disparity"].shape)
17
+
18
+ if shape[0] >= size[0] and shape[1] >= size[1]:
19
+ return sample
20
+
21
+ scale = [0, 0]
22
+ scale[0] = size[0] / shape[0]
23
+ scale[1] = size[1] / shape[1]
24
+
25
+ scale = max(scale)
26
+
27
+ shape[0] = math.ceil(scale * shape[0])
28
+ shape[1] = math.ceil(scale * shape[1])
29
+
30
+ # resize
31
+ sample["image"] = cv2.resize(
32
+ sample["image"], tuple(shape[::-1]), interpolation=image_interpolation_method
33
+ )
34
+
35
+ sample["disparity"] = cv2.resize(
36
+ sample["disparity"], tuple(shape[::-1]), interpolation=cv2.INTER_NEAREST
37
+ )
38
+ sample["mask"] = cv2.resize(
39
+ sample["mask"].astype(np.float32),
40
+ tuple(shape[::-1]),
41
+ interpolation=cv2.INTER_NEAREST,
42
+ )
43
+ sample["mask"] = sample["mask"].astype(bool)
44
+
45
+ return tuple(shape)
46
+
47
+
48
+ class Resize(object):
49
+ """Resize sample to given size (width, height).
50
+ """
51
+
52
+ def __init__(
53
+ self,
54
+ width,
55
+ height,
56
+ resize_target=True,
57
+ keep_aspect_ratio=False,
58
+ ensure_multiple_of=1,
59
+ resize_method="lower_bound",
60
+ image_interpolation_method=cv2.INTER_AREA,
61
+ ):
62
+ """Init.
63
+
64
+ Args:
65
+ width (int): desired output width
66
+ height (int): desired output height
67
+ resize_target (bool, optional):
68
+ True: Resize the full sample (image, mask, target).
69
+ False: Resize image only.
70
+ Defaults to True.
71
+ keep_aspect_ratio (bool, optional):
72
+ True: Keep the aspect ratio of the input sample.
73
+ Output sample might not have the given width and height, and
74
+ resize behaviour depends on the parameter 'resize_method'.
75
+ Defaults to False.
76
+ ensure_multiple_of (int, optional):
77
+ Output width and height is constrained to be multiple of this parameter.
78
+ Defaults to 1.
79
+ resize_method (str, optional):
80
+ "lower_bound": Output will be at least as large as the given size.
81
+ "upper_bound": Output will be at max as large as the given size. (Output size might be smaller than given size.)
82
+ "minimal": Scale as least as possible. (Output size might be smaller than given size.)
83
+ Defaults to "lower_bound".
84
+ """
85
+ self.__width = width
86
+ self.__height = height
87
+
88
+ self.__resize_target = resize_target
89
+ self.__keep_aspect_ratio = keep_aspect_ratio
90
+ self.__multiple_of = ensure_multiple_of
91
+ self.__resize_method = resize_method
92
+ self.__image_interpolation_method = image_interpolation_method
93
+
94
+ def constrain_to_multiple_of(self, x, min_val=0, max_val=None):
95
+ y = (np.round(x / self.__multiple_of) * self.__multiple_of).astype(int)
96
+
97
+ if max_val is not None and y > max_val:
98
+ y = (np.floor(x / self.__multiple_of) * self.__multiple_of).astype(int)
99
+
100
+ if y < min_val:
101
+ y = (np.ceil(x / self.__multiple_of) * self.__multiple_of).astype(int)
102
+
103
+ return y
104
+
105
+ def get_size(self, width, height):
106
+ # determine new height and width
107
+ scale_height = self.__height / height
108
+ scale_width = self.__width / width
109
+
110
+ if self.__keep_aspect_ratio:
111
+ if self.__resize_method == "lower_bound":
112
+ # scale such that output size is lower bound
113
+ if scale_width > scale_height:
114
+ # fit width
115
+ scale_height = scale_width
116
+ else:
117
+ # fit height
118
+ scale_width = scale_height
119
+ elif self.__resize_method == "upper_bound":
120
+ # scale such that output size is upper bound
121
+ if scale_width < scale_height:
122
+ # fit width
123
+ scale_height = scale_width
124
+ else:
125
+ # fit height
126
+ scale_width = scale_height
127
+ elif self.__resize_method == "minimal":
128
+ # scale as least as possbile
129
+ if abs(1 - scale_width) < abs(1 - scale_height):
130
+ # fit width
131
+ scale_height = scale_width
132
+ else:
133
+ # fit height
134
+ scale_width = scale_height
135
+ else:
136
+ raise ValueError(
137
+ f"resize_method {self.__resize_method} not implemented"
138
+ )
139
+
140
+ if self.__resize_method == "lower_bound":
141
+ new_height = self.constrain_to_multiple_of(
142
+ scale_height * height, min_val=self.__height
143
+ )
144
+ new_width = self.constrain_to_multiple_of(
145
+ scale_width * width, min_val=self.__width
146
+ )
147
+ elif self.__resize_method == "upper_bound":
148
+ new_height = self.constrain_to_multiple_of(
149
+ scale_height * height, max_val=self.__height
150
+ )
151
+ new_width = self.constrain_to_multiple_of(
152
+ scale_width * width, max_val=self.__width
153
+ )
154
+ elif self.__resize_method == "minimal":
155
+ new_height = self.constrain_to_multiple_of(scale_height * height)
156
+ new_width = self.constrain_to_multiple_of(scale_width * width)
157
+ else:
158
+ raise ValueError(f"resize_method {self.__resize_method} not implemented")
159
+
160
+ return (new_width, new_height)
161
+
162
+ def __call__(self, sample):
163
+ width, height = self.get_size(
164
+ sample["image"].shape[1], sample["image"].shape[0]
165
+ )
166
+
167
+ # resize sample
168
+ sample["image"] = cv2.resize(
169
+ sample["image"],
170
+ (width, height),
171
+ interpolation=self.__image_interpolation_method,
172
+ )
173
+
174
+ if self.__resize_target:
175
+ if "disparity" in sample:
176
+ sample["disparity"] = cv2.resize(
177
+ sample["disparity"],
178
+ (width, height),
179
+ interpolation=cv2.INTER_NEAREST,
180
+ )
181
+
182
+ if "depth" in sample:
183
+ sample["depth"] = cv2.resize(
184
+ sample["depth"], (width, height), interpolation=cv2.INTER_NEAREST
185
+ )
186
+
187
+ sample["mask"] = cv2.resize(
188
+ sample["mask"].astype(np.float32),
189
+ (width, height),
190
+ interpolation=cv2.INTER_NEAREST,
191
+ )
192
+ sample["mask"] = sample["mask"].astype(bool)
193
+
194
+ return sample
195
+
196
+
197
+ class NormalizeImage(object):
198
+ """Normlize image by given mean and std.
199
+ """
200
+
201
+ def __init__(self, mean, std):
202
+ self.__mean = mean
203
+ self.__std = std
204
+
205
+ def __call__(self, sample):
206
+ sample["image"] = (sample["image"] - self.__mean) / self.__std
207
+
208
+ return sample
209
+
210
+
211
+ class PrepareForNet(object):
212
+ """Prepare sample for usage as network input.
213
+ """
214
+
215
+ def __init__(self):
216
+ pass
217
+
218
+ def __call__(self, sample):
219
+ image = np.transpose(sample["image"], (2, 0, 1))
220
+ sample["image"] = np.ascontiguousarray(image).astype(np.float32)
221
+
222
+ if "mask" in sample:
223
+ sample["mask"] = sample["mask"].astype(np.float32)
224
+ sample["mask"] = np.ascontiguousarray(sample["mask"])
225
+
226
+ if "disparity" in sample:
227
+ disparity = sample["disparity"].astype(np.float32)
228
+ sample["disparity"] = np.ascontiguousarray(disparity)
229
+
230
+ if "depth" in sample:
231
+ depth = sample["depth"].astype(np.float32)
232
+ sample["depth"] = np.ascontiguousarray(depth)
233
+
234
+ return sample
model_farm_midas_v2_qcs8550_qnn2.16_w8a16_aidlite/python/utils.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import torch
3
+ import cv2
4
+ import os
5
+
6
+ from transforms import Resize, NormalizeImage, PrepareForNet
7
+
8
+ from torchvision.transforms import Compose
9
+ import sys
10
+ first_execution = True
11
+ def img_process(img_path):
12
+ global first_execution
13
+ first_execution = False
14
+ net_w, net_h = 256, 256
15
+ resize_mode = "upper_bound"
16
+ normalization = NormalizeImage(
17
+ mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]
18
+ )
19
+ transform = Compose(
20
+ [
21
+ Resize(
22
+ net_w,
23
+ net_h,
24
+ resize_target=None,
25
+ keep_aspect_ratio=False,
26
+ ensure_multiple_of=32,
27
+ resize_method=resize_mode,
28
+ image_interpolation_method=cv2.INTER_CUBIC,
29
+ ),
30
+ normalization,
31
+ PrepareForNet(),
32
+ ]
33
+ )
34
+ # image = utils.read_image(img_path) # in [0, 1]
35
+ image = cv2.imread(img_path)
36
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) / 255.0
37
+ org_size= image.shape[:2]
38
+ image = transform({"image": image})["image"]
39
+ sample = torch.from_numpy(image).to("cpu").unsqueeze(0)
40
+ height, width = sample.shape[2:]
41
+ print(f"Input resized to {width}x{height} before entering the encoder")
42
+
43
+ return sample,org_size
44
+
45
+
46
+
47
+ def write_depth(path, depth, grayscale=False, bits=1):
48
+ if not grayscale:
49
+ bits = 1
50
+
51
+ if not np.isfinite(depth).all():
52
+ depth=np.nan_to_num(depth, nan=0.0, posinf=0.0, neginf=0.0)
53
+ print("WARNING: Non-finite depth values present")
54
+
55
+ depth_min = depth.min()
56
+ depth_max = depth.max()
57
+
58
+ max_val = (2**(8*bits))-1
59
+
60
+ if depth_max - depth_min > np.finfo("float").eps:
61
+ out = max_val * (depth - depth_min) / (depth_max - depth_min)
62
+ else:
63
+ out = np.zeros(depth.shape, dtype=depth.dtype)
64
+
65
+ # print("out :",out.shape,out)
66
+ if not grayscale:
67
+ out = cv2.applyColorMap(np.uint8(out), cv2.COLORMAP_INFERNO)
68
+
69
+ if bits == 1:
70
+ cv2.imwrite(path , out.astype("uint8"))
71
+ elif bits == 2:
72
+ cv2.imwrite(path , out.astype("uint16"))
73
+
74
+ return
75
+
76
+ def write_pfm(path, image, scale=1):
77
+ with open(path, "wb") as file:
78
+ color = None
79
+
80
+ if image.dtype.name != "float32":
81
+ raise Exception("Image dtype must be float32.")
82
+
83
+ image = np.flipud(image)
84
+
85
+ if len(image.shape) == 3 and image.shape[2] == 3: # color image
86
+ color = True
87
+ elif (
88
+ len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1
89
+ ): # greyscale
90
+ color = False
91
+ else:
92
+ raise Exception("Image must have H x W x 3, H x W x 1 or H x W dimensions.")
93
+
94
+ file.write("PF\n" if color else "Pf\n".encode())
95
+ file.write("%d %d\n".encode() % (image.shape[1], image.shape[0]))
96
+
97
+ endian = image.dtype.byteorder
98
+
99
+ if endian == "<" or endian == "=" and sys.byteorder == "little":
100
+ scale = -scale
101
+
102
+ file.write("%f\n".encode() % scale)
103
+
104
+ image.tofile(file)