matlab对图像进行均值滤波-凯发k8官方网
个人学习笔记:采用聚类方法对图像进行分割,以下内容纯粹个人理解,如有错误请帮我指出!多谢!
图像分割就是把图像按照某些条件分成不同的区域,并提取出感兴趣的区域。传统的分割方法包括基于阈值的分割、基于区域的分割、基于边缘的分割等。当然,本次笔记写的是采用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 np import imageio from 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种明显不同的区域。
与50位技术专家面对面20年技术见证,附赠技术全景图总结
以上是凯发k8官方网为你收集整理的matlab对图像进行均值滤波_用k均值进行图像分割的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇:
- 下一篇: