diff --git a/Assignment 2/HuffmanEncoding.py b/Assignment 2/HuffmanEncoding.py new file mode 100644 index 0000000..f8f2aa4 --- /dev/null +++ b/Assignment 2/HuffmanEncoding.py @@ -0,0 +1,131 @@ +import re +import numpy as np +from PIL import Image +print("Huffman Compression Program") + +file = "output.png" +my_string = np.asarray(Image.open(file), np.uint8) +shape = my_string.shape +a = my_string + +my_string = str(my_string.tolist()) + + +letters = [] +only_letters = [] +for letter in my_string: + if letter not in letters: + frequency = my_string.count(letter) + letters.append(frequency) + letters.append(letter) + only_letters.append(letter) + +nodes = [] +while len(letters) > 0: + nodes.append(letters[0:2]) + letters = letters[2:] +nodes.sort() +huffman_tree = [] +huffman_tree.append(nodes) + + +def combine_nodes(nodes): + pos = 0 + newnode = [] + if len(nodes) > 1: + nodes.sort() + nodes[pos].append("1") + nodes[pos+1].append("0") + combined_node1 = (nodes[pos][0] + nodes[pos+1][0]) + combined_node2 = (nodes[pos][1] + nodes[pos+1][1]) + newnode.append(combined_node1) + newnode.append(combined_node2) + newnodes = [] + newnodes.append(newnode) + newnodes = newnodes + nodes[2:] + nodes = newnodes + huffman_tree.append(nodes) + combine_nodes(nodes) + return huffman_tree + + +newnodes = combine_nodes(nodes) + +huffman_tree.sort(reverse=True) +print("Huffman tree with merged pathways:") + +checklist = [] +for level in huffman_tree: + for node in level: + if node not in checklist: + checklist.append(node) + else: + level.remove(node) +count = 0 +for level in huffman_tree: + print("Level", count, ":", level) + count += 1 +print() + +letter_binary = [] +if len(only_letters) == 1: + lettercode = [only_letters[0], "0"] + letter_binary.append(letter_code*len(my_string)) +else: + for letter in only_letters: + code = "" + for node in checklist: + if len(node) > 2 and letter in node[1]: + code = code + node[2] + lettercode = [letter, code] + letter_binary.append(lettercode) +print(letter_binary) +print("Binary code generated:") +for letter in letter_binary: + print(letter[0], letter[1]) + +bitstring = "" +for character in my_string: + for item in letter_binary: + if character in item: + bitstring = bitstring + item[1] +binary = "0b"+bitstring +print("Your message as binary is:") + + +uncompressed_file_size = len(my_string)*7 +compressed_file_size = len(binary)-2 +print("Your original file size was", uncompressed_file_size, + "bits. The compressed size is:", compressed_file_size) +print("This is a saving of ", uncompressed_file_size-compressed_file_size, "bits") +output = open("compressed.txt", "w+") +print("Compressed file generated as compressed.txt") +output = open("compressed.txt", "w+") +print("Decoding.......") +output.write(bitstring) + +bitstring = str(binary[2:]) +uncompressed_string = "" +code = "" +for digit in bitstring: + code = code+digit + pos = 0 + for letter in letter_binary: + if code == letter[1]: + uncompressed_string = uncompressed_string+letter_binary[pos][0] + code = "" + pos += 1 + +temp = re.findall(r'\d+', uncompressed_string) +res = list(map(int, temp)) +res = np.array(res) +res = res.astype(np.uint8) +res = np.reshape(res, shape) +print(res) +print("Observe the shapes and input and output arrays are matching or not") +print("Input image dimensions:", shape) +print("Output image dimensions:", res.shape) +data = Image.fromarray(res) +data.save('previous.png') +if a.all() == res.all(): + print("Success") \ No newline at end of file diff --git a/Assignment 2/Observation.txt b/Assignment 2/Observation.txt new file mode 100644 index 0000000..de2fbae --- /dev/null +++ b/Assignment 2/Observation.txt @@ -0,0 +1,33 @@ +Name : Supriya Manikrao Pawar +PRN : 2020BTEIT00052 +Batch : T5 +Course : Computer Algorithm + +Assignment No:2 +Vector Quantization and Huffman Encoding + +Problem Statement: To use the Vector Quantization Algorithm to compressed an image. + Get the Huffman code of the input image using Huffman Encoding Algorithm. + +Quantization means approximation. +Here for this I have chosen 240*240 pixels PNG image which of 2 kb originally. +I have compressed this image using vector quantization and the reconstructed size is 1 kb. + +Files: + Images: + 1.OriginalGreyImage.png is the image before compressing + 2.ReconstructedImg.png is the image after compressing + + Coding: + 1.VectorQuatization is the file written in Python which contains the code for compressing image. + 2.HuffmanEncoding is the file in Python. + I have created these files by referring on the google and youTube. + + Observations: + File is reduced from 2 kb to 1 kb after compression. + Compression rate: Original image/Compressed image + = 2kb /1 kb + = 2 + + The time complexity for Huffman algorithm is O(nlogn). + n is the number of nodes of tree. \ No newline at end of file diff --git a/Assignment 2/OriginalGreyImage.png b/Assignment 2/OriginalGreyImage.png new file mode 100644 index 0000000..da394ac Binary files /dev/null and b/Assignment 2/OriginalGreyImage.png differ diff --git a/Assignment 2/ReconstructedImg.png b/Assignment 2/ReconstructedImg.png new file mode 100644 index 0000000..fd1cbc4 Binary files /dev/null and b/Assignment 2/ReconstructedImg.png differ diff --git a/Assignment 2/VectorQuantization.py b/Assignment 2/VectorQuantization.py new file mode 100644 index 0000000..0be843e --- /dev/null +++ b/Assignment 2/VectorQuantization.py @@ -0,0 +1,54 @@ +import argparse +from PyQt4 import QtCore +import numpy as np +from scipy import misc +from sklearn import cluster +import matplotlib.pyplot as plt + +def build_arg_parser():s + parser=argparse.ArgumentParser(description='Compress the input image\using clustering') + parser.add_argument("--input-file",dest="input_file",required=True,help="Input image") + parser.add_argument("--num-bits",dest="num_bits",required=False,type=int,help="Number of bits used to represent each pixel") + return parser + +def compress_image(img,num_cluster): + + x=img.reshape((-1,1)) + + kmeans=cluster.KMeans(n_clusters=num_clusters,n_init=4,random_state=5) + kmeans.fit(X) + centroids = kmeans.cluseter_centers_squeeze() + labels = kmeans.labels_ + + + input_image_compressed = np.choose(labels, centroids).reshape(img.shape) + return input_image_compressed + +def plot_image(img, title): + vmin = img.min() + vmax=img.max() + plt.figure() + plt.title(title) + plt.imshow(img, cmap=plt.cm.gray, vmin=min, vmax=max) + +if _name_=='_main_': + args = build_arg_parser().parse_args() + input_file = args.input_file + num_bits = args.num_bits + + if not 1 <= num_bits <= 8: + raise TypeError('Number of bits should be between 1 and 8') + + num_clusters = np.power(2,num_bits) + + compression_rate = round(100*(8.0 - args.num_bits)/8.0, 2) + print('\nThe size of the image will be reduced by a factor of', 8.0/args.num_bits) + print('\nCompression rate = '+ str(compression_rate)+'%') + input_image = misc.imread(input_file, True).astype(np.uint8) + + plot_image(input_image, 'Original image') + + input_image_compressed = compress_image(input_image, num_clusters) + plot_image(input_image_compressed, 'Compressed image; compression rate = '+ str(compression_rate)+'%') + + plt.show() \ No newline at end of file