find radius of xyz data

조회 수: 8 (최근 30일)
jordan Ashton
jordan Ashton 2022년 3월 28일
댓글: Torsten 2022년 3월 29일
@Image Analyst
I have a 3d point cloud that contains xyz data that I would like to find the radius of. I would like to use inclircle function to find the diameter that contains all points but it is not giving me my desired output. I dont know if it has to do with the fact that my point cloud is tilted.
Alternatively, I was thinking to find a way to find the length of the axis that would give me the diameter in this example. Thank you
I included zip containing my data
Code:
% Read data.
cloud = pcread('data.ply');
xyz = double(cloud.Location);
xyz(:,3) = [];
%k = convhull(xyz);
x = xyz(:,1);
y = xyz(:,2);
[center,radius] = minboundcircle(x,y)
theta = linspace(0,2*pi,100);
xc = center(1) + radius*cos(theta);
yc = center(2) + radius*sin(theta);
% Sometimes the minimal radius circle may pass
% through only two points.
plot(x,y,'ro',xc,yc,'b-')
set(gcf,'color','white')
% Create ylabel
ylabel({'Y'});
% Create xlabel
xlabel({'X'});
% Create title
title({'Minimum radius enclosing circle'},'Editing','on');
figure
pcshow(cloud);

답변 (3개)

Image Analyst
Image Analyst 2022년 3월 28일
Try this:
% Create a set of points in 3-D
xyz = rand(9, 3);
% Find distances between all of them with pdist2() in the stats toolbox.
distances = pdist2(xyz, xyz)
maxDistance = max(distances(:))
[index1, index2] = find(distances == maxDistance)
% Just take one singe they're symmetric.
index1 = index1(1);
index2 = index2(1);
fprintf('Furthest apart points:\n');
fprintf('(x1,y1,z1) = (%f, %f, %f)\n', xyz(index1, 1), xyz(index1, 2), xyz(index1, 3))
fprintf('(x2,y2,z2) = (%f, %f, %f)\n', xyz(index2, 1), xyz(index2, 2), xyz(index2, 3))
% Plot all of them.
plot3(xyz(:, 1), xyz(:, 2), xyz(:, 3), 'b.', 'MarkerSize', 20);
grid on;
xlabel('x');
ylabel('y');
zlabel('z');
% Plot the two that are farthest away and define the diameter.
hold on;
plot3([xyz(index1, 1), xyz(index2, 1)],...
[xyz(index1, 2), xyz(index2, 2)],...
[xyz(index1, 3), xyz(index2, 3)],...
'r-', 'LineWidth', 3);
  댓글 수: 1
Image Analyst
Image Analyst 2022년 3월 28일
편집: Image Analyst 2022년 3월 28일
On second thought, the two farthest away points in 3-D won't necessarily give you the diameter - imagine 3 equidistant points every 60 degrees along the perimeter.
I suppose if there are not too many points, you cold always brute force it with a triple for loop. John D'Errico (pronounced DEER - ih - coe I think, or maybe der-REE-coe) may know of a better way.

댓글을 달려면 로그인하십시오.


Torsten
Torsten 2022년 3월 28일
편집: Torsten 2022년 3월 29일
It's an optimization problem:
min: r^2
s.c.
(x_i-x_s)^2 + (y_i-y_s)^2 + (z_i-z_s)^2 <= r^2 (i=1,...,number of points in 3d cloud)
where the unknowns are x_s, y_s, z_s and r and the triples (x_i,y_i,z_i) are your point cloud data.
You can try "fmincon" to solve.
Here is a test case:
xyz = randn(100,3);
X = xyz(:,1);
Y = xyz(:,2);
Z = xyz(:,3);
xyz0(1) = sum(X)/numel(X);
xyz0(2) = sum(Y)/numel(Y);
xyz0(3) = sum(Z)/numel(Z);
xyz0(4) = max(sqrt(((X-xyz(1)).^2+(Y-xyz(2)).^2+(Z-xyz(3)).^2)));
xyz0
%xyz0 = [1 1 1 100];
sol = fmincon(@fun,xyz0,[],[],[],[],[],[],@(p)nonlcon(p,X,Y,Z))
end
function obj = fun(p)
obj = p(4).^2
end
function [c,ceq] = nonlcon(p,X,Y,Z)
ceq = [];
c = (X-p(1)).^2 + (Y-p(2)).^2 + (Z-p(3)).^2 - p(4)^2;
end
Maybe the center of gravity x_s = 1/n *sum_x_i, y_s = 1/n *sum_y_i , z_s = 1/n * sum_z_i is the solution.
I'm not sure.
After the test runs I can say: it's not the center of gravity.
  댓글 수: 3
Torsten
Torsten 2022년 3월 28일
편집: Torsten 2022년 3월 29일
That would be trivial to solve. It's just,
max_{i,j} ( norm([xi,yi,zi]-[xj,yj,zj]))
Maybe you mean max_{i,j} ( norm([xi,yi,zi]-[xj,yj,zj]))/2, but it's not correct.
Consider an equal-sided triangle in 2d with sidelength 1.
The radius of the circumcircle is 1/sqrt(3) > 1/2.
The radius that is really being sought is that of the tightest cylinder that will fit around the data, or in other words the tightest circle radius after projecting the (x,y,z) data onto a 2D plane.
Is it so ? If this is the usual definition of the radius of a point cloud, I didn't know.
Matt J
Matt J 2022년 3월 29일
Consider an equal-sided triangle in 2d with sidelength 1.
Yep. Never mind.

댓글을 달려면 로그인하십시오.


Matt J
Matt J 2022년 3월 29일
편집: Matt J 2022년 3월 29일
I would like to use inclircle [sic.] function to find the diameter
Are you trying to enclose the points in a sphere or a cylinder? If a sphere, how would a function having to do with circles be applicable to you?
And where did you get the 3rd party code routine "incircle"? If you got it here, note that the package also contains a routine called minboundsphere() which might be more applicable.
  댓글 수: 3
jordan Ashton
jordan Ashton 2022년 3월 29일
What I am asking specifically is how I can find the length of
plot3(xyz2Limit(:, 1) + xMean, xyz2Limit(:, 2) + yMean, xyz2Limit(:, 3) + zMean, 'k-', 'LineWidth', 4);
plot3(xyz3Limit(:, 1) + xMean, xyz3Limit(:, 2) + yMean, xyz3Limit(:, 3) + zMean, 'k-', 'LineWidth', 4);
from the example I linked
Torsten
Torsten 2022년 3월 29일
But the formulae for all the parameters in the plot command are given in the code - you just have to copy the lines.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Point Cloud Processing에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by