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:
+74
-73
@@ -10,9 +10,6 @@ from loguru import logger
|
||||
from .waytools import capActiveWindow, focusWindow, moveMouse
|
||||
from .waytools import sendKey as _sendKey
|
||||
|
||||
# TODO: Consider type hinting images from cv2.typing import MatLike
|
||||
|
||||
|
||||
class DFWINDOW:
|
||||
class TOOLS:
|
||||
@staticmethod
|
||||
@@ -471,11 +468,11 @@ class DFWINDOW:
|
||||
"map_height": int(self._map_height),
|
||||
"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)
|
||||
|
||||
def test_loadCalib(self):
|
||||
with open("./calib_info.json") as fh:
|
||||
with Path("./calib_info.json").open() as fh:
|
||||
calib_info = json.load(fh)
|
||||
|
||||
self._gridx = calib_info["gridx"]
|
||||
@@ -504,7 +501,13 @@ class DFWINDOW:
|
||||
|
||||
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()
|
||||
|
||||
# Create the big_map canvas
|
||||
@@ -523,86 +526,84 @@ class DFWINDOW:
|
||||
|
||||
if 1 == 1:
|
||||
# The initial setup
|
||||
new_x = self.contentWidth
|
||||
new_y = self.contentHeight
|
||||
canvas_pos = [0, 0]
|
||||
self.setGridPos(0, 0)
|
||||
pixels_added = (0,0)
|
||||
|
||||
# Never do more than this many loops
|
||||
sanity_steps_left = self.maxGridY + 1
|
||||
while sanity_steps_left > 0:
|
||||
# Capture a tile
|
||||
img = self.capContent()
|
||||
cap_start_x = max(self.TOOLS.firstNotBlackX(img), self.contentWidth - new_x)
|
||||
cap_start_y = max(self.TOOLS.firstNotBlackY(img), self.contentHeight - new_y)
|
||||
sanity_steps_left_x = self.maxGridX + 1
|
||||
new_x = self.contentWidth
|
||||
canvas_pos[0] = 0
|
||||
# Columns
|
||||
while sanity_steps_left_x > 0:
|
||||
|
||||
# use min with other restriction if needed in the future min(lastNotBlack,Other_limit)
|
||||
cap_end_x = self.TOOLS.lastNotBlackX(img)
|
||||
cap_end_y = self.TOOLS.lastNotBlackY(img)
|
||||
# Rows
|
||||
# Never do more than this many loops
|
||||
sanity_steps_left = self.maxGridY + 1
|
||||
new_y = self.contentHeight
|
||||
canvas_pos[1] = 0
|
||||
while sanity_steps_left > 0:
|
||||
# Capture a tile
|
||||
img = self.capContent()
|
||||
cap_start_x = max(self.TOOLS.firstNotBlackX(img), self.contentWidth - new_x)
|
||||
cap_start_y = max(self.TOOLS.firstNotBlackY(img), self.contentHeight - new_y)
|
||||
|
||||
pixels_added = self.addToCanvas(
|
||||
img[cap_start_y : cap_end_y + 1, cap_start_x : cap_end_x + 1], canvas_pos[0], canvas_pos[1]
|
||||
)
|
||||
canvas_pos[1] += pixels_added[1]
|
||||
# use min with other restriction if needed in the future min(lastNotBlack,Other_limit)
|
||||
cap_end_x = self.TOOLS.lastNotBlackX(img)
|
||||
cap_end_y = self.TOOLS.lastNotBlackY(img)
|
||||
|
||||
# Reasons to finish this column:
|
||||
# - pixels_added[1] < cap_height
|
||||
# - (with cur logic) cap_height < self.contentHeight
|
||||
# - self.curGridY >= self.maxGridY
|
||||
logger.trace(f"{cap_start_y=} {cap_end_y=} {self.contentHeight=} {pixels_added=} {canvas_pos=}")
|
||||
logger.trace(f"{self.curGridPos=} {self.map_canvas.shape=}")
|
||||
pixels_added = self.addToCanvas(
|
||||
img[cap_start_y : cap_end_y + 1, cap_start_x : cap_end_x + 1], canvas_pos[0], canvas_pos[1]
|
||||
)
|
||||
canvas_pos[1] += pixels_added[1]
|
||||
|
||||
sanity_steps_left -= 1 # Prevent runaway loops
|
||||
# Reasons to finish this column:
|
||||
# - pixels_added[1] < cap_height
|
||||
# - (with cur logic) cap_height < self.contentHeight
|
||||
# - self.curGridY >= self.maxGridY
|
||||
logger.trace(f"{cap_start_y=} {cap_end_y=} {self.contentHeight=} {pixels_added=} {canvas_pos=}")
|
||||
logger.trace(f"{self.curGridPos=} {self.map_canvas.shape=}")
|
||||
|
||||
sanity_steps_left -= 1 # Prevent runaway loops
|
||||
|
||||
if not (
|
||||
(cap_end_y + 1 < self.contentHeight)
|
||||
or (pixels_added[1] < ((cap_end_y + 1) - cap_start_y))
|
||||
or (self.curGridY >= self.maxGridY)
|
||||
or (canvas_pos[1] >= self.map_canvas.shape[0])
|
||||
):
|
||||
# pan down for more map, but watch limits
|
||||
steps_to_pan_down = min(self.maxGridY - self.curGridY, math.floor(self.contentHeight / self.stepSizeY))
|
||||
self.setGridPos(self.curGridX, self.curGridY + steps_to_pan_down)
|
||||
new_y = steps_to_pan_down * self.stepSizeY
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
if sanity_steps_left < 1:
|
||||
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_y + 1 < self.contentHeight)
|
||||
or (pixels_added[1] < ((cap_end_y + 1) - cap_start_y))
|
||||
or (self.curGridY >= self.maxGridY)
|
||||
or (canvas_pos[1] >= self.map_canvas.shape[0])
|
||||
(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])
|
||||
):
|
||||
# pan down for more map, but watch limits
|
||||
steps_to_pan_down = min(self.maxGridY - self.curGridY, math.floor(self.contentHeight / self.stepSizeY))
|
||||
self.setGridPos(0, self.curGridY + steps_to_pan_down)
|
||||
new_y = steps_to_pan_down * self.stepSizeY
|
||||
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 < 1:
|
||||
logger.debug(f"Our loop in the Y axis ran over. {sanity_steps_left=}")
|
||||
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:
|
||||
cv2.imwrite("./test_canvas.png", self.map_canvas)
|
||||
|
||||
# if 1 == 0:
|
||||
# self.setGridPos(0, 0)
|
||||
# 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")
|
||||
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)
|
||||
# cv2.imwrite("./map_tiles/test_canvas.png", self.map_canvas[y:h,x:w])
|
||||
return self.map_canvas[y:h,x:w]
|
||||
|
||||
return None
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import cv2
|
||||
import pydantic as pyd
|
||||
|
||||
from .dfwindow import DFWINDOW
|
||||
@@ -299,7 +301,19 @@ class WAYMONITORS:
|
||||
|
||||
def test5():
|
||||
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()
|
||||
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]
|
||||
# gg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||
# mm = np.mean(gg, axis=1)
|
||||
|
||||
Reference in New Issue
Block a user