I’ve written a Python script that captures screenshots and clicks on specific pixels based on their color. The goal is to click on red pixels, but for some reason, it’s clicking on blue pixels instead.
Here is the code:
import mss
import pyautogui
import numpy as np
import keyboard
top, left, width, height = 521, 1071, 451, 443
target_color = (255, 0, 0)
def click_at(x, y):
pyautogui.click(x, y)
def is_target_color(pixel):
tolerance = 20
r, g, b = pixel[:3]
return abs(r - target_color[0]) < tolerance and abs(g - target_color[1]) < tolerance and abs(b - target_color[2]) < tolerance
def create_border_mask(width, height, border_thickness):
mask = np.zeros((height, width), dtype=bool)
mask[:border_thickness, :] = True
mask[-border_thickness:, :] = True
mask[:, :border_thickness] = True
mask[:, -border_thickness:] = True
return mask
border_thickness = 2
border_mask = create_border_mask(width, height, border_thickness)
screenshot_count = 0
def main():
global screenshot_count
with mss.mss() as sct:
monitor = {"top": top, "left": left, "width": width, "height": height}
while True:
if keyboard.is_pressed("ctrl+1"):
print("Stopping...")
break
screenshot = sct.grab(monitor)
screenshot_count += 1
print(f"Screenshot taken: {screenshot_count}")
img = np.array(screenshot)
found = False
for y in range(height):
for x in range(width):
if border_mask[y, x]:
pixel = img[y, x][:3]
if is_target_color(pixel):
click_at(left + x, top + y)
found = True
break
else:
pass
if found:
break
print(f"Total screenshots taken: {screenshot_count}")
if __name__ == "__main__":
main()
I’ve tried adjusting the color matching logic, but I can’t seem to find the root cause of this issue.
As a newcomer to Python, I’m seeking help from the community to understand why the script isn’t accurately detecting red pixels. Any insights or suggestions would be greatly appreciated! (I want the code to run as fast as possible)
OpenCV by default use BGR Colour Space (due to historical reasons, see Why OpenCV Using BGR Colour Space Instead of RGB for details), you should either follow that in this line
r, g, b = pixel[:3]
or convert to RGB before processing, OpenCV: Changing Colorspaces does describe how to do that