how to extract (x) coordinates and (y) coordinates of the top boundary from bwimage

1 visualizzazione (ultimi 30 giorni)
  2 Commenti
ssyang gau
ssyang gau il 2 Ott 2024
% 读取图像
bw=im2bw( imread('test.jpg'),0.4)
% 反转图像,使曲线为黑色,背景为白色(可选,视具体图像而定)
% bw = ~bw;
% 获取图像尺寸
[height, width] = size(bw);
% 初始化坐标数组
x_coords = [];
y_coords = [];
% 对每一列,找到最高的白色像素点的 Y 坐标
for x = 1:width
column = bw(:, x);
y = find(column, 1, 'first'); % 找到第一个白色像素的行索引
if ~isempty(y)
x_coords(end+1) = x;
y_coords(end+1) = y;
end
end
% 绘制提取的曲线
figure;
imshow(img);
hold on;
plot(x_coords, y_coords, 'r-', 'LineWidth', 2);
title('提取的顶部曲线');
hold off;
% 保存坐标到变量或文件
% 例如,将坐标保存到变量中
top_curve_coords = [x_coords', y_coords'];
% 或者保存到 CSV 文件
% csvwrite('top_curve_coords.csv', top_curve_coords);
% 显示坐标(可选)
disp('顶部曲线的 X 坐标:');
disp(x_coords');
disp('顶部曲线的 Y 坐标:');
disp(y_coords');

Accedi per commentare.

Risposte (1)

Mathieu NOE
Mathieu NOE il 2 Ott 2024
Modificato: Mathieu NOE il 2 Ott 2024
hello
this is a solution that does not even require the Image processing toolbox
of course I had to do a bit of gym to convert from RGB to BW, but you can reintroduce im2bw as you do in your code.
and also I strongly reduces the size of your image to something a bit more manageable (factor 8 reduction in both directions) and much faster at the end.
maybe you could also avoid saving bw image in color format with jpeg , use directly png with 2 colors indexing (BW). This would save time and memory.
so here we go
as additionnal bonus you also get the bottom boundary , but if you have only interest in the top boundary , use xtop & ytop data as shown below :
A = imread('image2.jpg'); % image 2 is reduced by factor 8 in each direction
% a bit of gym to convert to grayscale , that we will "binarize" with
% logical operation
A = double(A);
% rgb2gray converts RGB values to grayscale values by forming a weighted sum of the R, G, and B components:
% 0.2989 * R + 0.5870 * G + 0.1140 * B
A = 0.299 * A(:,:,1) + 0.587 * A(:,:,2) + 0.114 * A(:,:,3);
A = flipud(A); % to have image displayed with correct y direction
[y,x] = find(A<0.5*256); % find black dots coordinates : threshold is set at 50% of 256
[xtop,ytop,xbottom,ybottom,] = top_bottom_boundary(x,y);
figure(1)
imagesc(A);
set(gca,'YDir','normal');
colormap('gray');
hold on
plot(x,y, 'k.', xtop, ytop, '-r', xbottom, ybottom, '-g','linewidth',2)
legend('data','top boundary','bottom boundary');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [x3,y3,x4,y4] = top_bottom_boundary(x,y)
% based on FEX : https://fr.mathworks.com/matlabcentral/answers/299796-tight-boundary-around-a-set-of-points
%split data into classes and find max/min for each class
class_label = unique(x);
upper_boundary = zeros(size(class_label));
lower_boundary = zeros(size(class_label));
for idx = 1:numel(class_label)
class = y(x == class_label(idx));
upper_boundary(idx) = max(class);
lower_boundary(idx) = min(class);
end
% left_boundary = y(x == class_label(1));
% right_boundary = y(x == class_label(end));
%
% % left_boundary
% x1 = class_label(1)*ones(size(left_boundary));
% y1 = left_boundary;
%
% % right_boundary
% x2 = class_label(end)*ones(size(right_boundary));
% y2 = right_boundary;
% top boundary
x3 = class_label;
y3 = upper_boundary;
% bottom boundary
x4 = class_label;
y4 = lower_boundary;
end
  2 Commenti
Mathieu NOE
Mathieu NOE il 2 Ott 2024
seems that the rendering on my PC shows a better matching boundary line vs image.
we could add a bit of smoothing if needed ? (also remember I use the reduced image for faster processing).

Accedi per commentare.

Categorie

Scopri di più su Convert Image Type in Help Center e File Exchange

Prodotti


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by