与K均值聚类并整形为彩色图像

时间:2019-02-21 13:54:48

标签: python image cluster-analysis k-means cv2

我正在对灰度图像应用K-Means聚类,并希望获得彩色图像,其中每种颜色都分配给一个唯一的聚类。我该怎么办?

我的代码是:

import numpy as np
import cv2
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

# this not work it show a black image
image = cv2.imread('/Users/myname/Downloads/under1.png')

median = cv2.medianBlur(image,3)

x,y,z = image.shape
xm,ym,zm = median.shape

image1 = median.reshape((median.shape[0]*median.shape[1],3))

# For shapefile
xs, ys, zs = np.meshgrid(
    np.linspace(0, 1, xm), # x
    np.linspace(0, 1, ym), # y
    np.linspace(0, 1, zm) # z
)

data_with_coordinates = np.column_stack([
    median.flatten(),
    xs.flatten(),
    ys.flatten()
])


n_cluster = 4

clt = KMeans(n_clusters=n_cluster)
clt.fit(image1)

cluster_centers = clt.cluster_centers_
cluster_labels = clt.labels_

labels = clt.predict(data_with_coordinates)

x,y,z = image.shape

clustered = (cluster_centers[cluster_labels]).astype(np.uint8).reshape(x, y, z)

plt.imshow(labels.reshape(median.shape))

# vedere i cluster come sono:

cv2.imwrite("ReshapedLabelRaster.png",cluster_labels.reshape(x,y))

plt.imsave('BatimetryClusteredColor' + str(n_cluster) + 'C.png',cluster_labels.reshape(x,y), cmap=plt.cm.nipy_spectral)

plt.show()

编辑: 我尝试将您的代码用于我的项目,但未获得良好结果。 enter image description here

现在,我将尝试了解是否有可能获得形状文件或图像,且其边缘在簇之间。

1 个答案:

答案 0 :(得分:0)

首先,您需要学习opencv-python。

输入

enter image description here

输出

enter image description here

这是我的代码:

import numpy as np
import cv2
from matplotlib import pyplot as mp
from sklearn.cluster import KMeans

# 0 means read gray-scale image
img = cv2.imread("1.jpg", 0)
cv2.imwrite("input_gray.png", img)
save_name="output.png"
h, w = img.shape
trans_img = [[i, j, img[i, j]] for i in range(h) for j in range(w)]

# 300 iters * pixels, very slow
kmeans = KMeans(n_clusters=12).fit(trans_img) 

trans_img_tag = kmeans.predict(trans_img)

print(kmeans.cluster_centers_)

img_process = np.zeros((h,w,3),dtype="uint8")

for i,e in enumerate(trans_img_tag):
    x, y = divmod(i, w)
    r,g,b = (e&4)/4,(e&2)/2,e&1
    if e&8:
        r,g,b = 0.5, g, b/2
    img_process[x, y]=r*255,g*255,b*255

cv2.imwrite(save_name,img_process,[int(cv2.IMWRITE_JPEG_QUALITY), 100]) #quality 100
cv2.imshow(save_name,img_process)
k = cv2.waitKey(0)
if k==ord('\x1b'): #esc exit
    cv2.destroyAllWindows()