Простой классификатор изображений с OpenCV

Как люди, мы, как правило, очень хорошо умеем находить различия в картинках. Например, давайте посмотрим на картинку выше и посмотрим, чем они отличаются. Во-первых, очевидно изменились фрукты, мороженое и напитки. Это было довольно просто, правда?

Однако для компьютеров это не такая уж простая задача. Компьютеры могут учиться только на том, чему мы обучаем их модели. Есть отличные модели, которые могут действительно хорошо классифицировать пакетные изображения, например TensorFlow от Google и Keras.

Благодаря подобным библиотекам классификаторов изображений компьютерное зрение резко выросло. Теперь мы можем создавать сложные модели, такие как эта в kaggle: Animals-10, которая содержит тысячи изображений десяти различных типов животных, а также не животных, уже обученных и очищенных. Все, что вам нужно сделать, это создать модель и посмотреть, насколько хорошо ваша модель может предсказать каждый тип животных. Для учебных пособий по оформлению моделей классификации изображений см. Прабху или Амитабха.

Однако я хотел создать классификатор изображений, который может определить, насколько похожи два изображения. Для этого нет необходимости в каких-либо сложных библиотеках, таких как TensorFlow, или моделях классификации изображений, подобных ссылкам выше. Есть два способа узнать, похоже ли изображение на другое. Первый - это среднеквадратическая ошибка (MSE), а второй - индекс структурного сходства (SSIM).

Они оба выглядят довольно устрашающе, но не о чем беспокоиться. MSE можно довольно легко вычислить, потому что NumPy, а SSIM - это встроенный метод в библиотеке изображений Sci-Kit, поэтому мы можем просто загрузить его.

Прежде чем мы это сделаем, давайте определим, что каждый вычисляет. MSE вычислит среднеквадратичную ошибку между каждым пикселем для двух сравниваемых изображений. В то время как SSIM будет делать противоположное и искать сходство в пикселях; то есть, если пиксели на двух изображениях совпадают и / имеют одинаковые значения плотности пикселей. Единственная проблема заключается в том, что MSE, как правило, имеет произвольно высокие числа, поэтому его сложнее стандартизировать. Хотя, как правило, чем выше MSE, тем меньше они похожи, но если mse между наборами изображений различаются случайным образом, нам будет труднее что-либо сказать. SSIM, с другой стороны, выставляет все по шкале от -1 до 1 (но я не смог получить оценку меньше 0). Оценка 1 означает, что они очень похожи, а оценка -1 означает, что они очень разные. На мой взгляд, это лучшая метрика измерения.

Теперь сосредоточимся на кодах и приступим к импорту всех необходимых библиотек:

Я использую CV2 (часть OpenCV) для чтения и редактирования своих изображений. Если вы хотите, вы также можете использовать вместо этого imread из matplotlib. Моя подруга Йиш Лим сделала это в своем блоге о матче покемонов, и это довольно круто.

Теперь перейдем к самой страшной части написания нашей формулы MSE:

Поскольку SSIM уже был импортирован через skimage, кодировать его вручную не нужно. Теперь мы создаем функцию, которая будет принимать два изображения, вычислять их mse и ssim и показывать нам значения сразу.

Теперь следующие три шага можно выполнить сразу с помощью цикла for, но давайте разберем его в приведенных ниже кодах, чтобы было легче следовать:

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

Теперь протестируем и посмотрим, работают ли наши MSE и SSIM, сравнив одно изображение с самим собой. Если это сработает, то мы должны получить MSE, равную 0, и SSIM, равную 1.

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

Давайте посмотрим, что только что сравнил наш простой алгоритм. Как видите, MSE сильно различается, поэтому трудно сказать, что к чему. Но глядя на SSIM, мы видим, что собака 2 и собака 3 наиболее похожи по сравнению с другими собаками. Визуально согласен, особенно с тем, как уши. Но я бы подумал, что собака 1 и собака 3 имели бы более высокий SSIM из-за их позы. На самом деле, до серого цикла изображений у собак 2 и 3 была похожая белая шерсть вокруг носа, а у собаки 1 - нет. Это, скорее всего, причина того, что у собак 2 и 3 значение SSIM выше, чем у собаки 1. Для кошек это немного сложнее. Кошка 1 и кошка 2 имели похожую форму, и снимок был сделан с одинакового расстояния, но кошка 2 и кошка 3 имели похожий цвет шерсти. Вероятно, поэтому кошка 1 и 3 оцениваются так же, как кошка 2 и 3, но не кошка 1 и кошка 2.

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

Как и ожидалось, собаки и кошки похожи, особенно по сравнению с неодушевленным объектом, таким как входные ворота Парка Юрского периода 1 (примечание стороны: такой отличный фильм!). Единственная причина, по которой собаки и кошки имеют высокий SSIM с изображением затвора, заключается в размере и фильтре оттенков серого, через который оно проходит.

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

В будущем я хотел бы использовать упомянутый мной набор данных kaggle Animal-10 с TensorFlow для запуска полной лаборатории классификации изображений.

Спасибо за прочтение.