Pref: Reuse image array to improve memory performance

This commit is contained in:
LmeSzinc 2024-06-05 01:31:17 +08:00
parent 004e1f03ee
commit 72d8673434
14 changed files with 18 additions and 18 deletions

View File

@ -273,7 +273,7 @@ class ModuleBase:
Returns: Returns:
Button: Or None if nothing matched. Button: Or None if nothing matched.
""" """
image = color_similarity_2d(self.image_crop(area), color=color) image = color_similarity_2d(self.image_crop(area, copy=False), color=color)
points = np.array(np.where(image > color_threshold)).T[:, ::-1] points = np.array(np.where(image > color_threshold)).T[:, ::-1]
if points.shape[0] < encourage ** 2: if points.shape[0] < encourage ** 2:
# Not having enough pixels to match # Not having enough pixels to match

View File

@ -122,7 +122,7 @@ class CharacterSwitch(UI):
expected_peaks = np.array([201, 279, 357, 435]) expected_peaks = np.array([201, 279, 357, 435])
expected_peaks_in_area = expected_peaks - area[1] expected_peaks_in_area = expected_peaks - area[1]
# Use Luminance to fit H264 video stream # Use Luminance to fit H264 video stream
image = rgb2luma(crop(self.device.image, area)) image = rgb2luma(crop(self.device.image, area, copy=False))
# Remove character names # Remove character names
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
image = cv2.erode(image, kernel) image = cv2.erode(image, kernel)

View File

@ -47,7 +47,7 @@ class CombatSkill(UI):
break break
# New skill icon # New skill icon
if prev_image is not None: if prev_image is not None:
if not match_template(self.image_crop(button), prev_image): if not match_template(self.image_crop(button, copy=False), prev_image):
logger.info(f'Skill used: {button} (icon changed)') logger.info(f'Skill used: {button} (icon changed)')
break break

View File

@ -22,7 +22,7 @@ class CombatState(UI):
return False return False
def _is_combat_button_active(self, button): def _is_combat_button_active(self, button):
image = rgb2luma(self.image_crop(button)) image = rgb2luma(self.image_crop(button, copy=False))
lines = cv2.reduce(image, 1, cv2.REDUCE_AVG).flatten() lines = cv2.reduce(image, 1, cv2.REDUCE_AVG).flatten()
# [122 122 122 182 141 127 139 135 130 135 136 141 147 149 149 150 147 145 # [122 122 122 182 141 127 139 135 130 135 136 141 147 149 149 150 147 145
# 148 150 150 150 150 150 144 138 134 141 136 133 173 183 130 128 127 126] # 148 150 150 150 150 150 144 138 134 141 136 133 173 183 130 128 127 126]

View File

@ -30,7 +30,7 @@ class SupportCharacter:
def __init__(self, name, screenshot, similarity=0.75): def __init__(self, name, screenshot, similarity=0.75):
self.name = name self.name = name
self.image = self._scale_character() self.image = self._scale_character()
self.screenshot = crop(screenshot, SupportCharacter._crop_area) self.screenshot = crop(screenshot, SupportCharacter._crop_area, copy=False)
self.similarity = similarity self.similarity = similarity
self.button = self._find_character() self.button = self._find_character()

View File

@ -33,10 +33,10 @@ class DailyQuestOcr(Ocr):
def pre_process(self, image): def pre_process(self, image):
image = super().pre_process(image) image = super().pre_process(image)
image = crop(image, OCR_DAILY_QUEST.area) image = crop(image, OCR_DAILY_QUEST.area, copy=False)
mask = MASK_DAILY_QUEST.matched_button.image mask = MASK_DAILY_QUEST.matched_button.image
# Remove "+200Activity" # Remove "+200Activity"
cv2.bitwise_and(image, mask, dst=image) image = cv2.bitwise_and(image, mask)
return image return image
def after_process(self, result): def after_process(self, result):

View File

@ -39,7 +39,7 @@ class DungeonState(UI):
) )
ocr = OcrSimUniPoint(OCR_SIMUNI_POINT) ocr = OcrSimUniPoint(OCR_SIMUNI_POINT)
value, _, total = ocr.ocr_single_line(crop(image, area), direct_ocr=True) value, _, total = ocr.ocr_single_line(crop(image, area, copy=False), direct_ocr=True)
if total and value <= total: if total and value <= total:
logger.attr('SimulatedUniverse', f'{value}/{total}') logger.attr('SimulatedUniverse', f'{value}/{total}')
self.config.stored.SimulatedUniverse.set(value, total) self.config.stored.SimulatedUniverse.set(value, total)

View File

@ -334,7 +334,7 @@ class DungeonUI(DungeonState):
# Check if having any content # Check if having any content
# List background: 254, guild border: 225 # List background: 254, guild border: 225
r, g, b = cv2.split(self.image_crop(LIST_LOADED_CHECK)) r, g, b = cv2.split(self.image_crop(LIST_LOADED_CHECK, copy=False))
minimum = cv2.min(cv2.min(r, g), b) minimum = cv2.min(cv2.min(r, g), b)
minimum = inrange(minimum, lower=0, upper=180) minimum = inrange(minimum, lower=0, upper=180)
if minimum.size > 100: if minimum.size > 100:

View File

@ -35,7 +35,7 @@ class ForgottenHallTeam(UI):
continue continue
def is_character_chosen(self, button: ButtonWrapper) -> bool: def is_character_chosen(self, button: ButtonWrapper) -> bool:
image = color_similarity_2d(self.image_crop(button), color=(255, 255, 255)) image = color_similarity_2d(self.image_crop(button, copy=False), color=(255, 255, 255))
color = cv2.mean(image)[0] color = cv2.mean(image)[0]
# print(button, color) # print(button, color)
# Chosen: # Chosen:

View File

@ -23,7 +23,7 @@ class ForgottenHallStageOcr(Ocr):
def _find_number(self, image): def _find_number(self, image):
raw = image.copy() raw = image.copy()
area = OCR_STAGE.area area = OCR_STAGE.area
image = crop(raw, area) image = crop(raw, area, copy=False)
yellow = color_similarity_2d(image, color=(255, 200, 112)) yellow = color_similarity_2d(image, color=(255, 200, 112))
gray = color_similarity_2d(image, color=(100, 109, 134)) gray = color_similarity_2d(image, color=(100, 109, 134))
image = np.maximum(yellow, gray) image = np.maximum(yellow, gray)

View File

@ -56,11 +56,11 @@ class Synthesize(CombatObtain):
Pages: Pages:
in: page_synthesize in: page_synthesize
""" """
image = self.image_crop(button) image = self.image_crop(button, copy=False)
image = cv2.GaussianBlur(image, (3, 3), 0) image = cv2.GaussianBlur(image, (3, 3), 0)
x2, y2 = image_size(image) x2, y2 = image_size(image)
y1 = y2 - int(y2 // 4) y1 = y2 - int(y2 // 4)
image = crop(image, (0, y1, x2, y2)) image = crop(image, (0, y1, x2, y2), copy=False)
# self.device.image_show(image) # self.device.image_show(image)
# print(image.shape) # print(image.shape)

View File

@ -150,7 +150,7 @@ class Minimap(MapResource):
# Image.fromarray((local_maximum * 255).astype(np.uint8)).save('local_maximum.png') # Image.fromarray((local_maximum * 255).astype(np.uint8)).save('local_maximum.png')
# Calculate the precise location using CUBIC # Calculate the precise location using CUBIC
# precise = crop(result, area=area_offset((-4, -4, 4, 4), offset=local_loca)) # precise = crop(result, area=area_offset((-4, -4, 4, 4), offset=local_loca), copy=False)
# precise_sim, precise_loca = cubic_find_maximum(precise, precision=0.05) # precise_sim, precise_loca = cubic_find_maximum(precise, precision=0.05)
# precise_loca -= 5 # precise_loca -= 5
precise_loca = np.array((0, 0)) precise_loca = np.array((0, 0))
@ -190,7 +190,7 @@ class Minimap(MapResource):
loca = state.loca loca = state.loca
local_loca = state.local_loca local_loca = state.local_loca
precise = crop(result, area=area_offset((-4, -4, 4, 4), offset=loca)) precise = crop(result, area=area_offset((-4, -4, 4, 4), offset=loca), copy=False)
precise_sim, precise_loca = cubic_find_maximum(precise, precision=0.05) precise_sim, precise_loca = cubic_find_maximum(precise, precision=0.05)
precise_loca -= 5 precise_loca -= 5
@ -265,7 +265,7 @@ class Minimap(MapResource):
logger.warning('No direction arrow on minimap') logger.warning('No direction arrow on minimap')
return return
image = crop(image, area=area) image = crop(image, area=area, copy=False)
scale = self.DIRECTION_ROTATION_SCALE * self.DIRECTION_SEARCH_SCALE scale = self.DIRECTION_ROTATION_SCALE * self.DIRECTION_SEARCH_SCALE
mapping = cv2.resize(image, None, fx=scale, fy=scale, interpolation=cv2.INTER_NEAREST) mapping = cv2.resize(image, None, fx=scale, fy=scale, interpolation=cv2.INTER_NEAREST)
result = cv2.matchTemplate(self.ArrowRotateMap, mapping, cv2.TM_CCOEFF_NORMED) result = cv2.matchTemplate(self.ArrowRotateMap, mapping, cv2.TM_CCOEFF_NORMED)

View File

@ -55,7 +55,7 @@ class ResourceGenerator(ResourceConst):
arrows = {} arrows = {}
for degree in range(0, 360): for degree in range(0, 360):
rotated = rotate_bound(image, degree) rotated = rotate_bound(image, degree)
rotated = crop(rotated, area=get_bbox(rotated, threshold=15)) rotated = crop(rotated, area=get_bbox(rotated, threshold=15), copy=False)
# rotated = cv2.resize(rotated, None, fx=self.ROTATE, fy=self.ROTATE, interpolation=cv2.INTER_NEAREST) # rotated = cv2.resize(rotated, None, fx=self.ROTATE, fy=self.ROTATE, interpolation=cv2.INTER_NEAREST)
rotated = color_similarity_2d(rotated, color=self.DIRECTION_ARROW_COLOR) rotated = color_similarity_2d(rotated, color=self.DIRECTION_ARROW_COLOR)
arrows[degree] = rotated arrows[degree] = rotated

View File

@ -101,7 +101,7 @@ class MapResource(ResourceConst):
Crop the minimap area on image. Crop the minimap area on image.
""" """
area = area_offset((-radius, -radius, radius, radius), offset=self.MINIMAP_CENTER) area = area_offset((-radius, -radius, radius, radius), offset=self.MINIMAP_CENTER)
image = crop(image, area) image = crop(image, area, copy=False)
return image return image
def get_circle_mask(self, image): def get_circle_mask(self, image):