如何在没有 for 循环的情况下用给定颜色填充图像数组?
How to pad an array of images with a given color without a for loop?
我有一个 numpy 图像数组,其中包含 numpy 图像数组,我试图在不使用 for 循环的情况下用给定颜色填充数组中的每个图像。换句话说,我希望一切都矢量化。
为了产生错误:取消注释行并注释它下面的行,你会得到 ValueError: operands could not be broadcast together with remapped shapes [original->remapped]: (3,) and requested shape (4,2)
您可以使用此图片进行测试。
这是我所做的:
import cv2
import numpy as np
import matplotlib.pyplot as plt
def pad_image(image, pad_width, values, mode='img_arr'):
"""
Add a pad(border) of a given width and value to the image.
Args:
image: Image array or a single image.
pad_width: The width of the pad.
values: Value of the pad layer.
mode: A string representation of the input
'img_arr': Array of images.
'img': A single image.
Return:
numpy array of padded images or a padded image.
"""
if mode == 'img_arr':
# The following commented line will give an error if constant_values is an RGB tuple.
# return np.pad(
# image, ((0, 0), (pad_width, pad_width), (pad_width, pad_width), (0, 0)), constant_values=values)
return np.array([cv2.copyMakeBorder(
img, pad_width, pad_width, pad_width, pad_width, cv2.BORDER_CONSTANT, value=values)
for img in image])
if mode == 'img':
return cv2.copyMakeBorder(
image, pad_width, pad_width, pad_width, pad_width, cv2.BORDER_CONSTANT, value=values)
if __name__ == '__main__':
tiger = cv2.imread('tiger.jpeg')
tiger_arr_test = np.array([tiger for i in range(1000)])
pad_width = 5
color = (255, 0, 0)
padded_arr = pad_image(tiger_arr_test, pad_width, color)
plt.imshow(padded_arr[0])
plt.title(f'First padded image of the array of images.')
plt.show()
padded_single = pad_image(tiger, pad_width, color, 'img')
print(padded_single.shape)
plt.imshow(padded_single)
plt.title('Padded single image.')
plt.show()
这是一种不使用 numpy.pad
的方法
import cv2
import numpy as np
tiger = cv2.imread('tiger.jpg')
tigers = np.array((tiger,tiger,tiger,tiger,tiger))
color = np.array((255, 0, 0))
pad = 5
sub = slice(pad,-pad)
使用原始形状制作边框颜色数组
z,a,b,c = tigers.shape
newshape = (z, pad+a+pad, pad+b+pad, c)
w = np.zeros(newshape,dtype=np.uint8) + color
然后把原来的数组赋值到新数组的中间就可以了
w[:,sub,sub,:] = tigers
plt.imshow(w[3])
plt.show()
plt.close()
使用numpy.pad
- 用零填充然后将颜色分配给四个边
q = np.pad(tigers,((0,0),(pad,pad),(pad,pad),(0,0)))
q[:,:,:5,:] = color
q[:,:,-5:,:] = color
q[:,:5,:,:] = color
q[:,-5:,:,:] = color
numpy.pad
并使用布尔掩码分配颜色
q = np.pad(tigers,((0,0),(pad,pad),(pad,pad),(0,0)))
mask = np.ones(q.shape[:-1],dtype=np.bool8)
mask[:,sub,sub] = False
q[mask] = color
我有一个 numpy 图像数组,其中包含 numpy 图像数组,我试图在不使用 for 循环的情况下用给定颜色填充数组中的每个图像。换句话说,我希望一切都矢量化。
为了产生错误:取消注释行并注释它下面的行,你会得到 ValueError: operands could not be broadcast together with remapped shapes [original->remapped]: (3,) and requested shape (4,2)
您可以使用此图片进行测试。
这是我所做的:
import cv2
import numpy as np
import matplotlib.pyplot as plt
def pad_image(image, pad_width, values, mode='img_arr'):
"""
Add a pad(border) of a given width and value to the image.
Args:
image: Image array or a single image.
pad_width: The width of the pad.
values: Value of the pad layer.
mode: A string representation of the input
'img_arr': Array of images.
'img': A single image.
Return:
numpy array of padded images or a padded image.
"""
if mode == 'img_arr':
# The following commented line will give an error if constant_values is an RGB tuple.
# return np.pad(
# image, ((0, 0), (pad_width, pad_width), (pad_width, pad_width), (0, 0)), constant_values=values)
return np.array([cv2.copyMakeBorder(
img, pad_width, pad_width, pad_width, pad_width, cv2.BORDER_CONSTANT, value=values)
for img in image])
if mode == 'img':
return cv2.copyMakeBorder(
image, pad_width, pad_width, pad_width, pad_width, cv2.BORDER_CONSTANT, value=values)
if __name__ == '__main__':
tiger = cv2.imread('tiger.jpeg')
tiger_arr_test = np.array([tiger for i in range(1000)])
pad_width = 5
color = (255, 0, 0)
padded_arr = pad_image(tiger_arr_test, pad_width, color)
plt.imshow(padded_arr[0])
plt.title(f'First padded image of the array of images.')
plt.show()
padded_single = pad_image(tiger, pad_width, color, 'img')
print(padded_single.shape)
plt.imshow(padded_single)
plt.title('Padded single image.')
plt.show()
这是一种不使用 numpy.pad
import cv2
import numpy as np
tiger = cv2.imread('tiger.jpg')
tigers = np.array((tiger,tiger,tiger,tiger,tiger))
color = np.array((255, 0, 0))
pad = 5
sub = slice(pad,-pad)
使用原始形状制作边框颜色数组
z,a,b,c = tigers.shape
newshape = (z, pad+a+pad, pad+b+pad, c)
w = np.zeros(newshape,dtype=np.uint8) + color
然后把原来的数组赋值到新数组的中间就可以了
w[:,sub,sub,:] = tigers
plt.imshow(w[3])
plt.show()
plt.close()
使用numpy.pad
- 用零填充然后将颜色分配给四个边
q = np.pad(tigers,((0,0),(pad,pad),(pad,pad),(0,0)))
q[:,:,:5,:] = color
q[:,:,-5:,:] = color
q[:,:5,:,:] = color
q[:,-5:,:,:] = color
numpy.pad
并使用布尔掩码分配颜色
q = np.pad(tigers,((0,0),(pad,pad),(pad,pad),(0,0)))
mask = np.ones(q.shape[:-1],dtype=np.bool8)
mask[:,sub,sub] = False
q[mask] = color