«Это третий день моего участия в первом испытании обновлений 2022 года. Подробную информацию о мероприятии см.:Вызов первого обновления 2022 г."
OpenCV получает доступ и управляет пикселями в разных цветовых пространствах
В этом разделе описывается, как использовать OpenCV для доступа и чтения значений пикселей и как их изменять. Кроме того, вы узнаете, как получить доступ к свойствам изображения. Если вы хотите обрабатывать несколько пикселей одновременно, вам необходимо создать область изображения (ROI).
В Python изображения представлены в виде массивов NumPy. Поэтому большинство операций, включенных в пример, относятся к NumPy.Рекомендуется иметь некоторое представление о пакете NumPy, чтобы лучше понять принцип кода примера, но не беда, если вы этого не сделаете, а используемые функции будут объяснены при необходимости.
Доступ к цветному изображению и манипулирование пикселями в OpenCV
Теперь давайте посмотрим, как обрабатывать изображения BGR в OpenCV. Как упоминалось выше, когда OpenCV загружает цветное изображение, синий канал является первым, зеленый канал — вторым, а красный канал — третьим.
Во-первых, используйтеcv2.imread()
функция чтения изображения. Изображение должно находиться в рабочем каталоге или должен быть указан полный путь к изображению. В этом примере прочитайтеsigonghuiye.jpeg
изображение и сохраните его в переменной img:
img = cv2.imread('sigonghuiye.jpeg')
изображение загружается вimg
После этого можно получить некоторые свойства изображения. Первый атрибут, который мы хотим извлечь из загруженного изображения, этоshape
, который сообщит нам количество строк, столбцов и каналов (если изображение цветное). Мы храним эту информацию вdimensions
в переменной:
dimensions = img.shape
Второе свойство — это размер изображения (img.size=высота изображения × ширина изображения × количество каналов изображения):
total_number_of_elements= img.size
Третье свойство — это тип данных изображения, доступ к которому можно получить черезimg.dtype
получить. Поскольку значения пикселей находятся в диапазоне [0-255], тип данных изображения — uint8 (unsigned char):
image_dtype = img.dtype
В приведенном выше примере мы использовалиcv2.imshow()
функция для отображения изображения в окне, здесь мы представляем ее более подробно, при использовании функции cv2.imshow() для отображения изображения окно автоматически адаптируется к размеру изображения. Первый параметр этой функции — имя окна, а второй параметр — отображаемое изображение. В этом случае, поскольку загруженное изображение уже сохранено в переменной img, используйте эту переменную в качестве второго аргумента:
cv2.imshow("original image", img)
После отображения изображения давайте представим функцию привязки клавиатуры —cv2.waitKey()
, который ожидает указанное количество миллисекунд для любого события клавиатуры. Параметр - время в миллисекундах. При выполнении этой функции выполнение программы будет приостановлено, а при нажатии любой клавиши выполнение программы продолжится. Если число миллисекунд равно 0 (cv2.waitKey(0)
), он будет бесконечно ждать нажатия клавиши:
cv2.waitKey(0)
Чтобы получить доступ (прочитать) к определенному значению пикселя, нам нужно передать в переменную img (содержащую загруженное изображение) строку и столбец нужного пикселя, например, чтобы получитьЗначение пикселя в:
(b, g, r) = img[6, 40]
Мы в трех переменных(b, g, r)
Три значения пикселей хранятся в . Имейте в виду, что OpenCV использует цветные изображения.BGR
Формат. Кроме того, мы можем получить доступ только к одному каналу за раз. В этом примере мы будем индексировать, используя строку, столбец и индекс нужного канала. Например, чтобы получить только пикселиСинее значение в:
b = img[6, 40, 0]
Значения пикселей также можно изменить таким же образом. Например, чтобы сделать пиксель (x=40, y=6) красным:
img[6, 40] = (0, 0, 255)
Иногда необходимо обработать не пиксель, а область. В этом случае должен быть предоставлен диапазон (он же срез) значений, а не одно значение. Например, чтобы получить верхний левый угол изображения:
top_left_corner = img[0:50, 0:50]
Переменнаяtop_left_corner
Можно рассматривать как другое изображение (меньше, чем img), но мы можем обращаться с ним таким же образом.
Наконец, если вы хотите закрыть и освободить все окна, вам нужно использоватьcv2.destroyAllWindows()
функция:
cv2.destroyAllWindows()
Доступ к изображениям в оттенках серого и манипулирование пикселями в OpenCV
Изображения в градациях серого имеют только один канал. Поэтому при обработке этих изображений вводятся некоторые отличия. Здесь мы сосредоточимся на этих различиях, и одни и те же части не будут повторяться.
Опять же, мы будем использовать функцию cv2.imread() для чтения изображения. В данном случае необходим второй параметр, потому что мы хотим загрузить изображение в оттенках серого. Второй параметр — это бит флага, указывающий, как читать изображение. Значение, необходимое для загрузки изображения в оттенках серого, равно cv2.IMREAD_grayscale:
gray_img = cv2.imread('logo.png', cv2.IMREAD_GRAYSCALE)
В этом случае мы сохраняем изображение в переменной gray_img. Если мы напечатаем размеры изображения (используя gray_img.shape), мы получим только два значения: строку и столбец. В изображениях в градациях серого информация о канале не предоставляется:
dimensions = gray_img.shape
shape вернет размеры изображения в виде кортежа - (828, 640).
Доступ к значениям пикселей можно получить по координатам строк и столбцов. В изображениях в градациях серого получается только одно значение (обычно называемое интенсивностью пикселя). Например, если мы хотим получить пикселиИнтенсивность пикселей при:
i = gray_img[6, 40]
Значения пикселей изображения также могут быть изменены таким же образом. Например, если вы хотите сделать пиксельЗначение at становится черным (интенсивность равна 0):
gray_img[6, 40] = 0