MATLAB图像处理:条纹骨架提取和长度分析
MATLAB图像处理:条纹骨架提取和长度分析
本代码使用MATLAB实现图像处理,对图像中的条纹进行骨架提取,并计算条纹长度,最终展示条纹长度的直方图。
% 读取原始图像
img = imread('7-1.tif');
% 转换为灰度图像
gray_img = rgb2gray(img);
% 二值化图像
bw_img = imbinarize(gray_img);
% 骨架化操作
skel_img = bwmorph(bw_img, 'skel', Inf);
% 计算像素长度
pixel_size = 0.0595; % 空间分辨率为0.0595(纳米/像素)
skel_img_diag = diag(skel_img);
skel_img_diag(skel_img_diag == 1) = 2 * pixel_size;
skel_img(logical(diag(skel_img_diag))) = 0;
% 消除分支条纹
branch_points = bwmorph(skel_img, 'branchpoints');
end_points = bwmorph(skel_img, 'endpoints');
skel_img(branch_points) = 0;
skel_img(end_points) = 0;
% 提取条纹
cc = bwconncomp(skel_img);
skel_props = regionprops(cc, 'PixelIdxList', 'PixelList', 'Area');
% 计算条纹长度
skel_lengths = zeros(numel(skel_props), 1);
for i = 1:numel(skel_props)
skel_length = skel_props(i).Area * pixel_size;
skel_lengths(i) = skel_length;
end
% 消除短条纹
long_skel_lengths = skel_lengths(skel_lengths >= 0.483);
% 统计数据和图像展示
disp(['Total number of stripes: ', num2str(numel(skel_props))]);
disp(['Total length of stripes: ', num2str(sum(skel_lengths)), ' nm']);
disp(['Number of long stripes: ', num2str(numel(long_skel_lengths))]);
disp(['Total length of long stripes: ', num2str(sum(long_skel_lengths)), ' nm']);
figure;
imshow(img);
hold on;
for i = 1:numel(skel_props)
plot(skel_props(i).PixelList(:, 2), skel_props(i).PixelList(:, 1), 'r');
end
title('Skeletonized Stripes');
figure;
histogram(long_skel_lengths, 'BinWidth', 1);
xlabel('Stripe Length (nm)');
ylabel('Frequency');
title('Histogram of Long Stripes');
代码中出现的错误
代码中出现“位置 1 处的索引无效。数组索引必须为正整数或逻辑值。”的错误提示。这个错误发生在skel_img(logical(skel_img_diag)) = 0;这行代码,是因为skel_img_diag是一个向量,而skel_img是一个矩阵,无法直接用skel_img_diag作为索引。
错误修复
通过修改代码,使用diag(skel_img_diag)获取skel_img_diag的对角线元素,再用logical函数将其转换为逻辑索引,就可以解决错误。
skel_img_diag = diag(skel_img);
skel_img_diag(skel_img_diag == 1) = 2 * pixel_size;
skel_img(logical(diag(skel_img_diag))) = 0;
代码解释
- 读取原始图像:
img = imread('7-1.tif');读取名为'7-1.tif'的图像文件。 - 转换为灰度图像:
gray_img = rgb2gray(img);将彩色图像转换为灰度图像。 - 二值化图像:
bw_img = imbinarize(gray_img);将灰度图像二值化,即把图像像素值转换为0或1。 - 骨架化操作:
skel_img = bwmorph(bw_img, 'skel', Inf);对二值化图像进行骨架化操作,提取条纹的中心线。 - 计算像素长度:
pixel_size = 0.0595;设定每个像素的长度为0.0595纳米。 - 消除分支条纹:
branch_points = bwmorph(skel_img, 'branchpoints');和end_points = bwmorph(skel_img, 'endpoints');提取条纹的端点和分支点,并将这些点设置为0,消除分支。 - 提取条纹:
cc = bwconncomp(skel_img);提取骨架化图像中的连通区域。 - 计算条纹长度:
skel_lengths = zeros(numel(skel_props), 1);和skel_length = skel_props(i).Area * pixel_size;计算每个连通区域的面积,并乘以像素长度,得到条纹的长度。 - 消除短条纹:
long_skel_lengths = skel_lengths(skel_lengths >= 0.483);筛选出长度大于0.483纳米的条纹。 - 统计数据和图像展示:
disp(['Total number of stripes: ', num2str(numel(skel_props))]);等代码展示了条纹数量、总长度、长条纹数量以及长条纹总长度。 - 图像展示:
figure; imshow(img); hold on;和plot(skel_props(i).PixelList(:, 2), skel_props(i).PixelList(:, 1), 'r');将原始图像和提取的骨架线叠加显示。 - 直方图展示:
figure; histogram(long_skel_lengths, 'BinWidth', 1);展示了长条纹长度的直方图。
本代码通过MATLAB实现图像处理,对图像中的条纹进行骨架提取,并计算条纹长度,最终展示条纹长度的直方图,为分析条纹特征提供参考。
原文地址: https://www.cveoy.top/t/topic/m1pT 著作权归作者所有。请勿转载和采集!