I have RGB images which have already been rescaled so that the longer edge becomes 256 pixels, now I want to pad the border with the median RGB values of that image so the resulting image is always 256x256 pixels.
This code already works, but I am sure there could be a simpler more elegant way to do this:
img = loadAndFitImage(filePath, maxSideLength=256, upscale=True)
shp = img.shape
#the shp in this case is typically (256,123,3) or (99,256,3)
leftPad = (256 - shp[0]) / 2
rightPad = 256 - shp[0] - leftPad
topPad = (256 - shp[1]) / 2
bottomPad = 256 - shp[1] - topPad
# this part looks like there might be a way to do it with one median call instead of 3:
median = (np.median(img[:, :, 0]),np.median(img[:, :, 1]),np.median(img[:, :, 2]))
img = np.lib.pad(img, ((leftPad,rightPad),(topPad,bottomPad),(0,0)),
'constant',constant_values=0)
if leftPad > 0:
img[:leftPad,:,0].fill(median[0])
img[:leftPad,:,1].fill(median[1])
img[:leftPad,:,2].fill(median[2])
if rightPad > 0:
img[-rightPad:,:,0].fill(median[0])
img[-rightPad:,:,1].fill(median[1])
img[-rightPad:,:,2].fill(median[2])
if topPad > 0:
img[:,:topPad,0].fill(median[0])
img[:,:topPad,1].fill(median[1])
img[:,:topPad,2].fill(median[2])
if bottomPad > 0:
img[:,-bottomPad:,0].fill(median[0])
img[:,-bottomPad:,1].fill(median[1])
img[:,-bottomPad:,2].fill(median[2])
Edit (Additional Info):
This is how the final result should look like:
This is how it should not look like (median per column):
A single RGB image can be represented using a three-dimensional (3D) NumPy array or a tensor. Since there are three color channels in the RGB image, we need an extra dimension for the color channel. A batch of 3 RGB images can be represented using a four-dimensional (4D) NumPy array or a tensor.
This function converts the input to an array By using numpy.array () function which takes an image as the argument and converts to NumPy array In order to get the value of each pixel of the NumPy array image, we need to print the retrieved data that got either from asarray () function or array () function.
Python provides many modules and API’s for converting an image into a NumPy array. Let’s discuss a few of them in detail. Using NumPy module. Numpy module in itself provides various methods to do the same. These methods are – Method 1: Using asarray() function. asarray() function is used to
You can read an image using the PIL open function, and convert it to an array using the numpy array function. Here, we read the images that were created previously, and print their NumPy shape:
You can do it easily with:
import numpy as np
a = np.asarray([[1,2,3,4,5,6],
[8,4,5,6,7,7],
[1,2,3,4,5,6],
[1,2,3,4,5,6],
[1,2,3,4,5,6],
[1,2,3,4,5,6]])
b = a * 3
c = a * 4
d = (a,b,c)
im = np.asarray([np.pad(x, (2,), 'constant', constant_values=(np.median(x) ,)) for x in d])
print im
Output:
[[[ 4 4 4 4 4 4 4 4 4 4]
[ 4 4 4 4 4 4 4 4 4 4]
[ 4 4 1 2 3 4 5 6 4 4]
[ 4 4 8 4 5 6 7 7 4 4]
[ 4 4 1 2 3 4 5 6 4 4]
[ 4 4 1 2 3 4 5 6 4 4]
[ 4 4 1 2 3 4 5 6 4 4]
[ 4 4 1 2 3 4 5 6 4 4]
[ 4 4 4 4 4 4 4 4 4 4]
[ 4 4 4 4 4 4 4 4 4 4]]
[[12 12 12 12 12 12 12 12 12 12]
[12 12 12 12 12 12 12 12 12 12]
[12 12 3 6 9 12 15 18 12 12]
[12 12 24 12 15 18 21 21 12 12]
[12 12 3 6 9 12 15 18 12 12]
[12 12 3 6 9 12 15 18 12 12]
[12 12 3 6 9 12 15 18 12 12]
[12 12 3 6 9 12 15 18 12 12]
[12 12 12 12 12 12 12 12 12 12]
[12 12 12 12 12 12 12 12 12 12]]
[[16 16 16 16 16 16 16 16 16 16]
[16 16 16 16 16 16 16 16 16 16]
[16 16 4 8 12 16 20 24 16 16]
[16 16 32 16 20 24 28 28 16 16]
[16 16 4 8 12 16 20 24 16 16]
[16 16 4 8 12 16 20 24 16 16]
[16 16 4 8 12 16 20 24 16 16]
[16 16 4 8 12 16 20 24 16 16]
[16 16 16 16 16 16 16 16 16 16]
[16 16 16 16 16 16 16 16 16 16]]]
Or in you particular case:
import numpy as np
from PIL import Image
filePath = '/home/george/Desktop/img.jpg'
Img = Image.open(filePath)
img = np.asarray(Img, np.int)
shp = np.shape(img)
img = img.transpose(2,0,1).reshape(3,215,215)
leftPad = round(float((255 - shp[0])) / 2)
rightPad = round(float(255 - shp[0]) - leftPad)
topPad = round(float((255 - shp[1])) / 2)
bottomPad = round(float(255 - shp[1]) - topPad)
pads = ((leftPad,rightPad),(topPad,bottomPad))
img_arr = np.ndarray((3,255,255),np.int)
for i,x in enumerate(img):
cons = np.int(np.median(x))
x_p = np.pad(x,pads,
'constant',
constant_values=cons)
img_arr[i,:,:] = x_p
im_shp = np.shape(img_arr)
ii = np.uint8(img_arr).transpose(1,2,0)
im = Image.fromarray(np.array( (ii) ))
im.show()
im.save((filePath), "JPEG")
Output:
I was also struggling on this and figured out an elegant answer:
color = np.median(img, axis=(0,1))
img = np.stack([np.pad(img[:,:,c], pad, mode='constant', constant_values=color[c]) for c in range(3)], axis=2)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With