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 |
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
网友评论