3

I am working with images and I want to pad numpy array with zeros. I looked at np.pad

For padding single array it works fine

x = np.array([[1,2],[3,4]])
y = np.pad(x,(1,1), 'constant')

x
=> array([[1, 2],
       [3, 4]])
y
=> array([[0, 0, 0, 0],
       [0, 1, 2, 0],
       [0, 3, 4, 0],
       [0, 0, 0, 0]])

How to implement if we have x type arrays in a list/array , like

c_x=np.array([[[2,2],[2,3]],[[3,2],[2,3]],[[4,4],[2,3]]])
c_y=np.pad(c_x,((0,0),(1,1),(0,0)),'constant')  #padding is present only on top and bottom

As such arrays contains R,G,B channel, Can that too be accounted when padding?

edit:

Say c_x stores list of 10 images on 28x28 pixels with RGB channel

Now I want to pad all 10 images , So after modifying 10 images are of 30x30 with pixels on border as [0,0,0]

2
  • It it not clear to me what the desired output is. Do you mean you want to add a border of zeros to an RGB image that is stored in an array with shape (3, m, n)? I think you are saying that c_y is not what you want. Could you show what the desired result is? Just enter it by hand for the small example. Commented May 23, 2017 at 22:33
  • @WarrenWeckesser you answered my question, I tried to put some info regarding RGB part Commented May 23, 2017 at 22:54

4 Answers 4

5

It is not clear to me what your desired output is, but I think it is either np.pad(c_x, ((1,1), (0,0), (0,0)), mode='constant') or np.pad(c_x, ((0,0), (1,1), (1,1)), mode='constant'):

In [228]: c_x
Out[228]: 
array([[[2, 2],
        [2, 3]],

       [[3, 2],
        [2, 3]],

       [[4, 4],
        [2, 3]]])

In [229]: np.pad(c_x, ((1,1), (0,0), (0,0)), mode='constant')
Out[229]: 
array([[[0, 0],
        [0, 0]],

       [[2, 2],
        [2, 3]],

       [[3, 2],
        [2, 3]],

       [[4, 4],
        [2, 3]],

       [[0, 0],
        [0, 0]]])

In [230]: np.pad(c_x, ((0,0), (1,1), (1,1)), mode='constant')
Out[230]: 
array([[[0, 0, 0, 0],
        [0, 2, 2, 0],
        [0, 2, 3, 0],
        [0, 0, 0, 0]],

       [[0, 0, 0, 0],
        [0, 3, 2, 0],
        [0, 2, 3, 0],
        [0, 0, 0, 0]],

       [[0, 0, 0, 0],
        [0, 4, 4, 0],
        [0, 2, 3, 0],
        [0, 0, 0, 0]]])
Sign up to request clarification or add additional context in comments.

2 Comments

Yup, seems like OP loves the np.pad and would go with it :)
@Warren Weckesser: It is very useful. If I consider the image RGB. I want to add the zero padding the image so that my original image is in center of the new image (i.e 256x256x3-->512x512x3). So is my code correct? delta_w = width_new - image.shape[0] delta_h = height_new - image.shape[1] top, bottom = delta_h // 2, delta_h - (delta_h // 2) left, right = delta_w // 2, delta_w - (delta_w // 2) image= np.pad(image, ((top, bottom), (left, right), (0,0)), mode='constant')
2

Here's one approach using initialization of output array with zeros and then assigning values into it -

def pad3D(c_x, padlen=1):
    m,n,r = c_x.shape
    c_y = np.zeros((m, n+2*padlen, r+2*padlen),dtype=c_x.dtype)
    c_y[:, padlen:-padlen, padlen:-padlen] = c_x
    return c_y

Now, considering that arrays could be image data and usually you might have the channel being represented by the last axis, while the first two axes representing the height and width, we need to change the indexing there. The modified portions would be the initialization and assignment :

c_y = np.zeros((m+2*padlen, n+2*padlen, r),dtype=c_x.dtype)
c_y[padlen:-padlen, padlen:-padlen, :] = c_x

So, if you notice, we are slicing with padlen:-padlen along the axes that needs padding. Using this general theory, you can handle various image data arrays for padding.

Sample run -

In [422]: c_x
Out[422]: 
array([[[2, 2],
        [2, 3]],

       [[3, 2],
        [2, 3]],

       [[4, 4],
        [2, 3]]])

In [423]: pad3D(c_x, padlen=1) # pads all across not just top and bottom
Out[423]: 
array([[[0, 0, 0, 0],
        [0, 2, 2, 0],
        [0, 2, 3, 0],
        [0, 0, 0, 0]],

       [[0, 0, 0, 0],
        [0, 3, 2, 0],
        [0, 2, 3, 0],
        [0, 0, 0, 0]],

       [[0, 0, 0, 0],
        [0, 4, 4, 0],
        [0, 2, 3, 0],
        [0, 0, 0, 0]]])

1 Comment

your implementation is good, but is it possible to do with np.pad itself without indexing and slicing
1

try this. with use of np.pad I know I m late but, It might help someone. :)

def padwithzero(vector, pad_width, iaxis, kwargs):
    vector[:pad_width[0]] = 0
    vector[-pad_width[1]:] = 0
    return vector


tmp_mainImg = np.pad(mainImg, 1, padwithzero)

print(tmp_mainImg)

Comments

0

I updated @Divakar's answer for 2D matrices:

import numpy
def pad2D(c_x, padlen=1):
    m, n = c_x.shape
    c_y = np.zeros((m + 2 * padlen, n + 2 * padlen), dtype = c_x.dtype)
    c_y[padlen:-padlen, padlen:-padlen] = c_x
    return c_y

this should also work with Numba!

import numpy as np
from numba import jit
@jit(nopython = True)
def pad2D(c_x, padlen=1):
    m, n = c_x.shape
    c_y = np.zeros((m + 2 * padlen, n + 2 * padlen), dtype = c_x.dtype)
    c_y[padlen:-padlen, padlen:-padlen] = c_x
    return c_y

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.