В этом блоге я поделюсь объясненной реализацией сегментации изображений с использованием кластеризации K-средних. Также я поделюсь своей реализацией Jupyter Notebook для справки.

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

Сегментация изображения:

В компьютерном зрении сегментация изображения — это процесс разделения изображения на несколько сегментов. Цель сегментации изображения состоит в том, чтобы изменить представление изображения во что-то более осмысленное и более простое для анализа. Обычно он используется для поиска объектов и создания границ.

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

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

Использование:

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

Есть много других применений сегментации изображений.

Теперь давайте рассмотрим метод чтения изображения и кластеризации различных областей изображения с использованием алгоритма кластеризации K-средних и OpenCV.

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

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

OpenCV:



Кластеризация K-средних:



Итак, теперь давайте начнем с кода.

Цветовая кластеризация:

Загрузите все необходимые библиотеки:

import numpy as np
import cv2
import matplotlib.pyplot as plt

Следующим шагом является загрузка изображения в цветовом пространстве RGB.

original_image = cv2.imread("/Users/path/../image1.jpg")

Исходное изображение:

Нам нужно преобразовать наше изображение из цветового пространства RGB в HSV, чтобы продолжить работу.

Но вопрос в том, почему??

Согласно Википедии, компоненты R, G и B цвета объекта в цифровом изображении коррелируют с количеством света, попадающего на объект, и, следовательно, друг с другом, описание изображения с точки зрения этих компонентов делает различение объектов затруднено. Описания в терминах оттенок/яркость/цветность или оттенок/яркость/насыщенность часто более уместны.

img=cv2.cvtColor(original_image,cv2.COLOR_BGR2RGB)

Затем преобразует изображение MxNx3 в матрицу Kx3, где K=MxN, а каждая строка теперь является вектором в трехмерном пространстве RGB.

vectorized = img.reshape((-1,3))

Мы преобразуем значения unit8 в числа с плавающей запятой, поскольку это требование метода k-means в OpenCV.

vectorized = np.float32(vectorized)

Мы собираемся сгруппировать с k = 3, потому что, если вы посмотрите на изображение выше, оно имеет 3 цвета: зеленую траву и лес, синее море и зеленовато-голубой морской берег.

Определите критерии, количество кластеров (K) и примените k-means()

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)

OpenCV предоставляет функцию cv2.kmeans(samples, nclusters(K), критерии, попытки, флаги) для цветовой кластеризации.

1. образцы: он должен иметь тип данных np.float32, и каждая функция должна быть помещена в один столбец.

2. nclusters(K): количество кластеров, необходимых в конце

3. критерии: это критерии завершения итерации. При выполнении этого критерия итерация алгоритма останавливается. На самом деле это должен быть кортеж из 3-х параметров. Это `( type, max_iter, epsilon )`:

Тип критериев прекращения. Он имеет 3 флага, как показано ниже:

  • cv.TERM_CRITERIA_EPS — остановить итерацию алгоритма, если достигнута заданная точность, epsilon.
  • cv.TERM_CRITERIA_MAX_ITER — остановить алгоритм после указанного количества итераций, max_iter.
  • cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER — остановить итерацию при выполнении любого из вышеуказанных условий.

4. попыток: Флаг, указывающий, сколько раз алгоритм выполняется с использованием различных начальных меток. Алгоритм возвращает метки, обеспечивающие наилучшую компактность. Эта компактность возвращается в качестве вывода.

5. флаги: этот флаг используется для указания того, как берутся начальные центры. Обычно для этого используются два флага: cv.KMEANS_PP_CENTERS и cv.KMEANS_RANDOM_CENTERS.

K = 3
attempts=10
ret,label,center=cv2.kmeans(vectorized,K,None,criteria,attempts,cv2.KMEANS_PP_CENTERS) 

Теперь конвертируйте обратно в uint8.

center = np.uint8(center)

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

res = center[label.flatten()]
result_image = res.reshape((img.shape))

Теперь давайте визуализируем результат вывода с K = 3.

figure_size = 15
plt.figure(figsize=(figure_size,figure_size))
plt.subplot(1,2,1),plt.imshow(img)
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(1,2,2),plt.imshow(result_image)
plt.title('Segmented Image when K = %i' % K), plt.xticks([]), plt.yticks([])
plt.show()

Таким образом, алгоритм разделил наше исходное изображение на три доминирующих цвета.

Давайте посмотрим, что произойдет, если мы изменим значение K=5:

Давайте перейдем к нашей следующей части — обнаружению Canny Edge.

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

Алгоритм обнаружения Canny Edge состоит из 5 шагов:

  1. Расчет градиента
  2. Немаксимальное подавление
  3. Двойной порог
  4. Отслеживание границ по гистерезису

OpenCV предоставляет функцию cv2.Canny(image, threshold1,threshold2) для обнаружения границ.

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

Функция находит края во входном изображении (8-битное входное изображение) и отмечает их в краях выходной карты, используя алгоритм Кэнни. Наименьшее значение между порогом 1 и порогом 2 используется для привязки к границе. Наибольшее значение используется для поиска начальных сегментов сильных ребер.

Исходное изображение:

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

edges = cv2.Canny(img,150,200)
plt.figure(figsize=(figure_size,figure_size))
plt.subplot(1,2,1),plt.imshow(img)
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(1,2,2),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()

Изображение будет выглядеть так:

Вот ссылка на мой Jupyter Notebook для справки.

Изображения можно найти в том же каталоге в папке с именем Images.



Итак, это все, что я могу сказать о сегментации изображений с использованием кластеризации K-средних. Я надеюсь, что вы найдете это полезным. Спасибо, что дочитали до конца.

Ссылки