[英]Image compression with Huffman coding
我使用 python 中的霍夫曼编码来压缩图像。 之后,我发现我的电脑中的图像大小为 318 KB,压缩后的文件大小为 107,551 KB(附图)。 我想知道,“图像尺寸是否正确?”。 换句话说,当我们在PC中谈论图像尺寸时,我们如何获得相应的尺寸? 如果我们看到附加的图像,那么,我的压缩算法有问题,对吗? 因为在附加图像中,图像大小为 318 KB,压缩文件为 107,551 KB。
这是我的代码如下:
path = input('Enter image path:')
image = np.asarray(Image.open(path))
pixels = []
for row in image:
for ch in row:
for pix in ch:
pixels.append(pix)
class Node:
def __init__(self, prob, symbol, left=None, right=None):
# probability of symbol
self.prob = prob
# symbol
self.symbol = symbol
# left node
self.left = left
# right node
self.right = right
# tree direction (0/1)
self.code = ''
""" A function to print the codes of symbols by traveling Huffman Tree"""
codes = dict()
def Calculate_Codes(node, val=''):
# huffman code for current node
newVal = val + str(node.code)
if(node.left):
Calculate_Codes(node.left, newVal)
if(node.right):
Calculate_Codes(node.right, newVal)
if(not node.left and not node.right):
codes[node.symbol] = newVal
return codes
""" A function to get the probabilities of symbols in given data"""
def Calculate_Probability(data):
symbols = dict()
for element in data:
if symbols.get(element) == None:
symbols[element] = 1
else:
symbols[element] += 1
return symbols
""" A function to obtain the encoded output"""
def Output_Encoded(data, coding):
encoding_output = []
for c in data:
# print(coding[c], end = '')
encoding_output.append(coding[c])
string = ''.join([str(item) for item in encoding_output])
return string
""" A function to calculate the space difference between compressed and non compressed data"""
def Total_Gain(data, coding):
before_compression = len(data) * 8 # total bit space to stor the data before compression
after_compression = 0
symbols = coding.keys()
for symbol in symbols:
count = data.count(symbol)
after_compression += count * len(coding[symbol]) #calculate how many bit is required for that symbol in total
print("Space usage before compression (in bits):", before_compression)
print("Space usage after compression (in bits):", after_compression)
def Huffman_Encoding(data):
symbol_with_probs = Calculate_Probability(data)
symbols = symbol_with_probs.keys()
probabilities = symbol_with_probs.values()
print("symbols: ", symbols)
print("probabilities: ", probabilities)
nodes = []
# converting symbols and probabilities into huffman tree nodes
for symbol in symbols:
nodes.append(Node(symbol_with_probs.get(symbol), symbol))
while len(nodes) > 1:
# sort all the nodes in ascending order based on their probability
nodes = sorted(nodes, key=lambda x: x.prob)
# for node in nodes:
# print(node.symbol, node.prob)
# pick 2 smallest nodes
right = nodes[0]
left = nodes[1]
left.code = 0
right.code = 1
# combine the 2 smallest nodes to create new node
newNode = Node(left.prob+right.prob, left.symbol+right.symbol, left, right)
nodes.remove(left)
nodes.remove(right)
nodes.append(newNode)
huffman_encoding = Calculate_Codes(nodes[0])
print("symbols with codes", huffman_encoding)
Total_Gain(data, huffman_encoding)
encoded_output = Output_Encoded(data,huffman_encoding)
return encoded_output, nodes[0]
encoding, tree = Huffman_Encoding(pixels)
file = open('compressed.txt','w')
file.write(encoding)
file.close()
您的图像已经有效地压缩为 JPEG。 任何无损压缩最终都会产生更大的结果。
加载图像后,解压缩立即将其从 0.3 MB 压缩到 6.6 MB。 您写出的内容是生成的位大小的八倍,因为您正在为 0 位写入0
字符,为 1 位写入1
字符。 所以现在我们的扩展系数是 53 到大约 17 MB。
我没有尝试查看您在这两者之间所做的事情,这显然是您对霍夫曼编码的尝试,但您的结果是 46 MB。 所以在某处还有另一个三个扩展的因素。
扩展 150 倍并不完全是我所说的压缩。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.