refactor: BrightPointAnalyzer -> PixelAnalyzer (#13915)

* feat: different filters for BrightPointAnalyzer

* refactor: rename BrightPointAnalyzer to PixelAnalyzer

* fix: 草忘了重命名文件了
This commit is contained in:
Weiyou Wang
2025-09-07 22:07:33 +10:00
committed by GitHub
parent 0e865982c6
commit 407b140bca
7 changed files with 114 additions and 70 deletions

View File

@@ -194,7 +194,7 @@
<ClInclude Include="Vision\Miscellaneous\RecruitImageAnalyzer.h" />
<ClInclude Include="Vision\Miscellaneous\StageDropsImageAnalyzer.h" />
<ClInclude Include="Vision\Miscellaneous\OperBoxImageAnalyzer.h" />
<ClInclude Include="Vision\Miscellaneous\BrightPointAnalyzer.h" />
<ClInclude Include="Vision\Miscellaneous\PixelAnalyzer.h" />
<ClInclude Include="Vision\MultiMatcher.h" />
<ClInclude Include="Vision\OCRer.h" />
<ClInclude Include="Vision\TemplDetOCRer.h" />
@@ -392,7 +392,7 @@
<ClCompile Include="Vision\Miscellaneous\RecruitImageAnalyzer.cpp" />
<ClCompile Include="Vision\Miscellaneous\StageDropsImageAnalyzer.cpp" />
<ClCompile Include="Vision\Miscellaneous\OperBoxImageAnalyzer.cpp" />
<ClCompile Include="Vision\Miscellaneous\BrightPointAnalyzer.cpp" />
<ClCompile Include="Vision\Miscellaneous\PixelAnalyzer.cpp" />
<ClCompile Include="Vision\MultiMatcher.cpp" />
<ClCompile Include="Vision\OCRer.cpp" />
<ClCompile Include="Vision\TemplDetOCRer.cpp" />

View File

@@ -839,7 +839,7 @@
<ClInclude Include="Vision\Miscellaneous\OperBoxImageAnalyzer.h">
<Filter>Source\Vision\Miscellaneous</Filter>
</ClInclude>
<ClInclude Include="Vision\Miscellaneous\BrightPointAnalyzer.h">
<ClInclude Include="Vision\Miscellaneous\PixelAnalyzer.h">
<Filter>Source\Vision\Miscellaneous</Filter>
</ClInclude>
<ClInclude Include="Vision\Config\MatcherConfig.h">
@@ -1377,7 +1377,7 @@
<ClCompile Include="Vision\Miscellaneous\OperBoxImageAnalyzer.cpp">
<Filter>Source\Vision\Miscellaneous</Filter>
</ClCompile>
<ClCompile Include="Vision\Miscellaneous\BrightPointAnalyzer.cpp">
<ClCompile Include="Vision\Miscellaneous\PixelAnalyzer.cpp">
<Filter>Source\Vision\Miscellaneous</Filter>
</ClCompile>
<ClCompile Include="Vision\Config\MatcherConfig.cpp">

View File

@@ -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<Point> brightPoints = analyzer.get_result();
std::vector<Point> 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 &&

View File

@@ -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<cv::Point> 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;
}

View File

@@ -1,25 +0,0 @@
#pragma once
#include "Vision/VisionHelper.h"
namespace asst
{
class BrightPointAnalyzer : public VisionHelper
{
public:
using Result = Point;
using ResultsVec = std::vector<Result>;
using ResultsVecOpt = std::optional<ResultsVec>;
using VisionHelper::VisionHelper;
virtual ~BrightPointAnalyzer() override = default;
ResultsVecOpt analyze();
// FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉
const auto& get_result() const noexcept { return m_result; }
private:
ResultsVec m_result;
};
}

View File

@@ -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<cv::Point> 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;
}

View File

@@ -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<Result>;
using ResultsVecOpt = std::optional<ResultsVec>;
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<int>& lb)
{
if (lb.size() == 3) {
m_lb = cv::Scalar(lb[0], lb[1], lb[2]);
}
}
void set_ub(const std::vector<int>& 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;
};
}