Перейти к содержимому

Как узнать цвет пикселя на экране python

  • автор:

Быстро узнать цвет пикселя на экране, Python

Мне нужно быстро узнавать цвет пикселя на экране и реагировать на его изменение. Я работаю на Linux, Fedora. Как это можно сделать быстро на Python? Я пробовал использовать pyautogui.pixelMatchesColor() но 5-7 проверок в секунду для меня слишком медленно. Как можно это реализовать так, чтобы скорость обработки была выше? Заранее спасибо.

Отслеживать

Positron NN

задан 20 мар 2020 в 18:16

Positron NN Positron NN

145 1 1 серебряный знак 9 9 бронзовых знаков

Если делать «быстро и тупо», я бы взял ffmpeg с x11grab и читал бы пиксели из его stdout

20 мар 2020 в 18:40

Наверное, я немножко опоздал, но библиотека mss позволяет захватить часть экрана и вроде бы довольно быстрая (на моём линуксе где-то до 7000 захватов в секунду получается)

16 апр 2020 в 20:19

0

Сортировка: Сброс на вариант по умолчанию

Знаете кого-то, кто может ответить? Поделитесь ссылкой на этот вопрос по почте, через Твиттер или Facebook.

  • python
  • python-3.x
  • linux
  • обработка-изображений

Bitmap. Get Pixel(Int32, Int32) Метод

Пространство имен: System.Drawing Сборка: System.Drawing.Common.dll Сборка: System.Drawing.dll Пакет: System.Drawing.Common v6.0.0 Пакет: System.Drawing.Common v7.0.0 Пакет: System.Drawing.Common v8.0.0

Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

Возвращает цвет указанного пикселя в этом изображении Bitmap.

public: System::Drawing::Color GetPixel(int x, int y);
public System.Drawing.Color GetPixel (int x, int y);
member this.GetPixel : int * int -> System.Drawing.Color
Public Function GetPixel (x As Integer, y As Integer) As Color
Параметры

Возвращаемая координата пикселя по оси X.

Возвращаемая координата пикселя по оси Y.

Возвращаемое значение

Структура Color, представляющая цвет указанного пикселя.

Исключения

Параметр x меньше 0, либо больше или равен Width.

Параметр y меньше 0, либо больше или равен Height.

Операция не удалась.

Примеры

Следующий пример кода предназначен для использования с Windows Forms и требует PaintEventArgs e , который является параметром обработчика Paint событий. Код получает цвет пикселя на растровом рисунке, а затем заполняет прямоугольник этим цветом.

private: void GetPixel_Example( PaintEventArgs^ e ) < // Create a Bitmap object from an image file. Bitmap^ myBitmap = gcnew Bitmap( "Grapes.jpg" ); // Get the color of a pixel within myBitmap. Color pixelColor = myBitmap->GetPixel( 50, 50 ); // Fill a rectangle with pixelColor. SolidBrush^ pixelBrush = gcnew SolidBrush( pixelColor ); e->Graphics->FillRectangle( pixelBrush, 0, 0, 100, 100 ); > 
private void GetPixel_Example(PaintEventArgs e) < // Create a Bitmap object from an image file. Bitmap myBitmap = new Bitmap("Grapes.jpg"); // Get the color of a pixel within myBitmap. Color pixelColor = myBitmap.GetPixel(50, 50); // Fill a rectangle with pixelColor. SolidBrush pixelBrush = new SolidBrush(pixelColor); e.Graphics.FillRectangle(pixelBrush, 0, 0, 100, 100); >
Private Sub GetPixel_Example(ByVal e As PaintEventArgs) ' Create a Bitmap object from an image file. Dim myBitmap As New Bitmap("Grapes.jpg") ' Get the color of a pixel within myBitmap. Dim pixelColor As Color = myBitmap.GetPixel(50, 50) ' Fill a rectangle with pixelColor. Dim pixelBrush As New SolidBrush(pixelColor) e.Graphics.FillRectangle(pixelBrush, 0, 0, 100, 100) End Sub 

OpenCV на python: поиск цветного объекта

Обнаружить объект заданного цвета — одна из базовых задач машинного зрения. Решение этой задачи может помочь совершенно разным роботам в выполнении их функций.

Возьмем, к примеру, робота-футболиста. Чтобы забить гол, ему нужно сначала найти мяч на поле. Как правило, мяч в таких соревнованиях имеет цвет, отличный от цвета поля.

OpenCV на python. Поиск цветного объекта

Или другой пример — автоматическая пейтбольная турель. Это такой робот, который выискивает перед собой цель, поворачивает орудие на нужные углы и стреляет шариками с краской. Опять таки, цель может иметь яркую цветную метку, отличающуюся от фона (оранжевое пятно на куртке игрока).

На этом уроке мы разберем алгоритм детектирования и вычисления координат цветового пятна в кадре. То есть будем водить объектом какого-то конкретного цвета перед камерой, а программа будет выдавать нам координаты этого объекта относительно краев видеокадра.

Алгоритм поиска цветового пятна в OpenCV. Моменты изображения

Стандартный прием в OpenCV для решения поставленной задачи складывается из двух этапов.

На первом этапе мы применяем цветовой фильтр и превращаем каждый кадр в черно-белую картинку. После наложения фильтра объект заданного цвета превращается в белое пятно, а всё остальное заливается черным цветом. Вот так выглядит результат обработки фильтром кадра из прошлого урока.

OpenCV на python. Цветовой фильтр

На следующем этапе мы используем алгоритм вычисления моментов. Момент изображения — это суммарная характеристика пятна, представляющая собой сумму всех точек (пикселей) этого пятна. При этом, имеется множество подвидов моментов, характеризующие разные свойства изображения.

Например, момент нулевого порядка m00 — это количество всех точек, составляющих пятно. Момент первого порядка m10 представляет собой сумму X координат точек, а m01 — сумму Y координат. Имеются также моменты m11, m20, m02, m22 и т.д.

Формула для вычисления моментов очень проста, и мы можем посчитать пиксели вручную. Однако, стандартные функции OpenCV написаны на языках более низкого уровня, чем python, и работают быстрее. Воспользуемся стандартной функцией для вычисления моментов кадра:

moments( кадр, двоичный )

Аргумент кадр представляет собой нашу предобработанную картинку. Аргумент двоичный определяет то, как алгоритм будет вычислять вес каждой точки. Напомню, что предыдущий метод inRange дал нам черно-белую картинку, в которой пиксели могут быть черными, белыми, а могут быть и серыми. Так вот, если аргумент двоичный равен 1, то вес всех точек с цветом, отличным от нуля будет равен единице. В противном случае, вес черной точки будет равен 0, а белой точки — 255.

Функция moments вернет нам массив моментов вплоть до третьего порядка. Но для вычисления координат центра пятна нам потребуются только моменты первого порядка m01 и m10, а также момент m00.

dM01 = moments['m01'] dM10 = moments['m10'] dArea = moments['m00']

Чтобы получить координаты X и Y искомого пятна, нам следует поделить полученные моменты m10 и m01 на нулевой момент m00. Таким образом мы найдем средние координаты X и Y всех точек, а это и есть центр пятна.

x = int(dM10 / dArea) y = int(dM01 / dArea)

Программа для поиска цветового пятна на Raspberry Pi и python

Основываясь на предыдущих уроках, напишем программу, которая будет искать в кадре объект зеленого цвета и рисовать небольшую окружность в его центре.

import cv2 import numpy as np import video if __name__ == '__main__': def callback(*arg): print (arg) cv2.namedWindow( "result" ) cap = video.create_capture(0) # HSV фильтр для зеленых объектов из прошлого урока hsv_min = np.array((53, 55, 147), np.uint8) hsv_max = np.array((83, 160, 255), np.uint8) while True: flag, img = cap.read() # преобразуем RGB картинку в HSV модель hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV ) # применяем цветовой фильтр thresh = cv2.inRange(hsv, hsv_min, hsv_max) # вычисляем моменты изображения moments = cv2.moments(thresh, 1) dM01 = moments['m01'] dM10 = moments['m10'] dArea = moments['m00'] # будем реагировать только на те моменты, # которые содержать больше 100 пикселей if dArea > 100: x = int(dM10 / dArea) y = int(dM01 / dArea) cv2.circle(img, (x, y), 10, (0,0,255), -1) cv2.imshow('result', img) ch = cv2.waitKey(5) if ch == 27: break cap.release() cv2.destroyAllWindows()

Запускаем программу и пробуем водить перед камерой зеленым объектом.

Примечание! Функция moment не может различить одно пятно в кадре или несколько. Так что, если в кадре окажется, например, два зеленых объекта, то они интерпретируются как один большой, и центр будет где-то между ними.

Программа для поиска цветового пятна на Raspberry Pi и python. Подсветка траектории

Для большей наглядности будем выводить в кадр траекторию движения объекта.

import cv2 import numpy as np import video if __name__ == '__main__': def callback(*arg): print (arg) def createPath( img ): h, w = img.shape[:2] return np.zeros((h, w, 3), np.uint8) cv2.namedWindow( "result" ) cap = video.create_capture(0) hsv_min = np.array((53, 55, 147), np.uint8) hsv_max = np.array((83, 160, 255), np.uint8) lastx = 0 lasty = 0 path_color = (0,0,255) flag, img = cap.read() path = createPath(img) while True: flag, img = cap.read() hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV ) thresh = cv2.inRange(hsv, hsv_min, hsv_max) moments = cv2.moments(thresh, 1) dM01 = moments['m01'] dM10 = moments['m10'] dArea = moments['m00'] if dArea > 100: x = int(dM10 / dArea) y = int(dM01 / dArea) cv2.circle(img, (x, y), 10, (0,0,255), -1) if lastx > 0 and lasty > 0: cv2.line(path, (lastx, lasty), (x,y), path_color, 5) lastx = x lasty = y # накладываем линию траектории поверх изображения img = cv2.add( img, path) cv2.imshow('result', img) ch = cv2.waitKey(5) if ch == 27: break cap.release() cv2.destroyAllWindows()

Пример работы программы на Raspberry Pi с обычной веб-камерой.

Your browser does not support the video tag.

Программа для поиска цветового пятна на Raspberry Pi и python. Вывод координат

И еще одна модификация. Будем рядом с обнаруженным центром пятна выводить его координаты.

import cv2 import numpy as np import video if __name__ == '__main__': def callback(*arg): print (arg) cv2.namedWindow( "result" ) cap = video.create_capture(0) hsv_min = np.array((53, 55, 147), np.uint8) hsv_max = np.array((83, 160, 255), np.uint8) color_yellow = (0,255,255) while True: flag, img = cap.read() img = cv2.flip(img,1) # отражение кадра вдоль оси Y hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV ) thresh = cv2.inRange(hsv, hsv_min, hsv_max) moments = cv2.moments(thresh, 1) dM01 = moments['m01'] dM10 = moments['m10'] dArea = moments['m00'] if dArea > 100: x = int(dM10 / dArea) y = int(dM01 / dArea) cv2.circle(img, (x, y), 5, color_yellow, 2) cv2.putText(img, "%d-%d" % (x,y), (x+10,y-10), cv2.FONT_HERSHEY_SIMPLEX, 1, color_yellow, 2) cv2.imshow('result', img) ch = cv2.waitKey(5) if ch == 27: break cap.release() cv2.destroyAllWindows()

Запускаем программу и проверяем работу алгоритма. Снова используем Raspberry Pi. Как видно на видео, мощности Raspberry Pi вполне хватает для выполнения поиска цветного объекта с помощью моментов.

Your browser does not support the video tag.

Ну вот и все на сегодня. На следующем уроке заставим роботов искать не просто цветные пятна, а целые геометрические фигуры!

Как узнать цвет пикселя на экране python

Добрый день, мне нужно сделать несколько скриптом с действиями, если пиксели в указанной области имеют определённые цвета.
1. Если правая кнопка мыши нажата и пиксель (940, 385) имеет цвет 0xC14F4F, то зажать и держать левую кнопку мыши. Как только отпустил правую кнопку мыши или пиксель (940, 385) не имеет цвет 0xC14F4F, то отпустить левую кнопку мыши.

 ~RButton:: while(GetKeyState("RButton", "P")) < PixelGetColor, color, 940, 385 if (color == 0xC14F4F) < Send, > else < Send, > > Send, return 

Last edited by Nagir on 31 May 2021, 06:18, edited 2 times in total.
Nagir Posts: 5 Joined: 31 May 2021, 01:40

Re: Нажатие кнопки по цвету пикселя в области

Суть в том, чтобы производился выстрел, когда прицел наведён на противника (становится красного цвета)
Image
Image

Last edited by gregster on 31 May 2021, 06:09, edited 1 time in total.
Reason: Images fixed.
mcl Posts: 342 Joined: 04 May 2018, 16:35

Re: Нажатие кнопки по цвету пикселя в области

В целом код, похоже, верный.
По умолчанию у PixelGetColor порядок цветовых каналов BGR, а не RGB − попробуйте изменить команду PixelGetColor на PixelGetColor, color, 940, 385, RGB ИЛИ поменять проверяемый цвет на 0x4F4FC1 .

github://oGDIp — GDI+ wrapper for AHK v1.1
Nagir Posts: 5 Joined: 31 May 2021, 01:40

Re: Нажатие кнопки по цвету пикселя в области

31 May 2021, 10:01

В целом код, похоже, верный.
По умолчанию у PixelGetColor порядок цветовых каналов BGR, а не RGB − попробуйте изменить команду PixelGetColor на PixelGetColor, color, 940, 385, RGB ИЛИ поменять проверяемый цвет на 0x4F4FC1 .

Добрый день! Спасибо большое за ответ. Всё равно бот не работает ни так, ни так.
Может я неверно указал координаты пикселя?
Как можно задать область пикселей? (чтобы проверял по всем прицелу)

mcl Posts: 342 Joined: 04 May 2018, 16:35

Re: Нажатие кнопки по цвету пикселя в области

01 Jun 2021, 07:08

Может я неверно указал координаты пикселя?
Как можно задать область пикселей? (чтобы проверял по всем прицелу)

Может быть. Если скриншоты выше сделаны вами, то есть два заслуживающих внимания момента:
1. Прицел расположен точно по центру экрана, размер скриншота − 1920×1080, положение прицела: 960:540.
2. Судя по размеру скриншотов, игра работает в полноэкранном режиме. В этом случае PixelGetColor может неверно определять цвет. Можно попробовать добавить ему режим Alt или Slow.

Проверять область пикселей можно командой PixelSearch, но она медленнее, плюс могут быть ложные срабатывания, если вы навели прицел на что-то красное, а область поиска велика.

Для отладки можно проверять цвет пикселя, например, через TrayTip или, для проверки работоспособности в полноэкранном режиме, звуковой сигнал:

~RButton:: CoordMode, Pixel, Client while(GetKeyState("RButton", "P")) < PixelGetColor, color, 940, 385, RGB Slow TrayTip,, % Format("0x", color) ; показать цвет пикселя в трее if ((color == "") || (color == 0x000000)) < ; если пиксель чёрный или цвет не удалось определить − SoundBeep, 100, 100 ; будет выдан звуковой сигнал Sleep 300 >else if (color == 0xC14F4F) < Send, > else < Send, > > Send, return 

github://oGDIp — GDI+ wrapper for AHK v1.1
Nagir Posts: 5 Joined: 31 May 2021, 01:40

Re: Нажатие кнопки по цвету пикселя в области

01 Jun 2021, 12:30
01 Jun 2021, 07:08

Может я неверно указал координаты пикселя?
Как можно задать область пикселей? (чтобы проверял по всем прицелу)

Может быть. Если скриншоты выше сделаны вами, то есть два заслуживающих внимания момента:
1. Прицел расположен точно по центру экрана, размер скриншота − 1920×1080, положение прицела: 960:540.
2. Судя по размеру скриншотов, игра работает в полноэкранном режиме. В этом случае PixelGetColor может неверно определять цвет. Можно попробовать добавить ему режим Alt или Slow.

Проверять область пикселей можно командой PixelSearch, но она медленнее, плюс могут быть ложные срабатывания, если вы навели прицел на что-то красное, а область поиска велика.

Для отладки можно проверять цвет пикселя, например, через TrayTip или, для проверки работоспособности в полноэкранном режиме, звуковой сигнал:

~RButton:: CoordMode, Pixel, Client while(GetKeyState("RButton", "P")) < PixelGetColor, color, 940, 385, RGB Slow TrayTip,, % Format("0x", color) ; показать цвет пикселя в трее if ((color == "") || (color == 0x000000)) < ; если пиксель чёрный или цвет не удалось определить − SoundBeep, 100, 100 ; будет выдан звуковой сигнал Sleep 300 >else if (color == 0xC14F4F) < Send, > else < Send, > > Send, return 

Спасибо огромное! Всё заработало!

Return F4::Reload ~RButton:: while(GetKeyState("RButton", "P")) < PixelGetColor, color, 960, 540, RGB if (color == 0xC14F4F) < Send, > else < Send, > > Send,

Правд иногда почему то «зависает» и перестает реагировать. Или может вдруг начать стрелять «одиночными» выстрелами, а не очередью. Почему так?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *