qc903113684 commited on
Commit
af0dd4f
·
verified ·
1 Parent(s): 274c5c0

Upload 47 files

Browse files
Files changed (47) hide show
  1. model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/README.md +57 -0
  2. model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/cpp/CMakeLists.txt +32 -0
  3. model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/cpp/baboon.png +0 -0
  4. model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/cpp/run_test.cpp +243 -0
  5. model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/models/RRDB_ESRGAN_x4.pth +3 -0
  6. model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/models/m_RRDB_esrgan_x4.pt +3 -0
  7. model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/models/m_RRDB_esrgan_x4_w8a16.qnn216.ctx.bin +3 -0
  8. model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/python/LR/baboon.png +0 -0
  9. model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/python/__pycache__/RRDBNet_arch.cpython-38.pyc +0 -0
  10. model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/python/__pycache__/RRDBNet_arch.cpython-39.pyc +0 -0
  11. model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/python/demo_qnn.py +84 -0
  12. model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/README.md +47 -0
  13. model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/cpp/CMakeLists.txt +32 -0
  14. model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/cpp/baboon.png +0 -0
  15. model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/cpp/run_test.cpp +243 -0
  16. model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/models/m_RRDB_esrgan_x4_w8a8.qnn216.ctx.bin +3 -0
  17. model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/python/LR/baboon.png +0 -0
  18. model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/python/__pycache__/RRDBNet_arch.cpython-38.pyc +0 -0
  19. model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/python/__pycache__/RRDBNet_arch.cpython-39.pyc +0 -0
  20. model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/python/demo_qnn.py +115 -0
  21. model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/README.md +57 -0
  22. model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/cpp/CMakeLists.txt +32 -0
  23. model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/cpp/baboon.png +0 -0
  24. model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/cpp/run_test.cpp +243 -0
  25. model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/models/m_RRDB_esrgan_x4_fp16.qnn216.ctx.bin +3 -0
  26. model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/python/LR/baboon.png +0 -0
  27. model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/python/__pycache__/RRDBNet_arch.cpython-38.pyc +0 -0
  28. model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/python/__pycache__/RRDBNet_arch.cpython-39.pyc +0 -0
  29. model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/python/demo_qnn.py +115 -0
  30. model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/README.md +57 -0
  31. model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/cpp/CMakeLists.txt +32 -0
  32. model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/cpp/baboon.png +0 -0
  33. model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/cpp/run_test.cpp +243 -0
  34. model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/models/m_RRDB_esrgan_x4_w8a8.qnn216.ctx.bin +3 -0
  35. model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/python/LR/baboon.png +0 -0
  36. model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/python/__pycache__/RRDBNet_arch.cpython-38.pyc +0 -0
  37. model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/python/__pycache__/RRDBNet_arch.cpython-39.pyc +0 -0
  38. model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/python/demo_qnn.py +115 -0
  39. model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/README.md +57 -0
  40. model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/cpp/CMakeLists.txt +32 -0
  41. model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/cpp/baboon.png +0 -0
  42. model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/cpp/run_test.cpp +243 -0
  43. model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/models/m_RRDB_esrgan_x4_w8a16.qnn216.ctx.bin +3 -0
  44. model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/python/LR/baboon.png +0 -0
  45. model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/python/__pycache__/RRDBNet_arch.cpython-38.pyc +0 -0
  46. model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/python/__pycache__/RRDBNet_arch.cpython-39.pyc +0 -0
  47. model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/python/demo_qnn.py +115 -0
model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/README.md ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Model Information
2
+
3
+ ### Source model
4
+
5
+ - Input shape: 128x128
6
+ - Number of parameters: 16.69M
7
+ - Model size: 63.8MB
8
+ - Output shape: 1x3x512x512
9
+
10
+ Source model repository: [ESRGAN](https://github.com/xinntao/ESRGAN/)
11
+
12
+ ### Converted Model
13
+
14
+ - Precision: W8A16
15
+ - Backend: QNN2.16
16
+ - Target Device: FV01 QCS6490
17
+
18
+ ## Inference with AidLite SDK
19
+
20
+ ### SDK installation
21
+ 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/)
22
+
23
+ - install AidLite SDK
24
+
25
+ ```bash
26
+ # Install the appropriate version of the aidlite sdk
27
+ sudo aid-pkg update
28
+ sudo aid-pkg install aidlite-sdk
29
+ # Download the qnn version that matches the above backend. Eg Install QNN2.23 Aidlite: sudo aid-pkg install aidlite-qnn223
30
+ sudo aid-pkg install aidlite-{QNN VERSION}
31
+ ```
32
+
33
+ - Verify AidLite SDK
34
+
35
+ ```bash
36
+ # aidlite sdk c++ check
37
+ python3 -c "import aidlite ; print(aidlite.get_library_version())"
38
+
39
+ # aidlite sdk python check
40
+ python3 -c "import aidlite ; print(aidlite.get_py_library_version())"
41
+ ```
42
+
43
+ ### Run demo
44
+ #### python
45
+ ```bash
46
+ cd python
47
+ python3 demo_qnn.py
48
+ ```
49
+
50
+ #### c++
51
+ ```bash
52
+ cd esrgan/model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/cpp
53
+ mkdir build && cd build
54
+ cmake ..
55
+ make
56
+ ./run_test
57
+ ```
model_farm_esrgan_qcs6490_qnn2.16_int16_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_esrgan_qcs6490_qnn2.16_int16_aidlite/cpp/baboon.png ADDED
model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/cpp/run_test.cpp ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
15
+ struct Args {
16
+ std::string target_model = "../../models/m_RRDB_esrgan_x4_w8a16.qnn216.ctx.bin";
17
+ std::string imgs = "../baboon.png";
18
+ int invoke_nums = 10;
19
+ std::string model_type = "QNN";
20
+ };
21
+
22
+
23
+ Args parse_args(int argc, char* argv[]) {
24
+ Args args;
25
+ for (int i = 1; i < argc; ++i) {
26
+ std::string arg = argv[i];
27
+ if (arg == "--target_model" && i + 1 < argc) {
28
+ args.target_model = argv[++i];
29
+ } else if (arg == "--imgs" && i + 1 < argc) {
30
+ args.imgs = argv[++i];
31
+ } else if (arg == "--invoke_nums" && i + 1 < argc) {
32
+ args.invoke_nums = std::stoi(argv[++i]);
33
+ } else if (arg == "--model_type" && i + 1 < argc) {
34
+ args.model_type = argv[++i];
35
+ }
36
+ }
37
+ return args;
38
+ }
39
+
40
+ std::string to_lower(const std::string& str) {
41
+ std::string lower_str = str;
42
+ std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(), [](unsigned char c) {
43
+ return std::tolower(c);
44
+ });
45
+ return lower_str;
46
+ }
47
+
48
+ int transpose(float* src, unsigned int* src_dims, unsigned int* tsp_dims, float* dest){
49
+
50
+ int current_coordinate[4] = {0, 0, 0, 0};
51
+ for(int a = 0; a < src_dims[0]; ++a){
52
+ current_coordinate[0] = a;
53
+ for(int b = 0; b < src_dims[1]; ++b){
54
+ current_coordinate[1] = b;
55
+ for(int c = 0; c < src_dims[2]; ++c){
56
+ current_coordinate[2] = c;
57
+ for(int d = 0; d < src_dims[3]; ++d){
58
+ current_coordinate[3] = d;
59
+
60
+ int old_index = current_coordinate[0]*src_dims[1]*src_dims[2]*src_dims[3] +
61
+ current_coordinate[1]*src_dims[2]*src_dims[3] +
62
+ current_coordinate[2]*src_dims[3] +
63
+ current_coordinate[3];
64
+
65
+ int new_index = current_coordinate[tsp_dims[0]]*src_dims[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
66
+ current_coordinate[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
67
+ current_coordinate[tsp_dims[2]]*src_dims[tsp_dims[3]] +
68
+ current_coordinate[tsp_dims[3]];
69
+
70
+ dest[new_index] = src[old_index];
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ return EXIT_SUCCESS;
77
+ }
78
+
79
+
80
+ void save_output_image_from_nhwc(float* output) {
81
+ unsigned int H = 512;
82
+ unsigned int W = 512;
83
+ unsigned int C = 3;
84
+ // Step 1: clip [0,1]
85
+ std::vector<float> clipped(H * W * C);
86
+ for (int i = 0; i < H * W * C; ++i) {
87
+ clipped[i] = std::min(1.0f, std::max(0.0f, output[i]));
88
+ }
89
+
90
+ // Step 2: NHWC (H,W,C) to CHW (C,H,W)
91
+ unsigned int src_dims1[4] = {H, W, C, 1};
92
+ unsigned int tsp_dims1[4] = {2, 0, 1, 3};
93
+ std::vector<float> chw(C * H * W);
94
+ transpose(clipped.data(), src_dims1, tsp_dims1, chw.data());
95
+
96
+ // Step 3: RGB to BGR
97
+ std::vector<float> chw_bgr(C * H * W);
98
+ for (int h = 0; h < H; ++h) {
99
+ for (int w = 0; w < W; ++w) {
100
+ for (int c = 0; c < C; ++c) {
101
+ int src_index = c * H * W + h * W + w;
102
+ int dst_c = 2 - c;
103
+ int dst_index = dst_c * H * W + h * W + w;
104
+ chw_bgr[dst_index] = chw[src_index];
105
+ }
106
+ }
107
+ }
108
+
109
+ // Step 4: CHW to HWC
110
+ unsigned int src_dims2[4] = {C, H, W, 1};
111
+ unsigned int tsp_dims2[4] = {1, 2, 0, 3};
112
+ std::vector<float> hwc(H * W * C);
113
+ transpose(chw_bgr.data(), src_dims2, tsp_dims2, hwc.data());
114
+
115
+ // Step 5: Convert to CV_8UC3 image
116
+ cv::Mat result(H, W, CV_8UC3);
117
+ for (int y = 0; y < H; ++y) {
118
+ for (int x = 0; x < W; ++x) {
119
+ int idx = (y * W + x) * C;
120
+ uchar b = static_cast<uchar>(std::round(hwc[idx + 0] * 255.0f));
121
+ uchar g = static_cast<uchar>(std::round(hwc[idx + 1] * 255.0f));
122
+ uchar r = static_cast<uchar>(std::round(hwc[idx + 2] * 255.0f));
123
+ result.at<cv::Vec3b>(y, x) = cv::Vec3b(b, g, r);
124
+ }
125
+ }
126
+
127
+ // Save the image
128
+ cv::imwrite("./result_img.jpg", result);
129
+ }
130
+
131
+
132
+ int invoke(const Args& args) {
133
+ std::cout << "Start main ... ... Model Path: " << args.target_model << "\n"
134
+ << "Image Path: " << args.imgs << "\n"
135
+ << "Inference Nums: " << args.invoke_nums << "\n"
136
+ << "Model Type: " << args.model_type << "\n";
137
+ Model* model = Model::create_instance(args.target_model);
138
+ if(model == nullptr){
139
+ printf("Create model failed !\n");
140
+ return EXIT_FAILURE;
141
+ }
142
+ Config* config = Config::create_instance();
143
+ if(config == nullptr){
144
+ printf("Create config failed !\n");
145
+ return EXIT_FAILURE;
146
+ }
147
+ config->implement_type = ImplementType::TYPE_LOCAL;
148
+ std::string model_type_lower = to_lower(args.model_type);
149
+ if (model_type_lower == "qnn"){
150
+ config->framework_type = FrameworkType::TYPE_QNN;
151
+ } else if (model_type_lower == "snpe2" || model_type_lower == "snpe") {
152
+ config->framework_type = FrameworkType::TYPE_SNPE2;
153
+ }
154
+ config->accelerate_type = AccelerateType::TYPE_DSP;
155
+ config->is_quantify_model = 1;
156
+
157
+ unsigned int model_h = 128;
158
+ unsigned int model_w = 128;
159
+ std::vector<std::vector<uint32_t>> input_shapes = {{1,model_h,model_w,3}};
160
+ std::vector<std::vector<uint32_t>> output_shapes = {{1,3,model_h*4,model_w*4}};
161
+ model->set_model_properties(input_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32, output_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32);
162
+ std::unique_ptr<Interpreter> fast_interpreter = InterpreterBuilder::build_interpretper_from_model_and_config(model, config);
163
+ if(fast_interpreter == nullptr){
164
+ printf("build_interpretper_from_model_and_config failed !\n");
165
+ return EXIT_FAILURE;
166
+ }
167
+ int result = fast_interpreter->init();
168
+ if(result != EXIT_SUCCESS){
169
+ printf("interpreter->init() failed !\n");
170
+ return EXIT_FAILURE;
171
+ }
172
+ // load model
173
+ fast_interpreter->load_model();
174
+ if(result != EXIT_SUCCESS){
175
+ printf("interpreter->load_model() failed !\n");
176
+ return EXIT_FAILURE;
177
+ }
178
+ printf("detect model load success!\n");
179
+
180
+ cv::Mat frame = cv::imread(args.imgs);
181
+ if (frame.empty()) {
182
+ printf("detect image load failed!\n");
183
+ return 1;
184
+ }
185
+ printf("img_src cols: %d, img_src rows: %d\n", frame.cols, frame.rows);
186
+ cv::Mat input_data;
187
+ cv::Mat frame_clone = frame.clone();
188
+ cv::cvtColor(frame_clone, frame_clone, cv::COLOR_BGR2RGB);
189
+ cv::resize(frame_clone, frame_clone, cv::Size(model_w, model_h));
190
+ frame_clone.convertTo(input_data, CV_32FC3, 1.0 / 255.0);
191
+
192
+ float *outdata0 = nullptr;
193
+ std::vector<float> invoke_time;
194
+ for (int i = 0; i < args.invoke_nums; ++i) {
195
+ result = fast_interpreter->set_input_tensor(0, input_data.data);
196
+ if(result != EXIT_SUCCESS){
197
+ printf("interpreter->set_input_tensor() failed !\n");
198
+ return EXIT_FAILURE;
199
+ }
200
+ auto t1 = std::chrono::high_resolution_clock::now();
201
+ result = fast_interpreter->invoke();
202
+ auto t2 = std::chrono::high_resolution_clock::now();
203
+ std::chrono::duration<double> cost_time = t2 - t1;
204
+ invoke_time.push_back(cost_time.count() * 1000);
205
+ if(result != EXIT_SUCCESS){
206
+ printf("interpreter->invoke() failed !\n");
207
+ return EXIT_FAILURE;
208
+ }
209
+ uint32_t out_data_0 = 0;
210
+ result = fast_interpreter->get_output_tensor(0, (void**)&outdata0, &out_data_0);
211
+ if(result != EXIT_SUCCESS){
212
+ printf("interpreter->get_output_tensor() 1 failed !\n");
213
+ return EXIT_FAILURE;
214
+ }
215
+
216
+ }
217
+
218
+ float max_invoke_time = *std::max_element(invoke_time.begin(), invoke_time.end());
219
+ float min_invoke_time = *std::min_element(invoke_time.begin(), invoke_time.end());
220
+ float mean_invoke_time = std::accumulate(invoke_time.begin(), invoke_time.end(), 0.0f) / args.invoke_nums;
221
+ float var_invoketime = 0.0f;
222
+ for (auto time : invoke_time) {
223
+ var_invoketime += (time - mean_invoke_time) * (time - mean_invoke_time);
224
+ }
225
+ var_invoketime /= args.invoke_nums;
226
+ printf("=======================================\n");
227
+ 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",
228
+ args.invoke_nums, mean_invoke_time, max_invoke_time, min_invoke_time, var_invoketime);
229
+ printf("=======================================\n");
230
+
231
+ // post process
232
+ save_output_image_from_nhwc(outdata0);
233
+
234
+
235
+ fast_interpreter->destory();
236
+ return 0;
237
+ }
238
+
239
+
240
+ int main(int argc, char* argv[]) {
241
+ Args args = parse_args(argc, argv);
242
+ return invoke(args);
243
+ }
model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/models/RRDB_ESRGAN_x4.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:65fece06e1ccb48853242aa972bdf00ad07a7dd8938d2dcbdf4221b59f6372ce
3
+ size 66929193
model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/models/m_RRDB_esrgan_x4.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:018ab32fd56641b382fa572180f0679cebbaef868885d2a1e626ee5a4453f542
3
+ size 67935783
model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/models/m_RRDB_esrgan_x4_w8a16.qnn216.ctx.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e254667574187295e925096f5c6386ef638cf5e79207329f83edbe44f485bdcd
3
+ size 25100616
model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/python/LR/baboon.png ADDED
model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/python/__pycache__/RRDBNet_arch.cpython-38.pyc ADDED
Binary file (3.2 kB). View file
 
model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/python/__pycache__/RRDBNet_arch.cpython-39.pyc ADDED
Binary file (3.22 kB). View file
 
model_farm_esrgan_qcs6490_qnn2.16_int16_aidlite/python/demo_qnn.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os.path as osp
2
+ import glob
3
+ import cv2
4
+ import numpy as np
5
+ # import torch
6
+ import time
7
+ import aidlite
8
+ import os
9
+
10
+ class esrganQnn:
11
+ def __init__(self):
12
+ super().__init__()
13
+ self.model = aidlite.Model.create_instance(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../models/m_RRDB_esrgan_x4_w8a16.qnn216.ctx.bin"))
14
+ if self.model is None:
15
+ print("Create model failed !")
16
+ return
17
+
18
+ self.config = aidlite.Config.create_instance()
19
+ if self.config is None:
20
+ print("build_interpretper_from_model_and_config failed !")
21
+ return
22
+
23
+ self.config.implement_type = aidlite.ImplementType.TYPE_LOCAL
24
+ self.config.framework_type = aidlite.FrameworkType.TYPE_QNN
25
+
26
+ self.config.accelerate_type = aidlite.AccelerateType.TYPE_DSP
27
+ self.config.is_quantify_model = 1
28
+
29
+ self.interpreter = aidlite.InterpreterBuilder.build_interpretper_from_model_and_config(self.model, self.config)
30
+ if self.interpreter is None:
31
+ print("build_interpretper_from_model_and_config failed !")
32
+ return
33
+ input_shapes = [[1, 128, 128,3]]
34
+ # input_shapes = [[1,3, 128, 128]]
35
+ output_shapes = [[1, 3,128*4,128*4]]
36
+ self.model.set_model_properties(input_shapes, aidlite.DataType.TYPE_FLOAT32,
37
+ output_shapes, aidlite.DataType.TYPE_FLOAT32)
38
+
39
+ if self.interpreter is None:
40
+ print("build_interpretper_from_model_and_config failed !")
41
+ result = self.interpreter.init()
42
+ if result != 0:
43
+ print(f"interpreter init failed !")
44
+ result = self.interpreter.load_model()
45
+ if result != 0:
46
+ print("interpreter load model failed !")
47
+
48
+ print(" model load success!")
49
+
50
+ def __call__(self, input):
51
+ self.interpreter.set_input_tensor(0,input)
52
+ self.interpreter.invoke()
53
+ features_0 = self.interpreter.get_output_tensor(0).reshape(1, 128*4,128*4,3).copy()
54
+
55
+ return features_0
56
+
57
+
58
+ esrgan_model= esrganQnn()
59
+
60
+ test_img_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)),'LR/*')
61
+
62
+ idx = 0
63
+ for path in glob.glob(test_img_folder):
64
+ idx += 1
65
+ base = osp.splitext(osp.basename(path))[0]
66
+ print(idx, base)
67
+ # read images
68
+ img = cv2.imread(path, cv2.IMREAD_COLOR)
69
+ img = cv2.resize(img, (128,128))
70
+ img = img * 1.0 / 255
71
+ img = img[:, :, [2, 1, 0]]
72
+ img_LR = np.expand_dims(img,axis=0).astype(np.float32)
73
+
74
+ t0 = time.time()
75
+ output = esrgan_model(img_LR) #.data.squeeze().float().cpu().clamp_(0, 1).numpy()
76
+ output = np.clip(output[0], 0, 1)
77
+ output = np.transpose(output, (2, 0, 1))
78
+ use_time = round((time.time() - t0) * 1000, 2)
79
+ print(f"Inference_time:{use_time} ms")
80
+ output = np.transpose(output[[2, 1, 0], :, :], (1, 2, 0))
81
+ output = (output * 255.0).round()
82
+ cv2.imwrite(os.path.join(os.path.dirname(os.path.abspath(__file__)),'results/{:s}_rlt_16qnn.png'.format(base)), output)
83
+ print("ok")
84
+ esrgan_model.interpreter.destory()
model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/README.md ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Model Information
2
+
3
+ ### Source model
4
+
5
+ - Input shape: 128x128
6
+ - Number of parameters: 16.69M
7
+ - Model size: 63.8MB
8
+ - Output shape: 1x3x512x512
9
+
10
+ Source model repository: [ESRGAN](https://github.com/xinntao/ESRGAN/)
11
+
12
+ ### Converted Model
13
+
14
+ - Precision: INT8
15
+ - Backend: QNN2.16
16
+ - Target Device: FV01 QCS6490
17
+
18
+ ## Inference with AidLite SDK
19
+
20
+ ### SDK installation
21
+ 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/)
22
+
23
+ - install AidLite SDK
24
+
25
+ ```bash
26
+ # Install the appropriate version of the aidlite sdk
27
+ sudo aid-pkg update
28
+ sudo aid-pkg install aidlite-sdk
29
+ # Download the qnn version that matches the above backend. Eg Install QNN2.23 Aidlite: sudo aid-pkg install aidlite-qnn223
30
+ sudo aid-pkg install aidlite-{QNN VERSION}
31
+ ```
32
+
33
+ - Verify AidLite SDK
34
+
35
+ ```bash
36
+ # aidlite sdk c++ check
37
+ python3 -c "import aidlite ; print(aidlite.get_library_version())"
38
+
39
+ # aidlite sdk python check
40
+ python3 -c "import aidlite ; print(aidlite.get_py_library_version())"
41
+ ```
42
+
43
+ ### Run demo
44
+ ```bash
45
+ cd python
46
+ python3 demo_qnn.py
47
+ ```
model_farm_esrgan_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_esrgan_qcs6490_qnn2.16_int8_aidlite/cpp/baboon.png ADDED
model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/cpp/run_test.cpp ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
15
+ struct Args {
16
+ std::string target_model = "../../models/m_RRDB_esrgan_x4_w8a8.qnn216.ctx.bin";
17
+ std::string imgs = "../baboon.png";
18
+ int invoke_nums = 10;
19
+ std::string model_type = "QNN";
20
+ };
21
+
22
+
23
+ Args parse_args(int argc, char* argv[]) {
24
+ Args args;
25
+ for (int i = 1; i < argc; ++i) {
26
+ std::string arg = argv[i];
27
+ if (arg == "--target_model" && i + 1 < argc) {
28
+ args.target_model = argv[++i];
29
+ } else if (arg == "--imgs" && i + 1 < argc) {
30
+ args.imgs = argv[++i];
31
+ } else if (arg == "--invoke_nums" && i + 1 < argc) {
32
+ args.invoke_nums = std::stoi(argv[++i]);
33
+ } else if (arg == "--model_type" && i + 1 < argc) {
34
+ args.model_type = argv[++i];
35
+ }
36
+ }
37
+ return args;
38
+ }
39
+
40
+ std::string to_lower(const std::string& str) {
41
+ std::string lower_str = str;
42
+ std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(), [](unsigned char c) {
43
+ return std::tolower(c);
44
+ });
45
+ return lower_str;
46
+ }
47
+
48
+ int transpose(float* src, unsigned int* src_dims, unsigned int* tsp_dims, float* dest){
49
+
50
+ int current_coordinate[4] = {0, 0, 0, 0};
51
+ for(int a = 0; a < src_dims[0]; ++a){
52
+ current_coordinate[0] = a;
53
+ for(int b = 0; b < src_dims[1]; ++b){
54
+ current_coordinate[1] = b;
55
+ for(int c = 0; c < src_dims[2]; ++c){
56
+ current_coordinate[2] = c;
57
+ for(int d = 0; d < src_dims[3]; ++d){
58
+ current_coordinate[3] = d;
59
+
60
+ int old_index = current_coordinate[0]*src_dims[1]*src_dims[2]*src_dims[3] +
61
+ current_coordinate[1]*src_dims[2]*src_dims[3] +
62
+ current_coordinate[2]*src_dims[3] +
63
+ current_coordinate[3];
64
+
65
+ int new_index = current_coordinate[tsp_dims[0]]*src_dims[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
66
+ current_coordinate[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
67
+ current_coordinate[tsp_dims[2]]*src_dims[tsp_dims[3]] +
68
+ current_coordinate[tsp_dims[3]];
69
+
70
+ dest[new_index] = src[old_index];
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ return EXIT_SUCCESS;
77
+ }
78
+
79
+
80
+ void save_output_image_from_nhwc(float* output) {
81
+ unsigned int H = 512;
82
+ unsigned int W = 512;
83
+ unsigned int C = 3;
84
+ // Step 1: clip [0,1]
85
+ std::vector<float> clipped(H * W * C);
86
+ for (int i = 0; i < H * W * C; ++i) {
87
+ clipped[i] = std::min(1.0f, std::max(0.0f, output[i]));
88
+ }
89
+
90
+ // Step 2: NHWC (H,W,C) to CHW (C,H,W)
91
+ unsigned int src_dims1[4] = {H, W, C, 1};
92
+ unsigned int tsp_dims1[4] = {2, 0, 1, 3};
93
+ std::vector<float> chw(C * H * W);
94
+ transpose(clipped.data(), src_dims1, tsp_dims1, chw.data());
95
+
96
+ // Step 3: RGB to BGR
97
+ std::vector<float> chw_bgr(C * H * W);
98
+ for (int h = 0; h < H; ++h) {
99
+ for (int w = 0; w < W; ++w) {
100
+ for (int c = 0; c < C; ++c) {
101
+ int src_index = c * H * W + h * W + w;
102
+ int dst_c = 2 - c;
103
+ int dst_index = dst_c * H * W + h * W + w;
104
+ chw_bgr[dst_index] = chw[src_index];
105
+ }
106
+ }
107
+ }
108
+
109
+ // Step 4: CHW to HWC
110
+ unsigned int src_dims2[4] = {C, H, W, 1};
111
+ unsigned int tsp_dims2[4] = {1, 2, 0, 3};
112
+ std::vector<float> hwc(H * W * C);
113
+ transpose(chw_bgr.data(), src_dims2, tsp_dims2, hwc.data());
114
+
115
+ // Step 5: Convert to CV_8UC3 image
116
+ cv::Mat result(H, W, CV_8UC3);
117
+ for (int y = 0; y < H; ++y) {
118
+ for (int x = 0; x < W; ++x) {
119
+ int idx = (y * W + x) * C;
120
+ uchar b = static_cast<uchar>(std::round(hwc[idx + 0] * 255.0f));
121
+ uchar g = static_cast<uchar>(std::round(hwc[idx + 1] * 255.0f));
122
+ uchar r = static_cast<uchar>(std::round(hwc[idx + 2] * 255.0f));
123
+ result.at<cv::Vec3b>(y, x) = cv::Vec3b(b, g, r);
124
+ }
125
+ }
126
+
127
+ // Save the image
128
+ cv::imwrite("./result_img.jpg", result);
129
+ }
130
+
131
+
132
+ int invoke(const Args& args) {
133
+ std::cout << "Start main ... ... Model Path: " << args.target_model << "\n"
134
+ << "Image Path: " << args.imgs << "\n"
135
+ << "Inference Nums: " << args.invoke_nums << "\n"
136
+ << "Model Type: " << args.model_type << "\n";
137
+ Model* model = Model::create_instance(args.target_model);
138
+ if(model == nullptr){
139
+ printf("Create model failed !\n");
140
+ return EXIT_FAILURE;
141
+ }
142
+ Config* config = Config::create_instance();
143
+ if(config == nullptr){
144
+ printf("Create config failed !\n");
145
+ return EXIT_FAILURE;
146
+ }
147
+ config->implement_type = ImplementType::TYPE_LOCAL;
148
+ std::string model_type_lower = to_lower(args.model_type);
149
+ if (model_type_lower == "qnn"){
150
+ config->framework_type = FrameworkType::TYPE_QNN;
151
+ } else if (model_type_lower == "snpe2" || model_type_lower == "snpe") {
152
+ config->framework_type = FrameworkType::TYPE_SNPE2;
153
+ }
154
+ config->accelerate_type = AccelerateType::TYPE_DSP;
155
+ config->is_quantify_model = 1;
156
+
157
+ unsigned int model_h = 128;
158
+ unsigned int model_w = 128;
159
+ std::vector<std::vector<uint32_t>> input_shapes = {{1,model_h,model_w,3}};
160
+ std::vector<std::vector<uint32_t>> output_shapes = {{1,3,model_h*4,model_w*4}};
161
+ model->set_model_properties(input_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32, output_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32);
162
+ std::unique_ptr<Interpreter> fast_interpreter = InterpreterBuilder::build_interpretper_from_model_and_config(model, config);
163
+ if(fast_interpreter == nullptr){
164
+ printf("build_interpretper_from_model_and_config failed !\n");
165
+ return EXIT_FAILURE;
166
+ }
167
+ int result = fast_interpreter->init();
168
+ if(result != EXIT_SUCCESS){
169
+ printf("interpreter->init() failed !\n");
170
+ return EXIT_FAILURE;
171
+ }
172
+ // load model
173
+ fast_interpreter->load_model();
174
+ if(result != EXIT_SUCCESS){
175
+ printf("interpreter->load_model() failed !\n");
176
+ return EXIT_FAILURE;
177
+ }
178
+ printf("detect model load success!\n");
179
+
180
+ cv::Mat frame = cv::imread(args.imgs);
181
+ if (frame.empty()) {
182
+ printf("detect image load failed!\n");
183
+ return 1;
184
+ }
185
+ printf("img_src cols: %d, img_src rows: %d\n", frame.cols, frame.rows);
186
+ cv::Mat input_data;
187
+ cv::Mat frame_clone = frame.clone();
188
+ cv::cvtColor(frame_clone, frame_clone, cv::COLOR_BGR2RGB);
189
+ cv::resize(frame_clone, frame_clone, cv::Size(model_w, model_h));
190
+ frame_clone.convertTo(input_data, CV_32FC3, 1.0 / 255.0);
191
+
192
+ float *outdata0 = nullptr;
193
+ std::vector<float> invoke_time;
194
+ for (int i = 0; i < args.invoke_nums; ++i) {
195
+ result = fast_interpreter->set_input_tensor(0, input_data.data);
196
+ if(result != EXIT_SUCCESS){
197
+ printf("interpreter->set_input_tensor() failed !\n");
198
+ return EXIT_FAILURE;
199
+ }
200
+ auto t1 = std::chrono::high_resolution_clock::now();
201
+ result = fast_interpreter->invoke();
202
+ auto t2 = std::chrono::high_resolution_clock::now();
203
+ std::chrono::duration<double> cost_time = t2 - t1;
204
+ invoke_time.push_back(cost_time.count() * 1000);
205
+ if(result != EXIT_SUCCESS){
206
+ printf("interpreter->invoke() failed !\n");
207
+ return EXIT_FAILURE;
208
+ }
209
+ uint32_t out_data_0 = 0;
210
+ result = fast_interpreter->get_output_tensor(0, (void**)&outdata0, &out_data_0);
211
+ if(result != EXIT_SUCCESS){
212
+ printf("interpreter->get_output_tensor() 1 failed !\n");
213
+ return EXIT_FAILURE;
214
+ }
215
+
216
+ }
217
+
218
+ float max_invoke_time = *std::max_element(invoke_time.begin(), invoke_time.end());
219
+ float min_invoke_time = *std::min_element(invoke_time.begin(), invoke_time.end());
220
+ float mean_invoke_time = std::accumulate(invoke_time.begin(), invoke_time.end(), 0.0f) / args.invoke_nums;
221
+ float var_invoketime = 0.0f;
222
+ for (auto time : invoke_time) {
223
+ var_invoketime += (time - mean_invoke_time) * (time - mean_invoke_time);
224
+ }
225
+ var_invoketime /= args.invoke_nums;
226
+ printf("=======================================\n");
227
+ 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",
228
+ args.invoke_nums, mean_invoke_time, max_invoke_time, min_invoke_time, var_invoketime);
229
+ printf("=======================================\n");
230
+
231
+ // post process
232
+ save_output_image_from_nhwc(outdata0);
233
+
234
+
235
+ fast_interpreter->destory();
236
+ return 0;
237
+ }
238
+
239
+
240
+ int main(int argc, char* argv[]) {
241
+ Args args = parse_args(argc, argv);
242
+ return invoke(args);
243
+ }
model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/models/m_RRDB_esrgan_x4_w8a8.qnn216.ctx.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c6e06342bfa355de053db65b7563b4b6417b5cba6c45aa0a4f09b4e5d795a4e3
3
+ size 22131016
model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/python/LR/baboon.png ADDED
model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/python/__pycache__/RRDBNet_arch.cpython-38.pyc ADDED
Binary file (3.2 kB). View file
 
model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/python/__pycache__/RRDBNet_arch.cpython-39.pyc ADDED
Binary file (3.22 kB). View file
 
model_farm_esrgan_qcs6490_qnn2.16_int8_aidlite/python/demo_qnn.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os.path as osp
2
+ import glob
3
+ import cv2
4
+ import numpy as np
5
+ import torch
6
+ import time
7
+ import aidlite
8
+ import os
9
+
10
+ class esrganQnn:
11
+ def __init__(self):
12
+ super().__init__()
13
+ self.model = aidlite.Model.create_instance(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../models/m_RRDB_esrgan_x4_w8a8.qnn216.ctx.bin"))
14
+ if self.model is None:
15
+ print("Create model failed !")
16
+ return
17
+
18
+ self.config = aidlite.Config.create_instance()
19
+ if self.config is None:
20
+ print("build_interpretper_from_model_and_config failed !")
21
+ return
22
+
23
+ self.config.implement_type = aidlite.ImplementType.TYPE_LOCAL
24
+ self.config.framework_type = aidlite.FrameworkType.TYPE_QNN
25
+
26
+ self.config.accelerate_type = aidlite.AccelerateType.TYPE_DSP
27
+ self.config.is_quantify_model = 1
28
+
29
+ self.interpreter = aidlite.InterpreterBuilder.build_interpretper_from_model_and_config(self.model, self.config)
30
+ if self.interpreter is None:
31
+ print("build_interpretper_from_model_and_config failed !")
32
+ return
33
+ input_shapes = [[1, 128, 128,3]]
34
+ # input_shapes = [[1,3, 128, 128]]
35
+ output_shapes = [[1, 3,128*4,128*4]]
36
+ self.model.set_model_properties(input_shapes, aidlite.DataType.TYPE_FLOAT32,
37
+ output_shapes, aidlite.DataType.TYPE_FLOAT32)
38
+
39
+ if self.interpreter is None:
40
+ print("build_interpretper_from_model_and_config failed !")
41
+ result = self.interpreter.init()
42
+ if result != 0:
43
+ print(f"interpreter init failed !")
44
+ result = self.interpreter.load_model()
45
+ if result != 0:
46
+ print("interpreter load model failed !")
47
+
48
+ print(" model load success!")
49
+
50
+ def __call__(self, input):
51
+ self.interpreter.set_input_tensor(0,input)
52
+ invoke_time=[]
53
+ invoke_nums =10
54
+ for i in range(invoke_nums):
55
+ result = self.interpreter.set_input_tensor(0, input.data)
56
+ if result != 0:
57
+ print("interpreter set_input_tensor() failed")
58
+ t1=time.time()
59
+ result = self.interpreter.invoke()
60
+ cost_time = (time.time()-t1)*1000
61
+ invoke_time.append(cost_time)
62
+
63
+ max_invoke_time = max(invoke_time)
64
+ min_invoke_time = min(invoke_time)
65
+ mean_invoke_time = sum(invoke_time)/invoke_nums
66
+ var_invoketime=np.var(invoke_time)
67
+ print("====================================")
68
+ 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}")
69
+ print("====================================")
70
+ features_0 = self.interpreter.get_output_tensor(0).reshape(1, 128*4,128*4,3).copy()
71
+
72
+ return features_0
73
+
74
+
75
+ def cosine_similarity(v1, v2):
76
+ v1 = v1.flatten()
77
+ v2 = v2.flatten()
78
+ # 计算点积
79
+ dot_product = np.dot(v1, v2)
80
+ # 计算每个向量的模长
81
+ norm_v1 = np.linalg.norm(v1)
82
+ norm_v2 = np.linalg.norm(v2)
83
+ # 防止除以零错误
84
+ norm_product = np.maximum(norm_v1 * norm_v2, 1e-8)
85
+ # 计算余弦相似度
86
+ return dot_product / norm_product
87
+
88
+ esrgan_model= esrganQnn()
89
+ test_img_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)),'LR/*')
90
+
91
+ idx = 0
92
+ for path in glob.glob(test_img_folder):
93
+ idx += 1
94
+ base = osp.splitext(osp.basename(path))[0]
95
+ print(idx, base)
96
+ # read images
97
+ img = cv2.imread(path, cv2.IMREAD_COLOR)
98
+ img = cv2.resize(img, (128,128))
99
+ img = img * 1.0 / 255
100
+ img = img[:, :, [2, 1, 0]]
101
+ img_LR = np.expand_dims(img,axis=0).astype(np.float32)
102
+ print("img_LR shape:",img_LR.shape)
103
+
104
+ t0 = time.time()
105
+ output = esrgan_model(img_LR) #.data.squeeze().float().cpu().clamp_(0, 1).numpy()
106
+
107
+ output = np.clip(output[0], 0, 1)
108
+ output = np.transpose(output, (2, 0, 1))
109
+ use_time = round((time.time() - t0) * 1000, 2)
110
+ print(f"Inference_time:{use_time} ms")
111
+ output = np.transpose(output[[2, 1, 0], :, :], (1, 2, 0))
112
+ output = (output * 255.0).round()
113
+ cv2.imwrite(os.path.join(os.path.dirname(os.path.abspath(__file__)),'{:s}_rlt_16qnn.png'.format(base)), output)
114
+ print("ok")
115
+ esrgan_model.interpreter.destory()
model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/README.md ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Model Information
2
+
3
+ ### Source model
4
+
5
+ - Input shape: 128x128
6
+ - Number of parameters: 16.69M
7
+ - Model size: 63.8MB
8
+ - Output shape: 1x3x512x512
9
+
10
+ Source model repository: [ESRGAN](https://github.com/xinntao/ESRGAN/)
11
+
12
+ ### Converted Model
13
+
14
+ - Precision: FP16
15
+ - Backend: QNN2.16
16
+ - Target Device: SNM972 QCS8550
17
+
18
+ ## Inference with AidLite SDK
19
+
20
+ ### SDK installation
21
+ 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/)
22
+
23
+ - install AidLite SDK
24
+
25
+ ```bash
26
+ # Install the appropriate version of the aidlite sdk
27
+ sudo aid-pkg update
28
+ sudo aid-pkg install aidlite-sdk
29
+ # Download the qnn version that matches the above backend. Eg Install QNN2.23 Aidlite: sudo aid-pkg install aidlite-qnn223
30
+ sudo aid-pkg install aidlite-{QNN VERSION}
31
+ ```
32
+
33
+ - Verify AidLite SDK
34
+
35
+ ```bash
36
+ # aidlite sdk c++ check
37
+ python3 -c "import aidlite ; print(aidlite.get_library_version())"
38
+
39
+ # aidlite sdk python check
40
+ python3 -c "import aidlite ; print(aidlite.get_py_library_version())"
41
+ ```
42
+
43
+ ### Run demo
44
+ #### python
45
+ ```bash
46
+ cd python
47
+ python3 demo_qnn.py
48
+ ```
49
+
50
+ #### c++
51
+ ```bash
52
+ cd esrgan/model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/cpp
53
+ mkdir build && cd build
54
+ cmake ..
55
+ make
56
+ ./run_test
57
+ ```
model_farm_esrgan_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_esrgan_qcs8550_qnn2.16_fp16_aidlite/cpp/baboon.png ADDED
model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/cpp/run_test.cpp ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
15
+ struct Args {
16
+ std::string target_model = "../../models/m_RRDB_esrgan_x4_fp16.qnn216.ctx.bin";
17
+ std::string imgs = "../baboon.png";
18
+ int invoke_nums = 10;
19
+ std::string model_type = "QNN";
20
+ };
21
+
22
+
23
+ Args parse_args(int argc, char* argv[]) {
24
+ Args args;
25
+ for (int i = 1; i < argc; ++i) {
26
+ std::string arg = argv[i];
27
+ if (arg == "--target_model" && i + 1 < argc) {
28
+ args.target_model = argv[++i];
29
+ } else if (arg == "--imgs" && i + 1 < argc) {
30
+ args.imgs = argv[++i];
31
+ } else if (arg == "--invoke_nums" && i + 1 < argc) {
32
+ args.invoke_nums = std::stoi(argv[++i]);
33
+ } else if (arg == "--model_type" && i + 1 < argc) {
34
+ args.model_type = argv[++i];
35
+ }
36
+ }
37
+ return args;
38
+ }
39
+
40
+ std::string to_lower(const std::string& str) {
41
+ std::string lower_str = str;
42
+ std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(), [](unsigned char c) {
43
+ return std::tolower(c);
44
+ });
45
+ return lower_str;
46
+ }
47
+
48
+ int transpose(float* src, unsigned int* src_dims, unsigned int* tsp_dims, float* dest){
49
+
50
+ int current_coordinate[4] = {0, 0, 0, 0};
51
+ for(int a = 0; a < src_dims[0]; ++a){
52
+ current_coordinate[0] = a;
53
+ for(int b = 0; b < src_dims[1]; ++b){
54
+ current_coordinate[1] = b;
55
+ for(int c = 0; c < src_dims[2]; ++c){
56
+ current_coordinate[2] = c;
57
+ for(int d = 0; d < src_dims[3]; ++d){
58
+ current_coordinate[3] = d;
59
+
60
+ int old_index = current_coordinate[0]*src_dims[1]*src_dims[2]*src_dims[3] +
61
+ current_coordinate[1]*src_dims[2]*src_dims[3] +
62
+ current_coordinate[2]*src_dims[3] +
63
+ current_coordinate[3];
64
+
65
+ int new_index = current_coordinate[tsp_dims[0]]*src_dims[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
66
+ current_coordinate[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
67
+ current_coordinate[tsp_dims[2]]*src_dims[tsp_dims[3]] +
68
+ current_coordinate[tsp_dims[3]];
69
+
70
+ dest[new_index] = src[old_index];
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ return EXIT_SUCCESS;
77
+ }
78
+
79
+
80
+ void save_output_image_from_nhwc(float* output) {
81
+ unsigned int H = 512;
82
+ unsigned int W = 512;
83
+ unsigned int C = 3;
84
+ // Step 1: clip [0,1]
85
+ std::vector<float> clipped(H * W * C);
86
+ for (int i = 0; i < H * W * C; ++i) {
87
+ clipped[i] = std::min(1.0f, std::max(0.0f, output[i]));
88
+ }
89
+
90
+ // Step 2: NHWC (H,W,C) to CHW (C,H,W)
91
+ unsigned int src_dims1[4] = {H, W, C, 1};
92
+ unsigned int tsp_dims1[4] = {2, 0, 1, 3};
93
+ std::vector<float> chw(C * H * W);
94
+ transpose(clipped.data(), src_dims1, tsp_dims1, chw.data());
95
+
96
+ // Step 3: RGB to BGR
97
+ std::vector<float> chw_bgr(C * H * W);
98
+ for (int h = 0; h < H; ++h) {
99
+ for (int w = 0; w < W; ++w) {
100
+ for (int c = 0; c < C; ++c) {
101
+ int src_index = c * H * W + h * W + w;
102
+ int dst_c = 2 - c;
103
+ int dst_index = dst_c * H * W + h * W + w;
104
+ chw_bgr[dst_index] = chw[src_index];
105
+ }
106
+ }
107
+ }
108
+
109
+ // Step 4: CHW to HWC
110
+ unsigned int src_dims2[4] = {C, H, W, 1};
111
+ unsigned int tsp_dims2[4] = {1, 2, 0, 3};
112
+ std::vector<float> hwc(H * W * C);
113
+ transpose(chw_bgr.data(), src_dims2, tsp_dims2, hwc.data());
114
+
115
+ // Step 5: Convert to CV_8UC3 image
116
+ cv::Mat result(H, W, CV_8UC3);
117
+ for (int y = 0; y < H; ++y) {
118
+ for (int x = 0; x < W; ++x) {
119
+ int idx = (y * W + x) * C;
120
+ uchar b = static_cast<uchar>(std::round(hwc[idx + 0] * 255.0f));
121
+ uchar g = static_cast<uchar>(std::round(hwc[idx + 1] * 255.0f));
122
+ uchar r = static_cast<uchar>(std::round(hwc[idx + 2] * 255.0f));
123
+ result.at<cv::Vec3b>(y, x) = cv::Vec3b(b, g, r);
124
+ }
125
+ }
126
+
127
+ // Save the image
128
+ cv::imwrite("./result_img.jpg", result);
129
+ }
130
+
131
+
132
+ int invoke(const Args& args) {
133
+ std::cout << "Start main ... ... Model Path: " << args.target_model << "\n"
134
+ << "Image Path: " << args.imgs << "\n"
135
+ << "Inference Nums: " << args.invoke_nums << "\n"
136
+ << "Model Type: " << args.model_type << "\n";
137
+ Model* model = Model::create_instance(args.target_model);
138
+ if(model == nullptr){
139
+ printf("Create model failed !\n");
140
+ return EXIT_FAILURE;
141
+ }
142
+ Config* config = Config::create_instance();
143
+ if(config == nullptr){
144
+ printf("Create config failed !\n");
145
+ return EXIT_FAILURE;
146
+ }
147
+ config->implement_type = ImplementType::TYPE_LOCAL;
148
+ std::string model_type_lower = to_lower(args.model_type);
149
+ if (model_type_lower == "qnn"){
150
+ config->framework_type = FrameworkType::TYPE_QNN;
151
+ } else if (model_type_lower == "snpe2" || model_type_lower == "snpe") {
152
+ config->framework_type = FrameworkType::TYPE_SNPE2;
153
+ }
154
+ config->accelerate_type = AccelerateType::TYPE_DSP;
155
+ config->is_quantify_model = 1;
156
+
157
+ unsigned int model_h = 128;
158
+ unsigned int model_w = 128;
159
+ std::vector<std::vector<uint32_t>> input_shapes = {{1,model_h,model_w,3}};
160
+ std::vector<std::vector<uint32_t>> output_shapes = {{1,3,model_h*4,model_w*4}};
161
+ model->set_model_properties(input_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32, output_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32);
162
+ std::unique_ptr<Interpreter> fast_interpreter = InterpreterBuilder::build_interpretper_from_model_and_config(model, config);
163
+ if(fast_interpreter == nullptr){
164
+ printf("build_interpretper_from_model_and_config failed !\n");
165
+ return EXIT_FAILURE;
166
+ }
167
+ int result = fast_interpreter->init();
168
+ if(result != EXIT_SUCCESS){
169
+ printf("interpreter->init() failed !\n");
170
+ return EXIT_FAILURE;
171
+ }
172
+ // load model
173
+ fast_interpreter->load_model();
174
+ if(result != EXIT_SUCCESS){
175
+ printf("interpreter->load_model() failed !\n");
176
+ return EXIT_FAILURE;
177
+ }
178
+ printf("detect model load success!\n");
179
+
180
+ cv::Mat frame = cv::imread(args.imgs);
181
+ if (frame.empty()) {
182
+ printf("detect image load failed!\n");
183
+ return 1;
184
+ }
185
+ printf("img_src cols: %d, img_src rows: %d\n", frame.cols, frame.rows);
186
+ cv::Mat input_data;
187
+ cv::Mat frame_clone = frame.clone();
188
+ cv::cvtColor(frame_clone, frame_clone, cv::COLOR_BGR2RGB);
189
+ cv::resize(frame_clone, frame_clone, cv::Size(model_w, model_h));
190
+ frame_clone.convertTo(input_data, CV_32FC3, 1.0 / 255.0);
191
+
192
+ float *outdata0 = nullptr;
193
+ std::vector<float> invoke_time;
194
+ for (int i = 0; i < args.invoke_nums; ++i) {
195
+ result = fast_interpreter->set_input_tensor(0, input_data.data);
196
+ if(result != EXIT_SUCCESS){
197
+ printf("interpreter->set_input_tensor() failed !\n");
198
+ return EXIT_FAILURE;
199
+ }
200
+ auto t1 = std::chrono::high_resolution_clock::now();
201
+ result = fast_interpreter->invoke();
202
+ auto t2 = std::chrono::high_resolution_clock::now();
203
+ std::chrono::duration<double> cost_time = t2 - t1;
204
+ invoke_time.push_back(cost_time.count() * 1000);
205
+ if(result != EXIT_SUCCESS){
206
+ printf("interpreter->invoke() failed !\n");
207
+ return EXIT_FAILURE;
208
+ }
209
+ uint32_t out_data_0 = 0;
210
+ result = fast_interpreter->get_output_tensor(0, (void**)&outdata0, &out_data_0);
211
+ if(result != EXIT_SUCCESS){
212
+ printf("interpreter->get_output_tensor() 1 failed !\n");
213
+ return EXIT_FAILURE;
214
+ }
215
+
216
+ }
217
+
218
+ float max_invoke_time = *std::max_element(invoke_time.begin(), invoke_time.end());
219
+ float min_invoke_time = *std::min_element(invoke_time.begin(), invoke_time.end());
220
+ float mean_invoke_time = std::accumulate(invoke_time.begin(), invoke_time.end(), 0.0f) / args.invoke_nums;
221
+ float var_invoketime = 0.0f;
222
+ for (auto time : invoke_time) {
223
+ var_invoketime += (time - mean_invoke_time) * (time - mean_invoke_time);
224
+ }
225
+ var_invoketime /= args.invoke_nums;
226
+ printf("=======================================\n");
227
+ 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",
228
+ args.invoke_nums, mean_invoke_time, max_invoke_time, min_invoke_time, var_invoketime);
229
+ printf("=======================================\n");
230
+
231
+ // post process
232
+ save_output_image_from_nhwc(outdata0);
233
+
234
+
235
+ fast_interpreter->destory();
236
+ return 0;
237
+ }
238
+
239
+
240
+ int main(int argc, char* argv[]) {
241
+ Args args = parse_args(argc, argv);
242
+ return invoke(args);
243
+ }
model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/models/m_RRDB_esrgan_x4_fp16.qnn216.ctx.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bc96c372fa7389448b8a06b9ce4d39d52f764d4017fbe44751dbf4f8b67a2205
3
+ size 38752576
model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/python/LR/baboon.png ADDED
model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/python/__pycache__/RRDBNet_arch.cpython-38.pyc ADDED
Binary file (3.2 kB). View file
 
model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/python/__pycache__/RRDBNet_arch.cpython-39.pyc ADDED
Binary file (3.22 kB). View file
 
model_farm_esrgan_qcs8550_qnn2.16_fp16_aidlite/python/demo_qnn.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os.path as osp
2
+ import glob
3
+ import cv2
4
+ import numpy as np
5
+ import torch
6
+ import time
7
+ import aidlite
8
+ import os
9
+
10
+ class esrganQnn:
11
+ def __init__(self):
12
+ super().__init__()
13
+ self.model = aidlite.Model.create_instance(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../models/m_RRDB_esrgan_x4_fp16.qnn216.ctx.bin"))
14
+ if self.model is None:
15
+ print("Create model failed !")
16
+ return
17
+
18
+ self.config = aidlite.Config.create_instance()
19
+ if self.config is None:
20
+ print("build_interpretper_from_model_and_config failed !")
21
+ return
22
+
23
+ self.config.implement_type = aidlite.ImplementType.TYPE_LOCAL
24
+ self.config.framework_type = aidlite.FrameworkType.TYPE_QNN
25
+
26
+ self.config.accelerate_type = aidlite.AccelerateType.TYPE_DSP
27
+ self.config.is_quantify_model = 1
28
+
29
+ self.interpreter = aidlite.InterpreterBuilder.build_interpretper_from_model_and_config(self.model, self.config)
30
+ if self.interpreter is None:
31
+ print("build_interpretper_from_model_and_config failed !")
32
+ return
33
+ input_shapes = [[1, 128, 128,3]]
34
+ # input_shapes = [[1,3, 128, 128]]
35
+ output_shapes = [[1, 3,128*4,128*4]]
36
+ self.model.set_model_properties(input_shapes, aidlite.DataType.TYPE_FLOAT32,
37
+ output_shapes, aidlite.DataType.TYPE_FLOAT32)
38
+
39
+ if self.interpreter is None:
40
+ print("build_interpretper_from_model_and_config failed !")
41
+ result = self.interpreter.init()
42
+ if result != 0:
43
+ print(f"interpreter init failed !")
44
+ result = self.interpreter.load_model()
45
+ if result != 0:
46
+ print("interpreter load model failed !")
47
+
48
+ print(" model load success!")
49
+
50
+ def __call__(self, input):
51
+ self.interpreter.set_input_tensor(0,input)
52
+ invoke_time=[]
53
+ invoke_nums =10
54
+ for i in range(invoke_nums):
55
+ result = self.interpreter.set_input_tensor(0, input.data)
56
+ if result != 0:
57
+ print("interpreter set_input_tensor() failed")
58
+ t1=time.time()
59
+ result = self.interpreter.invoke()
60
+ cost_time = (time.time()-t1)*1000
61
+ invoke_time.append(cost_time)
62
+
63
+ max_invoke_time = max(invoke_time)
64
+ min_invoke_time = min(invoke_time)
65
+ mean_invoke_time = sum(invoke_time)/invoke_nums
66
+ var_invoketime=np.var(invoke_time)
67
+ print("====================================")
68
+ 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}")
69
+ print("====================================")
70
+ features_0 = self.interpreter.get_output_tensor(0).reshape(1, 128*4,128*4,3).copy()
71
+
72
+ return features_0
73
+
74
+
75
+ def cosine_similarity(v1, v2):
76
+ v1 = v1.flatten()
77
+ v2 = v2.flatten()
78
+ # 计算点积
79
+ dot_product = np.dot(v1, v2)
80
+ # 计算每个向量的模长
81
+ norm_v1 = np.linalg.norm(v1)
82
+ norm_v2 = np.linalg.norm(v2)
83
+ # 防止除以零错误
84
+ norm_product = np.maximum(norm_v1 * norm_v2, 1e-8)
85
+ # 计算余弦相似度
86
+ return dot_product / norm_product
87
+
88
+ esrgan_model= esrganQnn()
89
+ test_img_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)),'LR/*')
90
+
91
+ idx = 0
92
+ for path in glob.glob(test_img_folder):
93
+ idx += 1
94
+ base = osp.splitext(osp.basename(path))[0]
95
+ print(idx, base)
96
+ # read images
97
+ img = cv2.imread(path, cv2.IMREAD_COLOR)
98
+ img = cv2.resize(img, (128,128))
99
+ img = img * 1.0 / 255
100
+ img = img[:, :, [2, 1, 0]]
101
+ img_LR = np.expand_dims(img,axis=0).astype(np.float32)
102
+ print("img_LR shape:",img_LR.shape)
103
+
104
+ t0 = time.time()
105
+ output = esrgan_model(img_LR) #.data.squeeze().float().cpu().clamp_(0, 1).numpy()
106
+
107
+ output = np.clip(output[0], 0, 1)
108
+ output = np.transpose(output, (2, 0, 1))
109
+ use_time = round((time.time() - t0) * 1000, 2)
110
+ print(f"Inference_time:{use_time} ms")
111
+ output = np.transpose(output[[2, 1, 0], :, :], (1, 2, 0))
112
+ output = (output * 255.0).round()
113
+ cv2.imwrite(os.path.join(os.path.dirname(os.path.abspath(__file__)),'{:s}_rlt_16qnn.png'.format(base)), output)
114
+ print("ok")
115
+ esrgan_model.interpreter.destory()
model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/README.md ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Model Information
2
+
3
+ ### Source model
4
+
5
+ - Input shape: 128x128
6
+ - Number of parameters: 16.69M
7
+ - Model size: 63.8MB
8
+ - Output shape: 1x3x512x512
9
+
10
+ Source model repository: [ESRGAN](https://github.com/xinntao/ESRGAN/)
11
+
12
+ ### Converted Model
13
+
14
+ - Precision: INT8
15
+ - Backend: QNN2.16
16
+ - Target Device: SNM972 QCS8550
17
+
18
+ ## Inference with AidLite SDK
19
+
20
+ ### SDK installation
21
+ 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/)
22
+
23
+ - install AidLite SDK
24
+
25
+ ```bash
26
+ # Install the appropriate version of the aidlite sdk
27
+ sudo aid-pkg update
28
+ sudo aid-pkg install aidlite-sdk
29
+ # Download the qnn version that matches the above backend. Eg Install QNN2.23 Aidlite: sudo aid-pkg install aidlite-qnn223
30
+ sudo aid-pkg install aidlite-{QNN VERSION}
31
+ ```
32
+
33
+ - Verify AidLite SDK
34
+
35
+ ```bash
36
+ # aidlite sdk c++ check
37
+ python3 -c "import aidlite ; print(aidlite.get_library_version())"
38
+
39
+ # aidlite sdk python check
40
+ python3 -c "import aidlite ; print(aidlite.get_py_library_version())"
41
+ ```
42
+
43
+ ### Run demo
44
+ #### python
45
+ ```bash
46
+ cd python
47
+ python3 demo_qnn.py
48
+ ```
49
+
50
+ #### c++
51
+ ```bash
52
+ cd esrgan/model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/cpp
53
+ mkdir build && cd build
54
+ cmake ..
55
+ make
56
+ ./run_test
57
+ ```
model_farm_esrgan_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_esrgan_qcs8550_qnn2.16_int8_aidlite/cpp/baboon.png ADDED
model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/cpp/run_test.cpp ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
15
+ struct Args {
16
+ std::string target_model = "../../models/m_RRDB_esrgan_x4_w8a8.qnn216.ctx.bin";
17
+ std::string imgs = "../baboon.png";
18
+ int invoke_nums = 10;
19
+ std::string model_type = "QNN";
20
+ };
21
+
22
+
23
+ Args parse_args(int argc, char* argv[]) {
24
+ Args args;
25
+ for (int i = 1; i < argc; ++i) {
26
+ std::string arg = argv[i];
27
+ if (arg == "--target_model" && i + 1 < argc) {
28
+ args.target_model = argv[++i];
29
+ } else if (arg == "--imgs" && i + 1 < argc) {
30
+ args.imgs = argv[++i];
31
+ } else if (arg == "--invoke_nums" && i + 1 < argc) {
32
+ args.invoke_nums = std::stoi(argv[++i]);
33
+ } else if (arg == "--model_type" && i + 1 < argc) {
34
+ args.model_type = argv[++i];
35
+ }
36
+ }
37
+ return args;
38
+ }
39
+
40
+ std::string to_lower(const std::string& str) {
41
+ std::string lower_str = str;
42
+ std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(), [](unsigned char c) {
43
+ return std::tolower(c);
44
+ });
45
+ return lower_str;
46
+ }
47
+
48
+ int transpose(float* src, unsigned int* src_dims, unsigned int* tsp_dims, float* dest){
49
+
50
+ int current_coordinate[4] = {0, 0, 0, 0};
51
+ for(int a = 0; a < src_dims[0]; ++a){
52
+ current_coordinate[0] = a;
53
+ for(int b = 0; b < src_dims[1]; ++b){
54
+ current_coordinate[1] = b;
55
+ for(int c = 0; c < src_dims[2]; ++c){
56
+ current_coordinate[2] = c;
57
+ for(int d = 0; d < src_dims[3]; ++d){
58
+ current_coordinate[3] = d;
59
+
60
+ int old_index = current_coordinate[0]*src_dims[1]*src_dims[2]*src_dims[3] +
61
+ current_coordinate[1]*src_dims[2]*src_dims[3] +
62
+ current_coordinate[2]*src_dims[3] +
63
+ current_coordinate[3];
64
+
65
+ int new_index = current_coordinate[tsp_dims[0]]*src_dims[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
66
+ current_coordinate[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
67
+ current_coordinate[tsp_dims[2]]*src_dims[tsp_dims[3]] +
68
+ current_coordinate[tsp_dims[3]];
69
+
70
+ dest[new_index] = src[old_index];
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ return EXIT_SUCCESS;
77
+ }
78
+
79
+
80
+ void save_output_image_from_nhwc(float* output) {
81
+ unsigned int H = 512;
82
+ unsigned int W = 512;
83
+ unsigned int C = 3;
84
+ // Step 1: clip [0,1]
85
+ std::vector<float> clipped(H * W * C);
86
+ for (int i = 0; i < H * W * C; ++i) {
87
+ clipped[i] = std::min(1.0f, std::max(0.0f, output[i]));
88
+ }
89
+
90
+ // Step 2: NHWC (H,W,C) to CHW (C,H,W)
91
+ unsigned int src_dims1[4] = {H, W, C, 1};
92
+ unsigned int tsp_dims1[4] = {2, 0, 1, 3};
93
+ std::vector<float> chw(C * H * W);
94
+ transpose(clipped.data(), src_dims1, tsp_dims1, chw.data());
95
+
96
+ // Step 3: RGB to BGR
97
+ std::vector<float> chw_bgr(C * H * W);
98
+ for (int h = 0; h < H; ++h) {
99
+ for (int w = 0; w < W; ++w) {
100
+ for (int c = 0; c < C; ++c) {
101
+ int src_index = c * H * W + h * W + w;
102
+ int dst_c = 2 - c;
103
+ int dst_index = dst_c * H * W + h * W + w;
104
+ chw_bgr[dst_index] = chw[src_index];
105
+ }
106
+ }
107
+ }
108
+
109
+ // Step 4: CHW to HWC
110
+ unsigned int src_dims2[4] = {C, H, W, 1};
111
+ unsigned int tsp_dims2[4] = {1, 2, 0, 3};
112
+ std::vector<float> hwc(H * W * C);
113
+ transpose(chw_bgr.data(), src_dims2, tsp_dims2, hwc.data());
114
+
115
+ // Step 5: Convert to CV_8UC3 image
116
+ cv::Mat result(H, W, CV_8UC3);
117
+ for (int y = 0; y < H; ++y) {
118
+ for (int x = 0; x < W; ++x) {
119
+ int idx = (y * W + x) * C;
120
+ uchar b = static_cast<uchar>(std::round(hwc[idx + 0] * 255.0f));
121
+ uchar g = static_cast<uchar>(std::round(hwc[idx + 1] * 255.0f));
122
+ uchar r = static_cast<uchar>(std::round(hwc[idx + 2] * 255.0f));
123
+ result.at<cv::Vec3b>(y, x) = cv::Vec3b(b, g, r);
124
+ }
125
+ }
126
+
127
+ // Save the image
128
+ cv::imwrite("./result_img.jpg", result);
129
+ }
130
+
131
+
132
+ int invoke(const Args& args) {
133
+ std::cout << "Start main ... ... Model Path: " << args.target_model << "\n"
134
+ << "Image Path: " << args.imgs << "\n"
135
+ << "Inference Nums: " << args.invoke_nums << "\n"
136
+ << "Model Type: " << args.model_type << "\n";
137
+ Model* model = Model::create_instance(args.target_model);
138
+ if(model == nullptr){
139
+ printf("Create model failed !\n");
140
+ return EXIT_FAILURE;
141
+ }
142
+ Config* config = Config::create_instance();
143
+ if(config == nullptr){
144
+ printf("Create config failed !\n");
145
+ return EXIT_FAILURE;
146
+ }
147
+ config->implement_type = ImplementType::TYPE_LOCAL;
148
+ std::string model_type_lower = to_lower(args.model_type);
149
+ if (model_type_lower == "qnn"){
150
+ config->framework_type = FrameworkType::TYPE_QNN;
151
+ } else if (model_type_lower == "snpe2" || model_type_lower == "snpe") {
152
+ config->framework_type = FrameworkType::TYPE_SNPE2;
153
+ }
154
+ config->accelerate_type = AccelerateType::TYPE_DSP;
155
+ config->is_quantify_model = 1;
156
+
157
+ unsigned int model_h = 128;
158
+ unsigned int model_w = 128;
159
+ std::vector<std::vector<uint32_t>> input_shapes = {{1,model_h,model_w,3}};
160
+ std::vector<std::vector<uint32_t>> output_shapes = {{1,3,model_h*4,model_w*4}};
161
+ model->set_model_properties(input_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32, output_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32);
162
+ std::unique_ptr<Interpreter> fast_interpreter = InterpreterBuilder::build_interpretper_from_model_and_config(model, config);
163
+ if(fast_interpreter == nullptr){
164
+ printf("build_interpretper_from_model_and_config failed !\n");
165
+ return EXIT_FAILURE;
166
+ }
167
+ int result = fast_interpreter->init();
168
+ if(result != EXIT_SUCCESS){
169
+ printf("interpreter->init() failed !\n");
170
+ return EXIT_FAILURE;
171
+ }
172
+ // load model
173
+ fast_interpreter->load_model();
174
+ if(result != EXIT_SUCCESS){
175
+ printf("interpreter->load_model() failed !\n");
176
+ return EXIT_FAILURE;
177
+ }
178
+ printf("detect model load success!\n");
179
+
180
+ cv::Mat frame = cv::imread(args.imgs);
181
+ if (frame.empty()) {
182
+ printf("detect image load failed!\n");
183
+ return 1;
184
+ }
185
+ printf("img_src cols: %d, img_src rows: %d\n", frame.cols, frame.rows);
186
+ cv::Mat input_data;
187
+ cv::Mat frame_clone = frame.clone();
188
+ cv::cvtColor(frame_clone, frame_clone, cv::COLOR_BGR2RGB);
189
+ cv::resize(frame_clone, frame_clone, cv::Size(model_w, model_h));
190
+ frame_clone.convertTo(input_data, CV_32FC3, 1.0 / 255.0);
191
+
192
+ float *outdata0 = nullptr;
193
+ std::vector<float> invoke_time;
194
+ for (int i = 0; i < args.invoke_nums; ++i) {
195
+ result = fast_interpreter->set_input_tensor(0, input_data.data);
196
+ if(result != EXIT_SUCCESS){
197
+ printf("interpreter->set_input_tensor() failed !\n");
198
+ return EXIT_FAILURE;
199
+ }
200
+ auto t1 = std::chrono::high_resolution_clock::now();
201
+ result = fast_interpreter->invoke();
202
+ auto t2 = std::chrono::high_resolution_clock::now();
203
+ std::chrono::duration<double> cost_time = t2 - t1;
204
+ invoke_time.push_back(cost_time.count() * 1000);
205
+ if(result != EXIT_SUCCESS){
206
+ printf("interpreter->invoke() failed !\n");
207
+ return EXIT_FAILURE;
208
+ }
209
+ uint32_t out_data_0 = 0;
210
+ result = fast_interpreter->get_output_tensor(0, (void**)&outdata0, &out_data_0);
211
+ if(result != EXIT_SUCCESS){
212
+ printf("interpreter->get_output_tensor() 1 failed !\n");
213
+ return EXIT_FAILURE;
214
+ }
215
+
216
+ }
217
+
218
+ float max_invoke_time = *std::max_element(invoke_time.begin(), invoke_time.end());
219
+ float min_invoke_time = *std::min_element(invoke_time.begin(), invoke_time.end());
220
+ float mean_invoke_time = std::accumulate(invoke_time.begin(), invoke_time.end(), 0.0f) / args.invoke_nums;
221
+ float var_invoketime = 0.0f;
222
+ for (auto time : invoke_time) {
223
+ var_invoketime += (time - mean_invoke_time) * (time - mean_invoke_time);
224
+ }
225
+ var_invoketime /= args.invoke_nums;
226
+ printf("=======================================\n");
227
+ 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",
228
+ args.invoke_nums, mean_invoke_time, max_invoke_time, min_invoke_time, var_invoketime);
229
+ printf("=======================================\n");
230
+
231
+ // post process
232
+ save_output_image_from_nhwc(outdata0);
233
+
234
+
235
+ fast_interpreter->destory();
236
+ return 0;
237
+ }
238
+
239
+
240
+ int main(int argc, char* argv[]) {
241
+ Args args = parse_args(argc, argv);
242
+ return invoke(args);
243
+ }
model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/models/m_RRDB_esrgan_x4_w8a8.qnn216.ctx.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e8e3ecf6ce818649cbb568d1cc79452d222a43b049847e0e7fc9496033a6fa81
3
+ size 22618440
model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/python/LR/baboon.png ADDED
model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/python/__pycache__/RRDBNet_arch.cpython-38.pyc ADDED
Binary file (3.2 kB). View file
 
model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/python/__pycache__/RRDBNet_arch.cpython-39.pyc ADDED
Binary file (3.22 kB). View file
 
model_farm_esrgan_qcs8550_qnn2.16_int8_aidlite/python/demo_qnn.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os.path as osp
2
+ import glob
3
+ import cv2
4
+ import numpy as np
5
+ import torch
6
+ import time
7
+ import aidlite
8
+ import os
9
+
10
+ class esrganQnn:
11
+ def __init__(self):
12
+ super().__init__()
13
+ self.model = aidlite.Model.create_instance(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../models/m_RRDB_esrgan_x4_w8a8.qnn216.ctx.bin"))
14
+ if self.model is None:
15
+ print("Create model failed !")
16
+ return
17
+
18
+ self.config = aidlite.Config.create_instance()
19
+ if self.config is None:
20
+ print("build_interpretper_from_model_and_config failed !")
21
+ return
22
+
23
+ self.config.implement_type = aidlite.ImplementType.TYPE_LOCAL
24
+ self.config.framework_type = aidlite.FrameworkType.TYPE_QNN
25
+
26
+ self.config.accelerate_type = aidlite.AccelerateType.TYPE_DSP
27
+ self.config.is_quantify_model = 1
28
+
29
+ self.interpreter = aidlite.InterpreterBuilder.build_interpretper_from_model_and_config(self.model, self.config)
30
+ if self.interpreter is None:
31
+ print("build_interpretper_from_model_and_config failed !")
32
+ return
33
+ input_shapes = [[1, 128, 128,3]]
34
+ # input_shapes = [[1,3, 128, 128]]
35
+ output_shapes = [[1, 3,128*4,128*4]]
36
+ self.model.set_model_properties(input_shapes, aidlite.DataType.TYPE_FLOAT32,
37
+ output_shapes, aidlite.DataType.TYPE_FLOAT32)
38
+
39
+ if self.interpreter is None:
40
+ print("build_interpretper_from_model_and_config failed !")
41
+ result = self.interpreter.init()
42
+ if result != 0:
43
+ print(f"interpreter init failed !")
44
+ result = self.interpreter.load_model()
45
+ if result != 0:
46
+ print("interpreter load model failed !")
47
+
48
+ print(" model load success!")
49
+
50
+ def __call__(self, input):
51
+ self.interpreter.set_input_tensor(0,input)
52
+ invoke_time=[]
53
+ invoke_nums =10
54
+ for i in range(invoke_nums):
55
+ result = self.interpreter.set_input_tensor(0, input.data)
56
+ if result != 0:
57
+ print("interpreter set_input_tensor() failed")
58
+ t1=time.time()
59
+ result = self.interpreter.invoke()
60
+ cost_time = (time.time()-t1)*1000
61
+ invoke_time.append(cost_time)
62
+
63
+ max_invoke_time = max(invoke_time)
64
+ min_invoke_time = min(invoke_time)
65
+ mean_invoke_time = sum(invoke_time)/invoke_nums
66
+ var_invoketime=np.var(invoke_time)
67
+ print("====================================")
68
+ 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}")
69
+ print("====================================")
70
+ features_0 = self.interpreter.get_output_tensor(0).reshape(1, 128*4,128*4,3).copy()
71
+
72
+ return features_0
73
+
74
+
75
+ def cosine_similarity(v1, v2):
76
+ v1 = v1.flatten()
77
+ v2 = v2.flatten()
78
+ # 计算点积
79
+ dot_product = np.dot(v1, v2)
80
+ # 计算每个向量的模长
81
+ norm_v1 = np.linalg.norm(v1)
82
+ norm_v2 = np.linalg.norm(v2)
83
+ # 防止除以零错误
84
+ norm_product = np.maximum(norm_v1 * norm_v2, 1e-8)
85
+ # 计算余弦相似度
86
+ return dot_product / norm_product
87
+
88
+ esrgan_model= esrganQnn()
89
+ test_img_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)),'LR/*')
90
+
91
+ idx = 0
92
+ for path in glob.glob(test_img_folder):
93
+ idx += 1
94
+ base = osp.splitext(osp.basename(path))[0]
95
+ print(idx, base)
96
+ # read images
97
+ img = cv2.imread(path, cv2.IMREAD_COLOR)
98
+ img = cv2.resize(img, (128,128))
99
+ img = img * 1.0 / 255
100
+ img = img[:, :, [2, 1, 0]]
101
+ img_LR = np.expand_dims(img,axis=0).astype(np.float32)
102
+ print("img_LR shape:",img_LR.shape)
103
+
104
+ t0 = time.time()
105
+ output = esrgan_model(img_LR) #.data.squeeze().float().cpu().clamp_(0, 1).numpy()
106
+
107
+ output = np.clip(output[0], 0, 1)
108
+ output = np.transpose(output, (2, 0, 1))
109
+ use_time = round((time.time() - t0) * 1000, 2)
110
+ print(f"Inference_time:{use_time} ms")
111
+ output = np.transpose(output[[2, 1, 0], :, :], (1, 2, 0))
112
+ output = (output * 255.0).round()
113
+ cv2.imwrite(os.path.join(os.path.dirname(os.path.abspath(__file__)),'{:s}_rlt_16qnn.png'.format(base)), output)
114
+ print("ok")
115
+ esrgan_model.interpreter.destory()
model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/README.md ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Model Information
2
+
3
+ ### Source model
4
+
5
+ - Input shape: 128x128
6
+ - Number of parameters: 16.69M
7
+ - Model size: 63.8MB
8
+ - Output shape: 1x3x512x512
9
+
10
+ Source model repository: [ESRGAN](https://github.com/xinntao/ESRGAN/)
11
+
12
+ ### Converted Model
13
+
14
+ - Precision: W8A16
15
+ - Backend: QNN2.16
16
+ - Target Device: SNM972 QCS8550
17
+
18
+ ## Inference with AidLite SDK
19
+
20
+ ### SDK installation
21
+ 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/)
22
+
23
+ - install AidLite SDK
24
+
25
+ ```bash
26
+ # Install the appropriate version of the aidlite sdk
27
+ sudo aid-pkg update
28
+ sudo aid-pkg install aidlite-sdk
29
+ # Download the qnn version that matches the above backend. Eg Install QNN2.23 Aidlite: sudo aid-pkg install aidlite-qnn223
30
+ sudo aid-pkg install aidlite-{QNN VERSION}
31
+ ```
32
+
33
+ - Verify AidLite SDK
34
+
35
+ ```bash
36
+ # aidlite sdk c++ check
37
+ python3 -c "import aidlite ; print(aidlite.get_library_version())"
38
+
39
+ # aidlite sdk python check
40
+ python3 -c "import aidlite ; print(aidlite.get_py_library_version())"
41
+ ```
42
+
43
+ ### Run demo
44
+ #### python
45
+ ```bash
46
+ cd python
47
+ python3 demo_qnn.py
48
+ ```
49
+
50
+ #### c++
51
+ ```bash
52
+ cd esrgan/model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/cpp
53
+ mkdir build && cd build
54
+ cmake ..
55
+ make
56
+ ./run_test
57
+ ```
model_farm_esrgan_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_esrgan_qcs8550_qnn2.16_w8a16_aidlite/cpp/baboon.png ADDED
model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/cpp/run_test.cpp ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
15
+ struct Args {
16
+ std::string target_model = "../../models/m_RRDB_esrgan_x4_w8a16.qnn216.ctx.bin";
17
+ std::string imgs = "../baboon.png";
18
+ int invoke_nums = 10;
19
+ std::string model_type = "QNN";
20
+ };
21
+
22
+
23
+ Args parse_args(int argc, char* argv[]) {
24
+ Args args;
25
+ for (int i = 1; i < argc; ++i) {
26
+ std::string arg = argv[i];
27
+ if (arg == "--target_model" && i + 1 < argc) {
28
+ args.target_model = argv[++i];
29
+ } else if (arg == "--imgs" && i + 1 < argc) {
30
+ args.imgs = argv[++i];
31
+ } else if (arg == "--invoke_nums" && i + 1 < argc) {
32
+ args.invoke_nums = std::stoi(argv[++i]);
33
+ } else if (arg == "--model_type" && i + 1 < argc) {
34
+ args.model_type = argv[++i];
35
+ }
36
+ }
37
+ return args;
38
+ }
39
+
40
+ std::string to_lower(const std::string& str) {
41
+ std::string lower_str = str;
42
+ std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(), [](unsigned char c) {
43
+ return std::tolower(c);
44
+ });
45
+ return lower_str;
46
+ }
47
+
48
+ int transpose(float* src, unsigned int* src_dims, unsigned int* tsp_dims, float* dest){
49
+
50
+ int current_coordinate[4] = {0, 0, 0, 0};
51
+ for(int a = 0; a < src_dims[0]; ++a){
52
+ current_coordinate[0] = a;
53
+ for(int b = 0; b < src_dims[1]; ++b){
54
+ current_coordinate[1] = b;
55
+ for(int c = 0; c < src_dims[2]; ++c){
56
+ current_coordinate[2] = c;
57
+ for(int d = 0; d < src_dims[3]; ++d){
58
+ current_coordinate[3] = d;
59
+
60
+ int old_index = current_coordinate[0]*src_dims[1]*src_dims[2]*src_dims[3] +
61
+ current_coordinate[1]*src_dims[2]*src_dims[3] +
62
+ current_coordinate[2]*src_dims[3] +
63
+ current_coordinate[3];
64
+
65
+ int new_index = current_coordinate[tsp_dims[0]]*src_dims[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
66
+ current_coordinate[tsp_dims[1]]*src_dims[tsp_dims[2]]*src_dims[tsp_dims[3]] +
67
+ current_coordinate[tsp_dims[2]]*src_dims[tsp_dims[3]] +
68
+ current_coordinate[tsp_dims[3]];
69
+
70
+ dest[new_index] = src[old_index];
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ return EXIT_SUCCESS;
77
+ }
78
+
79
+
80
+ void save_output_image_from_nhwc(float* output) {
81
+ unsigned int H = 512;
82
+ unsigned int W = 512;
83
+ unsigned int C = 3;
84
+ // Step 1: clip [0,1]
85
+ std::vector<float> clipped(H * W * C);
86
+ for (int i = 0; i < H * W * C; ++i) {
87
+ clipped[i] = std::min(1.0f, std::max(0.0f, output[i]));
88
+ }
89
+
90
+ // Step 2: NHWC (H,W,C) to CHW (C,H,W)
91
+ unsigned int src_dims1[4] = {H, W, C, 1};
92
+ unsigned int tsp_dims1[4] = {2, 0, 1, 3};
93
+ std::vector<float> chw(C * H * W);
94
+ transpose(clipped.data(), src_dims1, tsp_dims1, chw.data());
95
+
96
+ // Step 3: RGB to BGR
97
+ std::vector<float> chw_bgr(C * H * W);
98
+ for (int h = 0; h < H; ++h) {
99
+ for (int w = 0; w < W; ++w) {
100
+ for (int c = 0; c < C; ++c) {
101
+ int src_index = c * H * W + h * W + w;
102
+ int dst_c = 2 - c;
103
+ int dst_index = dst_c * H * W + h * W + w;
104
+ chw_bgr[dst_index] = chw[src_index];
105
+ }
106
+ }
107
+ }
108
+
109
+ // Step 4: CHW to HWC
110
+ unsigned int src_dims2[4] = {C, H, W, 1};
111
+ unsigned int tsp_dims2[4] = {1, 2, 0, 3};
112
+ std::vector<float> hwc(H * W * C);
113
+ transpose(chw_bgr.data(), src_dims2, tsp_dims2, hwc.data());
114
+
115
+ // Step 5: Convert to CV_8UC3 image
116
+ cv::Mat result(H, W, CV_8UC3);
117
+ for (int y = 0; y < H; ++y) {
118
+ for (int x = 0; x < W; ++x) {
119
+ int idx = (y * W + x) * C;
120
+ uchar b = static_cast<uchar>(std::round(hwc[idx + 0] * 255.0f));
121
+ uchar g = static_cast<uchar>(std::round(hwc[idx + 1] * 255.0f));
122
+ uchar r = static_cast<uchar>(std::round(hwc[idx + 2] * 255.0f));
123
+ result.at<cv::Vec3b>(y, x) = cv::Vec3b(b, g, r);
124
+ }
125
+ }
126
+
127
+ // Save the image
128
+ cv::imwrite("./result_img.jpg", result);
129
+ }
130
+
131
+
132
+ int invoke(const Args& args) {
133
+ std::cout << "Start main ... ... Model Path: " << args.target_model << "\n"
134
+ << "Image Path: " << args.imgs << "\n"
135
+ << "Inference Nums: " << args.invoke_nums << "\n"
136
+ << "Model Type: " << args.model_type << "\n";
137
+ Model* model = Model::create_instance(args.target_model);
138
+ if(model == nullptr){
139
+ printf("Create model failed !\n");
140
+ return EXIT_FAILURE;
141
+ }
142
+ Config* config = Config::create_instance();
143
+ if(config == nullptr){
144
+ printf("Create config failed !\n");
145
+ return EXIT_FAILURE;
146
+ }
147
+ config->implement_type = ImplementType::TYPE_LOCAL;
148
+ std::string model_type_lower = to_lower(args.model_type);
149
+ if (model_type_lower == "qnn"){
150
+ config->framework_type = FrameworkType::TYPE_QNN;
151
+ } else if (model_type_lower == "snpe2" || model_type_lower == "snpe") {
152
+ config->framework_type = FrameworkType::TYPE_SNPE2;
153
+ }
154
+ config->accelerate_type = AccelerateType::TYPE_DSP;
155
+ config->is_quantify_model = 1;
156
+
157
+ unsigned int model_h = 128;
158
+ unsigned int model_w = 128;
159
+ std::vector<std::vector<uint32_t>> input_shapes = {{1,model_h,model_w,3}};
160
+ std::vector<std::vector<uint32_t>> output_shapes = {{1,3,model_h*4,model_w*4}};
161
+ model->set_model_properties(input_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32, output_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32);
162
+ std::unique_ptr<Interpreter> fast_interpreter = InterpreterBuilder::build_interpretper_from_model_and_config(model, config);
163
+ if(fast_interpreter == nullptr){
164
+ printf("build_interpretper_from_model_and_config failed !\n");
165
+ return EXIT_FAILURE;
166
+ }
167
+ int result = fast_interpreter->init();
168
+ if(result != EXIT_SUCCESS){
169
+ printf("interpreter->init() failed !\n");
170
+ return EXIT_FAILURE;
171
+ }
172
+ // load model
173
+ fast_interpreter->load_model();
174
+ if(result != EXIT_SUCCESS){
175
+ printf("interpreter->load_model() failed !\n");
176
+ return EXIT_FAILURE;
177
+ }
178
+ printf("detect model load success!\n");
179
+
180
+ cv::Mat frame = cv::imread(args.imgs);
181
+ if (frame.empty()) {
182
+ printf("detect image load failed!\n");
183
+ return 1;
184
+ }
185
+ printf("img_src cols: %d, img_src rows: %d\n", frame.cols, frame.rows);
186
+ cv::Mat input_data;
187
+ cv::Mat frame_clone = frame.clone();
188
+ cv::cvtColor(frame_clone, frame_clone, cv::COLOR_BGR2RGB);
189
+ cv::resize(frame_clone, frame_clone, cv::Size(model_w, model_h));
190
+ frame_clone.convertTo(input_data, CV_32FC3, 1.0 / 255.0);
191
+
192
+ float *outdata0 = nullptr;
193
+ std::vector<float> invoke_time;
194
+ for (int i = 0; i < args.invoke_nums; ++i) {
195
+ result = fast_interpreter->set_input_tensor(0, input_data.data);
196
+ if(result != EXIT_SUCCESS){
197
+ printf("interpreter->set_input_tensor() failed !\n");
198
+ return EXIT_FAILURE;
199
+ }
200
+ auto t1 = std::chrono::high_resolution_clock::now();
201
+ result = fast_interpreter->invoke();
202
+ auto t2 = std::chrono::high_resolution_clock::now();
203
+ std::chrono::duration<double> cost_time = t2 - t1;
204
+ invoke_time.push_back(cost_time.count() * 1000);
205
+ if(result != EXIT_SUCCESS){
206
+ printf("interpreter->invoke() failed !\n");
207
+ return EXIT_FAILURE;
208
+ }
209
+ uint32_t out_data_0 = 0;
210
+ result = fast_interpreter->get_output_tensor(0, (void**)&outdata0, &out_data_0);
211
+ if(result != EXIT_SUCCESS){
212
+ printf("interpreter->get_output_tensor() 1 failed !\n");
213
+ return EXIT_FAILURE;
214
+ }
215
+
216
+ }
217
+
218
+ float max_invoke_time = *std::max_element(invoke_time.begin(), invoke_time.end());
219
+ float min_invoke_time = *std::min_element(invoke_time.begin(), invoke_time.end());
220
+ float mean_invoke_time = std::accumulate(invoke_time.begin(), invoke_time.end(), 0.0f) / args.invoke_nums;
221
+ float var_invoketime = 0.0f;
222
+ for (auto time : invoke_time) {
223
+ var_invoketime += (time - mean_invoke_time) * (time - mean_invoke_time);
224
+ }
225
+ var_invoketime /= args.invoke_nums;
226
+ printf("=======================================\n");
227
+ 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",
228
+ args.invoke_nums, mean_invoke_time, max_invoke_time, min_invoke_time, var_invoketime);
229
+ printf("=======================================\n");
230
+
231
+ // post process
232
+ save_output_image_from_nhwc(outdata0);
233
+
234
+
235
+ fast_interpreter->destory();
236
+ return 0;
237
+ }
238
+
239
+
240
+ int main(int argc, char* argv[]) {
241
+ Args args = parse_args(argc, argv);
242
+ return invoke(args);
243
+ }
model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/models/m_RRDB_esrgan_x4_w8a16.qnn216.ctx.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1ef9af1175914c55d210c01fdaa8d3acaf2d6f117b370ccc3f7d7b2351c16e3f
3
+ size 24006984
model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/python/LR/baboon.png ADDED
model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/python/__pycache__/RRDBNet_arch.cpython-38.pyc ADDED
Binary file (3.2 kB). View file
 
model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/python/__pycache__/RRDBNet_arch.cpython-39.pyc ADDED
Binary file (3.22 kB). View file
 
model_farm_esrgan_qcs8550_qnn2.16_w8a16_aidlite/python/demo_qnn.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os.path as osp
2
+ import glob
3
+ import cv2
4
+ import numpy as np
5
+ import torch
6
+ import time
7
+ import aidlite
8
+ import os
9
+
10
+ class esrganQnn:
11
+ def __init__(self):
12
+ super().__init__()
13
+ self.model = aidlite.Model.create_instance(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../models/m_RRDB_esrgan_x4_w8a16.qnn216.ctx.bin"))
14
+ if self.model is None:
15
+ print("Create model failed !")
16
+ return
17
+
18
+ self.config = aidlite.Config.create_instance()
19
+ if self.config is None:
20
+ print("build_interpretper_from_model_and_config failed !")
21
+ return
22
+
23
+ self.config.implement_type = aidlite.ImplementType.TYPE_LOCAL
24
+ self.config.framework_type = aidlite.FrameworkType.TYPE_QNN
25
+
26
+ self.config.accelerate_type = aidlite.AccelerateType.TYPE_DSP
27
+ self.config.is_quantify_model = 1
28
+
29
+ self.interpreter = aidlite.InterpreterBuilder.build_interpretper_from_model_and_config(self.model, self.config)
30
+ if self.interpreter is None:
31
+ print("build_interpretper_from_model_and_config failed !")
32
+ return
33
+ input_shapes = [[1, 128, 128,3]]
34
+ # input_shapes = [[1,3, 128, 128]]
35
+ output_shapes = [[1, 3,128*4,128*4]]
36
+ self.model.set_model_properties(input_shapes, aidlite.DataType.TYPE_FLOAT32,
37
+ output_shapes, aidlite.DataType.TYPE_FLOAT32)
38
+
39
+ if self.interpreter is None:
40
+ print("build_interpretper_from_model_and_config failed !")
41
+ result = self.interpreter.init()
42
+ if result != 0:
43
+ print(f"interpreter init failed !")
44
+ result = self.interpreter.load_model()
45
+ if result != 0:
46
+ print("interpreter load model failed !")
47
+
48
+ print(" model load success!")
49
+
50
+ def __call__(self, input):
51
+ self.interpreter.set_input_tensor(0,input)
52
+ invoke_time=[]
53
+ invoke_nums =10
54
+ for i in range(invoke_nums):
55
+ result = self.interpreter.set_input_tensor(0, input.data)
56
+ if result != 0:
57
+ print("interpreter set_input_tensor() failed")
58
+ t1=time.time()
59
+ result = self.interpreter.invoke()
60
+ cost_time = (time.time()-t1)*1000
61
+ invoke_time.append(cost_time)
62
+
63
+ max_invoke_time = max(invoke_time)
64
+ min_invoke_time = min(invoke_time)
65
+ mean_invoke_time = sum(invoke_time)/invoke_nums
66
+ var_invoketime=np.var(invoke_time)
67
+ print("====================================")
68
+ 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}")
69
+ print("====================================")
70
+ features_0 = self.interpreter.get_output_tensor(0).reshape(1, 128*4,128*4,3).copy()
71
+
72
+ return features_0
73
+
74
+
75
+ def cosine_similarity(v1, v2):
76
+ v1 = v1.flatten()
77
+ v2 = v2.flatten()
78
+ # 计算点积
79
+ dot_product = np.dot(v1, v2)
80
+ # 计算每个向量的模长
81
+ norm_v1 = np.linalg.norm(v1)
82
+ norm_v2 = np.linalg.norm(v2)
83
+ # 防止除以零错误
84
+ norm_product = np.maximum(norm_v1 * norm_v2, 1e-8)
85
+ # 计算余弦相似度
86
+ return dot_product / norm_product
87
+
88
+ esrgan_model= esrganQnn()
89
+ test_img_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)),'LR/*')
90
+
91
+ idx = 0
92
+ for path in glob.glob(test_img_folder):
93
+ idx += 1
94
+ base = osp.splitext(osp.basename(path))[0]
95
+ print(idx, base)
96
+ # read images
97
+ img = cv2.imread(path, cv2.IMREAD_COLOR)
98
+ img = cv2.resize(img, (128,128))
99
+ img = img * 1.0 / 255
100
+ img = img[:, :, [2, 1, 0]]
101
+ img_LR = np.expand_dims(img,axis=0).astype(np.float32)
102
+ print("img_LR shape:",img_LR.shape)
103
+
104
+ t0 = time.time()
105
+ output = esrgan_model(img_LR) #.data.squeeze().float().cpu().clamp_(0, 1).numpy()
106
+
107
+ output = np.clip(output[0], 0, 1)
108
+ output = np.transpose(output, (2, 0, 1))
109
+ use_time = round((time.time() - t0) * 1000, 2)
110
+ print(f"Inference_time:{use_time} ms")
111
+ output = np.transpose(output[[2, 1, 0], :, :], (1, 2, 0))
112
+ output = (output * 255.0).round()
113
+ cv2.imwrite(os.path.join(os.path.dirname(os.path.abspath(__file__)),'{:s}_rlt_16qnn.png'.format(base)), output)
114
+ print("ok")
115
+ esrgan_model.interpreter.destory()