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');ifsize(img,3)==3img_gray=rgb2gray(img);elseimg_gray=img;end% 2. 计算灰度共生矩阵% 'NumLevels': 将灰度级量化为8级(默认),可以更少以降低计算量% 'GrayLimits': 灰度范围,默认为[min(I(:)) max(I(:))],这里用[]自动计算% 'Offset': 指定方向和距离。这里计算4个方向(0°, 45°, 90°, 135°),距离为1offsets=[01;-11;-10;-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特征提取functionfeatures=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);fori=start_row:end_rowforj=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));endend% 2. 构建灰度差分直方图 (概率分布)% 将差分值量化为整数,最大差值为255diff_vector=diff_img(diff_img>0);% 只取非零差分(边界处为零)ifisempty(diff_vector)features=zeros(1,5);return;endnum_bins=256;% 差分范围是0-255p=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');ifsize(img,3)==3img_gray=rgb2gray(img);elseimg_gray=img;end% 定义4个方向(类似于GLCM)directions=[1,0;% 0° (水平)1,1;% 45° (对角)0,1;% 90° (垂直)-1,1];% 135° (反对角)% 为每个方向提取GLDS特征glds_features=[];fork=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');forf=1:length(feature_names)fprintf('%s\t',feature_names{f});endfprintf('\n');ford=1:size(glds_features,1)fprintf('%s\t\t',direction_names{d});forf=1:size(glds_features,2)fprintf('%.4f\t',glds_features(d,f));endfprintf('\n');end% 计算平均特征向量mean_glds_features=mean(glds_features,1);fprintf('\n--- Average GLDS Feature Vector ---\n');forf=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/csa/65376.html
实用建议:
- 对于大多数应用,GLCM是首选,因为它更成熟,特征描述能力更强。
- 在实际项目中,通常会将多个方向的特征取平均值或最大值,以得到旋转不变的纹理描述符。
- 可以结合多种方法(如GLCM + GLDS)来构建更强大的特征向量,用于机器学习分类。
- 在计算前,通常会对图像灰度级进行降级(如从256级降到8级),以降低计算复杂度和噪声影响。