实验目的
通过编程,实现将一幅彩色图像分割为若干个同质区域,即采用K-Means聚类算法来将像素分组从而实现图像分割。在实验中,要分别基于颜色特征和纹理特征实现图像分割,并通过分析比较两种视觉特征在图像分割中的性能。
实验设计
本实验设计4个功能函数
生成隶属度矩阵
函数说明
给定一个h * w *d 的矩阵featIm,其中h 和w 为原始图像的高度和宽度,d 表示图像中每一个像素点所提取的特征向量的维数。给定一个有k 个聚类中心点的矩阵meanFeatures(矩阵维度是k*d),其中每个中心点都是一个d 维的行向量(矩阵的一行),将输入图片中的每个像素映射到其所归属的k-means 某一个中心点去。函数的返回值定义为labelim,labelim 是一个h*w 的整数矩阵,用来表明每一个像素所属的聚类中心标号(1...k)。函数形式:
function [labelIm] = quantizeFeats (featIm, meanFeats)
实现思路
featIm 是一个 d 维矩阵,meanFeats 里面有 k 个中心点,每个中心点有 d 列,利用 kmeans 的思想,依次计算 featIm 中的每一个像素点到 k 个中心点的距离,选取最近的中心点的行号作为该点的标记值进行返回,返回的 labelIm 正好是 h*w 的矩阵。
代码展示
function labelIm = quantizeFeats (featIm, meanFeats)
height = size(featIm, 1);
width = size(featIm, 2);
dimension = size(featIm, 3);
% 计算原始图像 至 meanFeats 的距离,生成隶属度矩阵 labelIm
labelIm = ones(height, width);
for h=1:height
for w=1:width
minDis = -1;
for k=1:size(meanFeats, 1)
dis = 0;
for d=1:dimension
dis = dis + power(featIm(h, w, d) - meanFeats(k, d), 2);
end
dis = sqrt(dis);
if minDis < 0 || dis < minDis
labelIm(h, w) = k;
minDis = sqrt(dis);
end
end
end
end
return
% 给定一个h * w *d 的矩阵featim,其中h 和w 为原始图像的高度和宽度,d 表示图像中每一个像素点所提取的特征向量的维数。
% 给定一个有k 个聚类中心点的矩阵meanFeatures(矩阵维度是k*d),其中每个中心点都是一个d 维的行向量(矩阵的一行),
% 将输入图片中的每个像素映射到其所归属的k-means 某一个中心点去。
% 函数的返回值定义为labelim,labelim 是一个h*w 的整数矩阵,用来表明每一个像素所属的聚类中心标号(1...k)。
生成纹理基元编码集
函数说明
给定一个长度为n 且包含n 个灰度值图像的元胞数组imStack,以及滤波器组bank,基于所有n 个图片的过滤响应样本计算一个纹理基元编码集(如一组量化的滤波器组响应)。注意,元胞数组的特点是数组中的每个元素可以存储不同大小的矩阵,所以允许每张图片有不同的宽和高。其中bank 是一个包含d 个滤波器的m*m*d 矩阵,每个滤波器的大小为m*m,textons 是一个k*d 的矩阵,其中每一行代表一个纹理特征,如一个量化滤波器组的响应。函数形式:
function [textons] = createTextons(imStack, bank, k)
实现思路
imStack 是元胞数组,里面承载的是n 个灰度值图像,此处使用的滤波器组bank是49*49*38的矩阵,它包含38 个总过滤器,其中每个过滤器为49 x 49。首先将每一个灰度值图像使用滤波器组过滤,得到一个r1*c1*38的矩阵,其次把所有图像的过滤响应样本都合并为一个 row*38 的矩阵,再利用kmeans算法将其聚为 k 类,得到的聚类中心就可以作为一个纹理基元编码集。
代码展示
function [textons] = createTextons(imStack, bank, k)
[row, col] = size(imStack);
bankNum = size(bank, 3);
% 用滤波器过滤元胞数组中的n个灰度图,得到n个 bankNum 维的过滤响应样本
% 再将这n个过滤响应样本组合成一个大的样本集 textonsData
textonsData = [];
f