从 label_image 获取图像中对象的边缘
getting the edges of objects in an image from a label_image
我有一个 label_image
它实际上是一个数组,它将图像的每个像素分配给现实生活中的对象。因此,例如,如果 label_image
看起来像
0,0,0,0,0,0,0,0
0,1,1,1,0,0,0,0
0,1,1,1,0,0,0,0
0,1,1,1,0,2,0,0
0,0,0,0,2,2,2,0
0,0,0,0,0,2,0,0
0,0,0,0,0,0,0,0
那么可以理解为我的图片显示了两个物体,一个是方形的(靠近左上角,标记为第一个物体),另一个是菱形的(靠近右下角,标记为作为第二个对象)
零表示背景。
请问如何从 label_image
中获取对象的 edges/boundaries/outlines?在这个过度简化的示例中,我想以:
0,0,0,0,0,0,0,0
0,1,1,1,0,0,0,0
0,1,0,1,0,0,0,0
0,1,1,1,0,2,0,0
0,0,0,0,2,0,2,0
0,0,0,0,0,2,0,0
0,0,0,0,0,0,0,0
我正在使用 Python 3
如果将您的图像视为字符串矩阵可能是个好主意(每个标签都是一个字符串,即使它看起来像一个整数),这样您就可以从 count
内置方法中获益字符串:
mat = """
0,0,0,0,0,0,0,0
0,1,1,1,0,0,0,0
0,1,1,1,0,0,0,0
0,1,1,1,0,2,0,0
0,0,0,0,2,2,2,0
0,0,0,0,0,2,0,0
0,0,0,0,0,0,0,0
"""
# convert multi-line string into a matrix of string labels ('0','1' or '2')
mat = [line.split(',') for line in mat.strip().split('\n')]
# get matrix dimensions
rows, cols = len(mat), len(mat[0])
indices = []
for row in range(1, rows-1):
for col in range(1, cols-1):
# concatenate the labels of the 4 neighbors (N,S,W,E) for the current cell
nb = mat[row-1][col] + mat[row+1][col] + mat[row][col-1] + mat[row][col+1]
# if all neighbors have same label as current cell --> store pixel index
if nb.count(mat[row][col]) == 4:
indices.append((row,col))
for row, col in indices: # loop over all previously found interior pixels
mat[row][col] = '0' # force pixel label to '0'
print(mat)
输出:
[['0', '0', '0', '0', '0', '0', '0', '0'],
['0', '1', '1', '1', '0', '0', '0', '0'],
['0', '1', '0', '1', '0', '0', '0', '0'],
['0', '1', '1', '1', '0', '2', '0', '0'],
['0', '0', '0', '0', '2', '0', '2', '0'],
['0', '0', '0', '0', '0', '2', '0', '0'],
['0', '0', '0', '0', '0', '0', '0', '0']]
注意:如果你想要输入和输出相同的矩阵(如上面代码中所做的),你必须链接两个不同的循环:第一个检测所有内部像素(并将它们的索引存储到列表中),而第二个循环遍历存储的索引并将相应的像素设置为“0”。如果你能负担得起第二个矩阵来存储输出,整个过程可以在第一个循环中完成。
您可以使用 scipy 的 binary_erosion:
import numpy as np
from scipy import ndimage
eee = np.array([
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 2, 0, 0],
[0, 0, 0, 0, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]])
mask = ndimage.binary_erosion(eee.tolist())
eee[mask]=0
输出:
array([[0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 2, 0, 0],
[0, 0, 0, 0, 2, 0, 2, 0],
[0, 0, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]])
我有一个 label_image
它实际上是一个数组,它将图像的每个像素分配给现实生活中的对象。因此,例如,如果 label_image
看起来像
0,0,0,0,0,0,0,0
0,1,1,1,0,0,0,0
0,1,1,1,0,0,0,0
0,1,1,1,0,2,0,0
0,0,0,0,2,2,2,0
0,0,0,0,0,2,0,0
0,0,0,0,0,0,0,0
那么可以理解为我的图片显示了两个物体,一个是方形的(靠近左上角,标记为第一个物体),另一个是菱形的(靠近右下角,标记为作为第二个对象) 零表示背景。
请问如何从 label_image
中获取对象的 edges/boundaries/outlines?在这个过度简化的示例中,我想以:
0,0,0,0,0,0,0,0
0,1,1,1,0,0,0,0
0,1,0,1,0,0,0,0
0,1,1,1,0,2,0,0
0,0,0,0,2,0,2,0
0,0,0,0,0,2,0,0
0,0,0,0,0,0,0,0
我正在使用 Python 3
如果将您的图像视为字符串矩阵可能是个好主意(每个标签都是一个字符串,即使它看起来像一个整数),这样您就可以从 count
内置方法中获益字符串:
mat = """
0,0,0,0,0,0,0,0
0,1,1,1,0,0,0,0
0,1,1,1,0,0,0,0
0,1,1,1,0,2,0,0
0,0,0,0,2,2,2,0
0,0,0,0,0,2,0,0
0,0,0,0,0,0,0,0
"""
# convert multi-line string into a matrix of string labels ('0','1' or '2')
mat = [line.split(',') for line in mat.strip().split('\n')]
# get matrix dimensions
rows, cols = len(mat), len(mat[0])
indices = []
for row in range(1, rows-1):
for col in range(1, cols-1):
# concatenate the labels of the 4 neighbors (N,S,W,E) for the current cell
nb = mat[row-1][col] + mat[row+1][col] + mat[row][col-1] + mat[row][col+1]
# if all neighbors have same label as current cell --> store pixel index
if nb.count(mat[row][col]) == 4:
indices.append((row,col))
for row, col in indices: # loop over all previously found interior pixels
mat[row][col] = '0' # force pixel label to '0'
print(mat)
输出:
[['0', '0', '0', '0', '0', '0', '0', '0'],
['0', '1', '1', '1', '0', '0', '0', '0'],
['0', '1', '0', '1', '0', '0', '0', '0'],
['0', '1', '1', '1', '0', '2', '0', '0'],
['0', '0', '0', '0', '2', '0', '2', '0'],
['0', '0', '0', '0', '0', '2', '0', '0'],
['0', '0', '0', '0', '0', '0', '0', '0']]
注意:如果你想要输入和输出相同的矩阵(如上面代码中所做的),你必须链接两个不同的循环:第一个检测所有内部像素(并将它们的索引存储到列表中),而第二个循环遍历存储的索引并将相应的像素设置为“0”。如果你能负担得起第二个矩阵来存储输出,整个过程可以在第一个循环中完成。
您可以使用 scipy 的 binary_erosion:
import numpy as np
from scipy import ndimage
eee = np.array([
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 2, 0, 0],
[0, 0, 0, 0, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]])
mask = ndimage.binary_erosion(eee.tolist())
eee[mask]=0
输出:
array([[0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 2, 0, 0],
[0, 0, 0, 0, 2, 0, 2, 0],
[0, 0, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]])