mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-17 01:59:33 +08:00
89 lines
2.9 KiB
C++
89 lines
2.9 KiB
C++
#include "MultiMatcher.h"
|
||
|
||
#include "Utils/Ranges.hpp"
|
||
#include <utility>
|
||
|
||
#include "Utils/NoWarningCV.h"
|
||
|
||
#include "Config/TaskData.h"
|
||
#include "Config/TemplResource.h"
|
||
#include "Utils/Logger.hpp"
|
||
#include "Vision/Matcher.h"
|
||
|
||
using namespace asst;
|
||
|
||
MultiMatcher::ResultsVecOpt MultiMatcher::analyze() const
|
||
{
|
||
auto match_results = Matcher::preproc_and_match(make_roi(m_image, m_roi), m_params);
|
||
|
||
std::vector<Result> results;
|
||
for (size_t index = 0; index < match_results.size(); ++index) {
|
||
const auto& [matched, templ, templ_name] = match_results[index];
|
||
if (matched.empty()) {
|
||
continue;
|
||
}
|
||
|
||
double threshold = m_params.templ_thres[index];
|
||
int min_distance = (std::min)(templ.cols, templ.rows) / 2;
|
||
for (int i = 0; i != matched.rows; ++i) {
|
||
for (int j = 0; j != matched.cols; ++j) {
|
||
auto value = matched.at<float>(i, j);
|
||
if (value < threshold || std::isnan(value) || std::isinf(value)) {
|
||
continue;
|
||
}
|
||
|
||
Rect rect(j + m_roi.x, i + m_roi.y, templ.cols, templ.rows);
|
||
bool need_push = true;
|
||
// 如果有两个点离得太近,只取里面得分高的那个
|
||
// 一般相邻的都是刚刚push进去的,这里倒序快一点
|
||
for (auto& iter : ranges::reverse_view(results)) {
|
||
if (std::abs(j + m_roi.x - iter.rect.x) >= min_distance ||
|
||
std::abs(i + m_roi.y - iter.rect.y) >= min_distance) {
|
||
continue;
|
||
}
|
||
|
||
if (iter.score < value) {
|
||
iter.rect = rect;
|
||
iter.score = value;
|
||
iter.templ_name = templ_name;
|
||
} // else 这个点就放弃了
|
||
need_push = false;
|
||
break;
|
||
}
|
||
if (need_push) {
|
||
Result tmp;
|
||
tmp.rect = rect;
|
||
tmp.score = value;
|
||
tmp.templ_name = templ_name;
|
||
results.emplace_back(std::move(tmp));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (results.empty()) {
|
||
return std::nullopt;
|
||
}
|
||
|
||
#ifdef ASST_DEBUG
|
||
for (const auto& rect : results) {
|
||
cv::rectangle(m_image_draw, make_rect<cv::Rect>(rect.rect), cv::Scalar(0, 0, 255), 2);
|
||
cv::putText(
|
||
m_image_draw,
|
||
std::to_string(rect.score),
|
||
cv::Point(rect.rect.x, rect.rect.y),
|
||
1,
|
||
1,
|
||
cv::Scalar(0, 0, 255));
|
||
}
|
||
#endif
|
||
|
||
if (m_log_tracing) {
|
||
Log.trace("multi_match | ", "result:", results, "roi:", m_roi);
|
||
}
|
||
|
||
// FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉
|
||
m_result = std::move(results);
|
||
return m_result;
|
||
}
|