美文网首页
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