OpenCV-Python Кластеризация K-средних в OpenCV | 58

машинное обучение

Цель

  • Узнайте, как использовать функцию cv.kmeans() для кластеризации данных в OpenCV.

понимать параметры

Входные параметры

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

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

  3. criteria: Это условие завершения итерации. После выполнения этого условия итерация алгоритма останавливается. На самом деле это должен быть кортеж из 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- Остановить итерацию при выполнении любого из вышеперечисленных условий.

      б) max_iter - целое число, указывающее максимальное количество итераций. в. эпсилон - требуемая точность

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

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

Выходные параметры

  1. Компактность: это сумма квадратов расстояний от каждой точки до соответствующего центра.
  2. Метки: это массив меток (такой же, как «код» в предыдущем посте), где каждый элемент помечен «0», «1» .....
  3. Центр: это массив в центре кластера. Теперь мы увидим, как применять алгоритм K-Means на трех примерах.

1. Данные об одной функции

Учтите, что у вас есть набор данных только с одной функцией (т. е. с одним измерением). Например, мы можем решить нашу проблему с футболкой, вы используете только рост, чтобы определить размер футболки. Итак, мы сначала создаем данные и отображаем их в Matplotlib.

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
x = np.random.randint(25,100,25)
y = np.random.randint(175,255,25)
z = np.hstack((x,y))
z = z.reshape((50,1))
z = np.float32(z)
plt.hist(z,256,[0,256]),plt.show()

Итак, у нас есть «z», который представляет собой массив размером 50 со значениями в диапазоне от 0 до 255. Я изменяю форму "z" в вектор-столбец. Будет полезнее, если существует более одной функции. Затем я сделал данные типа np.float32. Получаем следующее изображение:

Теперь применим функцию KMeans. Перед этим нам нужно указать критерии. Моим критерием является остановка алгоритма и возврат ответа всякий раз, когда выполняются 10 итераций алгоритма или когда достигается точность эпсилон = 1,0.

# 定义终止标准 = ( type, max_iter = 10 , epsilon = 1.0 )
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
# 设置标志
flags = cv.KMEANS_RANDOM_CENTERS
# 应用K均值
compactness,labels,centers = cv.kmeans(z,2,None,criteria,10,flags)

Это дает нам компактность, метки и центры. В этом случае я получаю центры 60 и 207. Метки будут того же размера, что и тестовые данные, где центр тяжести каждых данных будет помечен «0», «1», «2» и т. д. Теперь мы разделим данные на разные кластеры на основе меток.

A = z[labels==0]
B = z[labels==1]

Теперь мы нарисуем A красным, B синим и его центр тяжести желтым.

# 现在绘制用红色'A',用蓝色绘制'B',用黄色绘制中心
plt.hist(A,256,[0,256],color = 'r')
plt.hist(B,256,[0,256],color = 'b')
plt.hist(centers,32,[0,256],color = 'y')
plt.show()

Получил следующие результаты:

2. Многофункциональные данные

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

Теперь я перехожу непосредственно к коду:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
X = np.random.randint(25,50,(25,2))
Y = np.random.randint(60,85,(25,2))
Z = np.vstack((X,Y))
# 将数据转换未 np.float32
Z = np.float32(Z)
# 定义停止标准,应用K均值
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
ret,label,center=cv.kmeans(Z,2,None,criteria,10,cv.KMEANS_RANDOM_CENTERS)
# 现在分离数据, Note the flatten()
A = Z[label.ravel()==0]
B = Z[label.ravel()==1]
# 绘制数据
plt.scatter(A[:,0],A[:,1])
plt.scatter(B[:,0],B[:,1],c = 'r')
plt.scatter(center[:,0],center[:,1],s = 80,c = 'y', marker = 's')
plt.xlabel('Height'),plt.ylabel('Weight')
plt.show()

Получаем следующие результаты:

3. Квантование цвета

Квантование цвета — это процесс уменьшения количества цветов в изображении. Одной из причин этого является уменьшение памяти. Иногда некоторые устройства могут быть ограничены, так что может быть воспроизведено только ограниченное количество цветов. Также в этих случаях выполняется цветовое квантование. Здесь мы используем кластеризацию k-средних для квантования цвета.

Здесь нет ничего нового, чтобы объяснять. Есть 3 функции, такие как R,G,B. Поэтому нам нужно преобразовать изображение в массив размером Mx3 (M — количество пикселей в изображении). После кластеризации мы применяем значения центроида (также R,G,B) ко всем пикселям, чтобы результирующее изображение имело заданное количество цветов. Опять же, нам нужно изменить его форму до формы исходного изображения. Вот код:

import numpy as np
import cv2 as cv
img = cv.imread('home.jpg')
Z = img.reshape((-1,3))
# 将数据转化为np.float32
Z = np.float32(Z)
# 定义终止标准 聚类数并应用k均值
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 8
ret,label,center=cv.kmeans(Z,K,None,criteria,10,cv.KMEANS_RANDOM_CENTERS)
# 现在将数据转化为uint8, 并绘制原图像
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img.shape))
cv.imshow('res2',res2)
cv.waitKey(0)
cv.destroyAllWindows()

Мы можем посмотреть на результат K=8

Добро пожаловать на сайт блога Panchuang AI:panchuang.net/

Официальная китайская документация OpenCV:woshicver.com/

Добро пожаловать на станцию ​​сводки ресурсов блога Panchuang:docs.panchuang.net/