Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 两两之间的成对距离;岛屿“/&引用;“连接部件”;在Numpy数组中_Python_Arrays_Numpy_Scipy_Image Segmentation - Fatal编程技术网

Python 两两之间的成对距离;岛屿“/&引用;“连接部件”;在Numpy数组中

Python 两两之间的成对距离;岛屿“/&引用;“连接部件”;在Numpy数组中,python,arrays,numpy,scipy,image-segmentation,Python,Arrays,Numpy,Scipy,Image Segmentation,考虑以下存储为numpy数组的图像: a = [[0,0,0,0,0,1,1,0,0,0], [0,0,0,0,1,1,1,1,0,0], [0,0,0,0,0,1,1,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,2,0,0,0,0], [0,0,0,0,0,2,2,0,0,0], [0,0,0,0,0,2,0,0,0,0], [0,0,0,0,3,3,3,0,0,0], [4

考虑以下存储为numpy数组的图像:

a = [[0,0,0,0,0,1,1,0,0,0],
     [0,0,0,0,1,1,1,1,0,0],
     [0,0,0,0,0,1,1,0,0,0],
     [0,0,0,0,0,0,0,0,0,0],
     [0,0,0,0,0,2,0,0,0,0],
     [0,0,0,0,0,2,2,0,0,0],
     [0,0,0,0,0,2,0,0,0,0],
     [0,0,0,0,3,3,3,0,0,0],
     [4,0,0,0,0,0,0,0,0,0],
     [4,4,0,0,0,0,0,0,0,0],
     [4,4,4,0,0,0,0,0,0,0]]

a = np.array(a)
零表示背景像素,1、2、3和4表示属于对象的像素。您可以看到,对象总是在图像中形成连续的岛或区域。我想知道每对物体之间的距离。作为距离度量,我希望在物体的像素之间,有一个最短的、最接近的直线距离。示例:
距离(2,3)=1,因为它们相互接触<代码>距离(1,2)=2,因为正好有一个背景像素将两个区域分开,或者换句话说,对象最近的像素相隔两个像素


有人能告诉我如何用Python解决这个问题吗?或者将我链接到一些资源?

这是您需要的:

from scipy.spatial.distance import cdist
def Distance(a, m, n):
  return cdist(np.argwhere(a==m),np.argwhere(a==n),'minkowski',p=1.).min()
或者类似地按照@MaxPowers注释(声明:
cityblock
更快):

找到岛屿的位置,计算位置的成对距离,得到最小值。我不能100%确定您想要的距离,但我认为您正在寻找
l1
norm。如果没有,您可以将
cdist
度量值更改为所需的度量值

输出:

Distance(a,2,3)
1.0
Distance(a,2,1)
2.0
Distance(a,3,1)
5.0
Distance(a,4,3)
5.0

对于许多BLOB或更大的BLOB,或者如果性能/内存效率是一个标准,您可能需要处理这些孤岛的轮廓。考虑到这一点,我们将使用获得轮廓,然后执行两两距离计算,并获得
min
1作为最终输出。实现看起来像这样,可以获得所有可能的成对距离-

from scipy.spatial.distance import cdist
import cv2

ids = np.arange(1, a.max()+1) #np.unique(a)[1:] if not in ranged sequence

idxs = []
for id_ in ids:
    im = (a == id_).astype(np.uint8)
    contours,_ = cv2.findContours(im, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    idx = contours[0][:, 0]
    idxs.append(idx)

# Get pairwise indices and then distances
r,c = np.triu_indices(len(ids), 1)
pdists = {(ids[i],ids[j]):cdist(idxs[i], idxs[j]).min() for (i, j) in zip(r, c)}
给定样本的输出dict-

In [225]: pdists
Out[225]: 
{(1, 2): 2.0,
 (1, 3): 5.0,
 (1, 4): 7.810249675906654,
 (2, 3): 1.0,
 (2, 4): 5.0,
 (3, 4): 3.605551275463989}
默认情况下,使用欧几里德距离作为度量。根据您对岛屿间直线的定义,您可能希望尝试其他度量,即
闵可夫斯基距离和
曼哈顿距离的
闵可夫斯基距离和
城市街区距离


因此,
cdist(idxs[i],idxs[j])
将更改为
cdist(idxs[i],idxs[j],metric=…)
,这是否回答了您的问题?不,不幸的是没有。您发布的链接处理的是1D案例,并且是一个完全不同的问题。我认为您的问题的解决方案基本相同。我会开始尝试调整里面的东西,看看你是否被困在什么地方。我想如果这些岛屿已经被“标记”了,下面的方法应该可以很好地工作。如果不需要,connectec组件会更多labeled@r0f13号岛和4号岛之间的直线是多少?我不确定这种情况下的距离定义是否清晰。请详细说明。谢谢。这回答了问题。您可以直接使用
metric='cityblock'
,速度更快,而且不需要
p
参数。@MaxPowers谢谢。不知道它有自己的度量标准。你能详细说明一下为什么那台性能更快吗?它们不应该几乎相似吗?L1范数计算为向量元素差值之和
Minkowski
使用
np.norm
计算为广义Lp范数。因此,阶梯取每个向量元素的幂,并计算其总差的根。@MaxPowers。非常感谢。我原以为它在
p=1
FYI的情况下会更智能,@Ehsan:per
minkowski
p=1
p=2
的情况下会更智能。这将在1.16.0版中提供。
In [225]: pdists
Out[225]: 
{(1, 2): 2.0,
 (1, 3): 5.0,
 (1, 4): 7.810249675906654,
 (2, 3): 1.0,
 (2, 4): 5.0,
 (3, 4): 3.605551275463989}