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 += self.POSITION_FEATURE_PAD
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(search_area, offset=np.multiply(search_position, self.POSITION_SEARCH_SCALE))
search_area = np.array(search_area).astype(np.int64)
@ -269,11 +269,12 @@ class Minimap(MapResource):
# Extract
minimap = self.get_minimap(image, radius=self.MINIMAP_RADIUS)
_, _, 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
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)
# Find derivative
gradx = cv2.Scharr(remap, cv2.CV_32F, 1, 0)
@ -284,7 +285,7 @@ class Minimap(MapResource):
# Magic parameters for scipy.find_peaks
para = {
# 'height': (50, 800),
'height': 50,
'height': 35,
# 'prominence': (0, 400),
# 'width': (0, d * scale / 20),
# 'distance': d * scale / 18,
@ -356,13 +357,14 @@ class Minimap(MapResource):
self.rotation_confidence = rotation_confidence
self.rotation = rotation
def update(self, image):
def update(self, image, show_log=True):
"""
Update minimap, costs about 7.88ms.
"""
self.update_position(image)
self.update_direction(image)
self.update_rotation(image)
if show_log:
self.log_minimap()
def log_minimap(self):

View File

@ -1,5 +1,6 @@
import os
import numpy as np
from PIL import Image
from module.base.utils import load_image
@ -16,13 +17,14 @@ class ResourceConst:
# Downscale GIMAP and minimap for faster run
POSITION_SEARCH_SCALE = 0.5
# 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
POSITION_MOVE_PATCH = (0.5, 0.5)
# Position starting from the upper-left corner of the template image
# but search an area larger than map
# 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
POSITION_AREA_DILATE = 5
@ -99,14 +101,25 @@ class ResourceConst:
Returns:
float: Distance to current position
"""
x1, y1 = self.position
x2, y2 = target
diff = ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5
return diff
return np.linalg.norm(np.subtract(target, self.position))
def is_position_near(self, target, threshold=5):
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):
"""
Args:
@ -136,5 +149,5 @@ class ResourceConst:
diff -= 360
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