在PythonNumpy数组中,如何知道哪个对象更接近一幅图像中的一个点?

在PythonNumpy数组中,如何知道哪个对象更接近一幅图像中的一个点?,python,numpy,scipy,medical-imaging,Python,Numpy,Scipy,Medical Imaging,我有一个numpy数组,它代表一个图像。图像有3种颜色:橙色(背景)、蓝色(object1)和绿色(object2)。我使用3个值(0、1和2)来表示numpy数组中的3种颜色。两个对象不重叠 我的问题是:如何知道哪个物体更靠近图像的中心(红点)?(此处,更近表示从对象到一个对象图像中心的最近距离小于从对象到Other对象图像中心的最近距离) 我的代码如下: import numpy as np from scipy import spatial import time sub_image1

我有一个numpy数组,它代表一个图像。图像有3种颜色:橙色(背景)、蓝色(object1)和绿色(object2)。我使用3个值(0、1和2)来表示numpy数组中的3种颜色。两个对象不重叠

我的问题是:如何知道哪个物体更靠近图像的中心(红点)?(此处,更近表示从对象到一个对象图像中心的最近距离小于从对象到Other对象图像中心的最近距离

我的代码如下:

import numpy as np
from scipy import spatial
import time

sub_image1 = np.ones((30, 30, 30))
sub_image2 = np.ones((20, 10, 15))

# pad the two sub_images to same shape (1200, 1200, 1200) to simulate my 3D medical data
img_1 = np.pad(sub_image1, ((1100, 70), (1100, 70), (1100, 70)))
img_2 = np.pad(sub_image1, ((1100, 80), (1130, 60), (1170, 15)))

def nerest_dis_to_center(img):
    position = np.where(img > 0)
    coordinates = np.transpose(np.array(position))  # get the coordinates where the voxels is not 0
    cposition = np.array(img.shape) / 2  # center point position/coordinate
    distance, index = spatial.KDTree(coordinates).query(cposition)
    return distance

t1 = time.time()
d1 = nerest_dis_to_center(img_1)
d2 = nerest_dis_to_center(img_2)

if d1 > d2:
    print("img2 object is nearer")
elif d2 > d1:
    print("img1 object is nearer")
else:
    print("They are the same far")
t2 = time.time()
print("used time: ", t2-t1)
# 30 seconds
上面的代码可以工作,但是速度很慢,并且需要很大的内存(大约30GB)。如果你想在你的电脑上复制我的代码,你可以用更小的形状来代替(320012001200)。有没有更有效的方法来实现我的目标

注意:实际上我的图像是3D CT医学图像,太大了无法上传。图像中的对象是随机的,可能是凸的,也可能不是凸的。这就是为什么我的实现要慢得多。为了澄清我的问题,我使用2D图像来解释我的方法。


这可能不是最终解决方案或最佳的w.r.t时间,必须使用实际数据进行测试。为了让我的想法通过,我选择了更小的矩阵大小和只有2D的情况

将numpy导入为np
将matplotlib.pyplot作为plt导入
sub_image1=np.one((30,30))#第一个对象
sub_image2=np.one((20,10))*2#第二个对象
#将两个sub_图像填充到相同的形状(120,120)
img_1=np.pad(sub_image1,((110,60),(60,110)))
img_2=np.pad(sub_image2,((100,80)、(130,60)))
final_image=img_1+img_2#在零背景下创建两个对象的最终图像
image\u center=(np.array([final\u image.shape[0],final\u image.shape[1]])/2.astype(np.int)
#标记中心
最终图像[图像中心[0],图像中心[1]=10
#查找对象所在位置的坐标
first_obj_coords=np.argwhere(final_image==1)#可能是最耗时的操作
second_obj_coords=np.argwhere(final_image==2)#可能是最耗时的
#找到他们的中心
第一目标中心=np.平均值(第一目标坐标,轴=0)
第二目标中心=np.平均值(第二目标坐标,轴=0)
#将中心旋转为int,以便使用它们进行索引
首个目标中心=np.楼层(首个目标中心).astype(int)
第二目标中心=np.楼层(第二目标中心).astype(int)
#标记对象的中心
最终图像[第一个对象中心[0],第一个对象中心[1]]=10
最终图像[第二个对象中心[0],第二个对象中心[1]]=10
#计算从中心到对象中心的距离
打印('到第一个对象的距离:',np.linalg.norm(图像中心-第一个对象中心))
打印('到第二个对象的距离:',np.linalg.norm(图像中心-第二个对象中心))
plt.imshow(最终图像)
plt.show()
输出 我解决了这个问题

因为这两个3D阵列太大了。因此,首先,我用最近邻法对它们进行了小样本的采样。然后继续:

import numpy as np
from scipy import spatial
import time

sub_image1 = np.ones((30, 30, 30))
sub_image2 = np.ones((20, 10, 15))

# pad the two sub_images to same shape (1200, 1200, 1200) to simulate my 3D medical data
img_1 = np.pad(sub_image1, ((1100, 70), (1100, 70), (1100, 70)))
img_2 = np.pad(sub_image1, ((1100, 80), (1130, 60), (1170, 15)))

ori_sz = np.array(img_1.shape)
trgt_sz = ori_sz / 4
zoom_seq = np.array(trgt_sz, dtype='float') / np.array(ori_sz, dtype='float')
img_1 = ndimage.interpolation.zoom(img_1, zoom_seq, order=0, prefilter=0)
img_2 = ndimage.interpolation.zoom(img_2, zoom_seq, order=0, prefilter=0)
print("it cost this secons to downsample the nearer image" + str(time.time() - t0))  # 0.8 seconds


def nerest_dis_to_center(img):
    position = np.where(img > 0)
    coordinates = np.transpose(np.array(position))  # get the coordinates where the voxels is not 0
    cposition = np.array(img.shape) / 2  # center point position/coordinate
    distance, index = spatial.KDTree(coordinates).query(cposition)
    return distance

t1 = time.time()
d1 = nerest_dis_to_center(img_1)
d2 = nerest_dis_to_center(img_2)

if d1 > d2:
    print("img2 object is nearer")
elif d2 > d1:
    print("img1 object is nearer")
else:
    print("They are the same far")
t2 = time.time()
print("used time: ", t2-t1)
# 1.1 seconds


您的对象形状是否固定?@sai No。形状没有固定。图像是凸面的,还是具有可靠的规则属性?这只是一个想法,但使用稀疏数组可能有助于提高速度。请提供预期结果。显示中间结果与预期结果的偏差。我们应该能够将您的代码块粘贴到文件中,运行它,并重现您的问题。首先感谢您的完整答案。然而,在我的问题中,“更近”并不是比较从一个物体的中心到图像中心的距离。我想比较从一个物体的“最近体素”到图像中心的距离。你是说像角体素?请看我的答案。
import numpy as np
from scipy import spatial
import time

sub_image1 = np.ones((30, 30, 30))
sub_image2 = np.ones((20, 10, 15))

# pad the two sub_images to same shape (1200, 1200, 1200) to simulate my 3D medical data
img_1 = np.pad(sub_image1, ((1100, 70), (1100, 70), (1100, 70)))
img_2 = np.pad(sub_image1, ((1100, 80), (1130, 60), (1170, 15)))

ori_sz = np.array(img_1.shape)
trgt_sz = ori_sz / 4
zoom_seq = np.array(trgt_sz, dtype='float') / np.array(ori_sz, dtype='float')
img_1 = ndimage.interpolation.zoom(img_1, zoom_seq, order=0, prefilter=0)
img_2 = ndimage.interpolation.zoom(img_2, zoom_seq, order=0, prefilter=0)
print("it cost this secons to downsample the nearer image" + str(time.time() - t0))  # 0.8 seconds


def nerest_dis_to_center(img):
    position = np.where(img > 0)
    coordinates = np.transpose(np.array(position))  # get the coordinates where the voxels is not 0
    cposition = np.array(img.shape) / 2  # center point position/coordinate
    distance, index = spatial.KDTree(coordinates).query(cposition)
    return distance

t1 = time.time()
d1 = nerest_dis_to_center(img_1)
d2 = nerest_dis_to_center(img_2)

if d1 > d2:
    print("img2 object is nearer")
elif d2 > d1:
    print("img1 object is nearer")
else:
    print("They are the same far")
t2 = time.time()
print("used time: ", t2-t1)
# 1.1 seconds