Hello, I want to limit the number of coordinates generated by the method bwboundaries or boundary while having the same step size.

1 view (last 30 days)
[b1,l1] = bwboundaries(Image1_seuil,'noholes');
[b2,l2] = bwboundaries(Image2_seuil,'noholes');
hold on
% Coordinates
% I want to have the same array size for x1, x2, y1 and y2
x1=[];
y1=[];
x2=[];
y2=[];
for k1 = 1:length(b1)
boundary1 = b1{k1};
plot(boundary1(:,2), boundary1(:,1), 'r', 'LineWidth', 1)
x1 = [x1; boundary1(:,2)];
y1 = [y1; boundary1(:,1)];
end
for k2 = 1:length(b2)
boundary2 = b2{k2};
plot(boundary2(:,2), boundary2(:,1), 'g', 'LineWidth', 1)
x2 = [x2; boundary2(:,2)];
y2 = [y2; boundary2(:,1)];
end

Accepted Answer

Mathieu NOE
Mathieu NOE on 3 May 2023
hello again
I could reduce the amount of data by a factor 3 roughly ,
more could be done if the large "straigth" lines did not include some local kincks
Code suggestion :
load('example.mat');
x1=[];
y1=[];
x2=[];
y2=[];
c_threshold = 0.5; % curvature threshold parameter
figure(1)
for k1 = 1:length(b1)
boundary1 = b1{k1};
x = boundary1(:,2);
y = boundary1(:,1);
[k] = find_high_curvature(x,y,c_threshold);
x_out = x(k);
y_out = y(k);
plot(x, y, '*r', x_out, y_out, 'ob' ,'LineWidth', 2)
hold on
x1 = [x1; x_out];
y1 = [y1; y_out];
end
figure(2)
for k2 = 1:length(b2)
boundary2 = b2{k2};
x = boundary2(:,2);
y = boundary2(:,1);
[k] = find_high_curvature(x,y,c_threshold);
x_out = x(k);
y_out = y(k);
plot(x, y, '*r', x_out, y_out, 'ob' ,'LineWidth', 2)
hold on
x2 = [x2; x_out];
y2 = [y2; y_out];
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [highCurvatureIndexes] = find_high_curvature(x,y,threshold)
% Now run along the (x, y) curve
% and find the radius of curvature at each location.
numberOfPoints = length(x);
curvature = zeros(1, numberOfPoints);
for t = 1 : numberOfPoints
if t == 1
index1 = numberOfPoints;
index2 = t;
index3 = t + 1;
elseif t >= numberOfPoints
index1 = t-1;
index2 = t;
index3 = 1;
else
index1 = t-1;
index2 = t;
index3 = t + 1;
end
% Get the 3 points.
x1 = x(index1);
y1 = y(index1);
x2 = x(index2);
y2 = y(index2);
x3 = x(index3);
y3 = y(index3);
% Now call Roger's formula:
% http://www.mathworks.com/matlabcentral/answers/57194#answer_69185
curvature(t) = 2*abs((x2-x1).*(y3-y1)-(x3-x1).*(y2-y1)) ./ ...
sqrt(((x2-x1).^2+(y2-y1).^2)*((x3-x1).^2+(y3-y1).^2)*((x3-x2).^2+(y3-y2).^2));
end
% Find high curvature points -
% indexes where the curvature is greater than threshold
highCurvatureIndexes = find(curvature > threshold);
end
  14 Comments
Joumana
Joumana on 9 May 2023
It dosen't have to be a specified number. But the number of coordinates rises gradually to be able to compare the calculations. I am sorry if I am not giving a clear explanation. Please tell me if you prefer me to explain in another way. And thank you for your help.
Mathieu NOE
Mathieu NOE on 9 May 2023
tried something different , like downsampling your data close enough to the target points
it's simply picking very n points and defining the decimation factor so that the total qty is close as posible to the given N value
this is a different approach that has no more anything to do with my initial curvature computation
tic
clc
clearvars
load('example.mat');
x1=[];
y1=[];
x2=[];
y2=[];
N = 200; % approx total number of points
for k1 = 1:length(b1)
boundary1 = b1{k1};
x1 = [x1; boundary1(:,2)];
y1 = [y1; boundary1(:,1)];
end
for k2 = 1:length(b2)
boundary2 = b2{k2};
x2 = [x2; boundary2(:,2)];
y2 = [y2; boundary2(:,1)];
end
figure(1)
subplot(1,2,1),plot(x1, y1, '*r', x2, y2, '*b','LineWidth', 1)
title('before resizing')
nx = numel(x1);
if nx>N % pick 1 every decim points
decim = ceil(nx/N);
ind = 1:decim:nx;
x1 = x1(ind);
y1 = y1(ind);
end
nx = numel(x2);
if nx>N % pick 1 every decim points
decim = ceil(nx/N);
ind = 1:decim:nx;
x2 = x2(ind);
y2 = y2(ind);
end
subplot(1,2,2),plot(x1, y1, '*r', x2, y2, '*b','LineWidth', 1)
title('after resizing')
%% Distance computations
% Distance x
% % original code (slow, only distancex alone needs +30 seconds to complete)
% distancex=[];
% for lenx1=1:length(x1)
% for lenx2=1:length(x2)
% distancex=[distancex x2(lenx2)-x1(lenx1)];
% end
% end
% prealocate data for faster execution (Elapsed time is 0.020392 seconds!!)
distancex=zeros(1,n1*n2);
k = 0;
for lenx1=1:n1
for lenx2=1:n2
k = k+1;
distancex(k)= x2(lenx2)-x1(lenx1);
end
end
% % another alternative code (suggestion up to you to try)
% % Elapsed time is 0.014494 seconds.
% distX = x2'-x1;
% distX = reshape(distX',1,[]); % convert 2D array to col vector
% diff = sum(abs(distancex-distX)) % diff = 0 !! distX and distancex are equal
% % Distance y
% for leny1=1:length(y1)
% for leny2=1:length(y2)
% distancey=[distancey y2(leny2)-y1(leny1)];
% end
% end
% prealocate data for faster execution (Elapsed time is 0.020392 seconds!!)
distancey=zeros(1,n1*n2);
k = 0;
for leny1=1:n1
for leny2=1:n2
k = k+1;
distancey(k)= y2(leny2)-y1(leny1);
end
end
% original code (slow)
% for i=1:n1*n2
% distance=[distance ( distancex(i)^2 + distancey(i)^2 )^0.5 ];
% end
% much faster and in one line :
distance = sqrt(distancex.^2 + distancey.^2);
%-----------------------Comparaison des valeurs des distances------------
% original code (slow)
% for a=1:length(x1):length(distance)
% Les_distances_min=[Les_distances_min min(distance(a:a+length(x1)-1))];
%
% end
% much faster
ind = 1:n1:n1*n2;
Les_distances_min=zeros(1,numel(ind));% prealocate data for faster execution
for k=1:numel(ind)
a = ind(k);
Les_distances_min(k)= min(distance(a:a+n1-1));
end
toc

Sign in to comment.

More Answers (0)

Categories

Find more on Cell Arrays in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!