From 407b140bca86cdd2eff0d44ceef8bc3f662a2876 Mon Sep 17 00:00:00 2001 From: Weiyou Wang <44151844+Alan-Charred@users.noreply.github.com> Date: Sun, 7 Sep 2025 22:07:33 +1000 Subject: [PATCH] refactor: BrightPointAnalyzer -> PixelAnalyzer (#13915) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: different filters for BrightPointAnalyzer * refactor: rename BrightPointAnalyzer to PixelAnalyzer * fix: 草忘了重命名文件了 --- src/MaaCore/MaaCore.vcxproj | 4 +- src/MaaCore/MaaCore.vcxproj.filters | 4 +- .../Map/RoguelikeRoutingTaskPlugin.cpp | 16 +++--- .../Miscellaneous/BrightPointAnalyzer.cpp | 33 ----------- .../Miscellaneous/BrightPointAnalyzer.h | 25 -------- .../Vision/Miscellaneous/PixelAnalyzer.cpp | 45 +++++++++++++++ .../Vision/Miscellaneous/PixelAnalyzer.h | 57 +++++++++++++++++++ 7 files changed, 114 insertions(+), 70 deletions(-) delete mode 100644 src/MaaCore/Vision/Miscellaneous/BrightPointAnalyzer.cpp delete mode 100644 src/MaaCore/Vision/Miscellaneous/BrightPointAnalyzer.h create mode 100644 src/MaaCore/Vision/Miscellaneous/PixelAnalyzer.cpp create mode 100644 src/MaaCore/Vision/Miscellaneous/PixelAnalyzer.h diff --git a/src/MaaCore/MaaCore.vcxproj b/src/MaaCore/MaaCore.vcxproj index 6a10b185a1..36556dc0a7 100644 --- a/src/MaaCore/MaaCore.vcxproj +++ b/src/MaaCore/MaaCore.vcxproj @@ -194,7 +194,7 @@ - + @@ -392,7 +392,7 @@ - + diff --git a/src/MaaCore/MaaCore.vcxproj.filters b/src/MaaCore/MaaCore.vcxproj.filters index cdfdc6c382..42609777c1 100644 --- a/src/MaaCore/MaaCore.vcxproj.filters +++ b/src/MaaCore/MaaCore.vcxproj.filters @@ -839,7 +839,7 @@ Source\Vision\Miscellaneous - + Source\Vision\Miscellaneous @@ -1377,7 +1377,7 @@ Source\Vision\Miscellaneous - + Source\Vision\Miscellaneous diff --git a/src/MaaCore/Task/Roguelike/Map/RoguelikeRoutingTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/Map/RoguelikeRoutingTaskPlugin.cpp index 1a535cc08c..0ef19acd44 100644 --- a/src/MaaCore/Task/Roguelike/Map/RoguelikeRoutingTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/Map/RoguelikeRoutingTaskPlugin.cpp @@ -11,7 +11,7 @@ #include "Utils/Logger.hpp" #include "Utils/NoWarningCV.h" #include "Vision/Matcher.h" -#include "Vision/Miscellaneous/BrightPointAnalyzer.h" +#include "Vision/Miscellaneous/PixelAnalyzer.h" #include "Vision/MultiMatcher.h" bool asst::RoguelikeRoutingTaskPlugin::load_params([[maybe_unused]] const json::value& params) @@ -503,7 +503,7 @@ void asst::RoguelikeRoutingTaskPlugin::generate_edges( } // 将 image转换为二值图像后计算亮点 - BrightPointAnalyzer analyzer(image); + PixelAnalyzer analyzer(image); const int center_x = node_x - (m_column_offset - m_node_width) / 2; // node 与 前一列节点的中点横坐标 const int node_y = m_map.get_node_y(node); @@ -529,21 +529,21 @@ void asst::RoguelikeRoutingTaskPlugin::generate_edges( } // 按照水平方向排序(从左到右) - std::vector brightPoints = analyzer.get_result(); + std::vector brightPixels = analyzer.get_result(); - auto [x_min_p, x_max_p] = ranges::minmax(brightPoints, /*comp=*/ {}, [](const Point& p) { return p.x; }); + auto [x_min_p, x_max_p] = ranges::minmax(brightPixels, /*comp=*/ {}, [](const Point& p) { return p.x; }); const int leftmost_x = x_min_p.x; const int rightmost_x = x_max_p.x; - auto leftmostBrightPoints = brightPoints | views::filter([&](const Point& p) { return p.x == leftmost_x; }); - auto rightmostBrightPoints = brightPoints | views::filter([&](const Point& p) { return p.x == rightmost_x; }); + auto leftmostBrightPixels = brightPixels | views::filter([&](const Point& p) { return p.x == leftmost_x; }); + auto rightmostBrightPixels = brightPixels | views::filter([&](const Point& p) { return p.x == rightmost_x; }); auto [leftmost_y_min_p, leftmost_y_max_p] = - ranges::minmax(leftmostBrightPoints, /*comp=*/ {}, [](const Point& p) { return p.y; }); + ranges::minmax(leftmostBrightPixels, /*comp=*/ {}, [](const Point& p) { return p.y; }); const int leftmost_y = (leftmost_y_min_p.y + leftmost_y_max_p.y) / 2; auto [rightmost_y_min_p, rightmost_y_max_p] = - ranges::minmax(rightmostBrightPoints, /*comp=*/ {}, [](const Point& p) { return p.y; }); + ranges::minmax(rightmostBrightPixels, /*comp=*/ {}, [](const Point& p) { return p.y; }); const int rightmost_y = (rightmost_y_min_p.y + rightmost_y_max_p.y) / 2; if ((std::abs(prev_y - node_y) < m_direction_threshold && diff --git a/src/MaaCore/Vision/Miscellaneous/BrightPointAnalyzer.cpp b/src/MaaCore/Vision/Miscellaneous/BrightPointAnalyzer.cpp deleted file mode 100644 index 1dfe4943e5..0000000000 --- a/src/MaaCore/Vision/Miscellaneous/BrightPointAnalyzer.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "BrightPointAnalyzer.h" - -#include "Utils/Logger.hpp" -#include "Utils/NoWarningCV.h" -#include "Utils/Ranges.hpp" - -using namespace asst; - -BrightPointAnalyzer::ResultsVecOpt BrightPointAnalyzer::analyze() -{ - const cv::Mat croppedImage = make_roi(m_image, m_roi); - cv::Mat grayImage; - cv::cvtColor(croppedImage, grayImage, cv::COLOR_BGR2GRAY); - cv::Mat binaryImage; - cv::threshold(grayImage, binaryImage, 250, 255, cv::THRESH_BINARY); - std::vector brightPoints; - cv::findNonZero(binaryImage, brightPoints); - - if (brightPoints.empty()) { - return std::nullopt; - } - - auto transform_view = brightPoints | views::transform([](const cv::Point& p) { return Point(p.x, p.y); }); - ResultsVec results(ranges::begin(transform_view), ranges::end(transform_view)); - - if (m_log_tracing) { - Log.trace("analyze_bright_points | num:", results.size()); - } - - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - m_result = std::move(results); - return m_result; -} diff --git a/src/MaaCore/Vision/Miscellaneous/BrightPointAnalyzer.h b/src/MaaCore/Vision/Miscellaneous/BrightPointAnalyzer.h deleted file mode 100644 index fd2f02266c..0000000000 --- a/src/MaaCore/Vision/Miscellaneous/BrightPointAnalyzer.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "Vision/VisionHelper.h" - -namespace asst -{ -class BrightPointAnalyzer : public VisionHelper -{ -public: - using Result = Point; - using ResultsVec = std::vector; - using ResultsVecOpt = std::optional; - - using VisionHelper::VisionHelper; - virtual ~BrightPointAnalyzer() override = default; - - ResultsVecOpt analyze(); - - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - const auto& get_result() const noexcept { return m_result; } - -private: - ResultsVec m_result; -}; -} diff --git a/src/MaaCore/Vision/Miscellaneous/PixelAnalyzer.cpp b/src/MaaCore/Vision/Miscellaneous/PixelAnalyzer.cpp new file mode 100644 index 0000000000..56aebfc783 --- /dev/null +++ b/src/MaaCore/Vision/Miscellaneous/PixelAnalyzer.cpp @@ -0,0 +1,45 @@ +#include "PixelAnalyzer.h" + +#include "Utils/Logger.hpp" +#include "Utils/NoWarningCV.h" +#include "Utils/Ranges.hpp" + +using namespace asst; + +PixelAnalyzer::ResultsVecOpt PixelAnalyzer::analyze() +{ + const cv::Mat croppedImage = make_roi(m_image, m_roi); + cv::Mat tempImage; + cv::Mat binaryImage; + switch (m_filter) { + case Filter::GRAY: + cv::cvtColor(croppedImage, tempImage, cv::COLOR_BGR2GRAY); + cv::threshold(tempImage, binaryImage, m_gray_lb, m_gray_ub, cv::THRESH_BINARY); + break; + case Filter::RGB: + cv::cvtColor(croppedImage, tempImage, cv::COLOR_BGR2RGB); + cv::inRange(tempImage, m_lb, m_ub, binaryImage); + break; + case Filter::HSV: + cv::cvtColor(croppedImage, tempImage, cv::COLOR_BGR2HSV); + cv::inRange(tempImage, m_lb, m_ub, binaryImage); + break; + } + std::vector pixelPoints; + cv::findNonZero(binaryImage, pixelPoints); + + if (pixelPoints.empty()) { + return std::nullopt; + } + + auto transform_view = pixelPoints | views::transform([](const cv::Point& p) { return Point(p.x, p.y); }); + ResultsVec results(ranges::begin(transform_view), ranges::end(transform_view)); + + if (m_log_tracing) { + Log.trace("analyze_bright_points | num:", results.size()); + } + + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + m_result = std::move(results); + return m_result; +} diff --git a/src/MaaCore/Vision/Miscellaneous/PixelAnalyzer.h b/src/MaaCore/Vision/Miscellaneous/PixelAnalyzer.h new file mode 100644 index 0000000000..245985c7b3 --- /dev/null +++ b/src/MaaCore/Vision/Miscellaneous/PixelAnalyzer.h @@ -0,0 +1,57 @@ +#pragma once + +#include "Vision/VisionHelper.h" + +namespace asst +{ +class PixelAnalyzer : public VisionHelper +{ +public: + enum class Filter + { + GRAY, + RGB, + HSV + }; + + using Result = Point; + using ResultsVec = std::vector; + using ResultsVecOpt = std::optional; + + using VisionHelper::VisionHelper; + virtual ~PixelAnalyzer() override = default; + + ResultsVecOpt analyze(); + + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + [[nodiscard]] const auto& get_result() const noexcept { return m_result; } + + void set_filter(const Filter filter) { m_filter = filter; } + + void set_gray_lb(const int gray_lb) { m_gray_lb = gray_lb; } + + void set_gray_ub(const int gray_ub) { m_ub = gray_ub; } + + void set_lb(const std::vector& lb) + { + if (lb.size() == 3) { + m_lb = cv::Scalar(lb[0], lb[1], lb[2]); + } + } + + void set_ub(const std::vector& ub) + { + if (ub.size() == 3) { + m_ub = cv::Scalar(ub[0], ub[1], ub[2]); + } + } + +private: + Filter m_filter = Filter::GRAY; + int m_gray_lb = 250; + int m_gray_ub = 255; + cv::Scalar m_lb = { 0, 0, 0 }; + cv::Scalar m_ub = { 0, 0, 0 }; + ResultsVec m_result; +}; +}