mirror of
https://github.com/LTTLabsOSS/markbench-tests.git
synced 2026-01-08 21:48:00 -05:00
move deprecated harnesses to deprecated folder (#5)
This commit is contained in:
@@ -1,191 +0,0 @@
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
from enum import Enum
|
||||
|
||||
import cv2
|
||||
import imutils
|
||||
import numpy as np
|
||||
import pyautogui as gui
|
||||
import pydirectinput as user
|
||||
|
||||
DEFAULT_MATCH_THRESHOLD = 0.8
|
||||
DEFAULT_INTERVAL = 2 # seconds
|
||||
DEFAULT_TIMEOUT = 60 # seconds
|
||||
|
||||
# path relative to script
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
images_dir = os.path.join(script_dir, "images")
|
||||
dir16x9 = os.path.join(images_dir, "16x9")
|
||||
dir16x10 = os.path.join(images_dir, "16x10")
|
||||
|
||||
templates = {
|
||||
"options": {
|
||||
"16x10": cv2.imread(os.path.join(dir16x9, "options_menu_1080.png"), cv2.IMREAD_UNCHANGED),
|
||||
"16x9": cv2.imread(os.path.join(dir16x9, "options_menu_1080.png"), cv2.IMREAD_UNCHANGED)
|
||||
},
|
||||
"benchmark": {
|
||||
"16x10": cv2.imread(os.path.join(dir16x9, "benchmark_1080.png"), cv2.IMREAD_UNCHANGED),
|
||||
"16x9": cv2.imread(os.path.join(dir16x9, "benchmark_1080.png"), cv2.IMREAD_UNCHANGED)
|
||||
},
|
||||
"header": {
|
||||
"16x10": cv2.imread(os.path.join(dir16x9, "results_header_1080.png"), cv2.IMREAD_UNCHANGED),
|
||||
"16x9": cv2.imread(os.path.join(dir16x9, "results_header_1080.png"), cv2.IMREAD_UNCHANGED)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def get_template(name, set="16x9"):
|
||||
return templates[name][set]
|
||||
|
||||
|
||||
class ClickType(Enum):
|
||||
SINGLE = 0 # uses .click()
|
||||
DOUBLE = 1 # uses .doubleclick()
|
||||
HARD = 2 # uses mouse.down() and mouse.up()
|
||||
|
||||
|
||||
def get_middle_of_rect(top_left_corner, height, width):
|
||||
x = top_left_corner[0] + (width / 2)
|
||||
y = top_left_corner[1] + (height / 2)
|
||||
return int(x), int(y) # round to avoid fractional pixels
|
||||
|
||||
|
||||
def click(top_left_corner, img):
|
||||
click_loc = get_middle_of_rect(top_left_corner, img.shape[0], img.shape[1])
|
||||
logging.info(f"Clicking {click_loc}")
|
||||
gui.click(click_loc[0], click_loc[1])
|
||||
|
||||
|
||||
def double_click(top_left_corner, img):
|
||||
click_loc = get_middle_of_rect(top_left_corner, img.shape[0], img.shape[1])
|
||||
logging.info(f"Double clicking {click_loc}")
|
||||
user.doubleClick(click_loc[0], click_loc[1])
|
||||
|
||||
|
||||
def hard_click(top_left_corner, img):
|
||||
click_loc = get_middle_of_rect(top_left_corner, img.shape[0], img.shape[1])
|
||||
print(f"Hard click loc {click_loc}")
|
||||
user.moveTo(click_loc[0], click_loc[1])
|
||||
user.mouseDown()
|
||||
user.mouseUp()
|
||||
|
||||
|
||||
def wait_and_click(template_name, name, click_type: ClickType = ClickType.SINGLE, timeout=DEFAULT_TIMEOUT):
|
||||
logging.info(f"Waiting to find and click on {name}")
|
||||
img, img_loc = wait_for_image_on_screen(template_name, timeout=timeout)
|
||||
print(f"Wait and click: {img_loc}")
|
||||
if click_type == ClickType.SINGLE:
|
||||
click(img_loc, img)
|
||||
elif click_type == ClickType.DOUBLE:
|
||||
double_click(img_loc, img)
|
||||
elif click_type == ClickType.HARD:
|
||||
hard_click(img_loc, img)
|
||||
else:
|
||||
raise ValueError("Unknown click type")
|
||||
|
||||
|
||||
class ImageNotFoundTimeout(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ImageNotFound(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def gcd(a, b):
|
||||
return a if b == 0 else gcd(b, a % b)
|
||||
|
||||
|
||||
def aspect_ratio(w, h):
|
||||
denom = int(gcd(w, h))
|
||||
x = int(w / denom)
|
||||
y = int(h / denom)
|
||||
if x == 8 and y == 5:
|
||||
return "16x10"
|
||||
elif x == 16 and y == 9:
|
||||
return "16x9"
|
||||
|
||||
|
||||
def locate_on_screen(template_name, threshold=DEFAULT_MATCH_THRESHOLD, debug=1):
|
||||
screen = gui.screenshot()
|
||||
screen = np.array(
|
||||
screen) # pyautogui is using Pillow which is giving a format that must be adapted to work with opencv.
|
||||
screen = cv2.cvtColor(screen, cv2.COLOR_RGB2BGR)
|
||||
(h, w) = screen.shape[:2]
|
||||
r = aspect_ratio(w, h)
|
||||
needle = get_template(template_name, r)
|
||||
return needle, locate_in_image(needle, screen, threshold=DEFAULT_MATCH_THRESHOLD, debug=0)
|
||||
|
||||
|
||||
# This approach was largely inspired by the article
|
||||
# https://pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/
|
||||
def locate_in_image(needle, haystack, threshold=DEFAULT_MATCH_THRESHOLD, debug=0):
|
||||
(tH, tW) = needle.shape[:2]
|
||||
|
||||
if debug:
|
||||
cv2.imshow("Looking For", needle)
|
||||
cv2.waitKey(0)
|
||||
|
||||
for scale in np.linspace(0.2, 1.0, 20)[::-1]:
|
||||
# resize the image according to the scale, and keep track
|
||||
# of the ratio of the resizing
|
||||
resized = imutils.resize(haystack, width=int(haystack.shape[1] * scale), inter=cv2.INTER_NEAREST)
|
||||
r = haystack.shape[1] / float(resized.shape[1])
|
||||
|
||||
# if the resized image is smaller than the template, then break
|
||||
# from the loop
|
||||
if resized.shape[0] < tH or resized.shape[1] < tW:
|
||||
break
|
||||
|
||||
result = cv2.matchTemplate(resized, needle, cv2.TM_CCOEFF_NORMED)
|
||||
(_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)
|
||||
|
||||
if debug:
|
||||
# draw a bounding box around the detected region
|
||||
# clone = np.dstack([edged, edged, edged])
|
||||
cv2.rectangle(resized, (maxLoc[0], maxLoc[1]),
|
||||
(maxLoc[0] + tW, maxLoc[1] + tH), (0, 0, 255), 2)
|
||||
cv2.imshow("Searching", resized)
|
||||
cv2.waitKey(0)
|
||||
|
||||
if maxVal >= threshold:
|
||||
found = (maxVal, maxLoc, r)
|
||||
|
||||
# unpack the bookkeeping variable and compute the (x, y) coordinates
|
||||
# of the bounding box based on the resized ratio
|
||||
(_, maxLoc, r) = found
|
||||
(startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r))
|
||||
(endX, endY) = (int((maxLoc[0] + tW) * r), int((maxLoc[1] + tH) * r))
|
||||
|
||||
# if debug:
|
||||
# draw a bounding box around the detected result and display the image
|
||||
cv2.rectangle(haystack, (startX, startY), (endX, endY), (0, 0, 255), 2)
|
||||
# cv2.imshow("Found", haystack)
|
||||
|
||||
print(f"x: {startX} y: {startY}")
|
||||
cv2.imwrite("found.png", haystack)
|
||||
|
||||
# cv2.waitKey(0)
|
||||
|
||||
return startX, startY
|
||||
raise ImageNotFound("Image not found on screen")
|
||||
|
||||
|
||||
def wait_for_image_on_screen(template_name, match_threshold=DEFAULT_MATCH_THRESHOLD, interval=DEFAULT_INTERVAL,
|
||||
timeout=DEFAULT_TIMEOUT):
|
||||
"""Function that will wait for an image to appear on screen. This function will check every
|
||||
interval for a match that meets is greater than the match threshold. The function will raise
|
||||
an error if the image is not found within the timeout given. Will return the location
|
||||
of the image if found"""
|
||||
t0 = time.time()
|
||||
t1 = t0
|
||||
while not t1 - t0 > timeout:
|
||||
try:
|
||||
img, loc = locate_on_screen(template_name, match_threshold)
|
||||
return img, loc
|
||||
except ImageNotFound:
|
||||
pass
|
||||
time.sleep(interval)
|
||||
t1 = time.time()
|
||||
raise ImageNotFoundTimeout("Could not find image on screen within timeout")
|
||||
@@ -1,3 +0,0 @@
|
||||
# Stub
|
||||
def get_resolution():
|
||||
return 0,0
|
||||
@@ -1,84 +0,0 @@
|
||||
import os
|
||||
from subprocess import Popen
|
||||
import logging
|
||||
import time
|
||||
import pydirectinput as user
|
||||
import sys
|
||||
|
||||
from cv2_utils import *
|
||||
from far_cry_6_utils import get_resolution
|
||||
|
||||
sys.path.insert(1, os.path.join(sys.path[0], '..'))
|
||||
|
||||
from harness_utils.logging import *
|
||||
from harness_utils.process import terminate_processes
|
||||
|
||||
DEFAULT_INSTALLATION_PATH = "C:\\Program Files (x86)\\Ubisoft\\Ubisoft Game Launcher\\games\\Far Cry 6\\bin"
|
||||
EXECUTABLE = "FarCry6.exe"
|
||||
SCRIPT_DIRECTORY = os.path.dirname(os.path.realpath(__file__))
|
||||
LOG_DIRECTORY = os.path.join(SCRIPT_DIRECTORY, "run")
|
||||
PROCESS_NAME = "FarCry6"
|
||||
|
||||
|
||||
def start_game():
|
||||
cmd = DEFAULT_INSTALLATION_PATH + '\\' + EXECUTABLE
|
||||
logging.info(cmd)
|
||||
return Popen(cmd)
|
||||
|
||||
|
||||
def run_benchmark():
|
||||
start_game()
|
||||
t1 = time.time()
|
||||
|
||||
time.sleep(50)
|
||||
|
||||
user.press("space")
|
||||
user.press("space")
|
||||
|
||||
wait_and_click('options', 'options button', click_type=ClickType.HARD)
|
||||
time.sleep(2)
|
||||
wait_and_click('benchmark', 'options button', click_type=ClickType.HARD)
|
||||
|
||||
t2 = time.time()
|
||||
logging.info(f"Setup took {round((t2 - t1), 2)} seconds")
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
time.sleep(75) # wait for benchmark to complete 60 + 15 grace
|
||||
wait_for_image_on_screen('header', 'results', interval=2, timeout=60)
|
||||
|
||||
end_time = time.time()
|
||||
logging.info(f"Benchark took {round((end_time - start_time), 2)} seconds")
|
||||
|
||||
# Exit
|
||||
terminate_processes(PROCESS_NAME)
|
||||
return start_time, end_time
|
||||
|
||||
|
||||
setup_log_directory(LOG_DIRECTORY)
|
||||
|
||||
logging.basicConfig(filename=f'{LOG_DIRECTORY}/harness.log',
|
||||
format=DEFAULT_LOGGING_FORMAT,
|
||||
datefmt=DEFAULT_DATE_FORMAT,
|
||||
level=logging.DEBUG)
|
||||
console = logging.StreamHandler()
|
||||
formatter = logging.Formatter(DEFAULT_LOGGING_FORMAT)
|
||||
console.setFormatter(formatter)
|
||||
logging.getLogger('').addHandler(console)
|
||||
|
||||
try:
|
||||
start_time, end_time = run_benchmark()
|
||||
height, width = get_resolution()
|
||||
result = {
|
||||
"resolution": format_resolution(width, height),
|
||||
"graphics_preset": "current",
|
||||
"start_time": seconds_to_milliseconds(start_time),
|
||||
"end_time": seconds_to_milliseconds(end_time)
|
||||
}
|
||||
|
||||
write_report_json(LOG_DIRECTORY, "report.json", result)
|
||||
except Exception as e:
|
||||
logging.error("Something went wrong running the benchmark!")
|
||||
logging.exception(e)
|
||||
terminate_processes(PROCESS_NAME)
|
||||
exit(1)
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.9 MiB |
@@ -1,8 +0,0 @@
|
||||
friendly_name: "Far Cry 6"
|
||||
executable: "farcry6.py"
|
||||
process_name: "FarCry6.exe"
|
||||
output_dir: "run"
|
||||
options:
|
||||
- name: preset
|
||||
type: select
|
||||
values: [current]
|
||||
@@ -1,17 +0,0 @@
|
||||
import cv2
|
||||
import os
|
||||
|
||||
from cv2_utils import *
|
||||
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
images_dir = os.path.join(script_dir, "images")
|
||||
test_images_dir = os.path.join(images_dir, "tests")
|
||||
|
||||
test_menus = {
|
||||
"mainmenu_1080": cv2.imread(os.path.join(test_images_dir, "main_menu_1080_32inch.png"), cv2.IMREAD_UNCHANGED),
|
||||
}
|
||||
|
||||
# found = locate_in_image(get_template('press_any'), test_menus['mainmenu_2k'], debug = 0)
|
||||
# print(found)
|
||||
found = locate_in_image(get_template('options'), test_menus['mainmenu_1080'], debug=0, threshold=0.8)
|
||||
print(found)
|
||||
Reference in New Issue
Block a user