1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > matlab对图像进行均值滤波_用K均值进行图像分割

matlab对图像进行均值滤波_用K均值进行图像分割

时间:2024-06-11 03:52:25

相关推荐

matlab对图像进行均值滤波_用K均值进行图像分割

个人学习笔记:采用聚类方法对图像进行分割,以下内容纯粹个人理解,如有错误请帮我指出!多谢!

图像分割就是把图像按照某些条件分成不同的区域,并提取出感兴趣的区域。传统的分割方法包括基于阈值的分割、基于区域的分割、基于边缘的分割等。当然,本次笔记写的是采用K均值聚类实现图像分割。(代码在文章结尾)

一、理论分析

K均值是一种比较常用的聚类算法,由于并不是本次笔记的重点,因此只进行算法的流程简单记录如下:

1、选取K个样本作为聚类中心

2、计算各个样本到聚类中心的距离

3、更新均值向量,重复以上步骤

分割算法核心:对图像的像素进行聚类,相似RGB值的像素被聚到一起,就形成了K个区域!

问题的核心在于如何使用K均值对图像的像素进行聚类,自己整理了以下的几个问题:

1、 K均值使用什么做样本?

K均值聚类就是把图像的像素点按照“值的接近程度”进行聚类,那么就会给每个像素点打标签(把每个位置R、G、B值看作是一个样本,R、G、B就是三个特征),有多少像素值(R、G、B算一个像素值)就有多少个样本。

2、 K均值得到的标签含义是什么?

K均值得到的结果标签就是width*height个0,1,2这种值,因为图像提供的样本数就是width*height个,也就是对每个位置的像素点打标签。含义就是亮度接近的像素标签值相同。

3、K均值聚类以后如何得到新的聚类图像

像素点的标签值表示它属于哪个类,后续使用标签值作为亮度值。如果是聚类结果为3, 那么标签值就有0,1,2三个,标签的shape是width*height,那么就是用0,1,2填充一张np.zeros(width, height)图像,就得到了最后的聚类结果。

标签值相同的位置因此也就亮度相同,得到的聚类图像仅仅包含k个亮度种类,比如K=3,那么聚类图像就只有三种亮度值

实现代码里面未解决的Bug:因为标签值0,1,2代表的仅仅是三个不同区域,但是没办反设定哪个区域是2(最亮的区域),也就是最后合成的图像哪个区域亮没办反控制(比如人脸区域应该更亮),只能多运行几次程序。

二:代码实现

算法流程分为以下四步:

1、读取图片

2、将图片像素转为样本形式

3、对样本进行聚类

4、创建空白图像

5、使用聚类结果对空白图像进行填充

6、保存聚类得到的标签图

步骤1和2:

# 1:read image

上述代码块的#1负责读取图片,#2负责把(w,h,3)的图像转为(w*h,3)的数据,每行就是一个样本,每个样本包含R、G、B三个特征值。

步骤3:

# 3: cluster, I thought: give every pixel (that in orignal image)# a label , so the label have same shape as image(gray)cls = KMeans(n_clusters=k_cluster).fit_predict(data)cls = cls.reshape(image.shape[0], image.shape[1])

聚类就是对上述的像素值进行聚类

步骤4:

# 4: create a image containercontainer = np.zeros(shape=(image.shape[0], image.shape[1]))

创建的像素值全为0的空白图像,用于存储聚类标签。

步骤5:

# 5: use cluster labels as "gray value" # and fill it into aimage containerfor i in range(image.shape[0]):for j in range(image.shape[1]):# cls[i, j]*30 ,because label value is 0, 1, 2# the bright difference betwwen labels is to smallcontainer[i, j] = cls[i, j]*60

将聚类标签值cls[i, j]乘以60作为亮度值(乘以70或者任何值都行,只要保证K*任何值不超过255)

步骤6:

# 6: saver the cluster imagecontainer = container.astype(np.uint8) imageio.imsave(save_name, container)

保存的时候一定要转换为uint8编码

完整的代码如下:

import numpy as npimport imageiofrom sklearn.cluster import KMeansdef image_cluster(image_name, save_name, k_cluster=3):"""cluster by KMeans for RGB image"""# 1:read imageimage = imageio.imread(image_name)# 2: convert (w, h, 3) into (w*h, 3)# R,G and B combine as 3 features # data will be a 2D matrix, each row have 3 values(R/G/B),# and each column has width*height values# this operation convert 3D to 2D, like reshape image2matrix = []for i in range(image.shape[0]):for j in range(image.shape[1]):r_v, g_v, b_v = image[i, j]image2matrix.append([r_v/255.0, g_v/255.0, b_v/255.0])data = np.mat(image2matrix)# 3: cluster, I thought: give every pixel (that in orignal image)# a label , so the label have same shape as image(gray)cls = KMeans(n_clusters=k_cluster).fit_predict(data)cls = cls.reshape(image.shape[0], image.shape[1])# 4: create a image containercontainer = np.zeros(shape=(image.shape[0], image.shape[1]))# 5: use cluster labels as "gray value" # and fill it into aimage containerfor i in range(image.shape[0]):for j in range(image.shape[1]):# cls[i, j]*30 ,because label value is 0, 1, 2# the bright difference betwwen labels is to smallcontainer[i, j] = cls[i, j]*60# 6: saver the cluster imagecontainer = container.astype(np.uint8) imageio.imsave(save_name, container)return Trueimage_cluster("data/vivian.jpg", "results/cluster.jpg")

对标题上费雯丽的照片进行聚类结果如下:

个人认为:K如果选择为2,那么图片视觉上看就应该包含“2种”明显不同的区域;K如果选择为3,那么图片中就应该包含3种明显不同的区域。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。