Image resizing is a fundamental process in digital image processing and computer graphics. It involves changing an image's dimensions (size) while preserving its content and visual information. Resizing images is used in various applications, ranging from photo editing to more advanced tasks like preparing images for machine learning, web display, computer vision, and more.
There are two types of image resizing:
Downsampling (Decimation): Decimation is reducing the dimensions of an image to a smaller size. Downsampling can result in a loss of fine details. It is crucial to carefully choose an appropriate resizing algorithm to preserve essential visual information.
Upsampling (Interpolation): Interpolation involves increasing the dimensions of an image to a larger size. Interpolation requires creating new pixel values based on existing ones. Different interpolation techniques are used to generate smooth transitions between pixels.
There are different downsampling methods, some of which are listed below:
Simple decimation (Subsampling): Select every nth pixel from the original image to create the decimated image. This basic technique can lead to aliasing artifacts if not combined with appropriate filtering.
Average pooling: Calculate the average pixel value in a local
Bilinear downsampling: Compute a weighted average of four neighboring pixels to calculate the value of a new pixel in the downsampled image. Reduces aliasing and provides smoother results.
Bayer decimation (Ordered dithering): Select pixels based on a pre-defined dither pattern. They are used in halftoning to simulate continuous tones with discrete values.
Thresholding: Retain pixels based on their intensity values. Keep pixels above a certain threshold and discard the rest.
Memory and storage optimization: Larger images require more memory and storage space. Resizing reduces the file size of images, making them more manageable for storage and transmission.
Performance: In applications like computer vision and machine learning, resizing images can improve processing efficiency by reducing the computational load while maintaining essential visual information.
Here we will be using bilinear downsampling:
def downsampling(image,n): #orignal height and width of the image original_height, original_width = image.shape #new height and width of the image divided by n new_height = original_height // n new_width = original_width // n #creating an empty 2d array containing zero's of the size of new height and width. resized_image = np.zeros((new_height, new_width), dtype=image.dtype) #Bilinear downsampling is used to compute the pixel value in the resized image. for i in range(new_height): for j in range(new_width): #find the corresponding pixel of reszied image in the orignal image x = j * n y = i * n #calculate the neighbors of the pixel in the orignal image #------> Note: Neighbors are the up,down,left and right cell of the current selected cell.<------ x0 = int(np.floor(x)) x1 = min(x0 + 1, original_width - 1) y0 = int(np.floor(y)) y1 = min(y0 + 1, original_height - 1) #calculate the fractional differences of the indices dx = x - x0 dy = y - y0 #calculating the pixel value of resized image through weighted average of #the four nearest pixel values from the original image. pixel_value = ( (1 - dx) * (1 - dy) * image[y0, x0]+ dx * (1 - dy) * image[y0, x1] + (1 - dx) * dy * image[y1, x0] + dx * dy * image[y1, x1] ) resized_image[i, j] = pixel_value return resized_image
There are different upsampling methods, some of which are listed below:
Nearest-neighbor: It copies the value of the nearest pixel to the new location. It can result in aliasing artifacts and may not preserve image quality well.
Bilinear: Uses a weighted average of the four nearest pixels to calculate the new pixel value. It provides smoother results than the nearest-neighbor but may not handle sharp edges or details effectively.
Bicubic: A interpolation method that considers 16 surrounding pixels to calculate the new pixel value. It produces smoother and higher-quality results than bilinear interpolation.
Lanczos: A more advanced interpolation method that uses a sinc function to interpolate pixel values. It provides sharper results, particularly for downscaling, but is computationally more intensive.
Fitting constraints: Images often need to be resized to fit specific constraints, such as display sizes for websites, social media, or mobile devices. Resizing ensures that images are appropriate for their intended platforms.
Zooming and cropping: Resizing can also zoom in or out on specific details of an image or crop and extract a region of interest.
Here we will be using bilinear upsampling:
def upsampling(image,n): #orignal height and width of the image original_height, original_width = image.shape #new height and width of the image divided by n new_height = n * original_height new_width = n * original_width #creating an empty 2d array containing zero's of the size of new height and width. my_resize = np.zeros((new_height, new_width), dtype=image.dtype) for i in range(new_height): for j in range(new_width): #find the corresponding pixel of reszied image in the orignal image x = j / n y = i / n #calculate the neighbors of the pixel in the orignal image #------> Note: Neighbors are the up,down,left and right cell of the current selected cell.<------ x0 = int(np.floor(x)) x1 = min(x0 + 1, original_width - 1) y0 = int(np.floor(y)) y1 = min(y0 + 1, original_height - 1) #calculate the fractional differences of the indices dx = x - x0 dy = y - y0 #calculating the pixel value of resized image through weighted average of #the four nearest pixel values from the original image. pixel_value = ( (1 - dx) * (1 - dy) * image[y0, x0] + dx * (1 - dy) * image[y0, x1] + (1 - dx) * dy * image[y1, x0] + dx * dy * image[y1, x1] ) my_resize[i, j] = pixel_value return my_resize
Free Resources