Files
MaaAssistantArknights/src/MeoAssistance/MultiMatchImageAnalyzer.cpp
2021-10-15 00:03:21 +08:00

78 lines
2.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "MultiMatchImageAnalyzer.h"
#include "Logger.hpp"
#include "Resource.h"
asst::MultiMatchImageAnalyzer::MultiMatchImageAnalyzer(const cv::Mat& image, const Rect& roi, std::string templ_name, double templ_thres)
: AbstractImageAnalyzer(image, roi),
m_templ_name(templ_name),
m_templ_thres(templ_thres)
{
;
}
bool asst::MultiMatchImageAnalyzer::analyze()
{
log.trace("MultiMatchImageAnalyzer::analyze | ", m_templ_name);
const cv::Mat& templ = resource.templ().get_templ(m_templ_name);
if (templ.empty()) {
log.error("templ is empty!");
return false;
}
return multi_match_templ(templ);
}
void asst::MultiMatchImageAnalyzer::sort_result()
{
// 按位置排个序
std::sort(m_result.begin(), m_result.end(),
[](const MatchRect& lhs, const MatchRect& rhs) -> bool {
if (std::abs(lhs.rect.y - rhs.rect.y) < 5) { // y差距较小则理解为是同一排的按x排序
return lhs.rect.x < rhs.rect.x;
}
else {
return lhs.rect.y < rhs.rect.y;
}
}
);
}
bool asst::MultiMatchImageAnalyzer::multi_match_templ(const cv::Mat& templ)
{
cv::Mat matched;
cv::matchTemplate(m_image, templ, matched, cv::TM_CCOEFF_NORMED);
int mini_distance = (std::min)(templ.cols, templ.rows) * 0.5;
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 >= m_templ_thres) {
Rect rect(j, i, templ.cols, templ.rows);
bool need_push = true;
// 如果有两个点离得太近,只取里面得分高的那个
// 一般相邻的都是刚刚push进去的这里倒序快一点
for (auto iter = m_result.rbegin(); iter != m_result.rend(); ++iter) {
if (std::abs(j - iter->rect.x) < mini_distance
&& std::abs(i - iter->rect.y) < mini_distance)
{
if (iter->score < value) {
iter->rect = rect;
iter->score = value;
} // else 这个点就放弃了
need_push = false;
break;
}
}
if (need_push) {
m_result.emplace_back(MatchRect{ AlgorithmType::MatchTemplate, value, rect });
}
}
}
}
if (!m_result.empty()) {
return true;
}
return false;
}