K-Means 实现图像分割

Posted blog4ljy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了K-Means 实现图像分割相关的知识,希望对你有一定的参考价值。

使用的环境,python3.5,opencv2

函数的格式为:

cv2.kmeans(data, K, bestLabels, criteria, attempts, flags)
'''
参数:
    data: 分类数据,最好是np.float32的数据,每个特征放一列。
    K: 分类数,opencv2的kmeans分类是需要已知分类数的。
    bestLabels:预设的分类标签或者None
    criteria:迭代停止的模式选择,这是一个含有三个元素的元组型数。格式为(type, max_iter, epsilon)
        其中,type有如下模式:
         —–cv2.TERM_CRITERIA_EPS :精确度(误差)满足epsilon停止。
         —-cv2.TERM_CRITERIA_MAX_ITER:迭代次数超过max_iter停止。
         —-cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER,两者合体,任意一个满足结束。
    attempts:重复试验kmeans算法次数,将会返回最好的一次结果
    flags:初始中心选择,有两种方法:
        ——v2.KMEANS_PP_CENTERS;
        ——cv2.KMEANS_RANDOM_CENTERS

返回值:
    compactness:紧密度,返回每个点到相应重心的距离的平方和
    labels:结果标记,每个成员被标记为0,1等
    centers:由聚类的中心组成的数组
'''

灰度图片分割

# -*- coding: utf-8 -*-
# @Author  : matthew
# @Software: PyCharm

import cv2
import matplotlib.pyplot as plt
import numpy as np


def seg_kmeans_gray():
    img = cv2.imread('000129.jpg', cv2.IMREAD_GRAYSCALE)

    # 展平
    img_flat = img.reshape((img.shape[0] * img.shape[1], 1))
    img_flat = np.float32(img_flat)

    # 迭代参数
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TermCriteria_MAX_ITER, 20, 0.5)
    flags = cv2.KMEANS_RANDOM_CENTERS

    # 聚类
    compactness, labels, centers = cv2.kmeans(img_flat, 2, None, criteria, 10, flags)

    # 显示结果
    img_output = labels.reshape((img.shape[0], img.shape[1]))
    plt.subplot(121), plt.imshow(img, 'gray'), plt.title('input')
    plt.subplot(122), plt.imshow(img_output, 'gray'), plt.title('kmeans')
    plt.show()


if __name__ == '__main__':
    seg_kmeans_gray()

结果:

技术分享图片

彩色图片分割

# -*- coding: utf-8 -*-
# @Author  : matthew
# @Software: PyCharm

import cv2
import matplotlib.pyplot as plt
import numpy as np

def seg_kmeans_color():
    img = cv2.imread('000129.jpg', cv2.IMREAD_COLOR)
    # 变换一下图像通道bgr->rgb,否则很别扭啊
    b, g, r = cv2.split(img)
    img = cv2.merge([r, g, b])

    # 3个通道展平
    img_flat = img.reshape((img.shape[0] * img.shape[1], 3))
    img_flat = np.float32(img_flat)

    # 迭代参数
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TermCriteria_MAX_ITER, 20, 0.5)
    flags = cv2.KMEANS_RANDOM_CENTERS

    # 聚类
    compactness, labels, centers = cv2.kmeans(img_flat, 2, None, criteria, 10, flags)

    # 显示结果
    img_output = labels.reshape((img.shape[0], img.shape[1]))
    plt.subplot(121), plt.imshow(img), plt.title('input')
    plt.subplot(122), plt.imshow(img_output, 'gray'), plt.title('kmeans')
    plt.show()


if __name__ == '__main__':
    seg_kmeans_color()

结果:

技术分享图片

以上是关于K-Means 实现图像分割的主要内容,如果未能解决你的问题,请参考以下文章

毕业了,在Python中使用 OpenCV 和K-Means 聚类对毕业照进行图像分割

Python图像处理丨基于K-Means聚类的图像区域分割

图像分割基于K-means聚类算法图像分割含Matlab源码 1476期

图像分割基于K-means聚类算法图像分割含Matlab源码 1476期

K-Means 实现图像分割

基于K-means聚类算法的图像分割