<jupyter_start><jupyter_text>Image size decreasing and Image smoothingAveraging of image pixels for decreasing its' size and using convolution for smoothing it and to better decreasing.<jupyter_code>import matplotlib.image as mpimg
import matplotlib.pyplot as plt
import numpy as np
from math import floor, ceil

#
# Smoothing image for next better resizing it using different kernel types
#
def convolution(img: np.array, krl: np.array) -> np.array:
    new_img = np.zeros((img.shape))
    
    for i in range(len(img)):
        for j in range(len(img)):
            new_img[i][j] = kernel(img, i, j, krl)
    
    return new_img

#
# highpass kernel is below
# using this kernel it will be easy to show edges
#  0 -1  0
# -1  4 -1
#  0 -1  0
#
# averaging kernel is array of ones
#  1  1  1
#  1  1  1
#  1  1  1
#
# simple gaussian kernel
#  1  2  1
#  2  4  2
#  1  2  1
# 
#
# Kernel function will take any kernel
# and return smoothed value for each pixel
#
def kernel(img: np.array, i: int, j: int, krl: np.array) -> np.array:
    radius = int((len(krl) - 1) / 2)    
    average = np.zeros((3))
    dividable = np.sum(krl) if np.sum(krl) > 0 else 1
    
    for k in range((len(krl))):
        for l in range((len(krl))):
            if i + k - radius < 0 or j + l - radius < 0 or i + k - radius >= len(img) or j + l - radius >= len(img):
                average += np.ones((3))
            else:
                average += img[i + k - radius][j + l - radius] * krl[k][l]
    
    return average / dividable

#
# Decreasing size of an image, there is also possibility to use bilinear interpolation for this
# calculate the average for nearest pixels for each new pixel and that's it
#
# for getting better results recommends to use convolution before
# you can see below that smoothed image will look better after decreasing its size
#

def size_decreasing(img: np.array, new_size: int) -> np.array:
    avg_img = np.zeros((new_size, new_size, 3))
    if len(img) / new_size <= 1.9:
        print('This size is too big -> so it returns original image')
        return img
    steps = ceil(len(img) / new_size)
    
    for i in range(new_size):
        for j in range(new_size):
            s = 0
            for k in range(i * steps, (i + 1) * steps):
                for l in range(j * steps, (j + 1) *steps):
                    if k >= len(img) or l >= len(img):
                        s += np.ones((3))
                    else:
                        s += img[k][l]
            
            avg_img[i][j] = s / steps ** 2
    
    return avg_img


img = mpimg.imread('toucan.jpg') / 255

plt.figure(figsize=(8,8))
plt.imshow(img)<jupyter_output><empty_output><jupyter_text>Showing the decreased image without using convolution<jupyter_code>plt.figure(figsize=(4, 4))
plt.imshow(size_decreasing(img, 44))<jupyter_output><empty_output><jupyter_text>Showing the smoothed image with using convolution with kernel of ones<jupyter_code>krl = np.ones((7, 7))
#krl = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
#krl = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])
#krl = np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]])

conv_img = convolution(img, krl)

plt.figure(figsize=(8,8))
plt.imshow(conv_img)<jupyter_output><empty_output><jupyter_text>And decreasing the size of smoothed image, you can see that it looks much better than previous decreased image<jupyter_code>plt.figure(figsize=(4, 4))
plt.imshow(size_decreasing(conv_img, 43))<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup