MATLAB中两种常用的纹理特征提取方法:灰度共生矩阵和灰度差分统计
1. 灰度共生矩阵
灰度共生矩阵是迄今为止最经典、最常用的纹理分析方法。它通过计算图像中特定方向和距离的像素对出现的频率来描述纹理。
原理简介
GLCM是一个方阵,其大小由图像的最大灰度级决定。矩阵中的元素 P(i, j | d, θ) 表示在给定空间距离 d 和方向 θ 时,灰度级 i 和灰度级 j 成对出现的概率。
常用方向 θ:
- 0° (水平)
- 45° (对角)
- 90° (垂直)
- 135° (反对角)
从GLCM中提取的常用统计特征:
- 对比度: 衡量局部灰度的变化程度,反映图像的清晰度和纹理沟壑的深浅。
Contrast = Σ|i-j|² * P(i,j) - 相关性: 衡量图像中局部灰度的线性相关性。
Correlation = Σ [ (i-μi)(j-μj) * P(i,j) ] / (σi * σj) - 能量: 也称为角二阶矩,是灰度共生矩阵元素值的平方和。反映图像灰度分布的均匀性和纹理的粗细程度。
Energy = Σ P(i,j)² - 同质性: 衡量GLCM中元素分布与对角线的接近程度。值越大,表示纹理越局部均匀。
Homogeneity = Σ P(i,j) / (1 + |i-j|) - 熵: 衡量图像中包含的随机性(信息量)。纹理越复杂,熵值越大。
Entropy = -Σ P(i,j) * log(P(i,j))
MATLAB 代码实现
MATLAB提供了 graycomatrix 和 graycoprops 函数来简化这一过程。
% 示例:使用MATLAB内置函数提取GLCM特征
clear; close all; clc;
% 1. 读取图像并转换为灰度图
img = imread('texture.jpg');
if size(img, 3) == 3
img_gray = rgb2gray(img);
else
img_gray = img;
end
% 2. 计算灰度共生矩阵
% 'NumLevels': 将灰度级量化为8级(默认),可以更少以降低计算量
% 'GrayLimits': 灰度范围,默认为[min(I(:)) max(I(:))],这里用[]自动计算
% 'Offset': 指定方向和距离。这里计算4个方向(0°, 45°, 90°, 135°),距离为1
offsets = [0 1; -1 1; -1 0; -1 -1]; % 对应 0°, 45°, 90°, 135°
[glcm, SI] = graycomatrix(img_gray, ...
'NumLevels', 8, ...
'GrayLimits', [], ...
'Offset', offsets);
% 3. 从GLCM中提取统计特征
% 支持的属性: 'Contrast', 'Correlation', 'Energy', 'Homogeneity'
props = graycoprops(glcm, {'Contrast', 'Correlation', 'Energy', 'Homogeneity'});
% 4. 显示结果
disp('GLCM Features for 4 directions (0°, 45°, 90°, 135°):');
disp('Contrast:');
disp(props.Contrast);
disp('Correlation:');
disp(props.Correlation);
disp('Energy (ASM):');
disp(props.Energy);
disp('Homogeneity:');
disp(props.Homogeneity);
% 5. 可视化 (可选)
figure;
subplot(2, 3, 1), imshow(img), title('Original Image');
subplot(2, 3, 2), imshow(rescale(SI)), title('Scaled Image (for GLCM)');
% 显示一个方向的GLCM (例如水平方向,第一个offset)
glcm_0deg = glcm(:, :, 1); % 取第一个方向的矩阵
subplot(2, 3, 3), imshow(glcm_0deg, []), title('GLCM (0°)');
subplot(2, 3, 4), bar(props.Contrast), title('Contrast'), xlabel('Direction Index');
subplot(2, 3, 5), bar(props.Energy), title('Energy'), xlabel('Direction Index');
subplot(2, 3, 6), bar(props.Homogeneity), title('Homogeneity'), xlabel('Direction Index');
% 6. 计算平均值作为最终纹理描述符 (常用方法)
mean_contrast = mean(props.Contrast);
mean_correlation = mean(props.Correlation);
mean_energy = mean(props.Energy);
mean_homogeneity = mean(props.Homogeneity);
fprintf('\n--- Average Feature Vector ---\n');
fprintf('Average Contrast: %.4f\n', mean_contrast);
fprintf('Average Correlation: %.4f\n', mean_correlation);
fprintf('Average Energy: %.4f\n', mean_energy);
fprintf('Average Homogeneity: %.4f\n', mean_homogeneity);
2. 灰度差分统计
GLDS是一种更简单、计算成本更低的纹理分析方法。它不关注像素对,而是关注单个像素与其邻域像素之间的灰度差。
原理简介
对于图像中的每个像素,计算其与邻域内像素的灰度差。然后统计这些差值的分布,并从这个分布中提取特征。
常用特征:
- 对比度:
Σ |Δ| * p(Δ)(类似于GLCM,但基于差分) - 角度二阶矩:
Σ p(Δ)²(类似于GLCM的能量) - 熵:
-Σ p(Δ) * log(p(Δ))(类似于GLCM的熵) - 均值:
Σ Δ * p(Δ) - 逆差分矩:
Σ p(Δ) / (1 + Δ²)(类似于GLCM的同质性)
MATLAB 代码实现
MATLAB没有内置GLDS函数,需要手动实现。
% 示例:手动实现GLDS特征提取
function features = extract_glds_features(img_gray, delta_x, delta_y)
% 此函数计算给定偏移量(delta_x, delta_y)的GLDS特征
% img_gray: 输入灰度图像
% delta_x, delta_y: 定义邻域关系的偏移量
[rows, cols] = size(img_gray);
% 1. 计算灰度差分图像
% 创建与原始图像同大小的矩阵来存储差分
diff_img = zeros(rows, cols);
% 计算有效的像素位置(避免边界问题)
start_row = max(1, 1 - delta_y);
end_row = min(rows, rows - delta_y);
start_col = max(1, 1 - delta_x);
end_col = min(cols, cols - delta_x);
for i = start_row:end_row
for j = start_col:end_col
% 计算当前像素与邻域像素的绝对灰度差
current_pixel = img_gray(i, j);
neighbor_pixel = img_gray(i + delta_y, j + delta_x);
diff_img(i, j) = abs(double(current_pixel) - double(neighbor_pixel));
end
end
% 2. 构建灰度差分直方图 (概率分布)
% 将差分值量化为整数,最大差值为255
diff_vector = diff_img(diff_img > 0); % 只取非零差分(边界处为零)
if isempty(diff_vector)
features = zeros(1, 5);
return;
end
num_bins = 256; % 差分范围是0-255
p = histcounts(diff_vector, 0:num_bins, 'Normalization', 'probability');
% 3. 从差分直方图中提取统计特征
delta = 0:(num_bins-1); % 可能的差分值
% 对比度
contrast = sum(delta .* p);
% 角度二阶矩 (能量)
asm = sum(p.^2);
% 熵 (避免log(0),给p一个很小的偏移量)
epsilon = 1e-10;
p_safe = p + epsilon;
entropy = -sum(p .* log2(p_safe));
% 均值
mean_value = sum(delta .* p);
% 逆差分矩
idm = sum(p ./ (1 + delta.^2));
% 4. 返回特征向量
features = [contrast, asm, entropy, mean_value, idm];
end
% 使用上述函数
clear; close all; clc;
% 读取图像
img = imread('texture.jpg');
if size(img, 3) == 3
img_gray = rgb2gray(img);
else
img_gray = img;
end
% 定义4个方向(类似于GLCM)
directions = [1, 0; % 0° (水平)
1, 1; % 45° (对角)
0, 1; % 90° (垂直)
-1, 1]; % 135° (反对角)
% 为每个方向提取GLDS特征
glds_features = [];
for k = 1:size(directions, 1)
delta_x = directions(k, 1);
delta_y = directions(k, 2);
features_single_dir = extract_glds_features(img_gray, delta_x, delta_y);
glds_features = [glds_features; features_single_dir];
end
% 显示结果
feature_names = {'Contrast', 'Energy (ASM)', 'Entropy', 'Mean', 'Inverse Diff Moment'};
direction_names = {'0°', '45°', '90°', '135°'};
disp('GLDS Features for 4 directions:');
fprintf('Direction\t');
for f = 1:length(feature_names)
fprintf('%s\t', feature_names{f});
end
fprintf('\n');
for d = 1:size(glds_features, 1)
fprintf('%s\t\t', direction_names{d});
for f = 1:size(glds_features, 2)
fprintf('%.4f\t', glds_features(d, f));
end
fprintf('\n');
end
% 计算平均特征向量
mean_glds_features = mean(glds_features, 1);
fprintf('\n--- Average GLDS Feature Vector ---\n');
for f = 1:length(feature_names)
fprintf('%s: %.4f\n', feature_names{f}, mean_glds_features(f));
end
总结与比较
| 特征 | 灰度共生矩阵 | 灰度差分统计 |
|---|---|---|
| 原理 | 基于像素对的二阶统计 | 基于像素差的一阶统计 |
| 计算复杂度 | 较高 | 较低 |
| MATLAB支持 | 内置函数 (graycomatrix, graycoprops) |
需手动实现 |
| 描述能力 | 强,能捕捉更复杂的纹理结构 | 较弱,但对简单纹理有效 |
| 鲁棒性 | 较好 | 对噪声相对敏感 |
| 适用场景 | 复杂的自然纹理、医学图像分析 | 实时应用、计算资源有限的场景 |
参考代码 matlab常用纹理特征提取方法(GLCM,GLDS) www.3dddown.com/cnb/65376.html
实用建议:
- 对于大多数应用,GLCM是首选,因为它更成熟,特征描述能力更强。
- 在实际项目中,通常会将多个方向的特征取平均值或最大值,以得到旋转不变的纹理描述符。
- 可以结合多种方法(如GLCM + GLDS)来构建更强大的特征向量,用于机器学习分类。
- 在计算前,通常会对图像灰度级进行降级(如从256级降到8级),以降低计算复杂度和噪声影响。

浙公网安备 33010602011771号