From 2b5ade4c6cfdde993e97252448f3c08522fea9eb Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sat, 15 Jun 2024 00:00:28 +0800 Subject: [PATCH] Fix: Mask slider controller when calculating slider length --- tasks/item/slider.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/tasks/item/slider.py b/tasks/item/slider.py index 6ec986ade..9d4e8b950 100644 --- a/tasks/item/slider.py +++ b/tasks/item/slider.py @@ -1,9 +1,9 @@ +import cv2 import numpy as np from scipy import signal from module.base.button import ButtonWrapper, ClickButton from module.base.timer import Timer -from module.base.utils import rgb2gray from module.exception import ScriptError from module.logger import logger from tasks.base.ui import UI @@ -43,27 +43,42 @@ class Slider: area = self.slider.area area = (area[0], area[1] - self.background, area[2], area[3] + self.background) image = self.main.image_crop(area, copy=False) - image = rgb2gray(image) - image = image.flatten('F') + r, g, _ = cv2.split(image) + image = r.flatten('F') wlen = area[3] - area[1] total = area[2] - area[0] parameters = { 'prominence': 15, 'wlen': wlen, - 'width': 4, + 'width': 2, 'distance': wlen / 2, } parameters.update(self.parameters) peaks, _ = signal.find_peaks(image, **parameters) 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 try: - right = np.where(np.diff(peaks) >= 3)[0][0] + right = np.where(diff >= 3)[0][0] peaks = peaks[:right + 1] except IndexError: pass + # Calculate actual slider area try: length = peaks[-1] @@ -73,6 +88,10 @@ class Slider: self.area = self.slider.area 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): """ Args: