From 0ba2315187db79f2421bf80116611237a4cd200b Mon Sep 17 00:00:00 2001 From: Horror Proton <107091537+horror-proton@users.noreply.github.com> Date: Wed, 24 Aug 2022 21:08:15 +0800 Subject: [PATCH 1/2] perf: use sobel derivatives in `StageDropsImageAnalyzer::analyze_baseline` --- resource/tasks.json | 2 +- src/MeoAssistant/StageDropsImageAnalyzer.cpp | 57 +++++++++++--------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/resource/tasks.json b/resource/tasks.json index 9c857366da..4f2760915c 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -8311,7 +8311,7 @@ "specialThreshold": 100, "specialThreshold_Doc": "基建长度阈值(不小于120)", "maskRange": [ - 35, + 70, 255 ], "rectMove": [ diff --git a/src/MeoAssistant/StageDropsImageAnalyzer.cpp b/src/MeoAssistant/StageDropsImageAnalyzer.cpp index f712f2dff8..fb0fd518ed 100644 --- a/src/MeoAssistant/StageDropsImageAnalyzer.cpp +++ b/src/MeoAssistant/StageDropsImageAnalyzer.cpp @@ -11,6 +11,8 @@ #include "AsstUtils.hpp" #include "Logger.hpp" +#include + bool asst::StageDropsImageAnalyzer::analyze() { LogTraceFunction; @@ -248,17 +250,35 @@ bool asst::StageDropsImageAnalyzer::analyze_baseline() auto task_ptr = Task.get("StageDrops-BaseLine"); - cv::Mat roi = m_image(utils::make_rect(task_ptr->roi)); - cv::Mat gray; - cv::cvtColor(roi, gray, cv::COLOR_BGR2GRAY); - cv::Mat bin; - cv::inRange(gray, task_ptr->mask_range.first, task_ptr->mask_range.second, bin); + cv::Mat preprocessed_roi; - cv::Rect bounding_rect = cv::boundingRect(bin); - cv::Mat bounding = gray(bounding_rect); - cv::Mat bgr_bounding = roi(bounding_rect); - cv::Mat hsv_bounding; - cv::cvtColor(bgr_bounding, hsv_bounding, cv::COLOR_BGR2HSV); + { + double angle = 60. / 180. * std::numbers::pi; + cv::Mat temp; // convert to float point for convenience + m_image.convertTo(temp, CV_32F, 1. / 255); + cv::Mat pdy; + cv::Mat pdx; + cv::Sobel(temp, pdy, CV_32F, 0, 1); + cv::Sobel(temp, pdx, CV_32F, 1, 0); + // prefer gradient in vertical direction, make value of those pixels positive + cv::sqrt(pdy.mul(pdy) - std::pow(std::tan(angle), 2.) * pdx.mul(pdx), temp); + + // cropping after derivatives, not before + temp(utils::make_rect(task_ptr->roi)).convertTo(preprocessed_roi, CV_8U, 255); + + // filling small gaps + cv::dilate(preprocessed_roi, preprocessed_roi, cv::getStructuringElement(cv::MORPH_RECT, { 3, 1 })); + // line must be thick enough + cv::erode(preprocessed_roi, preprocessed_roi, cv::getStructuringElement(cv::MORPH_RECT, { 3, 2 })); + + cv::cvtColor(preprocessed_roi, preprocessed_roi, cv::COLOR_BGR2GRAY); + } + + cv::Mat preprocessed_bin; + cv::inRange(preprocessed_roi, task_ptr->mask_range.first, task_ptr->mask_range.second, preprocessed_bin); + + cv::Rect bounding_rect = cv::boundingRect(preprocessed_bin); + cv::Mat bounding = preprocessed_bin(bounding_rect); int x_offset = task_ptr->roi.x + bounding_rect.x; int y_offset = task_ptr->roi.y + bounding_rect.y; @@ -271,28 +291,13 @@ bool asst::StageDropsImageAnalyzer::analyze_baseline() int spacing = 0; // split - int threshold = task_ptr->mask_range.first; - cv::Vec3i pre_hsv; for (int i = 0; i < bounding.cols; ++i) { uchar value = 0; for (int j = 0; j < bounding.rows; ++j) { value = std::max(value, bounding.at(j, i)); } - cv::Vec3i hsv = hsv_bounding.at(0, i); - static const int h_threshold = task_ptr->rect_move.x; - static const int s_threshold = task_ptr->rect_move.y; - static const int v_threshold = task_ptr->rect_move.width; - - bool is_white = value >= threshold; - if (pre_hsv != cv::Vec3i::zeros()) { - is_white &= - abs(pre_hsv[0] - hsv[0]) < h_threshold && - abs(pre_hsv[1] - hsv[1]) < s_threshold && - abs(pre_hsv[2] - hsv[2]) < v_threshold; - } - - pre_hsv = hsv; + bool is_white = value; if (in && !is_white) { in = false; From 1f87efb13fbb0bb19c664f9492a146d89d99906e Mon Sep 17 00:00:00 2001 From: MistEO Date: Thu, 25 Aug 2022 20:40:13 +0800 Subject: [PATCH 2/2] chore: fix typos --- resource/tasks.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resource/tasks.json b/resource/tasks.json index 4f2760915c..85a40d9385 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -8309,7 +8309,7 @@ "templThreshold": 17, "templThreshold_Doc": "这里用来作为基线间距阈值", "specialThreshold": 100, - "specialThreshold_Doc": "基建长度阈值(不小于120)", + "specialThreshold_Doc": "基线长度阈值(不小于100)", "maskRange": [ 70, 255