完成“精英化”识别demo

This commit is contained in:
MistEO
2021-08-18 23:07:36 +08:00
parent 7487992428
commit 77689acb67
7 changed files with 229 additions and 251 deletions

View File

@@ -28,9 +28,10 @@ namespace asst {
// return tuple< algorithmType, suitability, matched asst::rect>
std::tuple<AlgorithmType, double, asst::Rect> find_image(const cv::Mat& image, const std::string& templ, double templ_threshold);
// return pair< suitability, raw opencv::point>
std::pair<double, cv::Point> match_template(const cv::Mat& cur, const cv::Mat& templ);
std::optional<TextArea> feature_match(const cv::Mat& mat, const std::string& key);
// for debug
std::vector<TextArea> feature_match_all(const cv::Mat& mat);
void clear_cache();
@@ -49,9 +50,13 @@ namespace asst {
// return pair<特征点s特征点描述子向量>
std::pair<std::vector<cv::KeyPoint>, cv::Mat> surf_detect(const cv::Mat& mat);
// return pair< suitability, raw opencv::point>
std::pair<double, cv::Point> match_template(const cv::Mat& cur, const cv::Mat& templ);
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;

View File

@@ -68,13 +68,28 @@ Assistance::Assistance(AsstCallback callback, void* callback_arg)
return;
}
for (const std::string& name : InfrastConfiger::get_instance().m_mfg_opers) {
for (const auto& [key, name] : InfrastConfiger::get_instance().m_mfg_feat) {
ret = m_identify_ptr->add_text_image(name, GetResourceDir() + "operators\\" + Utf8ToGbk(name) + ".png");
if (!ret) {
callback_error();
return;
}
}
for (const auto& name : InfrastConfiger::get_instance().m_mfg_feat_whatever) {
ret = m_identify_ptr->add_text_image(name, GetResourceDir() + "operators\\" + Utf8ToGbk(name) + ".png");
if (!ret) {
callback_error();
return;
}
}
// 精一和精二的图片,调试用
ret = m_identify_ptr->add_text_image("Elite1", GetResourceDir() + "operators\\Elite1.png");
ret &= m_identify_ptr->add_text_image("Elite2", GetResourceDir() + "operators\\Elite2.png");
if (!ret) {
callback_error();
return;
}
m_working_thread = std::thread(working_proc, this);
m_msg_thread = std::thread(msg_proc, this);
@@ -289,7 +304,7 @@ void Assistance::working_proc(Assistance* p_this)
int retry_times = 0;
while (!p_this->m_thread_exit)
{
DebugTraceScope("Assistance::working_proc Loop");
//DebugTraceScope("Assistance::working_proc Loop");
std::unique_lock<std::mutex> lock(p_this->m_mutex);
if (!p_this->m_thread_idle && !p_this->m_tasks_queue.empty())
{
@@ -360,7 +375,7 @@ void Assistance::msg_proc(Assistance* p_this)
while (!p_this->m_thread_exit)
{
DebugTraceScope("Assistance::msg_proc Loop");
//DebugTraceScope("Assistance::msg_proc Loop");
std::unique_lock<std::mutex> lock(p_this->m_msg_mutex);
if (!p_this->m_msg_queue.empty())
{

View File

@@ -94,6 +94,145 @@ std::pair<std::vector<cv::KeyPoint>, cv::Mat> asst::Identify::surf_detect(const
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
)
{
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 = 200;
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.075;
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& mat)
{
OcrResult ocr_results = m_ocr_lite.detect(mat,
@@ -166,253 +305,25 @@ std::optional<TextArea> asst::Identify::feature_match(const cv::Mat& mat, const
if (m_feature_map.find(key) == m_feature_map.cend()) {
return std::nullopt;
}
static FlannBasedMatcher matcher;
auto&& [train_keypoints, train_mat_vector] = surf_detect(mat);
auto&& [query_keypoints, query_mat_vector] = m_feature_map[key];
std::vector<cv::DMatch> matches;
matcher.match(query_mat_vector, train_mat_vector, matches);
// 最大的距离
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));
}
}
}
// 使用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 != approach_matches.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 = 200;
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);
}
}
auto&& [train_keypoints, train_mat_vector] = surf_detect(mat);
#ifdef LOG_TRACE
std::cout << Utf8ToGbk(key) << " " << good_points.size() << " / " << query_keypoints.size() << std::endl;
// for debug
cv::Mat text_mat = cv::imread(GetResourceDir() + "operators\\" + Utf8ToGbk(key) + ".png");
cv::Mat approach_mat;
cv::drawMatches(text_mat, query_keypoints, mat, train_keypoints, ransac_matchs, approach_mat);
cv::Mat good_mat;
cv::drawMatches(text_mat, query_keypoints, mat, train_keypoints, good_matchs, good_mat);
cv::Mat query_mat = cv::imread(GetResourceDir() + "operators\\" + Utf8ToGbk(key) + ".png");
auto&& ret = feature_match(query_keypoints, query_mat_vector, train_keypoints, train_mat_vector,
query_mat, mat);
#else
auto&& ret = feature_match(query_keypoints, query_mat_vector, train_keypoints, train_mat_vector);
#endif
constexpr static const double MatchSizeRatioThreshold = 0.075;
if (good_points.size() >= query_keypoints.size() * MatchSizeRatioThreshold) {
if (ret) {
TextArea dst;
dst.text = key;
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.rect = { left, top, right - left, bottom - top };
dst.rect = std::move(ret.value());
return dst;
}
return std::nullopt;
}
std::vector<TextArea> asst::Identify::feature_match_all(const cv::Mat& mat)
{
DebugTraceFunction;
auto&& [train_keypoints, train_mat_vector] = surf_detect(mat);
static FlannBasedMatcher matcher;
std::vector<TextArea> matched_text_area;
for (auto&& [key, feature] : m_feature_map) {
auto&& [query_keypoints, query_mat_vector] = feature;
std::vector<cv::DMatch> matches;
matcher.match(query_mat_vector, train_mat_vector, matches);
// 最大的距离
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()) {
continue;
}
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));
}
}
}
// 使用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 != approach_matches.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;
}
}
// 做一次算数均值滤波,过滤异常的点
size_t point_size = train_ransac_keypoints.size();
if (point_size == 0) {
continue;
}
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 = 300;
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);
}
}
std::cout << Utf8ToGbk(key) << " " << good_points.size() << " / " << query_keypoints.size() << std::endl;
constexpr static const double MatchSizeRatioThreshold = 0.075;
if (good_points.size() >= query_keypoints.size() * MatchSizeRatioThreshold) {
TextArea textarea;
textarea.text = key;
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;
}
}
textarea.rect = { left, top, right - left, bottom - top };
//draw_rect = { left + 129, top, right - left, bottom - top };
matched_text_area.emplace_back(std::move(textarea));
}
// for debug
cv::Mat text_mat = cv::imread(GetResourceDir() + "operators\\" + Utf8ToGbk(key) + ".png");
cv::Mat approach_mat;
cv::drawMatches(text_mat, query_keypoints, mat, train_keypoints, ransac_matchs, approach_mat);
cv::Mat good_mat;
cv::drawMatches(text_mat, query_keypoints, mat, train_keypoints, good_matchs, good_mat);
else {
return std::nullopt;
}
return matched_text_area;
}
void Identify::clear_cache()

View File

@@ -372,7 +372,7 @@ std::shared_ptr<TaskInfo> ProcessTask::match_image(Rect* matched_rect)
break;
}
callback_json["rect"] = json::array({ rect.x, rect.y, rect.width, rect.height });
callback_json["elite_rect"] = json::array({ rect.x, rect.y, rect.width, rect.height });
callback_json["name"] = task_name;
if (matched_rect != NULL) {
*matched_rect = std::move(rect);
@@ -630,7 +630,7 @@ bool OpenRecruitTask::run()
task_json["type"] = "ClickTask";
for (const TextArea& text_area : all_tags) {
if (std::find(final_tags_name.cbegin(), final_tags_name.cend(), text_area.text) != final_tags_name.cend()) {
task_json["rect"] = json::array({ text_area.rect.x, text_area.rect.y, text_area.rect.width, text_area.rect.height });
task_json["elite_rect"] = json::array({ text_area.rect.x, text_area.rect.y, text_area.rect.width, text_area.rect.height });
task_json["retry_times"] = m_retry_times;
task_json["task_chain"] = m_task_chain;
m_callback(AsstMsg::AppendTask, task_json, m_callback_arg);
@@ -685,6 +685,53 @@ bool TestOcrTask::run()
return false;
}
std::vector<std::vector<std::string>> all_oper_combs; // 所有的干员组合
std::unordered_set<std::string> all_oper_name; // 所有干员名
std::string oper_end_flag; // 干员名结束标记识别到这个string就认为识别完成了
std::unordered_map<std::string, std::string> feature_cond_default; // 特征检测关键字如果OCR识别到了key的内容但是却没有value的内容则进行特征检测进一步确认
std::unordered_set<std::string> feature_whatever_default; // 无论如何都进行特征检测的
all_oper_combs = InfrastConfiger::get_instance().m_mfg_combs;
all_oper_name = InfrastConfiger::get_instance().m_mfg_opers;
oper_end_flag = InfrastConfiger::get_instance().m_mfg_end;
feature_cond_default = InfrastConfiger::get_instance().m_mfg_feat;
feature_whatever_default = InfrastConfiger::get_instance().m_mfg_feat_whatever;
std::unordered_map<std::string, std::string> feature_cond = feature_cond_default;
std::unordered_set<std::string> feature_whatever = feature_whatever_default;
auto detect_foo = [&](const cv::Mat& image) -> std::vector<TextArea> {
std::vector<TextArea> all_text_area = ocr_detect(image);
/* 过滤出所有制造站中的干员名 */
std::vector<TextArea> cur_name_textarea = text_search(
all_text_area,
all_oper_name,
Configer::get_instance().m_infrast_ocr_replace);
return cur_name_textarea;
};
const cv::Mat& image = get_format_image(true);
auto cur_name_textarea = detect_foo(image);
// for debug
cv::Mat elite1 = cv::imread(GetResourceDir() + "operators\\Elite1.png");
cv::Mat elite2 = cv::imread(GetResourceDir() + "operators\\Elite2.png");
for (const TextArea& textarea : cur_name_textarea)
{
cv::Rect elite_rect;
elite_rect.x = textarea.rect.x - 200;
elite_rect.y = textarea.rect.y - 200;
elite_rect.width = 200;
elite_rect.height = 150;
auto&& [socre1, point1] = m_identify_ptr->match_template(image(elite_rect), elite1);
auto&& [socre2, point2] = m_identify_ptr->match_template(image(elite_rect), elite2);
std::cout << Utf8ToGbk(textarea.text) << " elite1: " << socre1 << ", eilte2: " << socre2 << std::endl;
//m_identify_ptr->feature_match(image(elite_rect), "Elite1");
//m_identify_ptr->feature_match(image(elite_rect), "Elite2");
}
return true;
}

View File

@@ -3,7 +3,7 @@
using namespace asst;
void test_dorm(Assistance* ptr);
void test_ocr(Assistance* ptr);
void test_swipe(Assistance* ptr);
void test_infrast(Assistance* ptr);
@@ -24,7 +24,7 @@ int main(int argc, char** argv)
char ch = 0;
while (ch != 'q') {
test_infrast(ptr);
test_ocr(ptr);
//test_swipe(ptr);
ch = getchar();
@@ -43,7 +43,7 @@ void test_swipe(Assistance* ptr)
AsstTestSwipe(ptr, 1000, 300, 500, 300);
}
void test_dorm(Assistance* ptr)
void test_ocr(Assistance* ptr)
{
const char* text_array[] = { "×¢ÒâÁ¦" };

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB