[Обработка компьютерного зрения 2] Базовые знания об изображениях

задняя часть

Это второй день моего участия в августовском испытании обновлений, подробности о мероприятии:Испытание августовского обновления

Основы изображения

Автор: Зак Сок

1. Изображение в компьютере

В компьютерах изображения хранятся в двоичном виде. Но мы обычно не манипулируем изображениями в двоичном виде, мы предпочитаем думать об изображении как о наборе точек при работе с ним. Набор распределен в двух измерениях, каждая точка имеет свой цвет, и каждая точка неделима. Мы называем такую ​​точку [пикселем]. Например эта картинка:

Мы можем думать об этом как об изображении 5 * 5, где каждая точка черная.

Ранние компьютеры могли отображать только простые изображения, такие как [бинарные изображения]. Это изображение либо черное, либо белое, третий цвет не допускается. Например следующее:

Для такого изображения нам нужен только один двоичный бит (0, 1) на пиксель для его представления. Однако такое изображение не может удовлетворить потребности людей, поэтому есть изображение с большей детализацией, но еще без цвета, то есть [изображение в градациях серого], с которым мы столкнемся позже. Например следующее:

Изображение выше сохраняет большинство деталей реальной сцены. Если пиксели изображения в градациях серого представлены однобитным двоичным кодом, этого несколько недостаточно, поэтому изображение в градациях серого должно быть представлено 8-битным двоичным кодом, то есть 0-255. Поскольку жесткие диски больше не являются дефицитным ресурсом, двоичные образы обычно представляются 8-битными двоичными файлами. Используйте 0 для 0 (черный) и 255 для 1 (белый).

Если вы хотите представить цветное изображение, это сложнее.Вот изображение RGB изображения:

Так называемое RGB-изображение представляет собой изображение, пиксели которого представлены тремя значениями. Три значения представляют степень красного, зеленого и синего соответственно. Например, если уровень красного пикселя равен 255, а два других уровня цвета равны 0, то пиксель для нас красный. Комбинируя эти три цвета, мы можем подобрать 4 294 967 296 различных цветов.

Конечно, образы, в которых мы живем, намного богаче, такие как прозрачные изображения, динамические изображения и т. д. Я не буду здесь вдаваться в подробности.

2. Изображения в OpenCV

Понимание различных изображений, упомянутых выше, в равной степени применимо в OpenCV.

В OpenCV изображения хранятся в формате ndarray. ndarray — это массив в numpy, он имеет несколько измерений и может представлять полную информацию об изображении. Включая ширину и высоту картинки, значение пикселя и т.д. Мы можем попробовать посмотреть на ndarray изображения ниже:

Поскольку оно относительно длинное, мы перехватываем часть представления и получаем следующий результат:

[[[245 225 190]
  [245 225 190]
  [245 225 190]
  ...
  [214 195 184]
  [214 195 184]
  [214 195 184]]

 [[245 225 190]
  [245 225 190]
  [245 225 190]

На данном этапе нам не нужно уделять слишком много внимания содержимому массива, OpenCV предоставляет нам простой API для получения ключевой информации об изображении. Давайте кратко рассмотрим ниже.

3. Получить информацию об изображении

Прежде чем получить информацию об изображении, нам нужно использовать функцию imread для чтения изображения. Давайте посмотрим на следующий код:

import cv2
im = cv2.imread('xscn.jpg')
print("图像的形状:", im.shape)
print("图像的大小:", im.size)
print("图像的数据类型:", im.dtype)

Давайте сначала посмотрим на вывод,

图像的形状: (1080, 1920, 3)
图像的大小: 6220800
图像的数据类型: uint8

Давайте еще раз объясним каждый параметр:

  • форма: форма изображения, включая информацию о высоте, ширине и количестве слоев.
  • размер: значение высоты * ширины * количество слоев
  • dtype: тип каждых данных. Для изображений в градациях серого один элемент данных равен одному пикселю. Для изображений RGB эталоном является значение цвета в пикселе. unit8 представляет собой 8-битное двоичное положительное целое число (0-255)

Количество слоев означает, что пиксель состоит из нескольких данных. Например, количество слоев в изображении в градациях серого равно 1, а количество слоев в изображении RGB равно 3.

4. Координаты изображения

Для удобства мы можем построить систему координат для изображения, эту систему координат не нужно строить на самом деле, а просто для нашего удобства.

Давайте посмотрим на картинку ниже:

Мы строим систему координат, а затем сопоставляем левый верхний угол изображения с началом координат. Таким образом, мы можем определить пиксель в виде (x, y).Например, координаты точки A на рисунке равны (500, 300).

5. Получите значение пикселя

Для получения значения пикселя также требуется сначала прочитать изображение, а затем мы можем получить доступ к пикселю в указанном месте следующими способами:

im[y][x]

где im — наш объект изображения. x, y соответствуют x, y в координатах. Например следующий код:

import cv2
im = cv2.imread('xscn.jpg')
pixel = im[0][0]
print(pixel)

Результат выглядит следующим образом:

[245 225 190]

Поскольку изображение RGB считывается, один пиксель состоит из трех частей данных. Далее мы можем получить значение определенного цвета, например, если я хочу получить значение красного цвета в пикселе с координатами (100, 100), мы можем получить его так:

red = im[100][100][0]

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

red = im[100][100][2]

6. Измените значение пикселя

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

Для удобства просмотра выше эффект увеличения картинки 3*3. Мы используем код для изменения пикселей изображения:

import numpy as np
im = np.zeros((3, 3, 1), dtype=np.uint8)
im[0][2] = 255

Роль np.zeros заключается в создании многомерного массива. Мы напрямую понимаем это как создание вышеуказанного образа, и мы объясним это более подробно позже.

После создания изображения мы изменили пиксель в точке (2, 0) до 255. Ниже приведено измененное изображение:

Вы можете видеть, что указанный пиксель был изменен.