Skip to content

Instantly share code, notes, and snippets.

@winstxnhdw
Last active November 6, 2022 21:40
Show Gist options
  • Save winstxnhdw/1ae6101441a46aaf6ed5850621a04fef to your computer and use it in GitHub Desktop.
Save winstxnhdw/1ae6101441a46aaf6ed5850621a04fef to your computer and use it in GitHub Desktop.
Get the coordinates of any screenshot with PyScreeze and OpenCV.
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