在每个点的numpy矩阵中获取已知边界内的所有坐标点

半径

给定以下numpy矩阵

import numpy as np

np_matrix = np.array(
[[0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0,2,0,0,1,0,0,0,0,0,0]
,[0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0,2,2,0,0,0,0,0,0,0,0]
,[0,0,0,3,0,0,0,0,2,2,2,0,0,0,0,0,3,0,0,0,3,0,0,2,2,2,2,2,2,2,2,2]
,[0,0,0,3,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0]
,[0,0,0,3,0,0,2,0,1,0,0,0,2,0,0,0,3,0,0,0,0,3,3,3,3,3,0,0,0,0,0,0]
,[0,0,0,3,0,0,2,0,0,0,0,0,2,0,0,0,3,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3]
,[0,0,0,3,0,0,2,0,0,0,0,0,2,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
,[0,0,0,0,3,0,0,2,0,0,0,2,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
,[0,0,0,0,3,0,0,0,2,2,2,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
,[0,0,0,0,0,3,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
,[0,0,0,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
,[3,3,3,3,0,0,0,3,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
,[0,0,0,3,0,0,0,0,3,3,3,3,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0]
,[0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,3,3,3,3,0,0,0,0,0,0,0,0]
,[0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0]
,[0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3,0,0,2,2,2,0,0,3,0,0,0,0,0,0,0,0]
,[2,2,2,0,0,3,0,0,0,0,0,0,0,0,0,3,0,0,2,1,2,0,0,3,0,0,0,0,0,0,0,0]
,[0,0,2,2,0,3,3,0,0,0,0,0,0,0,0,3,3,0,2,2,2,0,0,3,0,0,0,0,0,0,0,0]
,[0,0,0,2,0,0,3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0]
,[1,0,0,2,0,0,3,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,3,0,0,0,0,0,0,0,0,0]
,[0,0,0,2,0,0,3,0,0,0,0,0,0,0,0,0,0,3,3,0,3,3,0,0,0,0,0,0,0,0,0,0]
,[0,0,0,2,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,0]
,[0,0,2,2,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
,[2,2,2,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
,[0,0,0,0,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3]
,[0,0,0,0,0,3,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,3,0,0,0,0,0,0,0]
,[0,0,0,3,3,0,0,0,0,3,3,3,3,2,2,2,2,2,2,3,3,0,0,0,3,0,0,0,0,0,2,2]
,[3,3,3,3,0,0,0,0,0,3,2,2,2,0,0,0,0,0,2,2,3,0,0,0,3,0,0,0,2,2,2,0]
,[0,0,0,0,0,0,0,0,0,3,2,0,0,0,0,0,0,0,0,2,3,0,0,0,3,0,0,2,2,0,0,0]
,[0,0,0,0,0,0,0,0,0,3,2,0,0,0,1,0,0,0,0,2,3,0,0,0,3,0,0,2,0,0,0,1]]
)

可以在这样的图片中直观地呈现出来: 在此处输入图片说明

红点从左到右编号,可以使用以下功能在矩阵中进行标识。感谢@DanielF在这个答案

def getRedDotsCoordinatesFromLeftToRight(np_matrix, red_dor_number=1):
    red_dots = np.where(np_matrix == red_dor_number)
    red_dots = tuple(g[np.argsort(red_dots[-1])] for g in red_dots)
    red_dots = np.stack(red_dots)[::-1].T
    return red_dots

red_dots = getRedDotsCoordinatesFromLeftToRight(np_matrix)
print(red_dots)

red_dots = np.array(
    [[ 0, 25],
    [ 4,  8],
    [16, 19],
    [19,  0],
    [29, 14],
    [29, 31]]
)    

两个问题:

  • 问题1:我们怎样才能识别所有的白点坐标(标记0的绿色范围内(标记2分别位于与红点(标有1
  • 问题2:我们怎样才能识别所有的白点坐标(标记0黑色边界之间(标记3和绿色边界(标记2分别位于与红点(标有1

我正在为此示例矩阵寻找此结果:

space_within_greenDots = np.array(
    [[[17,  0], [17,  1], [18,  0], [18,  1], [18,  2], [19,  1], [19,  2], [20,  0], [20,  1], [20,  2], [21,  0], [21,  1], [21,  2], [22,  0], [22,  1]],
    [[ 3,  8], [ 3,  9], [ 3, 10], [ 4,  7], [ 4,  9], [ 4, 10], [ 4, 11], [ 5,  7], [ 5,  8], [ 5,  9], [ 5, 10], [ 5, 11], [ 6,  7], [ 6,  8], [ 6,  9], [ 6, 10], [ 6, 11], [ 7,  8], [ 7,  9], [ 7, 10]],
    [[27, 13], [27, 14], [27, 15], [27, 16], [27, 17], [28, 11], [28, 12], [28, 13], [28, 14], [28, 15], [28, 16], [28, 17], [28, 18], [29, 11], [29, 12], [29, 13], [29, 15], [29, 16], [29, 17], [29, 18]],
    [],
    [[ 0, 23], [ 0, 24], [ 0, 26], [ 0, 27], [ 0, 28], [ 0, 29], [ 0, 30], [ 0, 31], [ 1, 24], [ 1, 25], [ 1, 26], [ 1, 27], [ 1, 28], [ 1, 29], [ 1, 30], [ 1, 31]],
    [[27, 31], [28, 29], [28, 30], [28, 31], [29, 28], [29, 29], [29, 30]]],
)    


space_between_darkDots_and_greenDots = np.array(
    [ [[12,  0], [12,  1], [12,  2], [13,  0], [13,  1], [13,  2], [13,  3], [14,  0], [14,  1], [14,  2], [14,  3], [15,  0], [15,  1], [15,  2], [15,  3], [15,  4], [16,  3], [16,  4], [17,  4], [18,  4], [18,  5], [19,  4], [19,  5], [20,  4], [20,  5], [21,  4], [21,  5], [22,  4], [22,  5], [23,  3], [23,  4], [23,  5], [24,  0], [24,  1], [24,  2], [24,  3], [24,  4], [25,  0], [25,  1], [25,  2], [25,  3], [25,  4], [26,  0], [26,  1], [26,  2]],
    [[ 0,  4], [ 0,  5], [ 0,  6], [ 0,  7], [ 0,  8], [ 0,  9], [ 0, 10], [ 0, 11], [ 0, 12], [ 0, 13], [ 0, 14], [ 0, 15], [ 1,  4], [ 1,  5], [ 1,  6], [ 1,  7], [ 1,  8], [ 1,  9], [ 1, 10], [ 1, 11], [ 1, 12], [ 1, 13], [ 1, 14], [ 1, 15], [ 2,  4], [ 2,  5], [ 2,  6], [ 2,  7], [ 2, 11], [ 2, 12], [ 2, 13], [ 2, 14], [ 2, 15], [ 3,  4], [ 3,  5], [ 3,  6], [ 3, 12], [ 3, 13], [ 3, 14], [ 3, 15], [ 4,  4], [ 4,  5], [ 4, 13], [ 4, 14], [ 4, 15], [ 5,  4], [ 5,  5], [ 5, 13], [ 5, 14], [ 5, 15], [ 6,  4], [ 6,  5], [ 6, 13], [ 6, 14], [ 6, 15], [ 7,  5], [ 7,  6], [ 7, 12], [ 7, 13], [ 7, 14], [ 8,  5], [ 8,  6], [ 8,  7], [ 8, 11], [ 8, 12], [ 8, 13], [ 8, 14], [ 9,  6], [ 9,  7], [ 9,  8], [ 9,  9], [ 9, 10], [ 9, 11], [ 9, 12], [ 9, 13], [10,  7], [10,  8], [10,  9], [10, 10], [10, 11], [10, 12], [11,  8], [11,  9], [11, 10], [11, 11]],
    [],
    [[13, 18], [13, 19], [14, 16], [14, 17], [14, 18], [14, 19], [14, 20], [14, 21], [14, 22], [15, 16], [15, 17], [15, 21], [15, 22], [16, 16], [16, 17], [16, 21], [16, 22], [17, 17], [17, 21], [17, 22], [18, 17], [18, 18], [18, 19], [18, 20], [18, 21], [18, 22], [19, 18], [19, 19], [19, 20], [19, 21], [20, 19]],
    [[ 0, 21], [ 1, 21], [ 2, 21], [ 2, 22], [ 3, 22], [ 3, 23], [ 3, 24], [ 3, 25], [ 3, 26], [ 3, 27], [ 3, 28], [ 3, 29], [ 3, 30], [ 3, 31], [ 4, 26], [ 4, 27], [ 4, 28], [ 4, 29], [ 4, 30], [ 4, 31]],
    [[25, 25], [25, 26], [25, 27], [25, 28], [25, 29], [25, 30], [25, 31], [26, 25], [26, 26], [26, 27], [26, 28], [26, 29], [27, 25], [27, 26], [27, 27], [28, 25], [28, 26], [29, 25], [29, 26]],
    ]
)

一些假设:

  • 矩阵形状可以变化。它不是固定大小。
  • 红点的数量因矩阵而异。但是矩阵中始终至少有一个红点。
乔·伊登

问题1使用递归泛洪算法的解决方案:

请参阅我制作的JavaScript演示中的Floodfill算法GitHub来源

我首先创建了一个泛洪功能,其功能与绘制程序一样,即在封闭区域中给定点时,将用一种颜色填充该区域直至边界。

然后,所有需要做的就是遍历每个红色像素(值1),并2用我们所处索引红点的颜色泛洪至绿色像素(值)(以便以后可以分别获得区域)。

然后,我们简单地使用您red_dots修改程序版本,使其更通用一些,以获取所有白色像素坐标的结果。

最后一步是单线完成的。它将所有内容转换为一个大列表,其中每个子列表都包含白色像素区域的坐标。

请注意,我们必须以列表结尾,因为它不是矩形,因此不能使用numpy数组(除非使用dtype=object)。

无论如何,这是代码:

import numpy as np

def inArrBounds(arr, c):
    return 0 <= c[0] < arr.shape[1] and 0 <= c[1] < arr.shape[0]

def floodfill(arr, start, fillCol, edgeCol):
    if arr[start[1],start[0]] in (fillCol, edgeCol):
        return
    arr[start[1], start[0]] = fillCol
    for p in ((start[0]+1, start[1]),
              (start[0]-1, start[1]), 
              (start[0], start[1]+1),
              (start[0], start[1]-1)):
        if inArrBounds(arr, p):
            floodfill(arr, p, fillCol, edgeCol)

def coordsLtR(arr, val):
    pnts = np.where(arr == val)
    pnts = tuple(g[np.argsort(pnts[-1])] for g in pnts)
    pnts = np.stack(pnts)[::-1].T
    return pnts

red_dots = coordsLtR(np_matrix, 1)
for i, dot in enumerate(red_dots):
    floodfill(np_matrix, dot, i+4, 2)
    np_matrix[dot[1], dot[0]] = 1

regions = [coordsLtR(np_matrix,i+4)[:,::-1].tolist() for i in range(len(red_dots))]

regions列表创建为:

[[17, 0], [18, 0], [20, 0], [21, 0], [22, 0], [17, 1], [18, 1], [19, 1], [20, 1], [21, 1], [22, 1], [18, 2], [19, 2], [20, 2], [21, 2]]
[[4, 7], [6, 7], [5, 7], [3, 8], [7, 8], [6, 8], [5, 8], [6, 9], [7, 9], [5, 9], [4, 9], [3, 9], [5, 10], [4, 10], [3, 10], [6, 10], [7, 10], [5, 11], [6, 11], [4, 11]]
[[28, 11], [29, 11], [29, 12], [28, 12], [27, 13], [29, 13], [28, 13], [27, 14], [28, 14], [29, 15], [28, 15], [27, 15], [27, 16], [29, 16], [28, 16], [28, 17], [29, 17], [27, 17], [28, 18], [29, 18]]
[]
[[0, 23], [0, 24], [1, 24], [1, 25], [0, 26], [1, 26], [0, 27], [1, 27], [0, 28], [1, 28], [0, 29], [1, 29], [0, 30], [1, 30], [0, 31], [1, 31]]
[[29, 28], [28, 29], [29, 29], [28, 30], [29, 30], [27, 31], [28, 31]]

为了直观地看到填充区域的np_matrix外观,下面是matplotlib图的屏幕截图:

洪水填埋


问题2解决方案

第二部分的逻辑保持不变,只是我们必须以正确的顺序进行操作。我要做的方法是用一种颜色填充到黑色边框,然后从中减去白色区域和绿色边框。

因此,我们需要单独工作,np_matrix以免干扰第一个。可以使用复制np.copy

然后,我们需要从红点填充到黑色边框,然后从填充区域中减去所有在白色区域或绿色中的坐标。

因此,使用上面的相同功能,代码如下:

def validBlackCoord(c):
    return not (any(c in s for s in white_regions) or np_matrix[c[0],c[1]] == 2)

red_dots = coordsLtR(np_matrix, 1)
white_matrix = np.copy(np_matrix)
for i, dot in enumerate(red_dots):
    floodfill(white_matrix, dot, i+4, 2)
    white_matrix[dot[1], dot[0]] = 1

white_regions = [coordsLtR(white_matrix,i+4)[:,::-1].tolist() for i in range(len(red_dots))]

black_matrix = np.copy(np_matrix)
for i, dot in enumerate(red_dots):
    floodfill(black_matrix, dot, i+4, 3)
    black_matrix[dot[1], dot[0]] = 1

black_regions = [coordsLtR(black_matrix,i+4)[:,::-1].tolist() for i in range(len(red_dots))]

black_regions = [list(filter(key=validBlackCoord, r)) for r in black_regions]

创建两个列表,white_regions与上面的相同,black_regions为:

[[12, 0], [24, 0], [15, 0], [25, 0], [14, 0], [13, 0], [26, 0], [24, 1], [15, 1], [14, 1], [25, 1], [13, 1], [12, 1], [26, 1], [24, 2], [25, 2], [26, 2], [12, 2], [15, 2], [13, 2], [14, 2], [24, 3], [14, 3], [15, 3], [23, 3], [16, 3], [13, 3], [25, 3], [22, 4], [19, 4], [21, 4], [15, 4], [17, 4], [23, 4], [25, 4], [20, 4], [18, 4], [24, 4], [16, 4], [22, 5], [21, 5], [20, 5], [18, 5], [23, 5], [19, 5]]
[[0, 4], [6, 4], [5, 4], [4, 4], [3, 4], [2, 4], [1, 4], [8, 5], [7, 5], [6, 5], [4, 5], [3, 5], [2, 5], [5, 5], [1, 5], [0, 5], [1, 6], [3, 6], [9, 6], [0, 6], [7, 6], [8, 6], [2, 6], [8, 7], [9, 7], [2, 7], [10, 7], [0, 7], [1, 7], [0, 8], [1, 8], [9, 8], [11, 8], [10, 8], [0, 9], [1, 9], [11, 9], [10, 9], [9, 9], [1, 10], [10, 10], [0, 10], [9, 10], [11, 10], [10, 11], [9, 11], [8, 11], [11, 11], [1, 11], [2, 11], [0, 11], [0, 12], [1, 12], [10, 12], [9, 12], [2, 12], [8, 12], [3, 12], [7, 12], [2, 13], [6, 13], [3, 13], [4, 13], [1, 13], [8, 13], [0, 13], [9, 13], [7, 13], [5, 13], [6, 14], [1, 14], [0, 14], [7, 14], [2, 14], [8, 14], [4, 14], [3, 14], [5, 14], [6, 15], [2, 15], [0, 15], [1, 15], [5, 15], [3, 15], [4, 15]]
[]
[[14, 16], [15, 16], [16, 16], [18, 17], [17, 17], [15, 17], [16, 17], [14, 17], [18, 18], [19, 18], [14, 18], [13, 18], [19, 19], [18, 19], [20, 19], [13, 19], [14, 19], [19, 20], [18, 20], [14, 20], [18, 21], [19, 21], [17, 21], [15, 21], [16, 21], [14, 21], [15, 22], [17, 22], [18, 22], [16, 22], [14, 22]]
[[0, 21], [2, 21], [1, 21], [3, 22], [2, 22], [3, 23], [3, 24], [3, 25], [3, 26], [4, 26], [4, 27], [3, 27], [4, 28], [3, 28], [3, 29], [4, 29], [3, 30], [4, 30], [3, 31], [4, 31]]
[[25, 25], [29, 25], [26, 25], [28, 25], [27, 25], [25, 26], [29, 26], [28, 26], [26, 26], [27, 26], [27, 27], [25, 27], [26, 27], [26, 28], [25, 28], [26, 29], [25, 29], [25, 30], [25, 31]]

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

角度Google Maps获取地图边界内的所有位置

从MySQL中东北和西南坐标的边界框内的数据库中获取所有点

如何在iOS中获取所有坐标点(X和Y)

在指定距离/边界内获取点标签-Python

计算以已知整数坐标的点为边界的区域的面积

如何在处理中返回矩形边界内的任何点?

使用QuadTree获取边界圆内的所有点

在three.js中获取鼠标点击点的3D坐标

检查位置的坐标是否在边界内

如何获取距 postGIS 中某个点一定距离处的边界框坐标?

用 Octave 中的圆形图案点生成坐标点

如何在numpy中获取给定大小的所有子矩阵?

在圆中获取点的坐标

在 R 中给定边界内使用 sf 的点的平滑密度图

获取矩阵的点积和给定数组中每个点的最快方法

边界框中的numpy过滤点

展开坐标列表以获取R组中的所有组合

Javascript-检查经纬度坐标是否在边界内

C#获取2点错误之间的所有像素坐标

获取字符串c#中字符边界内的特定字符

从英文文本中获取所有单词和标点符号

numpy查找矩阵行中数字对的所有组合的乘积

如何使用OpenCV或numpy在直线上打印每个点的坐标?

查找从矩阵中的一个点到矩阵中所有其他点的距离

获取具有指定边界坐标的地图

在 postgis 中返回边界框 100 英里内的所有点

试图删除每个单词的标点符号列表 - 最终删除所有标点符号

如何使用R中的Spatstat获取平面点模式(ppp)数据中每个点的边界框面积?

在二维numpy矩阵中找到特定点距离1内的所有点