使用Gabor滤波器提取纹理特征,再通过K-means聚类进行图像分割
使用Gabor滤波器提取纹理特征,再通过K-means聚类进行图像分割,是一个经典的纹理分割流程
·
使用Gabor滤波器提取纹理特征,再通过K-means聚类进行图像分割,是一个经典的纹理分割流程
整体流程概览
整个流程可以清晰地分为以下步骤,其核心是通过多尺度、多方向的Gabor滤波器组捕捉纹理信息:
完整的MATLAB实现代码
%% ====== 基于Gabor纹理特征与K-means聚类的图像分割 ======
clear; close all; clc;
%% 步骤1:读取并预处理图像
img = imread('texture_image.jpg'); % 请替换为你的图像路径
if size(img, 3) == 3
img_gray = rgb2gray(img); % 转换为灰度图
else
img_gray = img;
end
img_gray = im2double(img_gray); % 转换为双精度
figure('Position', [100, 100, 1200, 400]);
subplot(1,4,1);
imshow(img_gray); title('原始灰度图像');
[m, n] = size(img_gray);
%% 步骤2:设计并应用多尺度、多方向Gabor滤波器组
fprintf('设计Gabor滤波器组...\n');
% 2.1 定义滤波器参数(这些是关键参数,可根据纹理调整)
wavelengths = [3, 6, 9]; % 波长(像素),对应频率 f = 1/wavelength
orientations = [0, 45, 90, 135]; % 方向(度)
gaborBank = cell(length(wavelengths), length(orientations));
filterResponses = zeros(m, n, length(wavelengths)*length(orientations));
% 2.2 生成滤波器组并滤波
responseIdx = 1;
for wl = 1:length(wavelengths)
for or = 1:length(orientations)
% 创建Gabor滤波器
gaborBank{wl, or} = gabor(wavelengths(wl), orientations(or));
% 对图像进行滤波(实部和虚部)
[mag, ~] = imgaborfilt(img_gray, gaborBank{wl, or});
% 通常使用滤波响应的幅度作为纹理特征
filterResponses(:, :, responseIdx) = mag;
responseIdx = responseIdx + 1;
end
end
% 2.3 可视化部分滤波器及其响应
subplot(1,4,2);
montage(real(gaborBank{:, :}), 'Size', [length(wavelengths), length(orientations)]);
title('Gabor滤波器组(实部)');
subplot(1,4,3);
montage(filterResponses(:,:,1:4), 'Size', [2, 2]);
title('示例特征图(前4个)');
fprintf('Gabor滤波完成,生成 %d 个特征图。\n', size(filterResponses,3));
%% 步骤3:构建特征向量并降维
fprintf('构建特征向量并降维...\n');
% 3.1 将三维特征矩阵重塑为二维特征矩阵 [像素数 x 特征数]
numPixels = m * n;
featureMatrix = reshape(filterResponses, numPixels, []);
% 3.2 标准化特征(重要:使各维度特征具有可比性)
featureMatrix = zscore(featureMatrix); % 零均值,单位方差
% 3.3 主成分分析(PCA)降维(可选,但推荐用于加速和去噪)
desiredDim = 8; % 希望保留的主成分数量
[coeff, score, ~, ~, explained] = pca(featureMatrix);
featureMatrixReduced = score(:, 1:desiredDim);
fprintf('PCA降维完成:原始维度 %d -> 新维度 %d,前%d个主成分解释%.1f%%方差。\n', ...
size(featureMatrix,2), desiredDim, desiredDim, sum(explained(1:desiredDim)));
%% 步骤4:使用K-means对特征向量进行聚类
fprintf('进行K-means聚类...\n');
numClusters = 4; % 期望分割的区域数量(需根据图像先验调整)
maxIterations = 100; % 最大迭代次数
replicates = 3; % 重复次数(避免局部最优)
% 执行K-means聚类
[clusterIdx, centroids] = kmeans(featureMatrixReduced, numClusters, ...
'Distance', 'sqeuclidean', ...
'MaxIter', maxIterations, ...
'Replicates', replicates, ...
'Display', 'final');
% 将聚类标签重塑为图像格式
segmentedImg = reshape(clusterIdx, m, n);
%% 步骤5:后处理与结果可视化
fprintf('进行分割结果后处理...\n');
% 5.1 简单中值滤波去除小噪声点
segmentedImg = medfilt2(segmentedImg, [5, 5]);
% 5.2 显示最终分割结果
subplot(1,4,4);
imagesc(segmentedImg); axis image; axis off;
colormap(jet(numClusters)); % 为不同类别分配不同颜色
colorbar('Ticks', 1:numClusters, 'TickLabels', 1:numClusters);
title(sprintf('K-means分割结果 (%d类)', numClusters));
% 5.3 (可选)将分割结果叠加在原图上显示
figure('Position', [100, 500, 800, 400]);
subplot(1,2,1); imshow(img_gray); title('原始图像');
subplot(1,2,2);
if size(img, 3) == 3
imshow(img); hold on;
else
imshow(img_gray); hold on;
end
% 以透明方式显示分割边界
boundaries = bwperim(segmentedImg); % 获取区域边界
visboundaries(boundaries, 'Color', 'r', 'LineWidth', 1.5, 'EnhanceVisibility', false);
title('分割边界叠加图');
hold off;
fprintf('图像分割完成!\n');
核心参数详解与调优指南
代码中的几个关键参数直接影响分割效果,需要根据你的具体图像纹理进行调整:
| 参数 | 含义与调优建议 | 典型值/范围 |
|---|---|---|
wavelengths |
Gabor滤波器波长,决定感受野大小。纹理越粗糙,波长应越大。 | [3, 6, 9, 12] |
orientations |
Gabor滤波器方向,决定对纹理方向的敏感性。覆盖0°-180°即可(对称性)。 | [0, 30, 60, 90, 120, 150] |
numClusters |
K-means的聚类数,即期望分割出的纹理区域类别数。需先验估计。 | 2-8 |
desiredDim |
PCA降维后的特征维度。在保留信息与降低计算量/噪声间平衡。 | 5-15 |
参考代码 采用gabor提取出图像纹理特征,最后采用k-means方法聚类进行图像分割 www.youwenfan.com/contentcsa/98030.html
优化与改进
如果基础方案效果不理想,可以从以下几个方向进行优化:
-
特征增强:
- 多尺度融合:除了Gabor幅度,可考虑结合局部二值模式(LBP) 或灰度共生矩阵(GLCM) 特征,提供互补信息。
- 空间上下文:在特征向量中融入像素的坐标
(x, y),使聚类时考虑空间邻近性,得到更紧凑的区域。
-
聚类算法改进:
- 确定最佳聚类数:使用轮廓系数(Silhouette Score) 或肘部法则(Elbow Method) 评估不同
numClusters值的效果。 - 采用更优算法:K-means对初始值敏感且假设凸形簇。可尝试谱聚类(Spectral Clustering) 或均值漂移(Mean-Shift),它们对任意形状的纹理区域更有效。
- 确定最佳聚类数:使用轮廓系数(Silhouette Score) 或肘部法则(Elbow Method) 评估不同
-
后处理优化:
- 使用更鲁棒的方法:用形态学操作(开闭运算) 或连通组件分析 替代简单中值滤波,能更好地平滑区域并去除小噪声。
总结来说,你可以直接使用上述代码,并通过调整Gabor参数和聚类数量来适配你的图像。
更多推荐
所有评论(0)