Python找到3D点云或3D船体的长轴

发布于 2025-02-11 06:39:11 字数 1536 浏览 1 评论 0原文

我试图找到3D对象的“长轴”(描述为3D布尔或标签数组),该对象通过该对象的质心(或靠近)。

我想认为我可以简单地迭代对象中的每对点,然后在它们之间的最大距离中选择对,但是在下面的示例对象的情况下,该线不会穿过对象的中心。

同样,我认为我可以计算每对点之间的距离,以发现最长的一对在中心的最小距离内,但我担心自己在重新发明轮子。似乎应该有一些最小二乘线的拟合,但是我能够挖掘的唯一解决方案是2D阵列。

任何建议将不胜感激。

以下代码显示非常简单的3D形状的尺寸。我实际上感兴趣的形状包含数千个点,并且更复杂,但在1)两个点之间的最大距离可能远离对象的中心,2)它们连接,以便可以用一个来描述它们单连接轮廓。

import matplotlib.pyplot as plt
import numpy as np

# make a simple 3D shape
t = [[[0,0,0,0,0],
      [0,0,1,0,0],
      [0,0,0,0,0],
      [0,0,0,0,0],
      [0,0,0,0,0]],

     [[0,0,0,0,0],
      [0,0,1,0,0],
      [0,1,1,1,0],
      [0,0,0,0,0],
      [0,0,0,0,0]],

     [[0,0,0,0,0],
      [0,0,1,0,0],
      [0,1,1,1,0],
      [0,0,0,0,0],
      [0,0,0,0,0]],

     [[0,0,0,0,0],
      [0,0,1,0,0],
      [0,1,1,1,0],
      [0,0,0,0,0],
      [0,0,0,0,0]],

     [[0,0,0,0,0],
      [0,0,1,0,0],
      [0,0,0,0,0],
      [0,0,0,0,0],
      [0,0,0,0,0]]]

t = np.array(t)

# find the centroid of the object
coords = np.where(t == 1)
x = np.mean(coords[0])
y = np.mean(coords[1])
z = np.mean(coords[2])

# show the object at different angles
fig, (ax1, ax2, ax3) = plt.subplots(1, 3)
ax1.imshow(np.max(t, axis=0))
ax1.plot(x,y, 'ro')
ax1.set_title('xy')
ax2.imshow(np.max(t, axis=1))
ax2.plot(x,z, 'ro')
ax2.set_title('xz')
ax3.imshow(np.max(t, axis=2))
ax3.plot(y,z, 'ro')
ax3.set_title('yz')
plt.show()

I am trying to find the 'long axis' of a 3D object (described as a 3D boolean or label array), which passes through (or near) the centroid of that object.

I would like to think I could simply iterate over every pair of points in the object and pick the pair with the largest distance between them, but in the case of the example object below, that line would not pass through the center of the object.

Similarly, I think I could calculate the distance between every pair of points to find that longest pair that passes within some minimum distance of the center, but I'm worried that I'm reinventing the wheel. It seems like there should be some least-squares fit of a line but the only solutions I have been able to dig up have been for 2D arrays.

Any suggestions would be greatly appreciated.

The following code displays the dimensions of a very simple 3D shape. The shapes I am actually interested contains thousands of points and are more complex but are similar in that 1) the largest distance between two points may be far from the center of the object and 2) they are connected such that they could be described by a single connected outline.

import matplotlib.pyplot as plt
import numpy as np

# make a simple 3D shape
t = [[[0,0,0,0,0],
      [0,0,1,0,0],
      [0,0,0,0,0],
      [0,0,0,0,0],
      [0,0,0,0,0]],

     [[0,0,0,0,0],
      [0,0,1,0,0],
      [0,1,1,1,0],
      [0,0,0,0,0],
      [0,0,0,0,0]],

     [[0,0,0,0,0],
      [0,0,1,0,0],
      [0,1,1,1,0],
      [0,0,0,0,0],
      [0,0,0,0,0]],

     [[0,0,0,0,0],
      [0,0,1,0,0],
      [0,1,1,1,0],
      [0,0,0,0,0],
      [0,0,0,0,0]],

     [[0,0,0,0,0],
      [0,0,1,0,0],
      [0,0,0,0,0],
      [0,0,0,0,0],
      [0,0,0,0,0]]]

t = np.array(t)

# find the centroid of the object
coords = np.where(t == 1)
x = np.mean(coords[0])
y = np.mean(coords[1])
z = np.mean(coords[2])

# show the object at different angles
fig, (ax1, ax2, ax3) = plt.subplots(1, 3)
ax1.imshow(np.max(t, axis=0))
ax1.plot(x,y, 'ro')
ax1.set_title('xy')
ax2.imshow(np.max(t, axis=1))
ax2.plot(x,z, 'ro')
ax2.set_title('xz')
ax3.imshow(np.max(t, axis=2))
ax3.plot(y,z, 'ro')
ax3.set_title('yz')
plt.show()

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

七婞 2025-02-18 06:39:11

解决方案是在这里

只需使用

image=np.array([[0,0,0,0,0],
                [0,0,1,0,0],
                [0,1,1,1,0],
                [0,0,0,0,0],
                [0,0,0,0,0]]

The solution is here

Just use

image=np.array([[0,0,0,0,0],
                [0,0,1,0,0],
                [0,1,1,1,0],
                [0,0,0,0,0],
                [0,0,0,0,0]]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文