我有一个3d numpy数组,x,y和深度作为维度。这是一个包含各种对象标签的二进制数组。这些标签目前不是唯一的(所有对象的标签都是1),但它们表示的对象彼此之间是唯一的。我用二进制数组提取了每个物体的轮廓。我的目标是为每个等高线区域指定唯一的值。
对于一个简单的2d示例,我将创建一个具有横向不连续轮廓的numpy数组,类似于真实的数据:
countour_array = np.array([[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],
[1,1,1,1,1,1,1,1,1,1,1,1,1],
[0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,0,0,0,0,0,0,0,0],
[0,0,0,0,0,1,0,0,0,0,0,0,0],
[0,0,0,0,1,0,0,0,0,0,0,0,0],
[1,1,1,1,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,1,1,1,1],
[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]])
字符串
以及contour_array
的matplotlib图,以便于查看:
的数据
这就是预期的输出:
mask_array = np.array([[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],
[1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1],
[2,2,2,2,2,1,1,1,1,1,1,1,1],
[2,2,2,2,2,2,1,1,1,1,1,1,1],
[2,2,2,2,2,1,1,1,1,1,1,1,1],
[2,2,2,2,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1],
[3,3,3,3,3,3,3,3,3,3,3,3,3],
[3,3,3,3,3,3,3,3,3,3,3,3,3],
[3,3,3,3,3,3,3,3,3,3,3,3,3]])
型
以及mask_array
的matplotlib图,以便于查看:
的
您可以看到有4个需要标记的唯一对象。标签#2嵌入在标签#1内并且在x方向上横向不连续。标签#1在到达标签#3时也停止。
**编辑:**边界值需要与下面的填充值相同。参见掩模阵列图像。
上面的
是一个2d二进制数组,显示了从实际数据集中提取的轮廓i。正如你所看到的,这些轮廓在x空间中并不总是连续的。
我所尝试的
我的第一次尝试是迭代数据中的每一列,应用.cumsum()
生成唯一值,然后使用push()
向前填充每一列的数据。代码如下:
# create an empty array for the labels
mask_array = np.zeros_like(contour_array)
# determine shape of data for iteration
xx, yy, d = contour_array.shape
# loop through 3d array
for x in range(xx):
for y in range(yy):
# apply cumsum() to assign unique values to each object
mask_array[x,y,:] = contour_array[x,y,:].cumsum()*contour_array[x,y,:]
# replace zeros with nulls for for forward fill
mask_array[x,y,:] = np.where(mask_array[x,y,:] == 0, np.nan, mask_array[x,y,:])
# apply push to each column to create labels
mask_array[x,y,:] = push(mask_array[x,y,:])
# fill remaining nulls with 0
mask_array[np.isnan(mask_array)] = 0.0
型
虽然我的代码可能很慢,但如果对象或层在x空间中是连续的,这将工作,但因为它们是不连续的,所以输出是不连续的,并且错过了嵌入对象和连续层之间的变化。
- 我的第二次尝试 * 是使用上面的代码应用numpy
sliding_window_view()
移动窗口来尝试捕获横向变化。我真的不能得到这个操作和代码是不好的。 - 最后 *,我一直在研究使用
cv2.fillPoly()
,但不确定这是正确的道路。
1条答案
按热度按时间b4wnujal1#
可以使用简单的整体填充来标记每个对象的主体,然后清理边界值。
个字符