灰度共生矩阵
灰度共生矩阵是一种通过研究灰度的空间相关特性来描述纹理的常用方法。由于纹理的重复特性,在图像空间中相隔某距离的两像素之间会存在一定的灰度关系,即图像中灰度的空间相关特性。实验中使用graycomatrix 函数计算灰度共生矩阵。
下图显示 graycomatrix 如何计算 4×5 图像 I 的 GLCM 中的几个值。GLCM 中的元素 (1,1) 值为 1,因为图像中两个水平相邻的像素分别具有值 1 和 1 的情况只有一处。GLCM 中的元素 (1,2) 值为 2,因为图像中两个水平相邻的像素分别具有值 1 和 2 的情况有两处。graycomatrix 继续采用此方法填充 GLCM 中的所有值。
[glcm,SI] = graycomatrix(I,'Offset',[2 0],'Symmetric',true);
名称-值对组参数
‘Offset’,-----[2 0],
‘Symmetric’,-------true
graycomatrix根据图像的缩放版本计算GLCM。默认情况下,如果I是二值图像,graycomatrix会将图像缩放为两个灰度级。如果I是强度图像,则灰度矩阵将图像缩放为八个灰度级。可以使用“NumLevels”参数指定GrayComMatrix用于缩放图像的灰度级别数,以及GrayComMatrix使用“GrayLimits”参数缩放值的方式。
‘NumLevels’ 一个整数,指定灰度级的数目。例如,如果NumLevels为8,意思就是将图像I的灰度映射到1到8之间,它也决定了灰度共生矩阵的大小。默认值是8。
考虑值的顺序,指定为布尔值 true 或 false。例如,当 ‘Symmetric’ 设置为 true 时,graycomatrix 在计算值 1 与值 2 相邻的次数时,会将 1,2 和 2,1 对组都进行计数。当 ‘Symmetric’ 设置为 false 时,graycomatrix 根据 ‘offset’ 的值仅对 1,2 或 2,1 进行计数。
K-means
算法流程
读入图像,设定滑动窗口大小为14*14,复制边界中的值填充图像四周边界。类似卷积神经网络中的samepadding
使用确定的滑动窗口遍历图像的所有像素点,计算灰度共生矩阵,计算灰度共生矩阵(GLCM)的三个特征值:对比度,互相关,能量。将得到的对比度,互相关和能量特征信息进行缩放统一量纲后进行矩阵拼接。
将得到的灰度共生矩阵特征向量使用K-means聚类算法计算,对特征向量空间中的点进行聚类,得到每个点的聚类类别。
将聚类后的每个像素点重新排列映射为图像,根据聚类结果进行染色,完成纹理图像分割效果展示。
实现代码
clear;clc;
cluster_num = [2 3 4 5]; %k均值聚类数目
for num_data=1:4 %根据文件特点编写循环函数
image_name =
NumLevels = 30;
texture = get_texture_features( image_name , NumLevels );% 灰度共生矩阵
I_segmented = K_grouping( image_name, texture, cluster_num(num_data) );% k-means
I_segmented = Coloring(I_segmented,cluster_num(num_data))% Coloring
I = imread( image_name );
figure('NumberTitle', 'off', 'Name', 'k-means聚类图像分割');
subplot(1,2,1);
imshow(I);
xlabel('纹理图像');
subplot(1,2,2);
imshow(I_segmented);
xlabel('k-means聚类分割结果');
end
function texture = get_texture_features( image_name ,NumLevels)
window_size = 14;%设定窗口大小为14
dir_image = ['../data/',image_name];
I = imread( dir_image );
[rsize, csize] = size(I);
texture = [];
padding_size = fix( window_size/2 );%值维7 fix(n):取小于n的整数
I_padding = padarray( I, [ padding_size, padding_size], 'replicate', 'both' );
%7+168+7 复制边界中的值填充图像四周边界 https://blog.csdn.net/majinlei121/article/details/48286631
% 'both'表示在每一维的第一个元素前和最后一个元素后填充,此项为默认值。
for c = 1:csize
for r = 1:rsize
slidWin = I_padding( r : r+window_size-1 , c : c+window_size-1 );
glcm = graycomatrix( slidWin, 'NumLevels', NumLevels, 'Offset', [0 1] );
% 产生灰度共生矩阵,16种灰度,斜下45度方向
% https://blog.csdn.net/dan1900/article/details/40296985
% 参数:
% 'GrayLimits' 是两个元素的向量[low,high],指明了图像 I 中的灰度值如何线性归一化到灰度级别。
% 低于或等于low的灰度值置成1,大于或等于high的灰度值置成NumLevels。
% 如果其设为[],灰度共生矩阵将使用图像I的最小和最大灰度值分别作为GrayLimits的low和high,
% 即[min(I(:) , max(I(:)))]。
stats = graycoprops( glcm, 'Contrast Correlation Energy ' );
% 计算灰度共生矩阵(GLCM)的各个特征值:对比度,互相关,能量
texture_v = [ stats.Contrast*2, stats.Correlation*50, stats.Energy*100];
texture = [ texture ; texture_v ]; %矩阵的拼接
end
end
end
function I_segmented = K_grouping( image_name, texture, cluster_num )
I = imread( image_name );
[rsize, csize] = size(I);
clear I;
I_segmented = kmeans( texture, cluster_num );
I_segmented = reshape( I_segmented, rsize, csize ); %重新变为矩阵形式
end
function I_segmented = Coloring(I_segmented,cluster_num)
a = cat(3,I_segmented,I_segmented,I_segmented);
for i = 1:168
for j =1:168
if a(i,j,1)==1
a(i,j,1) =100;
end
end
end
for i = 1:168
for j =1:168
if a(i,j,2)==2
a(i,j,2) =100;
end
end
end
for i = 1:168
for j =1:168
if a(i,j,3)==3
a(i,j,3) =100;
end
end
end
for i = 1:168
for j =1:168
if a(i,j,3)==4
a(i,j,3) =200;
end
end
end
for i = 1:168
for j =1:168
if a(i,j,2)==5
a(i,j,2) =200;
end
end
end
I_segmented = a
I_segmented = uint8( I_segmented );
end
举个极端例子,如果你的图案都是45度,135角的斜线(正方形对角线),那你用这两个方向就没有意义了,因为得到的都是一样的值。这时就要用0,90度才能表征。