Python 3 Script to Compress or Minify Image Size Using Pillow and Numpy Library (K-means Algorithm) Full Project For Beginners

 

Welcome folks today in this post we will be compressing image using pillow and numpy library. We will be using python script for this purpose and we will be making use of k-means algorithm. All the full source code of the application is given below.

 

 

 

Get Started

 

 

 

In order to get started we need to install the following libraries using the pipcommand

 

pip install pillow

 

pip install numpy

 

After installing these libraries we need to make an app.py file and copy paste the following code

 

app.py

 

 

#! /usr/bin/env python3

import os
import sys

from PIL import Image
import numpy as np


def load_image(path):
    """ Load image from path. Return a numpy array """
    image = Image.open(path)
    return np.asarray(image) / 255


def initialize_K_centroids(X, K):
    """ Choose K points from X at random """
    m = len(X)
    return X[np.random.choice(m, K, replace=False), :]


def find_closest_centroids(X, centroids):
    m = len(X)
    c = np.zeros(m)
    
    for i in range(m):
        # Find distances
        distances = np.linalg.norm(X[i] - centroids, axis=1)

        # Assign closest cluster to c[i]
        c[i] = np.argmin(distances)

    return c


def compute_means(X, idx, K):
    _, n = X.shape
    centroids = np.zeros((K, n))
    for k in range(K):
        examples = X[np.where(idx == k)]
        mean = [np.mean(column) for column in examples.T]
        centroids[k] = mean
    return centroids


def find_k_means(X, K, max_iters=10):
    centroids = initialize_K_centroids(X, K)
    previous_centroids = centroids
    for _ in range(max_iters):
        idx = find_closest_centroids(X, centroids)
        centroids = compute_means(X, idx, K)
        if (previous_centroids==centroids).all():
            # The centroids aren't moving anymore.
            return centroids
        else:
            previous_centroids = centroids

    return centroids, idx


def main():
    try:
        image_path = sys.argv[1]
        assert os.path.isfile(image_path)
    except (IndexError, AssertionError):
        print('Please specify an image')

    # Load the image
    image = load_image(image_path)
    w, h, d = image.shape
    print('Image found with width: {}, height: {}, depth: {}'.format(w, h, d))

    # Get the feature matrix X
    X = image.reshape((w * h, d))
    K = 40 # the number of colors in the image

    # Get colors
    print('Runnign K-means')
    colors, _ = find_k_means(X, K, max_iters=20)

    # Indexes for color for each pixel
    idx = find_closest_centroids(X, colors)

    # Reconstruct the image
    idx = np.array(idx, dtype=np.uint8)
    X_reconstructed = np.array(colors[idx, :] * 255, dtype=np.uint8).reshape((w, h, d))
    compressed_image = Image.fromarray(X_reconstructed)

    # Save reconstructed image to disk
    compressed_image.save('out.png')


if __name__ == '__main__':
    main()

 

See also  Python 3 BeautifulSoup4 Script to Get the Number of Paragraph Tags of a Given HTML Document Full Project For Beginners

 

Now you just need to execute this pythonscript and also you need to pass the path of image as the argument to the script as follows

 

python app.py sample.jpg

 

 

So sample.jpg here is the path of the image it is there in the same directory so we are passing it to the script.

See also  Python 3 Instagramy + Pandas Script to Scrape Instagram Users Followers and Following Usernames and Posts Data and Analyze them Full Project For Beginners

 

Leave a Reply