Finished getPanoramaMap() functionality
- Created an outter loop to capture multiple columns of the map [dfwindow] - Crop the image to the map [dfwindow] - Instead of writing a file, return the image [dfwindow] - Save the map in the test function [imgtools.test5] - Experimented with faster timings [imgtools.test5]
This commit is contained in:
+43
-42
@@ -10,9 +10,6 @@ from loguru import logger
|
|||||||
from .waytools import capActiveWindow, focusWindow, moveMouse
|
from .waytools import capActiveWindow, focusWindow, moveMouse
|
||||||
from .waytools import sendKey as _sendKey
|
from .waytools import sendKey as _sendKey
|
||||||
|
|
||||||
# TODO: Consider type hinting images from cv2.typing import MatLike
|
|
||||||
|
|
||||||
|
|
||||||
class DFWINDOW:
|
class DFWINDOW:
|
||||||
class TOOLS:
|
class TOOLS:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -471,11 +468,11 @@ class DFWINDOW:
|
|||||||
"map_height": int(self._map_height),
|
"map_height": int(self._map_height),
|
||||||
"map_width": int(self._map_width),
|
"map_width": int(self._map_width),
|
||||||
}
|
}
|
||||||
with open("./calib_info.json", "w") as fh:
|
with Path("./calib_info.json").open("w") as fh:
|
||||||
json.dump(calib_info, fh)
|
json.dump(calib_info, fh)
|
||||||
|
|
||||||
def test_loadCalib(self):
|
def test_loadCalib(self):
|
||||||
with open("./calib_info.json") as fh:
|
with Path("./calib_info.json").open() as fh:
|
||||||
calib_info = json.load(fh)
|
calib_info = json.load(fh)
|
||||||
|
|
||||||
self._gridx = calib_info["gridx"]
|
self._gridx = calib_info["gridx"]
|
||||||
@@ -504,7 +501,13 @@ class DFWINDOW:
|
|||||||
|
|
||||||
return (int(safe_width), int(safe_height))
|
return (int(safe_width), int(safe_height))
|
||||||
|
|
||||||
def getPanoramaMap(self):
|
def getPanoramaMap(self) -> np.ndarray | None:
|
||||||
|
"""Capture a full size map from stitching together screen captures that are automatically taken.
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Calibrate the movement on the map
|
||||||
self.calibrateGrid()
|
self.calibrateGrid()
|
||||||
|
|
||||||
# Create the big_map canvas
|
# Create the big_map canvas
|
||||||
@@ -523,13 +526,21 @@ class DFWINDOW:
|
|||||||
|
|
||||||
if 1 == 1:
|
if 1 == 1:
|
||||||
# The initial setup
|
# The initial setup
|
||||||
new_x = self.contentWidth
|
|
||||||
new_y = self.contentHeight
|
|
||||||
canvas_pos = [0, 0]
|
canvas_pos = [0, 0]
|
||||||
self.setGridPos(0, 0)
|
self.setGridPos(0, 0)
|
||||||
|
pixels_added = (0,0)
|
||||||
|
|
||||||
|
sanity_steps_left_x = self.maxGridX + 1
|
||||||
|
new_x = self.contentWidth
|
||||||
|
canvas_pos[0] = 0
|
||||||
|
# Columns
|
||||||
|
while sanity_steps_left_x > 0:
|
||||||
|
|
||||||
|
# Rows
|
||||||
# Never do more than this many loops
|
# Never do more than this many loops
|
||||||
sanity_steps_left = self.maxGridY + 1
|
sanity_steps_left = self.maxGridY + 1
|
||||||
|
new_y = self.contentHeight
|
||||||
|
canvas_pos[1] = 0
|
||||||
while sanity_steps_left > 0:
|
while sanity_steps_left > 0:
|
||||||
# Capture a tile
|
# Capture a tile
|
||||||
img = self.capContent()
|
img = self.capContent()
|
||||||
@@ -562,47 +573,37 @@ class DFWINDOW:
|
|||||||
):
|
):
|
||||||
# pan down for more map, but watch limits
|
# pan down for more map, but watch limits
|
||||||
steps_to_pan_down = min(self.maxGridY - self.curGridY, math.floor(self.contentHeight / self.stepSizeY))
|
steps_to_pan_down = min(self.maxGridY - self.curGridY, math.floor(self.contentHeight / self.stepSizeY))
|
||||||
self.setGridPos(0, self.curGridY + steps_to_pan_down)
|
self.setGridPos(self.curGridX, self.curGridY + steps_to_pan_down)
|
||||||
new_y = steps_to_pan_down * self.stepSizeY
|
new_y = steps_to_pan_down * self.stepSizeY
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
if sanity_steps_left < 1:
|
if sanity_steps_left < 1:
|
||||||
logger.debug(f"Our loop in the Y axis ran over. {sanity_steps_left=}")
|
logger.debug(f"Our loop in the Y axis ran over. {sanity_steps_left=}")
|
||||||
|
|
||||||
|
sanity_steps_left_x -= 1
|
||||||
|
|
||||||
|
# Reset to next column
|
||||||
|
if not (
|
||||||
|
(cap_end_x + 1 < self.contentWidth) # pyright: ignore[reportPossiblyUnboundVariable]
|
||||||
|
or (pixels_added[0] < ((cap_end_x + 1) - cap_start_x)) # pyright: ignore[reportPossiblyUnboundVariable]
|
||||||
|
or (self.curGridX >= self.maxGridX)
|
||||||
|
or (canvas_pos[0] >= self.map_canvas.shape[1])
|
||||||
|
):
|
||||||
|
steps_to_pan_over = min(self.maxGridX - self.curGridX, math.floor(self.contentWidth / self.stepSizeX))
|
||||||
|
self.setGridPos(self.curGridX + steps_to_pan_over,0)
|
||||||
|
new_x = steps_to_pan_over * self.stepSizeX
|
||||||
|
canvas_pos[0] += pixels_added[0]
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
if sanity_steps_left_x < 1:
|
||||||
|
logger.debug(f"Our loop in the X axis ran over. {sanity_steps_left_x=}")
|
||||||
|
|
||||||
if self.map_canvas is not None:
|
if self.map_canvas is not None:
|
||||||
cv2.imwrite("./test_canvas.png", self.map_canvas)
|
x, y, w, h = cv2.boundingRect(cv2.findNonZero(cv2.threshold(self.map_canvas[:, :, 3], 230, 255, cv2.THRESH_BINARY)[1]))
|
||||||
|
# Path("./map_tiles").mkdir(exist_ok=True)
|
||||||
# if 1 == 0:
|
# cv2.imwrite("./map_tiles/test_canvas.png", self.map_canvas[y:h,x:w])
|
||||||
# self.setGridPos(0, 0)
|
return self.map_canvas[y:h,x:w]
|
||||||
# canvas_x = 0
|
|
||||||
# canvas_y = 0
|
|
||||||
|
|
||||||
# img = self.capContent()
|
|
||||||
# startx = self.TOOLS.firstNotBlackX(img)
|
|
||||||
# starty = self.TOOLS.firstNotBlackY(img)
|
|
||||||
# img_ul = img[starty:, startx:]
|
|
||||||
# # cv2.rectangle(img, (startx, starty), (self.contentWidth, self.contentHeight), (255, 255, 255, 255), 3)
|
|
||||||
# logger.debug(f"img_ul is {img_ul.shape[1]} x {img_ul.shape[0]}")
|
|
||||||
|
|
||||||
# last_add = self.addToCanvas(img_ul, 0, 0)
|
|
||||||
|
|
||||||
# steps_to_pan_down = math.floor(self.contentHeight / self.stepSizeY)
|
|
||||||
# logger.debug(f"{startx=} {starty=} {steps_to_pan_down=}")
|
|
||||||
# self.setGridPos(0, steps_to_pan_down)
|
|
||||||
# time.sleep(self.sleep_after_panning)
|
|
||||||
# img = self.capContent()
|
|
||||||
|
|
||||||
# new_starty = self.contentHeight - (steps_to_pan_down * self.stepSizeY)
|
|
||||||
# img_next = img[new_starty:, startx:]
|
|
||||||
# logger.debug(f"img_next is {img_next.shape[1]} x {img_next.shape[0]}")
|
|
||||||
# # cv2.rectangle(img, (startx, new_starty), (self.contentWidth, self.contentHeight), (255, 0, 0), 3)
|
|
||||||
|
|
||||||
# self.addToCanvas(img_next, 0, last_add[1])
|
|
||||||
# cv2.imwrite("./test_canvas.png", self.map_canvas)
|
|
||||||
# a = 1
|
|
||||||
# logger.debug(f"{new_starty=}")
|
|
||||||
|
|
||||||
logger.debug("place to break")
|
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import json
|
import json
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import cv2
|
||||||
import pydantic as pyd
|
import pydantic as pyd
|
||||||
|
|
||||||
from .dfwindow import DFWINDOW
|
from .dfwindow import DFWINDOW
|
||||||
@@ -299,7 +301,19 @@ class WAYMONITORS:
|
|||||||
|
|
||||||
def test5():
|
def test5():
|
||||||
dfw = DFWINDOW()
|
dfw = DFWINDOW()
|
||||||
|
|
||||||
|
# sleep_after_mouse = 0.2 # 2
|
||||||
|
# sleep_after_key = 0.08 # 08
|
||||||
|
# sleep_after_focus = 0.2 # 3
|
||||||
|
# sleep_after_panning = 0.2 # 3
|
||||||
|
dfw.sleep_after_key = 0.01
|
||||||
|
dfw.sleep_after_focus = 0.01
|
||||||
|
dfw.sleep_after_panning = 0.04
|
||||||
|
|
||||||
map_image = dfw.getPanoramaMap()
|
map_image = dfw.getPanoramaMap()
|
||||||
|
if map_image is not None:
|
||||||
|
Path("./map_tiles").mkdir(exist_ok=True)
|
||||||
|
cv2.imwrite("./map_tiles/test_canvas.png", map_image)
|
||||||
# img = dfw.capWindow()[60:-60,20:-20]
|
# img = dfw.capWindow()[60:-60,20:-20]
|
||||||
# gg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
# gg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||||
# mm = np.mean(gg, axis=1)
|
# mm = np.mean(gg, axis=1)
|
||||||
|
|||||||
Reference in New Issue
Block a user