MATLAB中两种常用的纹理特征提取方法:灰度共生矩阵和灰度差分统计

1. 灰度共生矩阵

灰度共生矩阵是迄今为止最经典、最常用的纹理分析方法。它通过计算图像中特定方向和距离的像素对出现的频率来描述纹理。

原理简介

GLCM是一个方阵,其大小由图像的最大灰度级决定。矩阵中的元素 P(i, j | d, θ) 表示在给定空间距离 d 和方向 θ 时,灰度级 i 和灰度级 j 成对出现的概率。

常用方向 θ:

  • 0° (水平)
  • 45° (对角)
  • 90° (垂直)
  • 135° (反对角)

从GLCM中提取的常用统计特征:

  1. 对比度: 衡量局部灰度的变化程度,反映图像的清晰度和纹理沟壑的深浅。
    Contrast = Σ|i-j|² * P(i,j)
  2. 相关性: 衡量图像中局部灰度的线性相关性。
    Correlation = Σ [ (i-μi)(j-μj) * P(i,j) ] / (σi * σj)
  3. 能量: 也称为角二阶矩,是灰度共生矩阵元素值的平方和。反映图像灰度分布的均匀性和纹理的粗细程度。
    Energy = Σ P(i,j)²
  4. 同质性: 衡量GLCM中元素分布与对角线的接近程度。值越大,表示纹理越局部均匀。
    Homogeneity = Σ P(i,j) / (1 + |i-j|)
  5. : 衡量图像中包含的随机性(信息量)。纹理越复杂,熵值越大。
    Entropy = -Σ P(i,j) * log(P(i,j))

MATLAB 代码实现

MATLAB提供了 graycomatrixgraycoprops 函数来简化这一过程。

% 示例:使用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是一种更简单、计算成本更低的纹理分析方法。它不关注像素对,而是关注单个像素与其邻域像素之间的灰度差。

原理简介

对于图像中的每个像素,计算其与邻域内像素的灰度差。然后统计这些差值的分布,并从这个分布中提取特征。

常用特征:

  1. 对比度: Σ |Δ| * p(Δ) (类似于GLCM,但基于差分)
  2. 角度二阶矩: Σ p(Δ)² (类似于GLCM的能量)
  3. : -Σ p(Δ) * log(p(Δ)) (类似于GLCM的熵)
  4. 均值: Σ Δ * p(Δ)
  5. 逆差分矩: Σ 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

实用建议:

  1. 对于大多数应用,GLCM是首选,因为它更成熟,特征描述能力更强。
  2. 在实际项目中,通常会将多个方向的特征取平均值或最大值,以得到旋转不变的纹理描述符。
  3. 可以结合多种方法(如GLCM + GLDS)来构建更强大的特征向量,用于机器学习分类。
  4. 在计算前,通常会对图像灰度级进行降级(如从256级降到8级),以降低计算复杂度和噪声影响。
posted @ 2026-04-30 10:39  风一直那个吹  阅读(14)  评论(0)    收藏  举报