Sce*_*esK 5 python opencv numpy
我有一个图像和一个面具.两者都是numpy数组.我通过GraphSegmentation(cv2.ximgproc.segmentation)获取掩码,因此该区域不是矩形,而是不分割.我想得到一个与蒙面区域大小相同的矩形,但我不知道有效的方法.
换句话说,未屏蔽的像素值为0,屏蔽像素的值大于0,所以我想得到一个矩形...
我的代码如下
segmentation = cv2.ximgproc.segmentation.createGraphSegmentation()
src = cv2.imread('image_file')
segment = segmentation.processImage(src)
for i in range(np.max(segment)):
dst = np.array(src)
dst[segment != i] = 0
cv2.imwrite('output_file', dst)
Run Code Online (Sandbox Code Playgroud)
如果你更喜欢纯 Numpy,你可以使用np.where
and来实现np.meshgrid
:
i, j = np.where(mask)
indices = np.meshgrid(np.arange(min(i), max(i) + 1),
np.arange(min(j), max(j) + 1),
indexing='ij')
sub_image = image[indices]
Run Code Online (Sandbox Code Playgroud)
np.where
返回一个数组元组,成对指定每个轴中每个非零元素的索引mask
。然后我们创建我们想要使用的所有行和列索引的数组np.arange
,并使用它np.meshgrid
来生成两个网格形状的数组,这些数组索引我们感兴趣的图像部分。请注意,我们指定矩阵样式索引使用index='ij'
以避免转置结果(默认为笛卡尔式索引)。
本质上,meshgrid
构造indices
使得:
image[indices][a, b] == image[indices[0][a, b], indices[1][a, b]]
Run Code Online (Sandbox Code Playgroud)
从以下开始:
>>> image = np.arange(12).reshape((4, 3))
>>> image
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
Run Code Online (Sandbox Code Playgroud)
假设我们要提取[[3,4],[6,7]]
子矩阵,它是以下掩码的边界矩形:
>>> mask = np.array([[0,0,0],[0,1,0],[1,0,0],[0,0,0]])
>>> mask
array([[0, 0, 0],
[0, 1, 0],
[1, 0, 0],
[0, 0, 0]])
Run Code Online (Sandbox Code Playgroud)
然后,应用上述方法:
>>> i, j = np.where(mask)
>>> indices = np.meshgrid(np.arange(min(i), max(i) + 1), np.arange(min(j), max(j) + 1), indexing='ij')
>>> image[indices]
array([[3, 4],
[6, 7]])
Run Code Online (Sandbox Code Playgroud)
这里,indices[0]
是一个行索引矩阵,而indices[1]
是相应的列索引矩阵:
>>> indices[0]
array([[1, 1],
[2, 2]])
>>> indices[1]
array([[0, 1],
[0, 1]])
Run Code Online (Sandbox Code Playgroud)
我认为使用np.amax
和np.amin
裁剪图像要快得多。
i, j = np.where(mask)
indices = np.meshgrid(np.arange(min(i), max(i) + 1),
np.arange(min(j), max(j) + 1),
indexing='ij')
sub_image = image[indices]
Run Code Online (Sandbox Code Playgroud)
耗时:50 毫秒
where = np.array(np.where(mask))
x1, y1 = np.amin(where, axis=1)
x2, y2 = np.amax(where, axis=1)
sub_image = image[x1:x2, y1:y2]
Run Code Online (Sandbox Code Playgroud)
耗时:5.6 毫秒
运行这两种方法(使用 NumPy 1.18.5)时,我没有得到 Hans 的结果。无论如何,有一种更有效的方法,您可以沿每个维度获取 arg-max
i, j = np.where(mask)
y, x = np.meshgrid(
np.arange(min(i), max(i) + 1),
np.arange(min(j), max(j) + 1),
indexing="ij",
)
Run Code Online (Sandbox Code Playgroud)
花了 38 毫秒
where = np.array(np.where(mask))
y1, x1 = np.amin(where, axis=1)
y2, x2 = np.amax(where, axis=1) + 1
sub_image = image[y1:y2, x1:x2]
Run Code Online (Sandbox Code Playgroud)
花了 35 毫秒
maskx = np.any(mask, axis=0)
masky = np.any(mask, axis=1)
x1 = np.argmax(maskx)
y1 = np.argmax(masky)
x2 = len(maskx) - np.argmax(maskx[::-1])
y2 = len(masky) - np.argmax(masky[::-1])
sub_image = image[y1:y2, x1:x2]
Run Code Online (Sandbox Code Playgroud)
花了 2 毫秒
归档时间: |
|
查看次数: |
4355 次 |
最近记录: |