Fix: Accurate search_half and optimize rotation parameters

This commit is contained in:
LmeSzinc 2023-08-19 03:10:49 +08:00
parent 083a8cbbc9
commit af37f4c252
2 changed files with 29 additions and 14 deletions

View File

@ -67,7 +67,7 @@ class Minimap(MapResource):
search_position = np.array(self.position, dtype=np.int64) search_position = np.array(self.position, dtype=np.int64)
search_position += self.POSITION_FEATURE_PAD search_position += self.POSITION_FEATURE_PAD
search_size = np.array(image_size(local)) * self.POSITION_SEARCH_RADIUS search_size = np.array(image_size(local)) * self.POSITION_SEARCH_RADIUS
search_half = (search_size // 2 * 2).astype(np.int64) search_half = (search_size // 2).astype(np.int64)
search_area = area_offset((0, 0, *(search_half * 2)), offset=-search_half) search_area = area_offset((0, 0, *(search_half * 2)), offset=-search_half)
search_area = area_offset(search_area, offset=np.multiply(search_position, self.POSITION_SEARCH_SCALE)) search_area = area_offset(search_area, offset=np.multiply(search_position, self.POSITION_SEARCH_SCALE))
search_area = np.array(search_area).astype(np.int64) search_area = np.array(search_area).astype(np.int64)
@ -269,11 +269,12 @@ class Minimap(MapResource):
# Extract # Extract
minimap = self.get_minimap(image, radius=self.MINIMAP_RADIUS) minimap = self.get_minimap(image, radius=self.MINIMAP_RADIUS)
_, _, v = cv2.split(rgb2yuv(minimap)) _, _, v = cv2.split(rgb2yuv(minimap))
image = cv2.subtract(255, v)
# image = cv2.GaussianBlur(image, (3, 3), 0) image = cv2.subtract(128, v)
image = cv2.GaussianBlur(image, (3, 3), 0)
# Expand circle into rectangle # Expand circle into rectangle
remap = cv2.remap(image, *self.RotationRemapData, cv2.INTER_LINEAR)[d * 2 // 10:d * 6 // 10].astype(np.float32) remap = cv2.remap(image, *self.RotationRemapData, cv2.INTER_LINEAR)[d * 1 // 10:d * 6 // 10].astype(np.float32)
remap = cv2.resize(remap, None, fx=scale, fy=scale, interpolation=cv2.INTER_LINEAR) remap = cv2.resize(remap, None, fx=scale, fy=scale, interpolation=cv2.INTER_LINEAR)
# Find derivative # Find derivative
gradx = cv2.Scharr(remap, cv2.CV_32F, 1, 0) gradx = cv2.Scharr(remap, cv2.CV_32F, 1, 0)
@ -284,7 +285,7 @@ class Minimap(MapResource):
# Magic parameters for scipy.find_peaks # Magic parameters for scipy.find_peaks
para = { para = {
# 'height': (50, 800), # 'height': (50, 800),
'height': 50, 'height': 35,
# 'prominence': (0, 400), # 'prominence': (0, 400),
# 'width': (0, d * scale / 20), # 'width': (0, d * scale / 20),
# 'distance': d * scale / 18, # 'distance': d * scale / 18,
@ -356,13 +357,14 @@ class Minimap(MapResource):
self.rotation_confidence = rotation_confidence self.rotation_confidence = rotation_confidence
self.rotation = rotation self.rotation = rotation
def update(self, image): def update(self, image, show_log=True):
""" """
Update minimap, costs about 7.88ms. Update minimap, costs about 7.88ms.
""" """
self.update_position(image) self.update_position(image)
self.update_direction(image) self.update_direction(image)
self.update_rotation(image) self.update_rotation(image)
if show_log:
self.log_minimap() self.log_minimap()
def log_minimap(self): def log_minimap(self):

View File

@ -1,5 +1,6 @@
import os import os
import numpy as np
from PIL import Image from PIL import Image
from module.base.utils import load_image from module.base.utils import load_image
@ -16,13 +17,14 @@ class ResourceConst:
# Downscale GIMAP and minimap for faster run # Downscale GIMAP and minimap for faster run
POSITION_SEARCH_SCALE = 0.5 POSITION_SEARCH_SCALE = 0.5
# Search the area that is 1.666x minimap, about 100px in wild on GIMAP # Search the area that is 1.666x minimap, about 100px in wild on GIMAP
POSITION_SEARCH_RADIUS = 1.333 POSITION_SEARCH_RADIUS = 1.666
# Can't figure out why but the result_of_0.5_lookup_scale + 0.5 ~= result_of_1.0_lookup_scale # Can't figure out why but the result_of_0.5_lookup_scale + 0.5 ~= result_of_1.0_lookup_scale
POSITION_MOVE_PATCH = (0.5, 0.5) POSITION_MOVE_PATCH = (0.5, 0.5)
# Position starting from the upper-left corner of the template image # Position starting from the upper-left corner of the template image
# but search an area larger than map # but search an area larger than map
# MINIMAP_RADIUS * POSITION_SEARCH_RADIUS * <max_scale> # MINIMAP_RADIUS * POSITION_SEARCH_RADIUS * <max_scale>
POSITION_FEATURE_PAD = int(MINIMAP_RADIUS * POSITION_SEARCH_RADIUS * 1.5) # POSITION_FEATURE_PAD = int(MINIMAP_RADIUS * POSITION_SEARCH_RADIUS * 1.5)
POSITION_FEATURE_PAD = 155
# Must be odd, equals int(9 * POSITION_SEARCH_SCALE) + 1 # Must be odd, equals int(9 * POSITION_SEARCH_SCALE) + 1
POSITION_AREA_DILATE = 5 POSITION_AREA_DILATE = 5
@ -99,14 +101,25 @@ class ResourceConst:
Returns: Returns:
float: Distance to current position float: Distance to current position
""" """
x1, y1 = self.position return np.linalg.norm(np.subtract(target, self.position))
x2, y2 = target
diff = ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5
return diff
def is_position_near(self, target, threshold=5): def is_position_near(self, target, threshold=5):
return self.position_diff(target) <= threshold return self.position_diff(target) <= threshold
def position2direction(self, target):
"""
Args:
target: Target position (x, y)
Returns:
float: Direction from current position to target position (0~360)
"""
diff = np.subtract(target, self.position)
theta = np.rad2deg(np.arccos(-diff[1] / np.linalg.norm(diff)))
if diff[0] < 0:
theta = 360 - theta
return theta
def direction_diff(self, target): def direction_diff(self, target):
""" """
Args: Args:
@ -136,5 +149,5 @@ class ResourceConst:
diff -= 360 diff -= 360
return diff return diff
def is_rotation_near(self, target, threshold=15): def is_rotation_near(self, target, threshold=10):
return abs(self.rotation_diff(target)) <= threshold return abs(self.rotation_diff(target)) <= threshold