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;

代码解释

  1. 读取原始图像img = imread('7-1.tif');读取名为'7-1.tif'的图像文件。
  2. 转换为灰度图像gray_img = rgb2gray(img);将彩色图像转换为灰度图像。
  3. 二值化图像bw_img = imbinarize(gray_img);将灰度图像二值化,即把图像像素值转换为0或1。
  4. 骨架化操作skel_img = bwmorph(bw_img, 'skel', Inf);对二值化图像进行骨架化操作,提取条纹的中心线。
  5. 计算像素长度pixel_size = 0.0595;设定每个像素的长度为0.0595纳米。
  6. 消除分支条纹branch_points = bwmorph(skel_img, 'branchpoints');end_points = bwmorph(skel_img, 'endpoints');提取条纹的端点和分支点,并将这些点设置为0,消除分支。
  7. 提取条纹cc = bwconncomp(skel_img);提取骨架化图像中的连通区域。
  8. 计算条纹长度skel_lengths = zeros(numel(skel_props), 1);skel_length = skel_props(i).Area * pixel_size;计算每个连通区域的面积,并乘以像素长度,得到条纹的长度。
  9. 消除短条纹long_skel_lengths = skel_lengths(skel_lengths >= 0.483);筛选出长度大于0.483纳米的条纹。
  10. 统计数据和图像展示disp(['Total number of stripes: ', num2str(numel(skel_props))]);等代码展示了条纹数量、总长度、长条纹数量以及长条纹总长度。
  11. 图像展示figure; imshow(img); hold on;plot(skel_props(i).PixelList(:, 2), skel_props(i).PixelList(:, 1), 'r');将原始图像和提取的骨架线叠加显示。
  12. 直方图展示figure; histogram(long_skel_lengths, 'BinWidth', 1);展示了长条纹长度的直方图。

本代码通过MATLAB实现图像处理,对图像中的条纹进行骨架提取,并计算条纹长度,最终展示条纹长度的直方图,为分析条纹特征提供参考。

MATLAB图像处理:条纹骨架提取和长度分析

原文地址: https://www.cveoy.top/t/topic/m1pT 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录