繁体   English   中英

哈夫曼编码图像压缩

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM