Loading problem...
When working with digital images in computer vision and graphics applications, we frequently need to change their dimensions—whether enlarging a thumbnail for detailed viewing or shrinking a high-resolution photograph for web display. The quality of this resizing operation significantly impacts the visual appearance of the result.
Nearest-neighbor interpolation, the simplest approach, merely selects the closest source pixel for each destination pixel. While computationally efficient, this method produces blocky, pixelated artifacts, especially when upscaling images.
Bilinear interpolation offers a superior alternative by considering the four nearest source pixels surrounding each destination coordinate and computing their weighted average based on relative distances. This produces smooth gradients and significantly reduces aliasing artifacts.
For each pixel ((x', y')) in the destination image, we first compute its corresponding floating-point coordinates ((x, y)) in the source image using the scale ratios:
$$x = x' \cdot \frac{\text{src_width} - 1}{\text{dst_width} - 1}$$ $$y = y' \cdot \frac{\text{src_height} - 1}{\text{dst_height} - 1}$$
We then identify the four surrounding source pixels by finding the floor and ceiling coordinates:
The fractional components determine the interpolation weights:
The interpolated pixel value is computed using the bilinear formula:
$$I(x, y) = (1-t_x)(1-t_y) \cdot I_{y_1,x_1} + t_x(1-t_y) \cdot I_{y_1,x_2} + (1-t_x)t_y \cdot I_{y_2,x_1} + t_x \cdot t_y \cdot I_{y_2,x_2}$$
where (I_{row,col}) denotes the pixel intensity at the given source position.
Implement a function that rescales both grayscale and RGB images to arbitrary target dimensions using bilinear interpolation. The function must handle:
image = [[0, 100], [100, 200]]
new_height = 4
new_width = 4[[0.0, 33.33, 66.67, 100.0], [33.33, 66.67, 100.0, 133.33], [66.67, 100.0, 133.33, 166.67], [100.0, 133.33, 166.67, 200.0]]The 2×2 grayscale image is upscaled to 4×4. The scale factor is (2-1)/(4-1) = 0.333... in both dimensions.
• Output pixel (0,0) maps to source (0,0), directly copying value 0. • Output pixel (1,1) maps to source (0.333, 0.333), interpolating between all four corners with weights based on fractional distances, yielding 66.67. • Output pixel (3,3) maps to source (1,1), directly copying value 200.
Intermediate pixels blend smoothly between corner values, creating a natural gradient.
image = [[[0, 0, 0], [255, 255, 255]], [[255, 255, 255], [0, 0, 0]]]
new_height = 4
new_width = 4[[[0.0, 0.0, 0.0], [85.0, 85.0, 85.0], [170.0, 170.0, 170.0], [255.0, 255.0, 255.0]], [[85.0, 85.0, 85.0], [113.33, 113.33, 113.33], [141.67, 141.67, 141.67], [170.0, 170.0, 170.0]], [[170.0, 170.0, 170.0], [141.67, 141.67, 141.67], [113.33, 113.33, 113.33], [85.0, 85.0, 85.0]], [[255.0, 255.0, 255.0], [170.0, 170.0, 170.0], [85.0, 85.0, 85.0], [0.0, 0.0, 0.0]]]A 2×2 RGB image with a checkerboard pattern (black and white corners) is upscaled to 4×4. Bilinear interpolation is applied independently to each R, G, and B channel.
• Corner pixels (0,0) and (3,3) retain their original black/white values. • The pattern inverts diagonally: top-left to bottom-right shows a gradient from black to white, while bottom-left to top-right goes from white to black. • Center pixels exhibit the characteristic smooth blending of bilinear interpolation.
image = [[0, 50, 100, 150], [50, 100, 150, 200], [100, 150, 200, 250], [150, 200, 250, 255]]
new_height = 2
new_width = 2[[0.0, 150.0], [150.0, 255.0]]The 4×4 grayscale image is downscaled to 2×2. The mapping coordinates correspond exactly to the four corner pixels of the source image:
• Output (0,0) maps to source (0,0) = 0 • Output (0,1) maps to source (0,3) = 150 • Output (1,0) maps to source (3,0) = 150 • Output (1,1) maps to source (3,3) = 255
Corner-to-corner mapping means no interpolation is needed—values are directly sampled.
Constraints