2 篇文章 0 订阅
2 篇文章 0 订阅

# 2.kmeans

kmeans步骤共可分为以下步骤：

1. 随机初始化k个聚类中心。

1. 计算所有像素点到聚类中心的距离。

1. 选择最近的聚类中心作为像素点的聚类种类。

1. 根据像素点的聚类种类更新聚类中心。

1. 重复步骤2-4直至聚类中心收敛。

# 3.代码

# 提取图像的像素值
features = []
for y in range(height):
for x in range(width):
features.append(image[y, x, :] / 255)
features = np.array(features)
# 初始化聚类中心
kmeans_centers = features[np.random.choice(len(features), k), :]
kmeans_centers = np.array(kmeans_centers)
# 计算所有像素点到聚类中心的距离矩阵
def euclidean_dist(X, Y):
Gx = np.matmul(X, X.T)
Gy = np.matmul(Y, Y.T)
diag_Gx = np.reshape(np.diag(Gx), (-1, 1))
diag_Gy = np.reshape(np.diag(Gy), (-1, 1))
return diag_Gx + diag_Gy.T - 2 * np.matmul(X, Y.T)
# 更新聚类中心
new_kmeans_centers = []
for j in range(k):
new_kmeans_centers.append(np.mean(features[segs==j, :], axis=0))
new_kmeans_centers = np.array(new_kmeans_centers)

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

if __name__ == '__main__':
# Initialize rgb pixel values for each class in kmeans using specific values
bgr_list = [(0, 0, 255),
(0, 255, 0),
(255, 0, 0),
(128, 128, 255),
(128, 255, 128),
(255, 128, 128),
(128, 0, 255),
(128, 255, 0),
(255, 128, 0),
(0, 128, 255),
(0, 255, 128),
(255, 0, 128)]
# Reading images using matplotlib library
height, width, channel = image.shape
# show original image
plt.figure()
plt.subplot(3, 3, 1)
plt.axis('off')
plt.title('Original')
plt.imshow(image)
# do kmeans segmentation
for i, k in enumerate(range(5, 13, 1)):
# extract bgr features
features = []
for y in range(height):
for x in range(width):
features.append(image[y, x, :] / 255)
features = np.array(features)
# initial segments center using random value in features
kmeans_centers = features[np.random.choice(len(features), k), :]
kmeans_centers = np.array(kmeans_centers)
# update
while True:
# calculate distance matrix
def euclidean_dist(X, Y):
Gx = np.matmul(X, X.T)
Gy = np.matmul(Y, Y.T)
diag_Gx = np.reshape(np.diag(Gx), (-1, 1))
diag_Gy = np.reshape(np.diag(Gy), (-1, 1))
return diag_Gx + diag_Gy.T - 2 * np.matmul(X, Y.T)
dist_matrix = []
for start in range(0, len(features), 1000):
dist_matrix.append(euclidean_dist(features[start:start+1000, :], kmeans_centers))
dist_matrix = np.concatenate(dist_matrix, axis=0)
# dist_matrix = euclidean_dist(features, kmeans_centers)
# get seg class for each sample
segs = np.argmin(dist_matrix, axis=1)
# update new kmeans center
new_kmeans_centers = []
for j in range(k):
new_kmeans_centers.append(np.mean(features[segs==j, :], axis=0))
new_kmeans_centers = np.array(new_kmeans_centers)
# calculate whether converge
if np.mean(abs(kmeans_centers - new_kmeans_centers)) < 0.1:
break
else:
kmeans_centers = new_kmeans_centers
# assign
segs = segs.reshape(height, width)
seg_result = np.zeros((height, width, channel), dtype=np.uint8)
for y in range(height):
for x in range(width):
seg_result[y, x, :] = bgr_list[segs[y, x]]

# show kmeans result
plt.subplot(3, 3, i+2)
plt.title('k={}'.format(k))
plt.axis('off')
plt.imshow(seg_result)
plt.savefig('result_a.jpg')

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

if __name__ == '__main__':
# Initialize rgb pixel values for each class in kmeans using specific values
bgr_list = [(0, 0, 255),
(0, 255, 0),
(255, 0, 0),
(128, 128, 255),
(128, 255, 128),
(255, 128, 128),
(128, 0, 255),
(128, 255, 0),
(255, 128, 0),
(0, 128, 255),
(0, 255, 128),
(255, 0, 128)]
# Reading images using matplotlib library
height, width, channel = image.shape
# show original image
plt.figure()
plt.subplot(3, 3, 1)
plt.axis('off')
plt.title('Original')
plt.imshow(image)
# do kmeans segmentation
for i, k in enumerate(range(5, 13, 1)):
# extract bgr and location features
features = []
for y in range(height):
for x in range(width):
features.append(np.concatenate((image[y, x, :] / 255, np.array([y / height, x / width])), axis=0))
features = np.array(features)
# initial segments center using random value in features
kmeans_centers = features[np.random.choice(len(features), k), :]
kmeans_centers = np.array(kmeans_centers)
# update
while True:
# calculate distance matrix
def euclidean_dist(X, Y):
Gx = np.matmul(X, X.T)
Gy = np.matmul(Y, Y.T)
diag_Gx = np.reshape(np.diag(Gx), (-1, 1))
diag_Gy = np.reshape(np.diag(Gy), (-1, 1))
return diag_Gx + diag_Gy.T - 2 * np.matmul(X, Y.T)
dist_matrix = []
for start in range(0, len(features), 1000):
dist_matrix.append(euclidean_dist(features[start:start+1000, :], kmeans_centers))
dist_matrix = np.concatenate(dist_matrix, axis=0)
# dist_matrix = euclidean_dist(features, kmeans_centers)
# get seg class for each sample
segs = np.argmin(dist_matrix, axis=1)
# update new kmeans center
new_kmeans_centers = []
for j in range(k):
new_kmeans_centers.append(np.mean(features[segs==j, :], axis=0))
new_kmeans_centers = np.array(new_kmeans_centers)
# calculate whether converge
if np.mean(abs(kmeans_centers - new_kmeans_centers)) < 0.1:
break
else:
kmeans_centers = new_kmeans_centers
# assign
segs = segs.reshape(height, width)
seg_result = np.zeros((height, width, channel), dtype=np.uint8)
for y in range(height):
for x in range(width):
seg_result[y, x, :] = bgr_list[segs[y, x]]

# show kmeans result
plt.subplot(3, 3, i+2)
plt.title('k={}'.format(k))
plt.axis('off')
plt.imshow(seg_result)
plt.savefig('result_b.jpg')

# 4.结果

• 2
点赞
• 12
收藏
• 打赏
• 0
评论
01-17 68
08-22 6588
10-20 7176
08-03 4830
03-05 4012
09-14 1039
07-04 1万+
07-02 3537
05-20 5180
11-29 1144
09-29 1652
01-12 300

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

Lizhi_Tech

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。