因此,我目前正在尝试找出一个更优化的解决方案来确定图像中的连通分量。目前,我有一个坐标具有特定值的数组。我想根据它们是否接触来创建这些坐标组。我正在使用一个 numpy 数组,目前我必须检查每个值(左上、中上、右上、左中、右中、左下、中下、右下)是否在该数组中。我通过以下代码这样做:
for x in range (0, groupCoords.shape[0]):
global tgroup
xCoord = groupCoords.item((x,0))
yCoord = groupCoords.item((x,1))
new = np.array([[xCoord, yCoord]])
if np.equal(Arr,[xCoord, yCoord+1]).all(1).any():
tgroup = np.append(tgroup, [[xCoord,yCoord+1]], axis=0)
new = np.append(new, [[xCoord,yCoord+1]], axis=0)
index = np.argwhere((Arr == [xCoord,yCoord+1]).all(1))
Arr = np.delete(Arr, (index), axis=0)
if np.equal(Arr,[xCoord, yCoord-1]).all(1).any():
tgroup = np.append(tgroup, [[xCoord, yCoord-1]],axis=0)
new = np.append(new, [[xCoord,yCoord-1]], axis=0)
index = np.argwhere((Arr == [xCoord,yCoord-1]).all(1))
Arr = np.delete(Arr, (index), axis=0)
if np.equal(Arr,[xCoord+1, yCoord]).all(1).any():
tgroup = np.append(tgroup, [[xCoord+1,yCoord]],axis=0)
new = np.append(new, [[xCoord+1,yCoord]], axis=0)
index = np.argwhere((Arr == [xCoord+1,yCoord]).all(1))
Arr = np.delete(Arr, (index), axis=0)
if np.equal(Arr,[xCoord+1, yCoord+1]).all(1).any():
tgroup = np.append(tgroup, [[xCoord+1,yCoord+1]],axis=0)
new = np.append(new, [[xCoord+1,yCoord+1]], axis=0)
index = np.argwhere((Arr == [xCoord+1,yCoord+1]).all(1))
Arr = np.delete(Arr, (index), axis=0)
if np.equal(Arr,[xCoord+1, yCoord-1]).all(1).any():
tgroup = np.append(tgroup, [[xCoord+1,yCoord-1]],axis=0)
new = np.append(new, [[xCoord+1,yCoord-1]], axis=0)
index = np.argwhere((Arr == [xCoord+1,yCoord-1]).all(1))
Arr = np.delete(Arr, (index), axis=0)
if np.equal(Arr,[xCoord-1, yCoord]).all(1).any():
tgroup = np.append(tgroup, [[xCoord-1,yCoord]],axis=0)
new = np.append(new, [[xCoord-1,yCoord]], axis=0)
index = np.argwhere((Arr == [xCoord-1,yCoord]).all(1))
Arr = np.delete(Arr, (index), axis=0)
if np.equal(Arr,[xCoord-1, yCoord+1]).all(1).any():
tgroup = np.append(tgroup, [[xCoord-1,yCoord+1]],axis=0)
new = np.append(new, [[xCoord-1,yCoord+1]], axis=0)
index = np.argwhere((Arr == [xCoord-1,yCoord+1]).all(1))
Arr = np.delete(Arr, (index), axis=0)
if np.equal(Arr,[xCoord-1, yCoord-1]).all(1).any():
tgroup = np.append(tgroup, [[xCoord-1,yCoord-1]],axis=0)
new = np.append(new, [[xCoord-1,yCoord-1]], axis=0)
index = np.argwhere((Arr == [xCoord-1,yCoord-1]).all(1))
Arr = np.delete(Arr, (index), axis=0)
但是,如果图像很大,这显然会花费大量时间。我的想法是创建一个 bool 矩阵,其尺寸为图像的宽度和高度,然后将值“true”分配给矩阵中与图像中的像素相对应的值(图像为黑白)。
我想知道,是否有可能不必像那样检查每个值,而是确定它们是否是标记为“true”的元素直接围绕另一个“true”值?
这是输入数组的样子:
[
[0 0]
[0 1]
[0 2]
[10 2]
]
输出看起来像
[
[0 0]
[0 1]
[0 2]
]
我希望改进的函数将检查“真实”值是否相交,并创建所有相交值的“网络”(它将继续运行找到的新值)。
最佳答案
方法 #1
我们可以获得欧氏距离并查看是否有任何距离在 sqrt(2)
范围内,这将覆盖 up-down
且 distance = 1
和 distance = sqrt(2)
的对角线。这将为我们提供一个掩码,当它被索引到组坐标数组中时,将为我们提供与之相连的掩码。
因此,使用 Scipy's cdist
的实现为了获得这些欧氏距离,将是 -
from scipy.spatial.distance import cdist
out = groupCoords[(cdist(groupCoords,Arr)<1.5).any(1)]
sample 运行-
In [401]: Arr
Out[401]:
array([[ 5, 4],
[11, 12],
[ 5, 3],
[ 1, 3],
[15, 8],
[55, 21]])
In [402]: groupCoords
Out[402]:
array([[2, 3], # In neighbourhood of (1,3)
[5, 6],
[6, 2], # In neighbourhood of (5,3)
[5, 3], # In neighbourhood of (5,4)
[5, 8]])
In [403]: groupCoords[(cdist(groupCoords,Arr)<1.5).any(1)]
Out[403]:
array([[2, 3],
[6, 2],
[5, 3]])
方法 #2
另一种方法是检查两个数组的第一列之间的绝对元素差异,第二列也是如此。最后,从这两个掩码中获取联合掩码并检查任何匹配项并再次索引到组数组中以获取过滤后的坐标。
因此,这种方法的实现将是 -
col0_mask = (np.abs(groupCoords[:,0,None] - Arr[:,0])<=1)
col1_mask = (np.abs(groupCoords[:,1,None] - Arr[:,1])<=1)
out = groupCoords[(col0_mask & col1_mask).any(1)]
方法 #3
另一种方法可能会更好,如果您将 Arr
作为 bool 数组而不是 2 列坐标数组。思路是dilate this boolean array
Arr
的坐标,然后查看 groupCoords
中的哪些坐标也位于此膨胀图像中。对于扩张,我们将使用一个 3 x 3
核来覆盖所有这些邻域。为了检测这些共同点,我们需要用这些 groupCoords
绘制图像。
因此,代码将是 -
from scipy.ndimage.morphology import binary_dilation
img = np.zeros(Arr.shape,dtype=bool)
img[groupCoords[:,0],groupCoords[:,1]] = 1
out = np.argwhere(binary_dilation(Arr,np.ones((3,3))) & img)
sample 运行-
In [444]: # Inputs : groupCoords and let's create a sample array for Arr
...: groupCoords = np.array([[2,3],[5,6],[6,2],[5,3],[5,8]])
...:
...: Arr_Coords = np.array([[5,4],[11,12],[5,3],[1,3],[15,8],[55,21]])
...: Arr = np.zeros(Arr_Coords.max(0)+1,dtype=bool)
...: Arr[Arr_Coords[:,0], Arr_Coords[:,1]] = 1
...:
In [445]: img = np.zeros(Arr.shape,dtype=bool)
...: img[groupCoords[:,0],groupCoords[:,1]] = 1
...: out = np.argwhere(binary_dilation(Arr,np.ones((3,3))) & img)
...:
In [446]: out
Out[446]:
array([[2, 3],
[5, 3],
[6, 2]])
关于python - 检查相邻值是否在 Numpy 矩阵中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41418717/