Skip to content

Commit 5be92b9

Browse files
committed
Merge branch 'develop' into release/v0.3.0
2 parents 5845f8f + bf72574 commit 5be92b9

File tree

78 files changed

+783
-85
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+783
-85
lines changed

README.md

Lines changed: 1 addition & 1 deletion

deploy/README.md

Lines changed: 2 additions & 0 deletions

deploy/cpp/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ if(WITH_MKL)
142142
if (WIN32)
143143
set(MKLDNN_LIB ${MKLDNN_PATH}/lib/mkldnn.lib)
144144
else ()
145-
set(MKLDNN_LIB ${MKLDNN_PATH}/lib/libmkldnn.so.0)
145+
set(MKLDNN_LIB ${MKLDNN_PATH}/lib/libmkldnn.so.1)
146146
endif ()
147147
endif()
148148
else()

deploy/cpp/demo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ int main(int argc, char** argv) {
2424
google::ParseCommandLineFlags(&argc, &argv, true);
2525
if (FLAGS_conf.empty() || FLAGS_input_dir.empty()) {
2626
std::cout << "Usage: ./predictor --conf=/config/path/to/your/model "
27-
<< "--input_dir=/directory/of/your/input/images";
27+
<< "--input_dir=/directory/of/your/input/images" << std::endl;
2828
return -1;
2929
}
3030
// 1. create a predictor and init it with conf

deploy/cpp/predictor/seg_predictor.cpp

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ namespace PaddleSolution {
8383

8484
int blob_out_len = length;
8585
int seg_out_len = eval_height * eval_width * eval_num_class;
86-
8786
if (blob_out_len != seg_out_len) {
8887
LOG(ERROR) << " [FATAL] unequal: input vs output [" <<
8988
seg_out_len << "|" << blob_out_len << "]" << std::endl;
@@ -97,25 +96,22 @@ namespace PaddleSolution {
9796
cv::Mat mask_png = cv::Mat(eval_height, eval_width, CV_8UC1);
9897
mask_png.data = _mask.data();
9998
std::string nname(fname);
100-
auto pos = fname.find(".");
99+
auto pos = fname.rfind(".");
101100
nname[pos] = '_';
102-
std::string mask_save_name = nname + ".png";
101+
std::string mask_save_name = nname + "_mask.png";
103102
cv::imwrite(mask_save_name, mask_png);
104103
cv::Mat scoremap_png = cv::Mat(eval_height, eval_width, CV_8UC1);
105104
scoremap_png.data = _scoremap.data();
106-
std::string scoremap_save_name = nname
107-
+ std::string("_scoremap.png");
105+
std::string scoremap_save_name = nname + std::string("_scoremap.png");
108106
cv::imwrite(scoremap_save_name, scoremap_png);
109107
std::cout << "save mask of [" << fname << "] done" << std::endl;
110108

111109
if (height && width) {
112110
int recover_height = *height;
113111
int recover_width = *width;
114-
cv::Mat recover_png = cv::Mat(recover_height,
115-
recover_width, CV_8UC1);
112+
cv::Mat recover_png = cv::Mat(recover_height, recover_width, CV_8UC1);
116113
cv::resize(scoremap_png, recover_png,
117-
cv::Size(recover_width, recover_height),
118-
0, 0, cv::INTER_CUBIC);
114+
cv::Size(recover_width, recover_height), 0, 0, cv::INTER_CUBIC);
119115
std::string recover_name = nname + std::string("_recover.png");
120116
cv::imwrite(recover_name, recover_png);
121117
}
@@ -176,8 +172,13 @@ namespace PaddleSolution {
176172
}
177173
paddle::PaddleTensor im_tensor;
178174
im_tensor.name = "image";
179-
im_tensor.shape = std::vector<int>{ batch_size, channels,
180-
eval_height, eval_width };
175+
if (!_model_config._use_pr) {
176+
im_tensor.shape = std::vector<int>{ batch_size, channels,
177+
eval_height, eval_width };
178+
} else {
179+
im_tensor.shape = std::vector<int>{ batch_size, eval_height,
180+
eval_width, channels};
181+
}
181182
im_tensor.data.Reset(input_buffer.data(),
182183
real_buffer_size * sizeof(float));
183184
im_tensor.dtype = paddle::PaddleDType::FLOAT32;
@@ -202,19 +203,45 @@ namespace PaddleSolution {
202203
std::cout << _outputs[0].shape[j] << ",";
203204
}
204205
std::cout << ")" << std::endl;
205-
const size_t nums = _outputs.front().data.length()
206-
/ sizeof(float);
207-
if (out_num % batch_size != 0 || out_num != nums) {
208-
LOG(ERROR) << "outputs data size mismatch with shape size.";
206+
207+
size_t nums = _outputs.front().data.length() / sizeof(float);
208+
if (_model_config._use_pr) {
209+
nums = _outputs.front().data.length() / sizeof(int64_t);
210+
}
211+
// size mismatch checking
212+
bool size_mismatch = out_num % batch_size;
213+
size_mismatch |= (!_model_config._use_pr) && (nums != out_num);
214+
size_mismatch |= _model_config._use_pr && (nums != eval_height * eval_width);
215+
if (size_mismatch) {
216+
LOG(ERROR) << "output with a unexpected size";
209217
return -1;
210218
}
211219

220+
if (_model_config._use_pr) {
221+
std::vector<uchar> out_data;
222+
out_data.resize(out_num);
223+
auto addr = reinterpret_cast<int64_t*>(_outputs[0].data.data());
224+
for (int r = 0; r < out_num; ++r) {
225+
out_data[r] = (int)(addr[r]);
226+
}
227+
for (int r = 0; r < batch_size; ++r) {
228+
cv::Mat mask_png = cv::Mat(eval_height, eval_width, CV_8UC1);
229+
mask_png.data = out_data.data() + eval_height*eval_width*r;
230+
auto name = imgs_batch[r];
231+
auto pos = name.rfind(".");
232+
name[pos] = '_';
233+
std::string mask_save_name = name + "_mask.png";
234+
cv::imwrite(mask_save_name, mask_png);
235+
}
236+
continue;
237+
}
238+
212239
for (int i = 0; i < batch_size; ++i) {
213240
float* output_addr = reinterpret_cast<float*>(
214241
_outputs[0].data.data())
215-
+ i * (out_num / batch_size);
242+
+ i * (nums / batch_size);
216243
output_mask(imgs_batch[i], output_addr,
217-
out_num / batch_size,
244+
nums / batch_size,
218245
&org_height[i],
219246
&org_width[i]);
220247
}
@@ -278,8 +305,14 @@ namespace PaddleSolution {
278305
return -1;
279306
}
280307
auto im_tensor = _main_predictor->GetInputTensor("image");
281-
im_tensor->Reshape({ batch_size, channels,
308+
if (!_model_config._use_pr) {
309+
im_tensor->Reshape({ batch_size, channels,
282310
eval_height, eval_width });
311+
} else {
312+
im_tensor->Reshape({ batch_size, eval_height,
313+
eval_width, channels});
314+
}
315+
283316
im_tensor->copy_from_cpu(input_buffer.data());
284317

285318
auto t1 = std::chrono::high_resolution_clock::now();
@@ -292,7 +325,6 @@ namespace PaddleSolution {
292325
auto output_names = _main_predictor->GetOutputNames();
293326
auto output_t = _main_predictor->GetOutputTensor(
294327
output_names[0]);
295-
std::vector<float> out_data;
296328
std::vector<int> output_shape = output_t->shape();
297329

298330
int out_num = 1;
@@ -303,6 +335,30 @@ namespace PaddleSolution {
303335
}
304336
std::cout << ")" << std::endl;
305337

338+
if (_model_config._use_pr) {
339+
std::vector<int64_t> out_data;
340+
out_data.resize(out_num);
341+
output_t->copy_to_cpu(out_data.data());
342+
343+
std::vector<uchar> mask_data;
344+
mask_data.resize(out_num);
345+
auto addr = reinterpret_cast<int64_t*>(out_data.data());
346+
for (int r = 0; r < out_num; ++r) {
347+
mask_data[r] = (int)(addr[r]);
348+
}
349+
for (int r = 0; r < batch_size; ++r) {
350+
cv::Mat mask_png = cv::Mat(eval_height, eval_width, CV_8UC1);
351+
mask_png.data = mask_data.data() + eval_height*eval_width*r;
352+
auto name = imgs_batch[r];
353+
auto pos = name.rfind(".");
354+
name[pos] = '_';
355+
std::string mask_save_name = name + "_mask.png";
356+
cv::imwrite(mask_save_name, mask_png);
357+
}
358+
continue;
359+
}
360+
361+
std::vector<float> out_data;
306362
out_data.resize(out_num);
307363
output_t->copy_to_cpu(out_data.data());
308364
for (int i = 0; i < batch_size; ++i) {

deploy/cpp/preprocessor/preprocessor_seg.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,18 @@ namespace PaddleSolution {
4040
LOG(ERROR) << "Only support rgb(gray) and rgba image.";
4141
return false;
4242
}
43-
4443
cv::Size resize_size(_config->_resize[0], _config->_resize[1]);
4544
int rw = resize_size.width;
4645
int rh = resize_size.height;
4746
if (*ori_h != rh || *ori_w != rw) {
4847
cv::resize(im, im, resize_size, 0, 0, cv::INTER_LINEAR);
4948
}
50-
utils::normalize(im, data, _config->_mean, _config->_std);
49+
50+
if (!_config->_use_pr) {
51+
utils::normalize(im, data, _config->_mean, _config->_std);
52+
} else {
53+
utils::flatten_mat(im, data);
54+
}
5155
return true;
5256
}
5357

deploy/cpp/utils/seg_conf_parser.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class PaddleSegModelConfigPaser {
2525
:_class_num(0),
2626
_channels(0),
2727
_use_gpu(0),
28+
_use_pr(0),
2829
_batch_size(1),
2930
_model_file_name("__model__"),
3031
_param_file_name("__params__") {
@@ -40,6 +41,7 @@ class PaddleSegModelConfigPaser {
4041
_class_num = 0;
4142
_channels = 0;
4243
_use_gpu = 0;
44+
_use_pr = 0;
4345
_batch_size = 1;
4446
_model_file_name.clear();
4547
_model_path.clear();
@@ -172,6 +174,12 @@ class PaddleSegModelConfigPaser {
172174
std::cerr << "Please set CHANNELS: x" << std::endl;
173175
return false;
174176
}
177+
// 15. use_pr
178+
if (config["DEPLOY"]["USE_PR"].IsDefined()) {
179+
_use_pr = config["DEPLOY"]["USE_PR"].as<int>();
180+
} else {
181+
_use_pr = 0;
182+
}
175183
return true;
176184
}
177185

@@ -238,6 +246,8 @@ class PaddleSegModelConfigPaser {
238246
std::string _predictor_mode;
239247
// DEPLOY.BATCH_SIZE
240248
int _batch_size;
249+
// USE_PR: OP Optimized model
250+
int _use_pr;
241251
};
242252

243253
} // namespace PaddleSolution

deploy/cpp/utils/utils.h

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
#include <opencv2/highgui/highgui.hpp>
2424

2525
#ifdef _WIN32
26-
#include <filesystem>
26+
#define GLOG_NO_ABBREVIATED_SEVERITIES
27+
#include <windows.h>
2728
#else
2829
#include <dirent.h>
2930
#include <sys/types.h>
@@ -67,15 +68,21 @@ namespace utils {
6768
// scan a directory and get all files with input extensions
6869
inline std::vector<std::string> get_directory_images(
6970
const std::string& path, const std::string& exts) {
71+
std::string pattern(path);
72+
pattern.append("\\*");
7073
std::vector<std::string> imgs;
71-
for (const auto& item :
72-
std::experimental::filesystem::directory_iterator(path)) {
73-
auto suffix = item.path().extension().string();
74-
if (exts.find(suffix) != std::string::npos && suffix.size() > 0) {
75-
auto fullname = path_join(path,
76-
item.path().filename().string());
77-
imgs.push_back(item.path().string());
78-
}
74+
WIN32_FIND_DATA data;
75+
HANDLE hFind;
76+
if ((hFind = FindFirstFile(pattern.c_str(), &data)) != INVALID_HANDLE_VALUE) {
77+
do {
78+
auto fname = std::string(data.cFileName);
79+
auto pos = fname.rfind(".");
80+
auto ext = fname.substr(pos + 1);
81+
if (ext.size() > 1 && exts.find(ext) != std::string::npos) {
82+
imgs.push_back(path + "\\" + data.cFileName);
83+
}
84+
} while (FindNextFile(hFind, &data) != 0);
85+
FindClose(hFind);
7986
}
8087
return imgs;
8188
}
@@ -103,6 +110,25 @@ namespace utils {
103110
}
104111
}
105112

113+
// flatten a cv::mat
114+
inline void flatten_mat(cv::Mat& im, float* data) {
115+
int rh = im.rows;
116+
int rw = im.cols;
117+
int rc = im.channels();
118+
#pragma omp parallel for
119+
for (int h = 0; h < rh; ++h) {
120+
const uchar* ptr = im.ptr<uchar>(h);
121+
int im_index = 0;
122+
int top_index = h * rw * rc;
123+
for (int w = 0; w < rw; ++w) {
124+
for (int c = 0; c < rc; ++c) {
125+
float pixel = static_cast<float>(ptr[im_index++]);
126+
data[top_index++] = pixel;
127+
}
128+
}
129+
}
130+
}
131+
106132
// argmax
107133
inline void argmax(float* out, std::vector<int>& shape,
108134
std::vector<uchar>& mask, std::vector<uchar>& scoremap) {
File renamed without changes.

0 commit comments

Comments
 (0)