Last active
November 6, 2022 21:40
-
-
Save winstxnhdw/1ae6101441a46aaf6ed5850621a04fef to your computer and use it in GitHub Desktop.
Get the coordinates of any screenshot with PyScreeze and OpenCV.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cv2 as cv | |
from numpy import asarray, ndarray | |
from pyscreeze import screenshot | |
IntVector2 = tuple[int, int] | |
class NoRegionSelected(Exception): | |
"""Raised when the user ends the selection without selecting a region.""" | |
class RegionOfInterest: | |
def __init__(self, screen: ndarray, window_name: str): | |
self.original_screen = screen | |
self.screen = screen.copy() | |
self.window_name = window_name | |
self.colour = (0, 255, 0) | |
self.thickness = 1 | |
self.bounds = [] | |
self.hold = False | |
def get_region_bounds(self) -> tuple[IntVector2, IntVector2]: | |
if not self.bounds: | |
raise NoRegionSelected('No region has been selected.') | |
unsorted_bounds = asarray(self.bounds, dtype=object).T | |
top_left_coordinates = (unsorted_bounds[0].min(), unsorted_bounds[1].min()) | |
bottom_right_coordinates = (unsorted_bounds[0].max(), unsorted_bounds[1].max()) | |
return top_left_coordinates, bottom_right_coordinates | |
def select_region_of_interest(self, event, x: int, y: int, *args): | |
if event == cv.EVENT_LBUTTONDOWN: | |
self.hold = True | |
self.screen = self.original_screen.copy() | |
self.bounds.clear() | |
self.bounds.append([x, y]) | |
elif event == cv.EVENT_MOUSEMOVE and self.hold: | |
self.screen = self.original_screen.copy() | |
cv.rectangle(self.screen, self.bounds[0], (x, y), self.colour, self.thickness) | |
cv.imshow(self.window_name, self.screen) | |
elif event == cv.EVENT_LBUTTONUP: | |
self.hold = False | |
self.bounds.append([x, y]) | |
cv.rectangle(self.screen, self.bounds[0], self.bounds[1], self.colour, self.thickness) | |
cv.imshow(self.window_name, self.screen) | |
def cv_region_crop(window_name: str) -> tuple[IntVector2, IntVector2]: | |
screen = cv.cvtColor(asarray(screenshot()), cv.COLOR_RGB2BGR) | |
roi = RegionOfInterest(screen, window_name) | |
cv.namedWindow(window_name, cv.WINDOW_GUI_NORMAL) | |
cv.setMouseCallback(window_name, roi.select_region_of_interest) | |
cv.imshow(window_name, screen) | |
while True: | |
key = cv.waitKey(1) | |
if key == ord('q'): | |
break | |
if cv.getWindowProperty(window_name, cv.WND_PROP_VISIBLE) < 1: | |
break | |
return roi.get_region_bounds() | |
def region_crop(window_name: str) -> tuple[IntVector2, IntVector2]: | |
region = cv_region_crop(window_name) | |
cv.destroyWindow(window_name) | |
return region |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment