Files
er_ai_env/find_ui_elements.py
2026-04-28 20:08:11 +02:00

88 lines
3.9 KiB
Python

import cv2
import numpy as np
import re
from vision_agent import EldenVision
class UISelector:
def __init__(self):
self.vision = EldenVision(2)
self.window_name = "FLUID CALIBRATOR: TAB=Switch, R=Mode, S=SAVE, Q=Quit"
cv2.namedWindow(self.window_name, cv2.WINDOW_NORMAL)
cv2.resizeWindow(self.window_name, 1280, 1280)
cv2.setMouseCallback(self.window_name, self.on_mouse)
self.rois = [
list(self.vision.player_hp_roi),
list(self.vision.player_fp_roi),
list(self.vision.player_sp_roi),
list(self.vision.boss_hp_roi)
]
self.names = ["HP (Red)", "FP (Blue)", "SP (Green)", "BOSS"]
self.colors = [(255, 0, 0), (255, 255, 0), (0, 255, 255), (0, 255, 0)]
self.types = ['red', 'blue', 'green', 'red']
self.active_idx = 0
self.mode = 'MOVE'
self.dragging = False
self.start_mouse = (0, 0)
self.start_roi = []
def on_mouse(self, event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
self.dragging = True
self.start_mouse = (x, y)
self.start_roi = list(self.rois[self.active_idx])
elif event == cv2.EVENT_MOUSEMOVE:
if not self.dragging: return
dx, dy = x - self.start_mouse[0], y - self.start_mouse[1]
roi = self.rois[self.active_idx]
if self.mode == 'MOVE':
roi[0], roi[1], roi[2], roi[3] = self.start_roi[0]+dy, self.start_roi[1]+dy, self.start_roi[2]+dx, self.start_roi[3]+dx
else:
roi[1], roi[3] = self.start_roi[1]+dy, self.start_roi[3]+dx
elif event == cv2.EVENT_LBUTTONUP:
self.dragging = False
def save_to_code(self):
file_path = "vision_agent.py"
with open(file_path, 'r') as f: content = f.read()
# Regex update to preserve logic but change coordinates
content = re.sub(r'self.player_hp_roi = \(.*?\)', f'self.player_hp_roi = {tuple(self.rois[0])}', content)
content = re.sub(r'self.player_fp_roi = \(.*?\)', f'self.player_fp_roi = {tuple(self.rois[1])}', content)
content = re.sub(r'self.player_sp_roi = \(.*?\)', f'self.player_sp_roi = {tuple(self.rois[2])}', content)
content = re.sub(r'self.boss_hp_roi = \(.*?\)', f'self.boss_hp_roi = {tuple(self.rois[3])}', content)
with open(file_path, 'w') as f: f.write(content)
print(f"\n[!!!] COORDINATES UPDATED in {file_path}")
def run(self):
while True:
obs, hp, fp, sp, boss = self.vision.get_state()
# AI sees RGB, but OpenCV needs BGR for imshow
frame_rgb = obs[:, :, -3:].copy()
frame_bgr = cv2.cvtColor(frame_rgb, cv2.COLOR_RGB2BGR)
# HUD
draw = frame_bgr
cv2.putText(draw, f"ACTIVE: {self.names[self.active_idx]} ({self.mode})", (10, 30), 0, 0.7, self.colors[self.active_idx], 2)
for i, roi in enumerate(self.rois):
cv2.rectangle(draw, (roi[2], roi[0]), (roi[3], roi[1]), self.colors[i], 4 if i==self.active_idx else 1)
# We can use the RGB frame for percent check, but color_type expects BGR-style logic or we adjust it
# Actually, vision_agent.get_bar_percent uses HSV, which we pre-calculate.
# For the tool, we just show the numbers returned by get_state.
cv2.putText(draw, f"HP: {hp:.0f}% FP: {fp:.0f}% SP: {sp:.0f}%", (10, 610), 0, 0.6, (255, 255, 255), 2)
cv2.imshow(self.window_name, draw)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'): break
elif key == ord('r'): self.mode = 'RESIZE' if self.mode == 'MOVE' else 'MOVE'
elif key == ord('\t'): self.active_idx = (self.active_idx + 1) % 4
elif key == ord('s'): self.save_to_code()
self.vision.stop()
cv2.destroyAllWindows()
if __name__ == "__main__":
UISelector().run()