Skip to content
Open
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
Binary file added 2020BTEIT00031_Assignment 2/compressed_image.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
219 changes: 219 additions & 0 deletions 2020BTEIT00031_Assignment 2/compression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
# Name:Vaishnvi Vivekanand Kulkarni
# PRN:2020BTEIT00031
# Program for image compression using 3-Dimensional Codebook



import cv2
import lbg
import math
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

def generate_training(img, block):
"""
This function will generate the training codevector from the image via non-overlapped patch.
"""
train_vec = []
x = block[0]
y = block[1]
for i in range(0, img.shape[0], x):
for j in range(0, img.shape[1], y):
train_vec.append(img[i:i + x, j:j + y].reshape((x * y)))
return (np.array(train_vec))

def generate_multi_training(path_list, block):
"""
This function will generate the training codevector from the multi-image via non-overlapped patch.
"""
img_list = []
for path in path_list:
img_list.append(cv2.imread(path, cv2.IMREAD_GRAYSCALE))
train_vec = []
x = block[0]
y = block[1]
for img in img_list:
for i in range(0, img.shape[0], x):
for j in range(0, img.shape[1], y):
train_vec.append(img[i:i + x, j:j + y].reshape((x * y)))
return (np.array(train_vec))


def distance(a, b):
"""
This function will calculate the distance (MSE) of two vectors.
"""
return np.mean((np.subtract(a, b) ** 2))


def closest_match(src, cb):
"""
This function will get the closest distance (nearest) of the compared vectors.
"""
c = np.zeros((cb.shape[0],))
for i in range(0, cb.shape[0]):
c[i] = distance(src, cb[i])
minimum = np.argmin(c, axis=0)
return minimum


def encode_image(img, cb, block):
"""
This function will encode (compress) the image by sending the image block, vectorize it then get the index of the
closest vector to form the compressed data.
"""
x = block[0]
y = block[1]
compressed = np.zeros((img.shape[0] // y, img.shape[1] // x))
ix = 0
for i in range(0, img.shape[0], x):
iy = 0
for j in range(0, img.shape[1], y):
src = img[i:i + x, j:j + y].reshape((x * y)).copy()
k = closest_match(src, cb)
compressed[ix, iy] = k
iy += 1
ix += 1
return compressed


def decode_image(cb, compressed, block):
"""
This function will decode the compressed data beck to the image by taking the index of the codebook then copy the associate vector to the image block.
"""
x = block[0]
y = block[1]
original = np.zeros((compressed.shape[0] * y, compressed.shape[1] * x))
ix = 0
for i in range(0, compressed.shape[0]):
iy = 0
for j in range(0, compressed.shape[1]):
original[ix:ix + x, iy:iy + y] = cb[int(compressed[i, j])].reshape(block)
iy += y
ix += x
return original


def save_weight(filename, cb):
"""
This function will save the absolute and relative weight as CSV file.
"""
fd = open(filename, 'a')
for i in range(0, cb.shape[0]):
linecsv = str(cb[i]) + '\n'
fd.write(linecsv)
fd.close()


def save_codebook(filename, cb):
"""
This function will save the codebook as CSV file.
"""
fd = open(filename, 'a')
for i in range(0, cb.shape[0]):
linecsv = ''
for j in range(0, cb.shape[1]):
linecsv = linecsv + str(cb[i, j]) + ','
linecsv = linecsv + '\n'
fd.write(linecsv)
fd.close()


def save_csv(root, csv, cb, cb_abs_w, cb_rel_w):
"""
This function will save the codebook and weight as CSV file given the associate name.
"""
numpy_cb = np.array(cb)
numpy_abs_w = np.array(cb_abs_w)
numpy_rel_w = np.array(cb_rel_w)
save_codebook(root + 'CB_' + csv + '.csv', numpy_cb)
save_weight(root + '3CB_abs_' + csv + '.csv', numpy_abs_w)
save_weight(root + '3CB_rel_' + csv + '.csv', numpy_rel_w)


def sim_protocol(img, cb_size, epsilon, block, root, outpng):
"""
This function needod for doing simulation for different scenario.
"""
train_X = generate_training(img, block)
cb, cb_abs_w, cb_rel_w = lbg.generate_codebook(train_X, cb_size, epsilon)
cb_n = np.array(cb)
cb_abs_w_n = np.array(cb_abs_w)
cb_rel_w_n = np.array(cb_rel_w)
result = encode_image(img, cb_n, block)
final_result = decode_image(cb_n, result, block)
fig = plt.gcf()
fig.set_figheight(6)
fig.set_figwidth(6)
plt.imshow(final_result, cmap='gray')
cv2.imwrite(root + outpng + '.png', final_result)
save_csv(root, outpng, cb_n, cb_abs_w_n, cb_rel_w_n)

def sim_multi_protocol(path_list, cb_size, epsilon, block, root, outpng):
"""
This function needod for doing simulation for different scenario.
"""
train_X = generate_multi_training(path_list, block)
cb, cb_abs_w, cb_rel_w = lbg.generate_codebook(train_X, cb_size, epsilon)
cb_n = np.array(cb)
cb_abs_w_n = np.array(cb_abs_w)
cb_rel_w_n = np.array(cb_rel_w)
save_csv(root, outpng, cb_n, cb_abs_w_n, cb_rel_w_n)
print('Weight Saved as: '+outpng)

def sim_testing_protocol(inpath_list, weight, block, outpng):
"""
This function needod for doing simulation for different scenario.
"""
fig, ax = plt.subplots(nrows=1, ncols=4)
idx = 1
for inpath in inpath_list:
img = cv2.imread(inpath, cv2.IMREAD_GRAYSCALE)
cb = pd.read_csv(weight, header=None).as_matrix().astype('int')
cb = cb[:,0:cb.shape[1]-1]
result = encode_image(img, cb, block)
final_result = decode_image(cb, result, block)
rem = inpath.replace('./images/', '')
cv2.imwrite(outpng + rem.replace('.csv',''), final_result)
psnr_value = psnr(img, final_result)
ax = plt.subplot(1, 4, idx)
ax.set_title('PSNR = {}'.format(psnr_value))
ax.imshow(final_result, cmap='gray')
idx+=1
fig.set_figheight(6)
fig.set_figwidth(24)
plt.show()


def psnr(img1, img2):
"""
This function will calculate the PSNR of two images.
"""
mse = np.mean( (img1 - img2) ** 2 )
if mse == 0:
return 100
PIXEL_MAX = 255.0
return 20 * math.log10(PIXEL_MAX / math.sqrt(mse))


def measure_psnr(apath, bpath):
"""
This function will doing PSNR comparison of two images.
"""
img1 = cv2.imread(apath, cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread(bpath, cv2.IMREAD_GRAYSCALE)
print('PSNR: {}'.format(psnr(img1, img2)))

fig, ax = plt.subplots(nrows=1, ncols=2)
ax1 = plt.subplot(1, 2, 1)
ax1.set_title("Original")
ax1.imshow(img1, cmap='gray')

ax2 = plt.subplot(1, 2, 2)
ax2.set_title("Result")
ax2.imshow(img2, cmap='gray')

fig.set_figheight(7)
fig.set_figwidth(14)
plt.show()
135 changes: 135 additions & 0 deletions 2020BTEIT00031_Assignment 2/encoding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Name:Vaishnvi Vivekanand Kulkarni
# PRN:2020BTEIT00031
# Program using huffman coding to compress the image

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")
16 changes: 16 additions & 0 deletions 2020BTEIT00031_Assignment 2/observation.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Name:Vaishnavi Vivekanand Kulkarni
PRN:2020BTEIT00031


Original image size:19kb
compressed image size:11kb

Observation:By using Vector quantization algorithm:
Output image is 40% smaller than input image
So, compressed ratio is:0.4


Huffman Encoding Time Complexity:

Time complexity: O(nlogn)

Binary file added 2020BTEIT00031_Assignment 2/original_image.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.