未验证 提交 e68b36f5 编写于 作者: Y yiicy 提交者: GitHub

[DEMO] update mask detection demo, test=develop (#2988)

update mask detection demo
上级 0ac026c9
...@@ -70,7 +70,11 @@ export LD_LIBRARY_PATH=/data/local/tmp/:$LD_LIBRARY_PATH ...@@ -70,7 +70,11 @@ export LD_LIBRARY_PATH=/data/local/tmp/:$LD_LIBRARY_PATH
adb pull /data/local/tmp/test_mask_detection_result.jpg ./ adb pull /data/local/tmp/test_mask_detection_result.jpg ./
``` ```
![test_mask_detection_result](https://user-images.githubusercontent.com/7383104/74279176-6200cd00-4d55-11ea-9fc0-83cfc2b3b37d.jpg) ![test_mask_detection_result](https://user-images.githubusercontent.com/7383104/75131866-bae64300-570f-11ea-9cad-17acfaea1cfc.jpg)
注:mask_detetion.cc 中的缩放因子shrink, 检测阈值detect_threshold, 可供自由配置:
- 缩放因子越大,模型运行速度越慢,检测准确率越高。
- 检测阈值越高,人脸筛选越严格,检测出的人脸框可能越少。
3. 编译并运行全量api的demo(注:当编译模式为tiny_pubish时将不存在该demo) 3. 编译并运行全量api的demo(注:当编译模式为tiny_pubish时将不存在该demo)
```shell ```shell
......
...@@ -81,6 +81,29 @@ void neon_mean_scale(const float* din, ...@@ -81,6 +81,29 @@ void neon_mean_scale(const float* din,
} }
} }
cv::Mat crop_img(const cv::Mat& img,
cv::Rect rec,
int res_width,
int res_height) {
float xmin = rec.x;
float ymin = rec.y;
float w = rec.width;
float h = rec.height;
float center_x = xmin + w / 2;
float center_y = ymin + h / 2;
cv::Point2f center(center_x, center_y);
float max_wh = std::max(w / 2, h / 2);
float scale = res_width / (2 * max_wh * 1.5);
cv::Mat rot_mat = cv::getRotationMatrix2D(center, 0.f, scale);
rot_mat.at<double>(0, 2) =
rot_mat.at<double>(0, 2) - (center_x - res_width / 2.0);
rot_mat.at<double>(1, 2) =
rot_mat.at<double>(1, 2) - (center_y - res_width / 2.0);
cv::Mat affine_img;
cv::warpAffine(img, affine_img, rot_mat, cv::Size(res_width, res_height));
return affine_img;
}
void pre_process(const cv::Mat& img, void pre_process(const cv::Mat& img,
int width, int width,
int height, int height,
...@@ -89,8 +112,12 @@ void pre_process(const cv::Mat& img, ...@@ -89,8 +112,12 @@ void pre_process(const cv::Mat& img,
float* data, float* data,
bool is_scale = false) { bool is_scale = false) {
cv::Mat resized_img; cv::Mat resized_img;
cv::resize( if (img.cols != width || img.rows != height) {
img, resized_img, cv::Size(width, height), 0.f, 0.f, cv::INTER_CUBIC); cv::resize(
img, resized_img, cv::Size(width, height), 0.f, 0.f, cv::INTER_CUBIC);
} else {
resized_img = img;
}
cv::Mat imgf; cv::Mat imgf;
float scale_factor = is_scale ? 1.f / 256 : 1.f; float scale_factor = is_scale ? 1.f / 256 : 1.f;
resized_img.convertTo(imgf, CV_32FC3, scale_factor); resized_img.convertTo(imgf, CV_32FC3, scale_factor);
...@@ -103,7 +130,7 @@ void RunModel(std::string det_model_dir, ...@@ -103,7 +130,7 @@ void RunModel(std::string det_model_dir,
std::string img_path) { std::string img_path) {
// Prepare // Prepare
cv::Mat img = imread(img_path, cv::IMREAD_COLOR); cv::Mat img = imread(img_path, cv::IMREAD_COLOR);
float shrink = 0.2; float shrink = 0.4;
int width = img.cols; int width = img.cols;
int height = img.rows; int height = img.rows;
int s_width = static_cast<int>(width * shrink); int s_width = static_cast<int>(width * shrink);
...@@ -138,7 +165,7 @@ void RunModel(std::string det_model_dir, ...@@ -138,7 +165,7 @@ void RunModel(std::string det_model_dir,
int64_t out_len = ShapeProduction(shape_out); int64_t out_len = ShapeProduction(shape_out);
// Filter Out Detection Box // Filter Out Detection Box
float detect_threshold = 0.3; float detect_threshold = 0.7;
std::vector<Object> detect_result; std::vector<Object> detect_result;
for (int i = 0; i < out_len / 6; ++i) { for (int i = 0; i < out_len / 6; ++i) {
if (outptr[1] >= detect_threshold) { if (outptr[1] >= detect_threshold) {
...@@ -172,10 +199,13 @@ void RunModel(std::string det_model_dir, ...@@ -172,10 +199,13 @@ void RunModel(std::string det_model_dir,
int detect_num = detect_result.size(); int detect_num = detect_result.size();
std::vector<float> classify_mean = {0.5f, 0.5f, 0.5f}; std::vector<float> classify_mean = {0.5f, 0.5f, 0.5f};
std::vector<float> classify_scale = {1.f, 1.f, 1.f}; std::vector<float> classify_scale = {1.f, 1.f, 1.f};
float classify_threshold = 0.5;
for (int i = 0; i < detect_num; ++i) { for (int i = 0; i < detect_num; ++i) {
cv::Rect rec_clip = detect_result[i].rec; cv::Rect rec_clip = detect_result[i].rec;
cv::Mat roi = img(rec_clip); cv::Mat roi = crop_img(img, rec_clip, classify_w, classify_h);
// uncomment two lines below, save roi img to disk
// std::string roi_name = "roi_" + std::to_string(i) + ".jpg";
// imwrite(roi_name, roi);
// Do PreProcess // Do PreProcess
pre_process(roi, pre_process(roi,
...@@ -193,35 +223,58 @@ void RunModel(std::string det_model_dir, ...@@ -193,35 +223,58 @@ void RunModel(std::string det_model_dir,
std::unique_ptr<const Tensor> output_tensor1( std::unique_ptr<const Tensor> output_tensor1(
std::move(predictor->GetOutput(1))); std::move(predictor->GetOutput(1)));
auto* outptr = output_tensor1->data<float>(); auto* outptr = output_tensor1->data<float>();
float prob = outptr[1];
// Draw Detection and Classification Results // Draw Detection and Classification Results
cv::rectangle(img, rec_clip, cv::Scalar(0, 0, 255), 2, cv::LINE_AA); bool flag_mask = prob > 0.5f;
std::string text = outptr[1] > classify_threshold ? "wear mask" : "no mask"; cv::Scalar roi_color;
int font_face = cv::FONT_HERSHEY_COMPLEX_SMALL; std::string text;
double font_scale = 1.f; if (flag_mask) {
int thickness = 1; text = "MASK: ";
roi_color = cv::Scalar(0, 255, 0);
} else {
text = "NO MASK: ";
roi_color = cv::Scalar(0, 0, 255);
prob = 1 - prob;
}
std::string prob_str = std::to_string(prob * 100);
int point_idx = prob_str.find_last_of(".");
text += prob_str.substr(0, point_idx + 3) + "%";
int font_face = cv::FONT_HERSHEY_SIMPLEX;
double font_scale = 0.25;
float thickness = 1;
cv::Size text_size = cv::Size text_size =
cv::getTextSize(text, font_face, font_scale, thickness, nullptr); cv::getTextSize(text, font_face, font_scale, thickness, nullptr);
float new_font_scale = rec_clip.width * 0.7 * font_scale / text_size.width;
text_size = int top_space = std::max(0.35 * text_size.height, 2.0);
cv::getTextSize(text, font_face, new_font_scale, thickness, nullptr); int bottom_space = top_space + 2;
int right_space = 0.05 * text_size.width;
int back_width = text_size.width + right_space;
int back_height = text_size.height + top_space + bottom_space;
// Configure text background
cv::Rect text_back =
cv::Rect(rec_clip.x, rec_clip.y - back_height, back_width, back_height);
// Draw roi object, text, and background
cv::rectangle(img, rec_clip, roi_color, 1);
cv::rectangle(img, text_back, cv::Scalar(225, 225, 225), -1);
cv::Point origin; cv::Point origin;
origin.x = rec_clip.x + 5; origin.x = rec_clip.x;
origin.y = rec_clip.y + text_size.height + 5; origin.y = rec_clip.y - bottom_space;
cv::putText(img, cv::putText(img,
text, text,
origin, origin,
font_face, font_face,
new_font_scale, font_scale,
cv::Scalar(0, 255, 255), cv::Scalar(0, 0, 0),
thickness, thickness);
cv::LINE_AA);
std::cout << "detect face, location: x=" << rec_clip.x std::cout << "detect face, location: x=" << rec_clip.x
<< ", y=" << rec_clip.y << ", width=" << rec_clip.width << ", y=" << rec_clip.y << ", width=" << rec_clip.width
<< ", height=" << rec_clip.height << ", height=" << rec_clip.height << ", wear mask: " << flag_mask
<< ", wear mask: " << (outptr[1] > classify_threshold) << ", prob: " << prob << std::endl;
<< std::endl;
} }
// Write Result to Image File // Write Result to Image File
...@@ -230,6 +283,8 @@ void RunModel(std::string det_model_dir, ...@@ -230,6 +283,8 @@ void RunModel(std::string det_model_dir,
std::string img_name = img_path.substr(start + 1, end - start - 1); std::string img_name = img_path.substr(start + 1, end - start - 1);
std::string result_name = img_name + "_mask_detection_result.jpg"; std::string result_name = img_name + "_mask_detection_result.jpg";
cv::imwrite(result_name, img); cv::imwrite(result_name, img);
std::cout << "write result to file: " << result_name << ", success."
<< std::endl;
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册