faster matching

This commit is contained in:
mrbesen 2022-03-12 20:56:07 +01:00
parent ca55845e5f
commit f3b56c378c
Signed by untrusted user: MrBesen
GPG Key ID: 596B2350DCD67504
3 changed files with 68 additions and 26 deletions

View File

@ -5,12 +5,17 @@
class Matcher {
private:
cv::Mat templ;
int32_t posx = -1;
int32_t posy = -1;
public:
Matcher(const std::string& filename);
Matcher(const cv::Mat& templ);
~Matcher();
// instead of searching for a match, just look at this position
void setOffset(int32_t x, int32_t y);
struct Match {
bool doesMatch = false;
int x = 0, y = 0;
@ -19,17 +24,11 @@ public:
bool operator==(const Match&) const;
bool operator!=(const Match&) const;
// get the center of the button
constexpr int getButtonX() const {
return x + (width/2);
}
constexpr int getButtonY() const {
return y + (height/2);
}
};
Match match(const cv::Mat& img);
private:
Match matchAll(const cv::Mat& img);
Match matchPos(const cv::Mat& img);
};

View File

@ -4,6 +4,7 @@
#include <Log.h>
#include "util.h"
#include "fakescreen.h"
void debugImage(cv::Mat img, const std::string& name) {
if(img.channels() > 3) {
@ -23,6 +24,8 @@ void LolAutoAccept::checkForGame() {
cv::resize(img, img, cv::Size(ScreenShot::DEFAULTWIDTH, ScreenShot::DEFAULTHEIGHT));
// debugImage(img, "resized");
Matcher::Match mat = acceptmatcher.match(img);
if(mat.doesMatch) {
@ -123,6 +126,10 @@ LolAutoAccept::LolAutoAccept() : acceptmatcher("imgs/Accept.png"), arrowmatcher(
inputs.addPoint({775, 105}); // search box
inputs.addPoint({380, 160}); // first champ
inputs.addPoint({638, 608}); // pick champ
acceptmatcher.setOffset(539, 529);
arrowmatcher.setOffset(615, 617);
banmatcher.setOffset(1232, 90);
}
void LolAutoAccept::setPrePick(const std::string& prePick) {
@ -147,17 +154,17 @@ void LolAutoAccept::run() {
screen = (wins.at(0)); // just take the first
// testing whole screen, but take a part of it, so it behaves like a focused screenshot
// screen = new FakeScreen(1, 683, 1280, 720);
// testing: whole screen:
// screen = new ScreenShot();
//delete other screens
for(uint32_t i = 1; i < wins.size(); ++i) {
ScreenShot* ss = wins.at(i);
delete ss;
}
lastacceptmatch = {false};
while(true) {
auto start = std::chrono::high_resolution_clock::now();
switch(state) {
case State::LOBBY:
checkForGame();
@ -167,8 +174,11 @@ void LolAutoAccept::run() {
default: break;
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> dur = (end-start);
Log::info << "iteration took: " << (dur.count() * 1000 ) << " ms";
std::this_thread::sleep_for(std::chrono::milliseconds(800));
}
delete wins.at(0);
delete screen;
}

View File

@ -2,6 +2,8 @@
#include <Log.h>
#include "util.h"
Matcher::Matcher(const std::string& filename) {
templ = cv::imread(filename, cv::IMREAD_COLOR);
}
@ -10,6 +12,12 @@ Matcher::Matcher(const cv::Mat& templ) {
}
Matcher::~Matcher() {}
void Matcher::setOffset(int32_t x, int32_t y) {
posx = x;
posy = y;
}
bool Matcher::Match::operator==(const Match& other) const {
return doesMatch == other.doesMatch && x == other.x && y == other.y && width == other.width && height == other.height;
}
@ -19,27 +27,52 @@ bool Matcher::Match::operator!=(const Match& other) const {
}
// https://stackoverflow.com/a/43133263/4399859
Matcher::Match Matcher::match(const cv::Mat& img) {
// create out mat
int result_cols = img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;
cv::Mat out(result_rows, result_cols, CV_32FC1);
// remove Alpha channel from input
cv::Mat converted;
cv::cvtColor(img, converted, cv::COLOR_RGBA2RGB);
if(posx < 0 || posy < 0) {
return matchAll(converted);
}
return matchPos(converted);
}
// https://stackoverflow.com/a/43133263/4399859
Matcher::Match Matcher::matchAll(const cv::Mat& img) {
// create out mat
int result_cols = img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;
cv::Mat out(result_rows, result_cols, CV_32FC1);
Log::info << "match size: " << result_cols << " " << result_cols;
// match
cv::matchTemplate(converted, templ, out, cv::TM_CCORR_NORMED);
cv::matchTemplate(img, templ, out, cv::TM_CCORR_NORMED);
double minVal; double maxVal;
cv::Point minLoc; cv::Point maxLoc;
cv::minMaxLoc( out, &minVal, &maxVal, &minLoc, &maxLoc, cv::Mat() );
Log::debug << "pixelcount: " << (templ.cols * templ.rows) << /* " minValbn: " << minValbn << " maxValbn: " << maxValbn << */ " minVal: " << minVal << " maxVal: " << maxVal << " minLoc: " << minLoc.x << " " << minLoc.y << " maxLoc: " << maxLoc.x << " " << maxLoc.y;
Log::debug << "pixelcount: " << (templ.cols * templ.rows) << " minVal: " << minVal << " maxVal: " << maxVal << " minLoc: " << minLoc.x << " " << minLoc.y << " maxLoc: " << maxLoc.x << " " << maxLoc.y;
bool matched = maxVal > 0.95;
return {matched, maxLoc.x, maxLoc.y, templ.cols, templ.rows};
}
}
Matcher::Match Matcher::matchPos(const cv::Mat& img) {
cv::Mat matchpart = img(cv::Range(posy, posy + templ.rows), cv::Range(posx, posx + templ.cols));
// create out mat (only one pxl)
cv::Mat out(1, 1, CV_32FC1);
// match
cv::matchTemplate(matchpart, templ, out, cv::TM_CCORR_NORMED);
float val = out.at<float>({0, 0});
bool matched = val > 0.95;
Log::debug << "val: " << val;
return {matched, posx, posy, templ.cols, templ.rows};
}