美文网首页
K均值区域分割

K均值区域分割

作者: 晨光523152 | 来源:发表于2019-06-10 22:29 被阅读0次

RGB转灰度图:B' = 0.299 R + 0.587 G + 0.114 B

def rgb2gry(img):
    R = img[:,:,0]
    G = img[:,:,1]
    B = img[:,:,2]
    B1 = 0.299*R + 0.587*G + 0.114*B
    return B1

灰度图转RGB: B = (B' - 0.299R - 0.587G) / 0.114

def gry2rgb(gry,R,G,img):
    B2 = (gry - 0.299*R - 0.587*G) / 0.114
    img1 = img
    img1[:,:,2] = B2
    return img1

原图来自于《超级马里奥:奥德赛》,是任天堂官方作为壁纸奖励发到我的邮件中的

img = io.imread('D:\\hl\\ns\\odyssey.jpg')
B1,R,G,B = rgb2gry(img)
plt.subplots_adjust(wspace = 1)
plt.figure(figsize=(10,6))
plt.subplot(1,2,1)
plt.imshow(img)
plt.subplot(1,2,2)
plt.imshow(B1,plt.cm.gray)
plt.show()
原图和灰度图.png
img1 = gry2rgb(B1,R,G,img)
plt.subplots_adjust(wspace = 1)
plt.figure(figsize=(10,6))
plt.subplot(1,2,1)
plt.imshow(B1,plt.cm.gray)
plt.subplot(1,2,2)
plt.imshow(img1)
plt.show()
灰度图和原图.png

K-means原理

基于欧氏距离计算相似性,按照距离远近来判断是否属于同一簇。k-means算法的基本过程:

  • 随机初始化K个聚类中心
  • 重复重复计算以下过程,直到聚类中心不再改变
    • 计算每个样本与聚类中心的欧氏距离,并将样本划到聚类最近的簇类
    • 重新计算每个簇的聚类中心,取每个簇的均值
  • 输出聚类中心,每个样本的簇

按照以前做k-means的时候样本的取法是,行是样本,列是特征

age weight ----- height
李雷 25 60 ----- 175
张三 30 70 ----- 172
李四 20 75 ----- 173

那做图像分割的时候,是不是也该按照这样的取法?

R G B
pixel1 25 60 50
pixel2 30 70 60
pixel3 20 75 70

对于灰度图像和RGB图像直接reshape就可以

row,col = B1.shape
gray_feature = B1.reshape(row*col,1)
rgb_feature = img.reshape(-1,3)

看网上的资料,有的把归一化后的图像 (灰度图/255) 作为输入,而有的没有,查阅资料发现:灰度数据的表示有 unit8 以及 double 两种类型。

  • unit8类型数据的取值范围为 [0,255]
  • double类型数据的取值范围为[0,1]
    为了查看两种取法对实验的结果的影响,做了两组实验,用sklearn里的KMeans。
plt.subplots_adjust(hspace = 15,wspace = 3)
plt.figure(figsize=(10,10))
plt.subplot(3,2,1)
plt.imshow(B1,plt.cm.gray)
plt.title('Original')
estimator = KMeans(n_clusters=2)
estimator.fit(gray_feature)
label_pred = estimator.labels_
gray_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,2)
plt.imshow(gray_label,plt.cm.gray)
plt.title('k = 2')
estimator = KMeans(n_clusters=4)
estimator.fit(gray_feature)
label_pred = estimator.labels_
gray_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,3)
plt.imshow(gray_label,plt.cm.gray)
plt.title('k = 4')
estimator = KMeans(n_clusters=6)
estimator.fit(gray_feature)
label_pred = estimator.labels_
gray_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,4)
plt.imshow(gray_label,plt.cm.gray)
plt.title('k = 6')
estimator = KMeans(n_clusters=8)
estimator.fit(gray_feature)
label_pred = estimator.labels_
gray_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,5)
plt.imshow(gray_label,plt.cm.gray)
plt.title('k = 8')
estimator = KMeans(n_clusters=10)
estimator.fit(gray_feature)
label_pred = estimator.labels_
gray_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,6)
plt.imshow(gray_label,plt.cm.gray)
plt.title('k = 10')
plt.show()
未归一化的灰度图实验.png
B2 = B1/255
gray_feature1 = B2.reshape(row*col,1)
plt.subplots_adjust(hspace = 15,wspace = 3)
plt.figure(figsize=(10,10))
plt.subplot(3,2,1)
plt.imshow(B1,plt.cm.gray)
plt.title('Original')
estimator = KMeans(n_clusters=2)
estimator.fit(gray_feature1)
label_pred = estimator.labels_
gray_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,2)
plt.imshow(gray_label,plt.cm.gray)
plt.title('k = 2')
estimator = KMeans(n_clusters=4)
estimator.fit(gray_feature1)
label_pred = estimator.labels_
gray_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,3)
plt.imshow(gray_label,plt.cm.gray)
plt.title('k = 4')
estimator = KMeans(n_clusters=6)
estimator.fit(gray_feature1)
label_pred = estimator.labels_
gray_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,4)
plt.imshow(gray_label,plt.cm.gray)
plt.title('k = 6')
estimator = KMeans(n_clusters=8)
estimator.fit(gray_feature1)
label_pred = estimator.labels_
gray_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,5)
plt.imshow(gray_label,plt.cm.gray)
plt.title('k = 8')
estimator = KMeans(n_clusters=10)
estimator.fit(gray_feature1)
label_pred = estimator.labels_
gray_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,6)
plt.imshow(gray_label,plt.cm.gray)
plt.title('k = 10')
plt.show()
归一化的灰度图实验.png

讲真,我真看不出来这两个实验结果有啥区别(打算下次课上取问问老师),我唯一能看出来的是 K=2 的时候,感觉实验结果图更好看,分的更清楚。反而看 K=10 的时候,太模糊了,连轮廓都看不太清。这个就说明了K-means的一个不好的地方,聚类簇个数需要人为的设定。

再试试RGB图像的分割效果。

plt.subplots_adjust(hspace = 15,wspace = 3)
plt.figure(figsize=(10,10))
plt.subplot(3,2,1)
plt.imshow(img)
plt.title('Original')
estimator = KMeans(n_clusters=2)
estimator.fit(rgb_feature)
label_pred = estimator.labels_
rgb_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,2)
img1 = gry2rgb(rgb_label,R,G,img)
plt.imshow(img1)
plt.title('k = 2')
estimator = KMeans(n_clusters=4)
estimator.fit(rgb_feature)
label_pred = estimator.labels_
rgb_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,3)
img1 = gry2rgb(rgb_label,R,G,img)
plt.imshow(img1)
plt.title('k = 4')
estimator = KMeans(n_clusters=6)
estimator.fit(rgb_feature)
label_pred = estimator.labels_
rgb_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,4)
img1 = gry2rgb(rgb_label,R,G,img)
plt.imshow(img1)
plt.title('k = 6')
estimator = KMeans(n_clusters=8)
estimator.fit(rgb_feature)
label_pred = estimator.labels_
rgb_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,5)
img1 = gry2rgb(rgb_label,R,G,img)
plt.imshow(img1)
plt.title('k = 8')
estimator = KMeans(n_clusters=10)
estimator.fit(rgb_feature)
label_pred = estimator.labels_
rgb_label = label_pred.reshape(B1.shape)
plt.subplot(3,2,6)
img1 = gry2rgb(rgb_label,R,G,img)
plt.imshow(img1)
plt.title('k = 10')
plt.show()
rgb实验.png

感觉跑出来的实验结果图有点怪怪的,为什么底色会变了?是我跑出来的label变成rgb图像那部分不对吗?
待续....

参考资料:https://zhuanlan.zhihu.com/p/26054250
https://blog.csdn.net/i1020/article/details/85782010
https://blog.csdn.net/qq_41383956/article/details/88593538
https://blog.csdn.net/sinat_26917383/article/details/70240628

相关文章

网友评论

      本文标题:K均值区域分割

      本文链接:https://www.haomeiwen.com/subject/rbfxfctx.html