Skip to content

Added Nearest neighbour algorithm #1934

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
69 changes: 69 additions & 0 deletions digital_image_processing/resize/resize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
""" Multiple image resizing techniques """
import numpy as np
from cv2 import imread, imshow, waitKey, destroyAllWindows


class NearestNeighbour:
"""
Simplest and fastest version of image resizing.
Source: https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation
"""

def __init__(self, img, dst_width: int, dst_height: int):
if dst_width < 0 or dst_height < 0:
raise ValueError(f"Destination width/height should be > 0")

self.img = img
self.src_w = img.shape[1]
self.src_h = img.shape[0]
self.dst_w = dst_width
self.dst_h = dst_height

self.ratio_x = self.src_w / self.dst_w
self.ratio_y = self.src_h / self.dst_h

self.output = self.output_img = (
np.ones((self.dst_h, self.dst_w, 3), np.uint8) * 255
)

def process(self):
for i in range(self.dst_h):
for j in range(self.dst_w):
self.output[i][j] = self.img[self.get_y(i)][self.get_x(j)]

def get_x(self, x: int) -> int:
"""
Get parent X coordinate for destination X
:param x: Destination X coordinate
:return: Parent X coordinate based on `x ratio`
>>> nn = NearestNeighbour(imread("digital_image_processing/image_data/lena.jpg", 1), 100, 100)
>>> nn.ratio_x = 0.5
>>> nn.get_x(4)
2
"""
return int(self.ratio_x * x)

def get_y(self, y: int) -> int:
"""
Get parent Y coordinate for destination Y
:param y: Destination X coordinate
:return: Parent X coordinate based on `y ratio`
>>> nn = NearestNeighbour(imread("digital_image_processing/image_data/lena.jpg", 1), 100, 100)
>>> nn.ratio_y = 0.5
>>> nn.get_y(4)
2
"""
return int(self.ratio_y * y)


if __name__ == "__main__":
dst_w, dst_h = 800, 600
im = imread("image_data/lena.jpg", 1)
n = NearestNeighbour(im, dst_w, dst_h)
n.process()

imshow(
f"Image resized from: {im.shape[1]}x{im.shape[0]} to {dst_w}x{dst_h}", n.output
)
waitKey(0)
destroyAllWindows()
8 changes: 8 additions & 0 deletions digital_image_processing/test_digital_image_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import digital_image_processing.convert_to_negative as cn
import digital_image_processing.sepia as sp
import digital_image_processing.dithering.burkes as bs
import digital_image_processing.resize.resize as rs
from cv2 import imread, cvtColor, COLOR_BGR2GRAY
from numpy import array, uint8
from PIL import Image
Expand Down Expand Up @@ -82,3 +83,10 @@ def test_burkes(file_path: str = "digital_image_processing/image_data/lena_small
burkes = bs.Burkes(imread(file_path, 1), 120)
burkes.process()
assert burkes.output_img.any()

def test_nearest_neighbour(
file_path: str = "digital_image_processing/image_data/lena_small.jpg",
):
nn = rs.NearestNeighbour(imread(file_path, 1), 400, 200)
nn.process()
assert nn.output.any()