Компьютерное зрение | Вводный курс ML

Компьютерное зрение

Все курсы > Вводный курс > Занятие 18

Компьютерное зрение (computer vision) — это область, занимающаяся анализом фото и видео изображений. Построенные на основе этого анализа модели помогают смартфонам узнавать своих владельцев, дорожным камерам распознавать номера автомобилей, а роботам объезжать препятствия.

компьютерное зрение

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

Работа с изображениями в Питоне

Любое цифровое изображение — это по сути матрица, а в случае Питона, массив Numpy, в котором положение пикселей (составных частей, pixel или picture element) задано координатами.

координатная система цифрового изображения

Значениями такой матрицы будут оттенки цветов. Сочетание пикселей разных оттенков и создает цифровое изображение.

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

По традиции вначале откроем ноутбук к этому занятию

Черно-белые изображения

В случае черно-белого изображения, или правильнее сказать, изображения в оттенках серого (grayscale image), речь идет об одном слое матрицы.

матрица изображения в оттенках серого

Для каждого пикселя у нас есть 256 оттенков от черного (0) до белого (255). С точки зрения Питона, речь идет о двумерном массиве (координаты пикселя по вертикали и горизонтали).

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

черно-белая фотография оператора библиотеки skimage

По умолчанию, imshow преобразует черно-белые фото в цветные. Чтобы этого избежать, нужно указать параметр цветовой схемы cmap = 'gray'.

Повторюсь, отдельного класса для изображений в Питоне нет, мы работаем с массивами Numpy.

Посмотрим на его размерность. Должно быть два измерения.

А также на общее количество пикселей.

Мы можем вывести тип значения нашей матрицы, общий диапазон оттенков, а также значение (оттенок) конкретного пикселя.

Для того чтобы вывести этот оттенок на экран, воспользуемся библиотекой PIL (Python Imaging Library).

цвет с оттенком 158

Цветные изображения

У цветного изображения (color image) таких слоев, или правильнее говорить каналов (channels), три: красный, зелёный и синий (red, green, blue или RGB).

три канала матрицы цветного изображения

Комбинация интенсивности этих цветов и определяет цвет каждого пикселя. Вот несколько примеров.

названия, коды RGB и примеры цветов

Теперь поработаем с цветными изображениями в Питоне.

цветная фотография кошки библиотеки skimage

В данном случае измерений у массива Numpy уже три, координата по вертикали, по горизонтали и слой. Значениями будет интенсивность каждого из трёх цветов (также от 0 до 255).

цвет с оттенками 138, 98, 63

Каждый из трёх базовых цветов или каналов можно изолировать.

пример изолирования трех базовых цветов (каналов): красного, зеленого и синего

Если эти картинки наложить друг на друга, мы восстановим исходное изображение.

Гистограмма

Как чёрно-белое, так и цветное изображение можно визуализировать с помощью гистограммы. По горизонтали будут отложены оттенки от 0 до 255, а по вертикали количество пикселей каждого из оттенков. Начнем с черно-белого.

Функции calcHist мы передаем следующие параметры:

  • image: само изображение [camera_img]
  • channels: для ч/б фотографии это [0]
  • mask: так как мы строим гистограмму всего изображения, то фильтр или срез (mask) равен None
  • histSize: количество интервалов (bins) [256]
  • ranges: диапазон оттенков [0,256]
гистограмма черно-белого изображения

Аналогичным образом создадим гистограмму цветного изображения.

гистограмма цветного изображения

Гистограмма может использоваться, например, при поиске порогового значения (threshold) в процессе обработки изображения (об этом ниже).

Обработка изображений

Начнем с простых операций. Например, мы можем вырезать часть изображения по координатам.

срез изображения по координатам

Кроме того, мы можем изменить цвет конкретного пикселя или закрасить целую область.

изменение (значения пикселей) изображения

Также ожидаемо библиотека skimage позволяет преобразовывать цветные изображения в черно-белые.

преобразование цветного изображения в черно-белое

Так как наши изображения не что иное, как матрицы, мы можем применять к ним матричные вычисления и благодаря этому трансформировать их. В частности, матрицы можно транспонировать (т.е. каждую строчку исходной матрицы записать в виде столбцов в том же порядке).

транспонирование матрицы

Если транспонировать первые две оси цветного изображения (не трогая при этом третью, цветовую ось) картинка повернется.

поворот изображения через транспонирование матрицы

Помимо этого, решая задачи сегментации изображения (то есть выделения однородных областей, image segmentation), мы можем применить пороговое преобразование (image thresholding). Например, для того чтобы разделить передний и задний план изображения.

На практике мы задаем некий порог, и все пиксели, значение (оттенок) которых ниже порога, делаем черными, а выше — белыми. Таким образом, мы создаем по-настоящему черно-белое изображение (binary image).

пороговое преобразование изображения

На гистограмме это бы выглядело следующим образом.

пороговое значение на гистограмме

Вопрос поиска оптимального порогового значения выходит за рамки вводного курса.

Классификация изображений на примере датасета MNIST

Классификация изображений (image classification) — это задача машинного обучения с учителем. У нас есть набор изображений (наши признаки) и описание того, что представлено на этих изображениях (наша целевая переменная).

Для наших целей мы возьмём классический датасет MNIST, содержащий изображения написанных от руки цифр от 0 до 9.

датасет MNIST библиотеки Scikit-learn

После обучения модель сможет самостоятельно определять, что представлено на изображении.

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

В качестве алгоритма мы будем использовать метод опорных векторов (support vector machine или SVM).

Про метод опорных векторов (SVM)

Принцип этого классификатора заключается в том, чтобы построить плоскость (а вернее гиперплоскость, потому что мы работаем в многомерном пространстве) между несколькими точками каждого класса. Эти точки называются опорными векторами (support vectors).

метод опорных векторов (SVM)

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

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

метод ядра (kernel trick) в алгоритме SVM

Это называется kernel trick (метод ядра). Помимо возведения в квадрат существуют и другие функции ядра.

Практика

Для начала импортируем необходимые библиотеки и сам набор данных из библиотеки Scikit-learn.

Посмотрим, что внутри. Традиционно для Scikit-learn встроенный набор данных представляет собой объект Bunch. Вот его компоненты.

Изображения хранятся в компоненте images. Всего у нас 1797 изображений.

Каждое изображение представлено двумерным массивом 8 x 8 (что соответствует 64 пикселям).

Сам массив выглядит следующим образом.

Давайте посмотрим на первые четыре изображения.

первые четыре изображения датасета MNIST библиотеки Scikit-learn

Теперь необходимо подготовить данные. В первую очередь, двумерные матрицы каждого изображения нужно преобразовать в одномерные.

преобразование двумерной матрицы изображения в одномерную

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

матрица из нескольких одномерных изображений после преобразования

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

Как мы видим, массив «вытянулся». Удостоверимся, что мы все сделали правильно.

В процессе обучения модели в первую очередь разобьём данные на обучающую и тестовую выборки.

Затем используем метод опорных векторов для обучения модели и формирования прогноза.

С помощью атрубута support_ мы можем посмотреть на индексы точек (изображений), которые использовались в качестве опорных векторов при обучении модели.

Если применить индексы support_ к нашему датасету, то мы выберем (отфильтруем) изображения, которые использовал классификатор.

Всего же в обучающей выборке в два раза больше данных.

Для оценки качества модели вначале воспользуемся метрикой accuracy. Напомню, что она показывает долю правильных предсказаний. В случае с мультиклассовой классификацией она рассчитывается как среднее арифметическое accuracy по всем классам.

Accuracy по каждому классу будет удобно посмотреть с помощью матрицы ошибок.

матрица ошибок алгоритма классификации изображений

В частности, мы видим, что алгоритм дважды ошибся с цифрой 9, классифицировав ее как 7 и 8.

Мы также можем посмотреть на результат нашей работы визуально.

прогноз алгоритма SVM для датасета MNIST библиотеки Scikit-learn

Подведем итог

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

Конечно, построенная нами модель очень проста и в реальной жизни задачи классификации, а также более сложные задачи, например, распознавание изображений (image recognition) чаще решаются с помощью глубокого обучения и нейронных сетей.

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

Вопросы для закрепления

Сколько оттенков серого есть в черно-белой (grayscale) фотографии? Сколько слоев и оттенков есть в цветной фотографии?

Посмотреть правильный ответ

Что такое гистограмма изображения?

Посмотреть правильный ответ

Что такое изображение с точки зрения компьютера и Питона?

Посмотреть правильный ответ

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


Ответы на вопросы

Вопрос. Вы не могли бы более подробно рассказать про функцию plt.subplots()? Не очень понятно, что передается в переменные fig и ax.

Ответ. Добавил небольшое объяснение и несколько примеров в конце ноутбука к этому занятию⧉.


Вопрос. Я правильно понимаю, что изображения разделяют на черно-белые, серые и цветные?

Ответ. Да, совершенно верно, на черно-белые (binary), с оттенками серого (grayscale) и цветные (color).


Вопрос. Расскажите, пожалуйста, подробнее, почему в 8 битах содержится 256 значений.

Ответ. Смотрите, предположим у нас только два бита, первый может получить значение 0 или 1 и второй также — 0 или 1. Тогда всего у нас есть четыре возможных комбинации: 00, 10, 01, 11. Рассчитать это можно, возведя 2 в степень, равную количеству имеющихся битов. Если у нас два бита, то $2^2=4.$

Аналогично, если у нас 8 битов, то $2^8=256.$


Вопрос. Можете еще раз объяснить, как используется метод .reshape()?

Ответ. Метод .reshape() применяется к массивам Numpy и меняет их размерность. Например, переводит одномерные массивы в двумерные.

Я добавил несколько примеров в дополнительных материалах в конце ноутбука⧉. Мы также будем более подробно разбираться с массивами Numpy на курсе программирования на Питоне.