用Python和skimage提取图像纹理特征:从灰度共生矩阵(GLCM)到6个关键属性实战
·
Python图像纹理分析实战:基于灰度共生矩阵的6大特征提取与应用
在工业质检、医学影像分析等领域,图像纹理特征往往比颜色或形状更能揭示本质差异。想象一下:当我们需要区分织物瑕疵、肺结节良恶性或不同地表植被时,人眼难以捕捉的微观纹理模式恰恰是机器学习模型的最佳输入特征。本文将带您用Python的skimage库,通过灰度共生矩阵(GLCM)这一经典方法,从图像中提取6种关键纹理属性,并应用于实际分类任务。
1. 环境配置与数据准备
1.1 安装必要库
确保已安装以下Python库(推荐使用Anaconda环境):
pip install scikit-image numpy matplotlib pandas
1.2 示例数据集构建
我们模拟两种典型纹理图像作为案例数据:
import numpy as np
from skimage import io, color
# 生成规则纹理(如工业品合格样本)
regular_texture = np.zeros((200, 200))
regular_texture[::10, :] = 1
regular_texture[:, ::10] = 1
# 生成随机纹理(如瑕疵样本)
random_texture = np.random.rand(200, 200)
random_texture = (random_texture > 0.9).astype(np.uint8)
# 保存示例图像
io.imsave('regular.jpg', (regular_texture*255).astype(np.uint8))
io.imsave('random.jpg', (random_texture*255).astype(np.uint8))
2. 灰度共生矩阵原理精要
2.1 GLCM核心概念
灰度共生矩阵通过统计像素对的空间关系来描述纹理。关键参数包括:
- 距离(d) : 像素对间隔(如1表示相邻像素)
- 角度(θ) : 像素对方向(0°、45°、90°、135°)
- 灰度级(L) : 图像量化等级(通常256级)
2.2 数学表达
对于图像I,GLCM元素P(i,j|d,θ)表示在方向θ上相距d的两个像素分别具有灰度值i和j的概率。归一化公式:
P(i,j) = count(i,j) / sum(count)
3. 特征提取实战
3.1 计算GLCM基础矩阵
from skimage.feature import greycomatrix
# 加载图像并转换为灰度
image = io.imread('regular.jpg', as_gray=True)
image = (image * 255).astype(np.uint8) # 转换为8位灰度
# 计算4个方向的GLCM
glcm = greycomatrix(image,
distances=[1], # 像素距离
angles=[0, np.pi/4, np.pi/2, 3*np.pi/4], # 四个方向
levels=256, # 灰度级数
symmetric=True, # 对称计数
normed=True) # 归一化
3.2 六种纹理特征解析
使用 greycoprops 提取特征并解释其物理意义:
| 特征名称 | 数学表达式 | 物理意义 | 应用场景示例 |
|---|---|---|---|
| 对比度 | ∑ | i-j | ²·P(i,j) |
| 相异性 | ∑ | i-j | ·P(i,j) |
| 同质性 | ∑P(i,j)/(1+ | i-j | ) |
| 能量 | √∑P(i,j)² | 纹理规则性 | 织物图案分类 |
| 相关性 | ∑(i-μ)(j-μ)P(i,j)/σ² | 线性依赖程度 | 遥感地表特征分析 |
| ASM(角二阶矩) | ∑P(i,j)² | 图像均匀性 | 工业产品一致性检测 |
提取全部特征的代码实现:
from skimage.feature import greycoprops
properties = ['contrast', 'dissimilarity', 'homogeneity',
'energy', 'correlation', 'ASM']
features = {}
for prop in properties:
features[prop] = greycoprops(glcm, prop).ravel()
4. 完整项目案例:表面缺陷分类
4.1 数据预处理流程
import os
from tqdm import tqdm
def extract_texture_features(image_path):
img = io.imread(image_path, as_gray=True)
img = (img * 255).astype(np.uint8)
glcm = greycomatrix(img, distances=[1, 3],
angles=[0, np.pi/4, np.pi/2, 3*np.pi/4],
levels=256, symmetric=True, normed=True)
feature_vector = []
for prop in properties:
vals = greycoprops(glcm, prop).ravel()
feature_vector.extend(vals)
return np.array(feature_vector)
# 遍历数据集目录
dataset_dir = 'surface_defects/'
X, y = [], []
for label, class_name in enumerate(['normal', 'defect']):
class_dir = os.path.join(dataset_dir, class_name)
for img_file in tqdm(os.listdir(class_dir)):
img_path = os.path.join(class_dir, img_file)
features = extract_texture_features(img_path)
X.append(features)
y.append(label)
X = np.array(X)
y = np.array(y)
4.2 特征可视化分析
使用Seaborn绘制特征分布图:
import seaborn as sns
import pandas as pd
df = pd.DataFrame(X, columns=[f'{prop}_{d}_{a}'
for prop in properties
for d in [1,3]
for a in [0,45,90,135]])
df['label'] = y
# 绘制对比度特征分布
sns.boxplot(x='label', y='contrast_1_0', data=df)
plt.title('Contrast Feature Distribution')
plt.show()
4.3 分类模型构建
使用随机森林进行纹理分类:
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
clf = RandomForestClassifier(n_estimators=100)
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print(classification_report(y_test, y_pred))
5. 高级技巧与优化建议
5.1 参数调优指南
- 距离选择 :根据纹理周期调整(细纹理用1-3,粗纹理用5-10)
- 角度组合 :各向同性纹理可减少角度数量
- 灰度量化 :适当减少levels可提升计算效率(如64级)
5.2 多尺度特征融合
distances = [1, 3, 5]
angles = [0, np.pi/4, np.pi/2, 3*np.pi/4]
glcm_multi = greycomatrix(image, distances=distances,
angles=angles, levels=64)
5.3 实时处理优化
对于视频流等实时场景:
# 使用GPU加速
import cupy as cp
from numba import jit
@jit(nopython=True)
def fast_glcm(img, distance, angle):
# 实现优化的GLCM计算
pass
6. 实际应用中的挑战与解决方案
6.1 常见问题排查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 特征区分度低 | 距离/角度选择不当 | 尝试不同距离角度组合 |
| 计算速度慢 | 图像尺寸过大 | 降采样或分块处理 |
| 旋转敏感 | 未考虑各向同性 | 取各方向特征均值 |
| 光照影响大 | 未做光照归一化 | 使用Gamma校正或直方图均衡化 |
6.2 与其他特征融合
结合LBP(局部二值模式)提升效果:
from skimage.feature import local_binary_pattern
radius = 3
n_points = 8 * radius
lbp = local_binary_pattern(image, n_points, radius, method='uniform')
# 将LBP特征与GLCM特征拼接
combined_features = np.concatenate([glcm_features, lbp_histogram])
在工业现场部署时,我们发现将GLCM特征与简单的形态学特征结合,能在保持90%+准确率的同时将处理速度提升3倍。对于嵌入式设备,建议预先计算好最优的距��角度参数组合,并采用查表法优化计算过程。
更多推荐

所有评论(0)