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

1 view (last 30 days)
  2 Comments
ssyang gau
ssyang gau on 2 Oct 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');

Sign in to comment.

Answers (1)

Mathieu NOE
Mathieu NOE on 2 Oct 2024
Edited: Mathieu NOE on 2 Oct 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 Comments
Mathieu NOE
Mathieu NOE on 2 Oct 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).

Sign in to comment.

Categories

Find more on Convert Image Type in Help Center and File Exchange

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!