Python 根据向量在数组中绘制对象

Python 根据向量在数组中绘制对象,python,numpy,vector,Python,Numpy,Vector,目标: 我正在写代码来计算两个3D向量之间的角度(很简单)。然而,向量是根据由单独程序执行的数据对齐来定义的。更精确地说,对齐程序将获取卷,并根据常见特征对其进行对齐。这些特征本质上是一条粗白线,在一张非常嘈杂的灰度图像中,有一条较小的线从中出来 使用遮罩,我将粗白线和细白线分别对齐,然后使用已知的旋转将它们放回原始图像中的位置,然后我可以计算出它们之间的角度(几千张图像) 当前问题: 虽然我相当确信这是可行的,但我想通过创建一些示例数据并通过校准程序运行它,然后通过我的代码来测试它 使用以下代

目标:

我正在写代码来计算两个3D向量之间的角度(很简单)。然而,向量是根据由单独程序执行的数据对齐来定义的。更精确地说,对齐程序将获取卷,并根据常见特征对其进行对齐。这些特征本质上是一条粗白线,在一张非常嘈杂的灰度图像中,有一条较小的线从中出来

使用遮罩,我将粗白线和细白线分别对齐,然后使用已知的旋转将它们放回原始图像中的位置,然后我可以计算出它们之间的角度(几千张图像)

当前问题:

虽然我相当确信这是可行的,但我想通过创建一些示例数据并通过校准程序运行它,然后通过我的代码来测试它

使用以下代码在numpy中轻松创建一个充满随机灰度值的3D numpy数组:

def RandomNoise():
NoiseArray = np.random.normal(0,1,(100,100,100))

return NoiseArray
然后我需要插入一条粗白线,然后从中心以随机角度插入一条小白线。我想我可以加上一条粗白线作为一个平面横跨整个3D空间,保持在同一位置。我只是停留在关于在随机角度放置较薄的白线。我想把它定义为一个向量,然后对它应用随机旋转,记录旋转,然后在数组中渲染为一个圆柱体,但我不知道怎么做

编辑:为了澄清“粗”白线本质上只是一个横跨整个3D空间的白色平面,在x和y方向上有一个定义的高度(例如100100阵列中的20个像素)。“细”白线是一个定义半径的圆柱体(比如100100阵列中的10个像素),我想以不同的角度从白线平面出来,所以它应该在较粗白线的一端“旋转”

正是这个白色圆柱体,我想定义为一个向量,然后使用旋转矩阵对其应用随机旋转,然后再绘制到3D阵列中

任何帮助都将不胜感激

谢谢

编辑:请求的草图


您的问题是,我不完全确定不同的行应该如何相互对齐,但我将为您提供以下小脚本,在任何情况下都可以作为起点。对于可以从scipy包中使用的旋转

import matplotlib.pyplot as plt
import numpy as np
from scipy.ndimage import rotate

np.random.seed(181003)

N = 100  # Number of images.
m, n = 100, 100  # row and column dimension.
test = np.random.uniform(0, 1, (N, m, n))

def create_bars(d):
    """Parameter d indicates thickness of the bar in number of rows"""
    bars = np.zeros((N, m, n), dtype=float)
    bars[:, m//2 - d : m//2 + d, :] = np.random.uniform(0.95, 1.0, (N, 2*d, n))
    for i, angle in enumerate(np.random.uniform(0, 180, N)):  # Angle in degrees.
        bars[i, :, :] = rotate(bars[i], angle, reshape=False)
    return bars

test += create_bars(m // 5)  # Thick bars.
test += create_bars(m // 25)  # Thin bars.

for i in range(3):
    plt.figure()
    plt.imshow(test[i])
plt.show()
从下面的示例图像中,您可以看到重叠区域的强度高于其他条。如果不希望出现这种情况,则需要同时创建记号条和细条,并且可以处理重叠区域

基于OP的更新进行编辑 我们可以通过3D阵列的相应索引生成平面和圆柱体。我们可以旋转这些索引,以获得旋转形状的新索引(我们需要在旋转之前将索引居中,然后再次向后移动)。下面是一些示例代码:

"""Coordinate system is z, y, x for indexing the 3D array (i.e. test[z, y, x])."""

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def rotate_z(angle):
    return np.array([
        [1, 0, 0],
        [0, np.cos(angle), -np.sin(angle)],
        [0, np.sin(angle), np.cos(angle)],
    ])

def rotate_y(angle):
    return np.array([
        [np.cos(angle), 0, np.sin(angle)],
        [0, 1, 0],
        [-np.sin(angle), 0, np.cos(angle)],
    ])

def rotate_x(angle):
    return np.array([
        [np.cos(angle), -np.sin(angle), 0],
        [np.sin(angle), np.cos(angle), 0],
        [0, 0, 1],
    ])

l = m = n = 40  # Use only small number of points due to plotting.
test = np.random.uniform(0, 0.95, (l, m, n))

d = l // 10  # Thickness of plane.
i_thick = np.array([*np.ndindex(d, m, n)]).T  # Indices for plane.
i_thick[0, :] -= d // 2
i_thick[1, :] -= m // 2
i_thick[2, :] -= n // 2

angle_y = angle_x = 0  # Angles about which the plane is rotated.
i_thick = rotate_y(angle_y) @ i_thick
i_thick = rotate_x(angle_x) @ i_thick
i_thick[0, :] += d // 2 + l // 2
i_thick[1, :] += m // 2
i_thick[2, :] += n // 2
i_thick = np.clip(np.round(i_thick).astype(int), 0, np.array(test.shape)[:, None] - 1)  # Correct rounding errors.

test[i_thick.tolist()] = np.random.uniform(0.95, 1.0, i_thick.shape[1])  # Add the plane.

r = m // 8  # Radius of cylinder.
i_cylinder = np.array([*np.ndindex(l, m, n)])
i_cylinder = i_cylinder[
    (i_cylinder[:, 0] < l // 2)
    & (np.sqrt((i_cylinder[:, 1] - m // 2)**2 + (i_cylinder[:, 2] - n // 2)**2) < r)
].T
i_cylinder[0, :] -= l // 2
i_cylinder[1, :] -= m // 2
i_cylinder[2, :] -= n // 2

# Align cylinder with plane.
i_cylinder = rotate_y(angle_y) @ i_cylinder
i_cylinder = rotate_x(angle_x) @ i_cylinder

angle2_z = angle2_y = angle2_x = 0  # Angles about which the cylinder is rotated.
i_cylinder = rotate_z(angle2_z) @ i_cylinder
i_cylinder = rotate_y(angle2_y) @ i_cylinder
i_cylinder = rotate_x(angle2_x) @ i_cylinder

i_cylinder[0, :] += l // 2
i_cylinder[1, :] += m // 2
i_cylinder[2, :] += n // 2
i_cylinder = np.clip(np.round(i_cylinder).astype(int), 0, np.array(test.shape)[:, None] - 1)

test[i_cylinder.tolist()] = np.random.uniform(0.95, 1.0, i_cylinder.shape[1])

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
test_plot = test.copy()
test_plot = np.moveaxis(test_plot, [0, 1, 2], [-1, 0, 1])  # Reorder axes from `z, y, x` to `y, x, z` in order to be aligned with plt.scatter.
test_plot = np.flip(test_plot, axis=2)  # Flip along `z` in order to plot top-to-bottom rather than bottom-to-top.
ax.scatter(*np.array([*np.ndindex(m, n, l)]).T[:, test_plot.ravel() >= 0.95].tolist(), s=1)
ax.set_xlim([0, test.shape[1] - 1])
ax.set_ylim([0, test.shape[0] - 1])
ax.set_zlim([0, test.shape[2] - 1])
plt.show()
“坐标系为z,y,x,用于索引3D阵列(即测试[z,y,x])”
将numpy作为np导入
将matplotlib.pyplot作为plt导入
从mpl_toolkits.mplot3d导入Axes3D
def旋转_z(角度):
返回np.array([
[1, 0, 0],
[0,np.cos(角度),-np.sin(角度)],
[0,np.sin(角),np.cos(角)],
])
def旋转y(角度):
返回np.array([
[np.cos(角),0,np.sin(角)],
[0, 1, 0],
[-np.sin(角度),0,np.cos(角度)],
])
def旋转_x(角度):
返回np.array([
[np.cos(角度),-np.sin(角度),0],
[np.sin(角度),np.cos(角度),0],
[0, 0, 1],
])
l=m=n=40#由于绘图,仅使用少量点。
试验=np.随机均匀(0,0.95,(l,m,n))
d=l//10#平面厚度。
i_-thick=np.array([*np.ndindex(d,m,n)]).T#平面指数。
i_厚度[0,:]-=d//2
i_厚[1,:]-=m//2
i_thick[2,:]-=n//2
角度_y=角度_x=0#平面绕其旋转的角度。
i_厚=旋转y(角度y)@i_厚
i_厚=旋转_x(角度_x)@i_厚
i_厚度[0,:]+=d//2+l//2
i_厚度[1,:]+=m//2
i_厚度[2,:]+=n//2
i_-thick=np.clip(np.round(i_-thick).astype(int),0,np.array(test.shape)[:,None]-1)#纠正舍入错误。
test[i_-thick.tolist()]=np.random.uniform(0.95,1.0,i_-thick.shape[1])#添加平面。
r=m//8#圆柱体半径。
i_圆柱体=np.数组([*np.ndindex(l,m,n)])
i_圆柱体=i_圆柱体[
(i_圆柱体[:,0]=0.95].tolist(),s=1)
ax.set_xlim([0,测试形状[1]-1])
ax.set_ylim([0,测试形状[0]-1])
ax.set_zlim([0,测试形状[2]-1])
plt.show()
例如,两个未旋转的形状:

通过
-pi/2
和圆柱体a围绕
x
旋转的平面的另一个示例