我必须为 MRI 数据增强做类似的事情:
可能代码可以优化,但它可以按原样运行。
我的数据是代表 MRI 扫描仪的 3 维 numpy 数组。它的大小为 [128,128,128],但可以修改代码以接受任何尺寸。此外,当平面位于立方体边界之外时,您必须在主函数中为变量 fill 提供默认值,在我的情况下,我选择: data_cube[0:5,0:5 ,0:5].mean()
def create_normal_vector(x, y,z):
normal = np.asarray([x,y,z])
normal = normal/np.sqrt(sum(normal**2))
return normal
def get_plane_equation_parameters(normal,point):
a,b,c = normal
d = np.dot(normal,point)
return a,b,c,d #ax+by+cz=d
def get_point_plane_proximity(plane,point):
#just aproximation
return np.dot(plane[0:-1],point) - plane[-1]
def get_corner_interesections(plane, cube_dim = 128): #to reduce the search space
#dimension is 128,128,128
corners_list = []
only_x = np.zeros(4)
min_prox_x = 9999
min_prox_y = 9999
min_prox_z = 9999
min_prox_yz = 9999
for i in range(cube_dim):
temp_min_prox_x=abs(get_point_plane_proximity(plane,np.asarray([i,0,0])))
# print("pseudo distance x: {0}, point: [{1},0,0]".format(temp_min_prox_x,i))
if temp_min_prox_x < min_prox_x:
min_prox_x = temp_min_prox_x
corner_intersection_x = np.asarray([i,0,0])
only_x[0]= i
temp_min_prox_y=abs(get_point_plane_proximity(plane,np.asarray([i,cube_dim,0])))
# print("pseudo distance y: {0}, point: [{1},{2},0]".format(temp_min_prox_y,i,cube_dim))
if temp_min_prox_y < min_prox_y:
min_prox_y = temp_min_prox_y
corner_intersection_y = np.asarray([i,cube_dim,0])
only_x[1]= i
temp_min_prox_z=abs(get_point_plane_proximity(plane,np.asarray([i,0,cube_dim])))
#print("pseudo distance z: {0}, point: [{1},0,{2}]".format(temp_min_prox_z,i,cube_dim))
if temp_min_prox_z < min_prox_z:
min_prox_z = temp_min_prox_z
corner_intersection_z = np.asarray([i,0,cube_dim])
only_x[2]= i
temp_min_prox_yz=abs(get_point_plane_proximity(plane,np.asarray([i,cube_dim,cube_dim])))
#print("pseudo distance z: {0}, point: [{1},{2},{2}]".format(temp_min_prox_yz,i,cube_dim))
if temp_min_prox_yz < min_prox_yz:
min_prox_yz = temp_min_prox_yz
corner_intersection_yz = np.asarray([i,cube_dim,cube_dim])
only_x[3]= i
corners_list.append(corner_intersection_x)
corners_list.append(corner_intersection_y)
corners_list.append(corner_intersection_z)
corners_list.append(corner_intersection_yz)
corners_list.append(only_x.min())
corners_list.append(only_x.max())
return corners_list
def get_points_intersection(plane,min_x,max_x,data_cube,shape=128):
fill = data_cube[0:5,0:5,0:5].mean() #this can be a parameter
extended_data_cube = np.ones([shape+2,shape,shape])*fill
extended_data_cube[1:shape+1,:,:] = data_cube
diag_image = np.zeros([shape,shape])
min_x_value = 999999
for i in range(shape):
for j in range(shape):
for k in range(int(min_x),int(max_x)+1):
current_value = abs(get_point_plane_proximity(plane,np.asarray([k,i,j])))
#print("current_value:{0}, val: [{1},{2},{3}]".format(current_value,k,i,j))
if current_value < min_x_value:
diag_image[i,j] = extended_data_cube[k,i,j]
min_x_value = current_value
min_x_value = 999999
return diag_image
它的工作方式如下:
你创建一个法线向量:
例如 [5,0,3]
normal1=create_normal_vector(5, 0,3) #this is only to normalize
然后你创建一个点:
(我的立方体数据形状是 [128,128,128])
point = [64,64,64]
你计算平面方程参数,[a,b,c,d] 其中 ax+by+cz=d
plane1=get_plane_equation_parameters(normal1,point)
然后为了减少搜索空间,您可以计算平面与立方体的交点:
corners1 = get_corner_interesections(plane1,128)
其中corners1 = [交叉点[x,0,0],交叉点[x,128,0],交叉点[x,0,128],交叉点[x,128,128],最小交叉点[x,y,z],最大值交点 [x,y,z]]
通过所有这些,您可以计算立方体与平面之间的交点:
image1 = get_points_intersection(plane1,corners1[-2],corners1[-1],data_cube)
一些例子:
正常是 [1,0,0] 点是 [64,64,64]
正常是[5,1,0],[5,1,1],[5,0,1]点是[64,64,64]:
正常是[5,3,0],[5,3,3],[5,0,3]点是[64,64,64]:
正常为 [5,-5,0],[5,-5,-5],[5,0,-5] 点为 [64,64,64]:
谢谢。