Numpy:对导致"operands could not be broadcast together with shapes (4,4,3) (4,4,5)"错误的 RGB 图像使用 np.pad()



我有一个函数color_image_padding,它采用RGB图像并添加一层零填充的边界。该图像的维度为(Width, Height, 3),其中3表示3个颜色通道。

我的代码是:
import numpy as np
def color_image_padding(image: np.ndarray) -> np.ndarray:
return np.pad(image, pad_width=1)

我看到这个错误:

"operands could not be broadcast together with shapes (4,4,3) (4,4,5)"

可能是颜色通道导致了这个错误。np.pad没有将图像分成3个矩阵并相应地添加零填充吗?

提前感谢您的协助!

编辑

请看下面的评论…事实证明,广义函数image_padding()抛出了一个错误消息,因为一些灰度图像(即2D Numpy矩阵)被传入。下面是一个简单的例子:

bar = np.ones((1, 3))
bar.ndim
2
def image_padding(image: np.ndarray, amt: int) -> np.ndarray:
return np.pad(image, pad_width=((amt, amt), (amt, amt), (0, 0)))
image_padding(bar, 2)

完整回溯:

ValueError                                Traceback (most recent call last)
~AppDataLocalTemp/ipykernel_8116/4065018867.py in <module>
----> 1 img(bar, 3)
~AppDataLocalTemp/ipykernel_8116/1455868751.py in img(image, amt)
1 def img(image, amt):
----> 2     return np.pad(image, pad_width=((amt, amt), (amt, amt), (0, 0)))
<__array_function__ internals> in pad(*args, **kwargs)
~anaconda3libsite-packagesnumpylibarraypad.py in pad(array, pad_width, mode, **kwargs)
741 
742     # Broadcast to shape (array.ndim, 2)
--> 743     pad_width = _as_pairs(pad_width, array.ndim, as_index=True)
744 
745     if callable(mode):
~anaconda3libsite-packagesnumpylibarraypad.py in _as_pairs(x, ndim, as_index)
516     # Converting the array with `tolist` seems to improve performance
517     # when iterating and indexing the result (see usage in `pad`)
--> 518     return np.broadcast_to(x, (ndim, 2)).tolist()
519 
520 
<__array_function__ internals> in broadcast_to(*args, **kwargs)
~anaconda3libsite-packagesnumpylibstride_tricks.py in broadcast_to(array, shape, subok)
409            [1, 2, 3]])
410     """
--> 411     return _broadcast_to(array, shape, subok=subok, readonly=True)
412 
413 
~anaconda3libsite-packagesnumpylibstride_tricks.py in _broadcast_to(array, shape, subok, readonly)
346                          'negative')
347     extras = []
--> 348     it = np.nditer(
349         (array,), flags=['multi_index', 'refs_ok', 'zerosize_ok'] + extras,
350         op_flags=['readonly'], itershape=shape, order='C')
ValueError: operands could not be broadcast together with remapped shapes [original->remapped]: (3,2)  and requested shape (2,2)

测试图像是灰度还是彩色可以解决这个问题:

def image_padding(image: np.ndarray, amt: int) -> np.ndarray:
if image.ndim == 2:
return np.pad(image, pad_width=(amt, amt))
elif img.ndim == 3:
return np.pad(image, pad_width=((amt, amt), (amt, amt), (0, 0)))

这复制你的错误——使用这三个术语pad_width二维数组:

ok with 3d:

In [194]: x = np.ones((5,5,3),int)
In [196]: amt_padding=1;np.pad(x, pad_width=((amt_padding, amt_padding), (amt_padding, amt_padding), (0, 0))).shape
Out[196]: (7, 7, 3)

但是如果数组是2d:

In [197]: amt_padding=1;np.pad(x[:,:,0], pad_width=((amt_padding, amt_padding), (amt_padding, amt_padding), (0, 0)))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [197], in <cell line: 1>()
----> 1 amt_padding=1;np.pad(x[:,:,0], pad_width=((amt_padding, amt_padding), (amt_padding, amt_padding), (0, 0)))
File <__array_function__ internals>:5, in pad(*args, **kwargs)
File ~anaconda3libsite-packagesnumpylibarraypad.py:743, in pad(array, pad_width, mode, **kwargs)
740     raise TypeError('`pad_width` must be of integral type.')
742 # Broadcast to shape (array.ndim, 2)
--> 743 pad_width = _as_pairs(pad_width, array.ndim, as_index=True)
745 if callable(mode):
746     # Old behavior: Use user-supplied function with np.apply_along_axis
747     function = mode
File ~anaconda3libsite-packagesnumpylibarraypad.py:518, in _as_pairs(x, ndim, as_index)
514     raise ValueError("index can't contain negative values")
516 # Converting the array with `tolist` seems to improve performance
517 # when iterating and indexing the result (see usage in `pad`)
--> 518 return np.broadcast_to(x, (ndim, 2)).tolist()
File <__array_function__ internals>:5, in broadcast_to(*args, **kwargs)
File ~anaconda3libsite-packagesnumpylibstride_tricks.py:411, in broadcast_to(array, shape, subok)
366 @array_function_dispatch(_broadcast_to_dispatcher, module='numpy')
367 def broadcast_to(array, shape, subok=False):
368     """Broadcast an array to a new shape.
369 
370     Parameters
(...)
409            [1, 2, 3]])
410     """
--> 411     return _broadcast_to(array, shape, subok=subok, readonly=True)
File ~anaconda3libsite-packagesnumpylibstride_tricks.py:348, in _broadcast_to(array, shape, subok, readonly)
345     raise ValueError('all elements of broadcast shape must be non-'
346                      'negative')
347 extras = []
--> 348 it = np.nditer(
349     (array,), flags=['multi_index', 'refs_ok', 'zerosize_ok'] + extras,
350     op_flags=['readonly'], itershape=shape, order='C')
351 with it:
352     # never really has writebackifcopy semantics
353     broadcast = it.itviews[0]
ValueError: operands could not be broadcast together with remapped shapes [original->remapped]: (3,2)  and requested shape (2,2)

它将任务传递给np.nditer(通过broadcast_to),这会引发错误。这就解释了为什么我以前从没见过它。我已经探索了一些nditer,但我不经常使用或推荐给其他人。

_as_pairswidths扩展为

In [206]: np.lib.arraypad._as_pairs(1,3, as_index=True)
Out[206]: ((1, 1), (1, 1), (1, 1))
In [207]: np.lib.arraypad._as_pairs(((1,),(2,),(3,)),3, as_index=True)
Out[207]: [[1, 1], [2, 2], [3, 3]]

相关内容