feat.集成企鹅物流识别库,删除特征点检测相关接口

This commit is contained in:
MistEO
2021-10-04 15:54:55 +08:00
parent cc71b23d8b
commit 2e5452503a
41 changed files with 9 additions and 431 deletions

View File

@@ -837,74 +837,6 @@
"endFlag_Doc": "识别到这里面的名字,就不继续往后识别了,一般用列表里的最后一个人名"
}
],
"featureKey_Doc": "特征检测的关键字如果OCR识别到了左边的内容但是却没有右边的内容则进行特征检测进一步确认",
"featureKey": [
[
"森",
"森蚺"
],
[
"白面",
"白面鸮"
],
[
"灰",
"灰烬"
],
[
"早",
"早露"
],
[
"石",
"燧石"
],
[
"深",
"深靛"
],
[
"影",
"傀影"
],
[
"峨",
"嵯峨"
],
[
"利安",
"卡涅利安"
],
[
"星",
"陨星"
],
[
"冬",
"凛冬"
],
[
"狮",
"狮蝎"
]
],
"featureWhatever_Doc": "这里面的无论如何都进行特征检测",
"featureWhatever": [
"砾",
"煌",
"山",
"黑",
"W",
"夕",
"红",
"芬",
"梅",
"宴",
"孑",
"吽",
"空",
"阿"
],
"allNames": [
"桃金娘",
"食铁兽",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -84,20 +84,6 @@ Assistance::Assistance(AsstCallback callback, void* callback_arg)
throw "resource broken";
}
for (const auto& [key, name] : InfrastConfiger::get_instance().m_oper_name_feat) {
ret = m_identify_ptr->add_text_image(name, GetResourceDir() + "operators\\" + Utf8ToGbk(name) + ".png");
if (!ret) {
callback_error(name);
throw "resource broken";
}
}
for (const auto& name : InfrastConfiger::get_instance().m_oper_name_feat_whatever) {
ret = m_identify_ptr->add_text_image(name, GetResourceDir() + "operators\\" + Utf8ToGbk(name) + ".png");
if (!ret) {
callback_error(name);
throw "resource broken";
}
}
for (const auto& file : std::filesystem::directory_iterator(GetResourceDir() + "penguin-stats-recognize\\items")) {
ret = m_identify_ptr->penguin_load_templ(file.path().stem().u8string(), file.path().u8string());
if (!ret) {

View File

@@ -5,7 +5,6 @@
#include <filesystem>
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/imgproc/types_c.h>
namespace penguin {
@@ -17,7 +16,6 @@ namespace penguin {
using namespace asst;
using namespace cv;
using namespace cv::xfeatures2d;
bool Identify::add_image(const std::string& name, const std::string& path)
{
@@ -29,18 +27,6 @@ bool Identify::add_image(const std::string& name, const std::string& path)
return true;
}
bool asst::Identify::add_text_image(const std::string& text, const std::string& path)
{
Mat image = imread(path);
if (image.empty()) {
return false;
}
m_feature_map.emplace(text, surf_detect(image));
return true;
}
Mat Identify::image_2_hist(const cv::Mat& src)
{
Mat src_hsv;
@@ -66,165 +52,6 @@ double Identify::image_hist_comp(const cv::Mat& src, const cv::MatND& hist)
return 1 - compareHist(image_2_hist(src), hist, CV_COMP_BHATTACHARYYA);
}
std::pair<std::vector<cv::KeyPoint>, cv::Mat> asst::Identify::surf_detect(const cv::Mat& image)
{
// 灰度图转换
cv::Mat mat_gray;
cv::cvtColor(image, mat_gray, cv::COLOR_RGB2GRAY);
constexpr int min_hessian = 400;
// SURF特征点检测
static cv::Ptr<SURF> detector = SURF::create(min_hessian);
std::vector<KeyPoint> keypoints;
cv::Mat mat_vector;
// 找到特征点并计算特征描述子(向量)
detector->detectAndCompute(mat_gray, Mat(), keypoints, mat_vector);
return std::make_pair(std::move(keypoints), std::move(mat_vector));
}
std::optional<asst::Rect> asst::Identify::feature_match(
const std::vector<cv::KeyPoint>& query_keypoints, const cv::Mat& query_mat_vector,
const std::vector<cv::KeyPoint>& train_keypoints, const cv::Mat& train_mat_vector
#ifdef LOG_TRACE
, const cv::Mat query_mat, const cv::Mat train_mat
#endif
)
{
if (query_mat_vector.empty() || train_mat_vector.empty()) {
DebugTraceError("feature_match | input vector is empty");
return std::nullopt;
}
std::vector<cv::DMatch> matches;
static FlannBasedMatcher matcher;
matcher.match(query_mat_vector, train_mat_vector, matches);
#ifdef LOG_TRACE
//std::cout << matches.size() << " / " << query_keypoints.size() << std::endl;
cv::Mat allmatch_mat;
cv::drawMatches(query_mat, query_keypoints, train_mat, train_keypoints, matches, allmatch_mat);
#endif
// 最大的距离
auto max_iter = std::max_element(matches.cbegin(), matches.cend(),
[](const cv::DMatch& lhs, const cv::DMatch& rhs) ->bool {
return lhs.distance < rhs.distance;
}); // 描述符欧式距离knn
if (max_iter == matches.cend()) {
return std::nullopt;;
}
float maxdist = max_iter->distance;
std::vector<cv::DMatch> approach_matches;
std::vector<cv::KeyPoint> train_approach_keypoints;
std::vector<cv::KeyPoint> query_approach_keypoints;
std::vector<cv::Point> train_approach_points;
std::vector<cv::Point> query_approach_points;
// 利用距离进行一次逼近
constexpr static const double MatchRatio = 0.4;
int approach_index = 0;
for (const cv::DMatch dmatch : matches) {
if (dmatch.distance < maxdist * MatchRatio) {
// 按理说不会越界,以防万一还是检查一下
if (dmatch.queryIdx >= 0 && dmatch.queryIdx < query_keypoints.size()
&& dmatch.trainIdx >= 0 && dmatch.trainIdx < train_keypoints.size()) {
approach_matches.emplace_back(dmatch);
train_approach_points.emplace_back(train_keypoints.at(dmatch.trainIdx).pt);
query_approach_points.emplace_back(query_keypoints.at(dmatch.queryIdx).pt);
train_approach_keypoints.emplace_back(train_keypoints.at(dmatch.trainIdx));
query_approach_keypoints.emplace_back(query_keypoints.at(dmatch.queryIdx));
}
}
}
#ifdef LOG_TRACE
cv::Mat approach_mat;
cv::drawMatches(query_mat, query_keypoints, train_mat, train_keypoints, approach_matches, approach_mat);
#endif
if (query_approach_points.empty()) {
return std::nullopt;
}
// 使用RANSAC剔除异常值
std::vector<uchar> ransac_status;
cv::Mat fundametal = cv::findFundamentalMat(query_approach_points, train_approach_points, ransac_status, cv::FM_RANSAC);
std::vector<cv::DMatch> ransac_matchs;
std::vector<cv::KeyPoint> train_ransac_keypoints;
std::vector<cv::KeyPoint> query_ransac_keypoints;
int index = 0;
for (size_t i = 0; i != ransac_status.size(); ++i) {
if (ransac_status.at(i) != 0) {
train_ransac_keypoints.emplace_back(train_approach_keypoints.at(i));
query_ransac_keypoints.emplace_back(query_approach_keypoints.at(i));
cv::DMatch dmatch = approach_matches.at(i);
ransac_matchs.emplace_back(std::move(dmatch));
++index;
}
}
// 做一次算数均值滤波过滤异常的点。这个算法有点蠢TODO可以看下怎么改
size_t point_size = train_ransac_keypoints.size();
if (point_size == 0) {
return std::nullopt;
}
cv::Point sum_point = std::accumulate(
train_ransac_keypoints.cbegin(), train_ransac_keypoints.cend(), cv::Point(),
[](cv::Point sum, const cv::KeyPoint& rhs) -> cv::Point {
return cv::Point(sum.x + rhs.pt.x, sum.y + rhs.pt.y);
});
cv::Point avg_point(sum_point.x / point_size, sum_point.y / point_size);
std::vector<cv::DMatch> good_matchs;
std::vector<cv::Point> good_points;
// TODO这个阈值需要根据分辨率进行缩放而且最好写到配置文件里
constexpr static int DistanceThreshold = 100;
for (size_t i = 0; i != train_ransac_keypoints.size(); ++i) {
// 没必要算距离x y各算一下就行了省点CPU时间
//int distance = std::sqrt(std::pow(avg_point.x - cur_x, 2) + std::pow(avg_point.y - cur_y, 2));
cv::Point2f& pt = train_ransac_keypoints.at(i).pt;
int x_distance = std::abs(avg_point.x - pt.x);
int y_distance = std::abs(avg_point.y - pt.y);
if (x_distance < DistanceThreshold && y_distance < DistanceThreshold) {
good_matchs.emplace_back(ransac_matchs.at(i));
good_points.emplace_back(pt);
}
}
#ifdef LOG_TRACE
cv::Mat ransac_mat;
cv::drawMatches(query_mat, query_keypoints, train_mat, train_keypoints, ransac_matchs, ransac_mat);
cv::Mat good_mat;
cv::drawMatches(query_mat, query_keypoints, train_mat, train_keypoints, good_matchs, good_mat);
#endif
constexpr static const double MatchSizeRatioThreshold = 0.1;
if (good_points.size() >= query_keypoints.size() * MatchSizeRatioThreshold) {
Rect dst;
int left = 0, right = 0, top = 0, bottom = 0;
for (const cv::Point& pt : good_points) {
if (pt.x < left || left == 0) {
left = pt.x;
}
if (pt.x > right || right == 0) {
right = pt.x;
}
if (pt.y < top || top == 0) {
top = pt.y;
}
if (pt.y > bottom || bottom == 0) {
bottom = pt.y;
}
}
dst = { left, top, right - left, bottom - top };
return dst;
}
return std::nullopt;
}
std::vector<TextArea> asst::Identify::ocr_detect(const cv::Mat& image)
{
OcrResult ocr_results = m_ocr_lite.detect(image,
@@ -360,34 +187,6 @@ std::vector<asst::Identify::FindImageResult> asst::Identify::find_all_images(
return results;
}
std::optional<TextArea> asst::Identify::feature_match(const cv::Mat& image, const std::string& templ_name)
{
//DebugTraceFunction;
if (m_feature_map.find(templ_name) == m_feature_map.cend()) {
return std::nullopt;
}
auto&& [query_keypoints, query_mat_vector] = m_feature_map[templ_name];
auto&& [train_keypoints, train_mat_vector] = surf_detect(image);
#ifdef LOG_TRACE
cv::Mat query_mat = cv::imread(GetResourceDir() + "operators\\" + Utf8ToGbk(templ_name) + ".png");
auto&& ret = feature_match(query_keypoints, query_mat_vector, train_keypoints, train_mat_vector,
query_mat, image);
#else
auto&& ret = feature_match(query_keypoints, query_mat_vector, train_keypoints, train_mat_vector);
#endif
if (ret) {
TextArea dst;
dst.text = templ_name;
dst.rect = std::move(ret.value());
return dst;
}
else {
return std::nullopt;
}
}
void Identify::clear_cache()
{
m_cache_map.clear();
@@ -411,15 +210,7 @@ bool asst::Identify::ocr_init_models(const std::string& dir)
const std::string rec_filename = dir + RecName;
const std::string keys_filename = dir + KeysName;
if (std::filesystem::exists(dst_filename)
&& std::filesystem::exists(cls_filename)
&& std::filesystem::exists(rec_filename)
&& std::filesystem::exists(keys_filename))
{
m_ocr_lite.initModels(dst_filename, cls_filename, rec_filename, keys_filename);
return true;
}
return false;
return m_ocr_lite.initModels(dst_filename, cls_filename, rec_filename, keys_filename);
}
std::optional<asst::Rect> asst::Identify::find_text(const cv::Mat& image, const std::string& text)
@@ -500,10 +291,8 @@ bool asst::Identify::penguin_load_templ(const std::string& item_id, const std::s
std::string asst::Identify::penguin_recognize(const cv::Mat& image)
{
cv::Mat resize_mat;
cv::resize(image, resize_mat, cv::Size(1024, 768));
std::vector<uchar> buf;
cv::imencode(".png", resize_mat, buf);
cv::imencode(".png", image, buf);
return penguin::recognize(buf.data(), buf.size());
}

View File

@@ -33,7 +33,6 @@ namespace asst {
/*** OpenCV package ***/
bool add_image(const std::string& name, const std::string& path);
bool add_text_image(const std::string& text, const std::string& path);
constexpr static double NotAddCache = 999.0;
FindImageResult find_image(
@@ -41,8 +40,6 @@ namespace asst {
std::vector<FindImageResult> find_all_images(
const cv::Mat& image, const std::string& templ_name, double threshold = 0, bool rect_zoom = true) const;
std::optional<TextArea> feature_match(const cv::Mat& image, const std::string& key);
void clear_cache();
/*** OcrLite package ***/
@@ -67,21 +64,8 @@ namespace asst {
// return pair< suitability, raw opencv::point>
std::pair<double, cv::Point> match_template(const cv::Mat& image, const cv::Mat& templ);
// return pair<特征点s特征点描述子向量>
std::pair<std::vector<cv::KeyPoint>, cv::Mat> surf_detect(const cv::Mat& mat);
std::optional<Rect> feature_match(
const std::vector<cv::KeyPoint>& query_keypoints, const cv::Mat& query_mat_vector,
const std::vector<cv::KeyPoint>& train_keypoints, const cv::Mat& train_mat_vector
#ifdef LOG_TRACE
, const cv::Mat query_mat = cv::Mat(), const cv::Mat train_mat = cv::Mat()
#endif
);
std::unordered_map<std::string, cv::Mat> m_mat_map;
bool m_use_cache = true; // 是否使用缓存——总开关
std::unordered_map<std::string, std::pair<cv::Rect, cv::Mat>> m_cache_map; // 位置、直方图缓存
// value: pair<特征点s特征点描述子向量>
std::unordered_map<std::string, std::pair<std::vector<cv::KeyPoint>, cv::Mat>> m_feature_map;
OcrLiteCaller m_ocr_lite;
};

View File

@@ -82,8 +82,6 @@ std::optional<std::unordered_map<std::string, OperInfrastInfo>> asst::IdentifyOp
};
m_callback(AsstMsg::TaskStart, task_start_json, m_callback_arg);
std::unordered_map<std::string, std::string> feature_cond = InfrastConfiger::get_instance().m_oper_name_feat;
std::unordered_set<std::string> feature_whatever = InfrastConfiger::get_instance().m_oper_name_feat_whatever;
std::unordered_map<std::string, OperInfrastInfo> detected_opers;
int times = 0;
@@ -100,7 +98,7 @@ std::optional<std::unordered_map<std::string, OperInfrastInfo>> asst::IdentifyOp
std::future<bool> swipe_future = std::async(
std::launch::async, &IdentifyOperTask::swipe, this, reverse, WinMacro::SwipeExtraDelayDefault);
auto cur_name_textarea = detect_operators_name(image, feature_cond, feature_whatever);
auto cur_name_textarea = detect_operators_name(image);
int oper_numer = detected_opers.size();
for (const TextArea& textarea : cur_name_textarea) {

View File

@@ -124,11 +124,7 @@ bool asst::InfrastAbstractTask::append_task_to_back_to_infrast_home()
return true;
}
std::vector<TextArea> asst::InfrastAbstractTask::detect_operators_name(
const cv::Mat& image,
std::unordered_map<std::string,
std::string>& feature_cond,
std::unordered_set<std::string>& feature_whatever)
std::vector<TextArea> asst::InfrastAbstractTask::detect_operators_name(const cv::Mat& image)
{
DebugTraceFunction;
@@ -191,98 +187,6 @@ std::vector<TextArea> asst::InfrastAbstractTask::detect_operators_name(
std::make_move_iterator(lower_part_names.begin()),
std::make_move_iterator(lower_part_names.end()));
// 如果ocr结果中已经有某个干员了就没必要再尝试对他特征检测了直接删了
for (const TextArea& textarea : all_opers_textarea) {
auto cond_iter = std::find_if(feature_cond.begin(), feature_cond.end(),
[&textarea](const auto& pair) -> bool {
return textarea.text == pair.second;
});
if (cond_iter != feature_cond.end()) {
feature_cond.erase(cond_iter);
}
auto whatever_iter = std::find_if(feature_whatever.begin(), feature_whatever.end(),
[&textarea](const std::string& str) -> bool {
return textarea.text == str;
});
if (whatever_iter != feature_whatever.end()) {
feature_whatever.erase(whatever_iter);
}
}
// 用特征检测再筛选一遍OCR识别漏了的——有关键字的
for (const TextArea& textarea : all_text_area) {
auto find_iter = std::find_if(all_opers_textarea.cbegin(), all_opers_textarea.cend(),
[&textarea](const auto& rhs) -> bool {
return textarea.text == rhs.text; });
if (find_iter != all_opers_textarea.cend()) {
continue;
}
for (auto iter = feature_cond.begin(); iter != feature_cond.end(); ++iter) {
auto& [key, value] = *iter;
// 识别到了key但是没识别到value这种情况就需要进行特征检测进一步确认了
if (textarea.text.find(key) != std::string::npos
&& textarea.text.find(value) == std::string::npos) {
// 把key所在的矩形放大一点送去做特征检测不需要把整张图片都送去检测
Rect magnified_area = textarea.rect.center_zoom(2.0, image.cols, image.rows);
// key是关键字而已真正要识别的是value
auto&& ret = OcrAbstractTask::m_identify_ptr->feature_match(
image(make_rect<cv::Rect>(magnified_area)), value);
if (ret) {
// 匹配上了下次就不用再匹配这个了,直接删了
all_opers_textarea.emplace_back(value, textarea.rect);
iter = feature_cond.erase(iter);
--iter;
// 也从whatever里面删了
auto whatever_iter = std::find_if(feature_whatever.begin(), feature_whatever.end(),
[&textarea](const std::string& str) -> bool {
return textarea.text == str;
});
if (whatever_iter != feature_whatever.end()) {
feature_whatever.erase(whatever_iter);
}
// 顺便再涂黑了避免后面被whatever特征检测的误识别
// 注意这里是浅拷贝原图image也会被涂黑
//cv::rectangle(draw_image, cv_rect, cv::Scalar(0, 0, 0), -1);
}
}
}
}
// 用特征检测再筛选一遍OCR识别漏了的——无论如何都进行识别的
for (auto iter = feature_whatever.begin(); iter != feature_whatever.end(); ++iter) {
// 上半部分长条形的图片
auto&& upper_ret = OcrAbstractTask::m_identify_ptr->feature_match(upper_part_name_image, *iter);
if (upper_ret) {
TextArea temp = std::move(upper_ret.value());
#ifdef LOG_TRACE // 也顺便涂黑一下,方便看谁没被识别出来
// 注意这里是浅拷贝原图image也会被涂黑
cv::rectangle(upper_part_name_image, make_rect<cv::Rect>(temp.rect), cv::Scalar(0, 0, 0), -1);
#endif
// 因为图片是裁剪过的,所以对应原图的坐标要加上裁剪的参数
temp.rect.y += cropped_upper_y;
all_opers_textarea.emplace_back(std::move(temp));
iter = feature_whatever.erase(iter);
--iter;
continue;
}
// 下半部分长条形的图片
auto&& lower_ret = OcrAbstractTask::m_identify_ptr->feature_match(lower_part_name_image, *iter);
if (lower_ret) {
TextArea temp = std::move(lower_ret.value());
#ifdef LOG_TRACE // 也顺便涂黑一下,方便看谁没被识别出来
// 注意这里是浅拷贝原图image也会被涂黑
cv::rectangle(lower_part_name_image, make_rect<cv::Rect>(temp.rect), cv::Scalar(0, 0, 0), -1);
#endif
// 因为图片是裁剪过的,所以对应原图的坐标要加上裁剪的参数
temp.rect.y += cropped_lower_y;
all_opers_textarea.emplace_back(std::move(temp));
iter = feature_whatever.erase(iter);
--iter;
continue;
}
}
return all_opers_textarea;
}

View File

@@ -23,9 +23,7 @@ namespace asst {
virtual bool append_task_to_back_to_infrast_home(); // 添加返回主界面的任务
// 检测干员名
virtual std::vector<TextArea> detect_operators_name(const cv::Mat& image,
std::unordered_map<std::string, std::string>& feature_cond,
std::unordered_set<std::string>& feature_whatever);
virtual std::vector<TextArea> detect_operators_name(const cv::Mat& image);
virtual bool enter_station(const std::vector<std::string>& templ_names, int index, double threshold = 0.8);
virtual bool click_first_operator();

View File

@@ -15,12 +15,6 @@ bool InfrastConfiger::parse(const json::value& json)
for (const json::value& name : json.at("allNames").as_array()) {
m_all_opers_name.emplace(name.as_string());
}
for (const json::value& pair : json.at("featureKey").as_array()) {
m_oper_name_feat.emplace(pair[0].as_string(), pair[1].as_string());
}
for (const json::value& name : json.at("featureWhatever").as_array()) {
m_oper_name_feat_whatever.emplace(name.as_string());
}
// 每个基建设施中的干员组合信息
for (const json::value& facility : json.at("infrast").as_array()) {

View File

@@ -20,8 +20,6 @@ namespace asst {
}
std::unordered_set<std::string> m_all_opers_name; // 所有干员的名字
std::unordered_map<std::string, std::string> m_oper_name_feat; // 根据关键字需要特征检测干员名如果OCR识别到了key的内容但是却没有value的内容则进行特征检测进一步确认
std::unordered_set<std::string> m_oper_name_feat_whatever; // 无论如何都进行特征检测的干员名
// 各个设施内的可能干员组合注意值是vector是有序的
std::unordered_map<std::string, std::vector<OperInfrastComb>> m_infrast_combs;
// 各个设施的识别结束标记,识别到这个名字就停止继续识别了,一般放列表中最后几个人名

View File

@@ -123,9 +123,6 @@ std::optional<std::unordered_map<std::string, OperInfrastInfo>> asst::InfrastPro
return std::nullopt;
}
std::unordered_map<std::string, std::string> feature_cond = InfrastConfiger::get_instance().m_oper_name_feat;
std::unordered_set<std::string> feature_whatever = InfrastConfiger::get_instance().m_oper_name_feat_whatever;
std::vector<std::string> end_flag_vec = InfrastConfiger::get_instance().m_infrast_end_flag[m_facility];
std::unordered_map<std::string, OperInfrastInfo> cur_opers_info;
@@ -139,7 +136,7 @@ std::optional<std::unordered_map<std::string, OperInfrastInfo>> asst::InfrastPro
std::future<bool> swipe_future = std::async(
std::launch::async, &InfrastProductionTask::swipe, this, false, WinMacro::SwipeExtraDelayDefault);
auto cur_name_textarea = detect_operators_name(image, feature_cond, feature_whatever);
auto cur_name_textarea = detect_operators_name(image);
for (const TextArea& textarea : cur_name_textarea) {
OperInfrastInfo info;
// 考虑map中没有这个名字的情况包括一开始识别漏了、抽到了新干员但没更新等也有可能是本次识别错了
@@ -255,15 +252,13 @@ bool asst::InfrastProductionTask::swipe_and_select(const std::vector<std::string
swipe_to_the_left();
auto need_to_select = name_comb;
std::unordered_map<std::string, std::string> feature_cond = InfrastConfiger::get_instance().m_oper_name_feat;
std::unordered_set<std::string> feature_whatever = InfrastConfiger::get_instance().m_oper_name_feat_whatever;
// 一边滑动一边点击最优解中的干员
for (int i = 0; i != swipe_max_times; ++i) {
if (need_exit()) {
return false;
}
const cv::Mat& image = m_controller_ptr->get_image(true);
auto cur_name_textarea = detect_operators_name(image, feature_cond, feature_whatever);
auto cur_name_textarea = detect_operators_name(image);
for (TextArea& text_area : cur_name_textarea) {
// 点过了就不会再点了直接从最优解vector里面删了

View File

@@ -128,7 +128,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libmeojson.lib;OcrLiteOnnx.lib;opencv_world3413.lib;penguin-stats-recognize.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>libmeojson.lib;OcrLiteOnnx.lib;opencv_world453.lib;penguin-stats-recognize.lib;%(AdditionalDependencies)</AdditionalDependencies>
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
<AdditionalLibraryDirectories>$(SolutionDir)3rdparty\lib\</AdditionalLibraryDirectories>
</Link>
@@ -172,7 +172,7 @@ xcopy /e /y /i /c $(SolutionDir)3rdparty\resource $(TargetDir)resource</Command>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libmeojson.lib;OcrLiteOnnx.lib;opencv_world3413.lib;penguin-stats-recognize.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>libmeojson.lib;OcrLiteOnnx.lib;opencv_world453.lib;penguin-stats-recognize.lib;%(AdditionalDependencies)</AdditionalDependencies>
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
<AdditionalLibraryDirectories>$(SolutionDir)3rdparty\lib\</AdditionalLibraryDirectories>
</Link>