Как дополнить массив изображений с заданным цветом без для l oop? - PullRequest
0 голосов
/ 02 февраля 2020

У меня есть массив numpy изображений, который содержит numpy массив изображений, и я пытаюсь дополнить каждое изображение в массиве заданным цветом, не используя для l oop. Другими словами, я хочу, чтобы все было векторизовано.

Для создания ошибки: раскомментируйте закомментированную строку и закомментируйте нижеприведенную строку, вы получите ValueError: операнды не могут быть переданы вместе с переназначенными формами [original-> remapped]: (3,) и запрошенная форма (4,2)

Вы можете использовать это изображение для тестирования.

Tiger

Вот что я сделал:

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()

1 Ответ

1 голос
/ 03 февраля 2020

Вот способ сделать это без использования 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
...