Fix: Mask slider controller when calculating slider length

This commit is contained in:
LmeSzinc 2024-06-15 00:00:28 +08:00
parent a94d0144ea
commit 2b5ade4c6c

View File

@ -1,9 +1,9 @@
import cv2
import numpy as np import numpy as np
from scipy import signal from scipy import signal
from module.base.button import ButtonWrapper, ClickButton from module.base.button import ButtonWrapper, ClickButton
from module.base.timer import Timer from module.base.timer import Timer
from module.base.utils import rgb2gray
from module.exception import ScriptError from module.exception import ScriptError
from module.logger import logger from module.logger import logger
from tasks.base.ui import UI from tasks.base.ui import UI
@ -43,27 +43,42 @@ class Slider:
area = self.slider.area area = self.slider.area
area = (area[0], area[1] - self.background, area[2], area[3] + self.background) area = (area[0], area[1] - self.background, area[2], area[3] + self.background)
image = self.main.image_crop(area, copy=False) image = self.main.image_crop(area, copy=False)
image = rgb2gray(image) r, g, _ = cv2.split(image)
image = image.flatten('F') image = r.flatten('F')
wlen = area[3] - area[1] wlen = area[3] - area[1]
total = area[2] - area[0] total = area[2] - area[0]
parameters = { parameters = {
'prominence': 15, 'prominence': 15,
'wlen': wlen, 'wlen': wlen,
'width': 4, 'width': 2,
'distance': wlen / 2, 'distance': wlen / 2,
} }
parameters.update(self.parameters) parameters.update(self.parameters)
peaks, _ = signal.find_peaks(image, **parameters) peaks, _ = signal.find_peaks(image, **parameters)
peaks //= wlen peaks //= wlen
diff = np.diff(peaks)
# Mask controller
# Controller has orange border (240, 150, 57) and white center
r = cv2.reduce(r, 0, cv2.REDUCE_AVG).flatten()
g = cv2.reduce(g, 0, cv2.REDUCE_AVG).flatten()
mask = np.all([r > 160, g > 80], axis=0)
try:
index = np.where(mask == True)
left = max(index[0][0] - 3, 0)
right = min(index[0][-1] + 3, len(peaks))
diff[left:right] = 0
except IndexError:
pass
# Ignore non-continuous peaks, which may be the letter to the right of slider # Ignore non-continuous peaks, which may be the letter to the right of slider
try: try:
right = np.where(np.diff(peaks) >= 3)[0][0] right = np.where(diff >= 3)[0][0]
peaks = peaks[:right + 1] peaks = peaks[:right + 1]
except IndexError: except IndexError:
pass pass
# Calculate actual slider area # Calculate actual slider area
try: try:
length = peaks[-1] length = peaks[-1]
@ -73,6 +88,10 @@ class Slider:
self.area = self.slider.area self.area = self.slider.area
logger.info(f'Slider length: {length}/{total}') logger.info(f'Slider length: {length}/{total}')
if length < total / 2:
logger.warning('Detected slider too short')
# self.main.device.image_save()
def set(self, value: int, total: int, skip_first_screenshot=True): def set(self, value: int, total: int, skip_first_screenshot=True):
""" """
Args: Args: