有没有一种方法可以检测和删除图像数组中的零填充?在某种程度上,我的问题与this非常相似,除了图像已经旋转,我不知道Angular 。
我基本上是从一个较大的图像中裁剪出一个盒子,它的边缘可能没有填充(由于平移或旋转)。现在,作物可能包含一些这种填充物。但是,在这种情况下,我想在填充边缘开始的地方剪裁长方体。图像在CHW中(可以很容易地更改为HWC)。
在这种情况下,所有通道中的填充都为0。然而,由于旋转,有时可能0并不总是在数组中完全水平或垂直的条带中。有没有一种方法来检测是否有0一直到数组中的边缘,以及边缘从哪里开始?
示例1,其中arr
是具有3个通道的图像,宽度和高度为4(3,4,4),并且裁剪在最右边缘包含垂直填充:
array([[[1., 1., 1., 0.],
[1., 1., 1., 0.],
[1., 1., 1., 0.],
[1., 1., 1., 0.]],
[[1., 1., 1., 0.],
[1., 1., 1., 0.],
[1., 1., 1., 0.],
[1., 1., 1., 0.]],
[[1., 1., 1., 0.],
[1., 1., 1., 0.],
[1., 1., 1., 0.],
[1., 1., 1., 0.]]])
在这个例子中,我会像这样对数组进行切片,以去除零填充:arr[:, :, :-1]
示例2,我们在右上角有一些填充:
array([[[1., 1., 0., 0.],
[1., 1., 1., 0.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]],
[[1., 1., 0., 0.],
[1., 1., 1., 0.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]],
[[1., 1., 0., 0.],
[1., 1., 1., 0.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]]])
在这个例子中,我将通过返回arr2[:, 1:, :-1]
来裁剪图像以去除任何填充。
我想在Tensorflow中做这件事,所以Tensor运算会很棒,但我正在试图找出任何算法,例如使用numpy,可以实现这个结果。
3条答案
按热度按时间pokxtpni1#
如果你不介意扔掉一些图像,并且只要它不包含填充,你就可以接受自由裁剪,你可以得到一个非常有效的解决方案:
如果它必须是最大的可能作物,那么需要更多的工作。本质上,我们必须检查每个相邻的子图像,如果它包含填充,然后比较它们的大小。
主旨:假设无填充子图像的左上角位于
(x1,y1)
,右下角位于(x2, y2)
,那么我们可以将子阵列中的像素数量理解为维度为[y1, x1, y2, x2]
的秩4Tensor。如果组合不是有效的子图像,即如果它具有负的宽度或高度,或者它包含填充像素,则我们将像素数设置为0。现在
rectangles
包含子图像的所有角点,这些角点具有最大数量的像素,而不包含任何边界像素。它已经相当矢量化了,所以你应该能够将它从numpy迁移到tensorflow。rekjcdws2#
请尝试此解决方案:
11dmarpk3#
我的解决方案采用了不同的方法,假设填充部分是黑色或白色:
1.浏览图像中的每一行和每一列,看看平均值是
0
还是255
。1.如果正好是任一数字,则从图像中完全删除该行或列。
1.这样做是为了整个画面
我使用Google Colab,所以可能有点不同:
这就是before和after的样子。