How do I downsample an image of any resolution to a quarter of the size by averaging the pixels in numpy?
What I came up through research only works for images that are square (i.e 512 X 512 down to 128 X 128) but will not work for images that are different dimensions (i.e 2400 X 1800 down to 600 X 450). In those cases I get a IndexError: index 450 is out of bounds for axis 1 with size 450.
I am trying to perform this task with numpy array manipulation and without installing other packages and libraries.
I researched a function
numpy.mean()
but I don't know how to use it in reference to this problem.
import cv2
import numpy as np
def quarter_res_avg(im):
original_width = im.shape[1]
original_height = im.shape[0]
width = original_width / 4
height = original_height / 4
resized_image = np.zeros(shape=(width, height, 3), dtype=np.uint8)
scale = 4
for i in range(width):
for j in range(height):
temp = np.array([0, 0, 0])
for x in range(scale):
for y in range(scale):
temp += im[i*scale+x, j*scale+y]
resized_image[i, j] = temp/(scale*scale)
return resized_image
im = cv2.imread('Lenna_test_image.png', 1)
cv2.imwrite('Lenna_test_image_avg.png', quarter_res_avg(im))
Any ideas are much appreciated.
Thanks.
resized_image = np.zeros(shape=(height, width, 3), dtype=np.uint8)and your indices in the loop need swapping.np.mean(), delete the 5 lines startingtemp=...and useresized[WWW] = np.mean(im[XXX:XXX+4, YYY:YYY+4], axis=ZZZ)where you need to think about WWW, XXX, YYY, ZZZ.resized_image = np.zeros(shape=(height, width, 3), dtype=np.uint8)and the indicesfor i in range(height): for j in range(width):did the trick. I have been playing around with the np.mean() but I still don't understand how it works. Can you explain it to me in reference to this problem?im[0:2, 0:3]and you should see the first 2 rows and 3 cols ofim. Then printnp.mean(im[0:2, 0:3],axis=2)so you get the means of all the elements on the top-left corner of your image.for i in range(0, original_height, scale): for j in range(0, original_width, scale): resized_image[i/scale, j/scale] = np.mean(im[i:i + scale, j:j+scale], axis=(0, 1)) return resized_image