数字图像处理知识
1.Huffman编码
#Huffman编码
class Node:
def __init__(self, name, weight):
self.name = name # 节点名
self.weight = weight # 节点权重
self.left = None # 节点左子树
self.right = None # 节点右子树
self.father = None # 节点父节点
# 判断是否是左子树
def is_left_child(self):
return self.father.left == self
#创建最初的叶子节点
def create_prim_nodes(Data_set, Labels):
if len(Data_set) != len(Labels):
raise Exception('数据和标签不匹配!')
nodes = []
for i in range(len(Labels)):
nodes.append(Node(Labels[i], Data_set[i]))
return nodes
#创建huffman树
def create_HF_tree(nodes):
tree_nodes = nodes.copy()
while len(tree_nodes) > 1: # 只剩根节点时,退出循环
tree_nodes.sort(key=lambda node: node.weight) # 升序排列
new_left = tree_nodes.pop(0)
new_right = tree_nodes.pop(0)
new_node = Node(None, (new_left.weight + new_right.weight))
new_node.left = new_left
new_node.right = new_right
new_left.father = new_right.father = new_node
tree_nodes.append(new_node)
tree_nodes[0].father = None # 根节点父亲为None
return tree_nodes[0] # 返回根节点
#获取huffman编码
def get_huffman_code(nodes):
codes = {}
for node in nodes:
code = ''
name = node.name
while node.father != None:
if node.is_left_child():
code = '0' + code
else:
code = '1' + code
node = node.father
codes[name] = code
return codes
if __name__ == '__main__':
labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
data_set = [19, 12, 6, 3, 5, 15, 34, 110]
nodes = create_prim_nodes(data_set, labels) # 创建初始叶子节点
root = create_HF_tree(nodes) # 创建huffman树
codes = get_huffman_code(nodes) # 获取huffman编码
# 打印huffman码
for key in codes.keys():
print(key, ': ', codes[key])
运行结果
a : 001
b : 0100
c : 01010
d : 010110
e : 010111
f : 000
g : 011
h : 1
2.行程编码
#行程编码示例
import cv2 as cv
import numpy as np
grayimg = cv.imread('E:\\DIP_Photo\\Diningroom.jpg', 0)
rows, cols = grayimg.shape
image1 = grayimg.flatten() # 把灰度化后的二维图像降维为一维列表
print(len(image1))
#二值化操作
for i in range(len(image1)):
if image1[i] >= 127:
image1[i] = 255
if image1[i] < 127:
image1[i] = 0
data = []
image3 = []
count = 1
#行程压缩编码
for i in range(len(image1) - 1):
if count == 1:
image3.append(image1[i])
if image1[i] == image1[i + 1]:
count = count + 1
if i == len(image1) - 2:
image3.append(image1[i])
data.append(count)
else:
data.append(count)
count = 1
if image1[len(image1) - 1] != image1[-1]:
image3.append(image1[len(image1) - 1])
data.append(1)
#压缩率
ys_rate = len(image3) / len(image1) * 100
print('压缩率为' + str(ys_rate) + '%')
#行程编码解码
rec_image = []
for i in range(len(data)):
for j in range(data[i]):
rec_image.append(image3[i])
rec_image = np.reshape(rec_image, (rows, cols))
#cv.imwrite('output_SHZU.jpg', rec_image)
cv.imshow('rec_image', rec_image) # 重新输出二值化图像
cv.waitKey(0)
运行结果
240000
压缩率为1.92375%
3.算数编码
#算数编码的实现
def get_dict_from_singal():
singal_dict = {'A': (0, 0.1), 'B': (0.1, 0.5), 'C': (0.5, 0.7), 'D': (0.7, 1)}
return singal_dict
def encoder(singal, singal_dict):
Low = 0
High = 1
for s in singal:
CodeRange = High - Low
High = Low + CodeRange * singal_dict[s][1]
Low = Low + CodeRange * singal_dict[s][0]
return Low
def decoder(encoded_number, singal_dict, singal_length):
singal = []
while singal_length:
for k, v in singal_dict.items():
if v[0] <= encoded_number < v[1]:
singal.append(k)
range = v[1] - v[0]
encoded_number -= v[0]
encoded_number /= range
break
singal_length -= 1
return singal
def main():
singal_dict = get_dict_from_singal()
singal = 'CADACDB'
ans = encoder(singal, singal_dict)
print(ans)
singal_rec = decoder(ans, singal_dict, len(singal))
print(singal_rec)
if __name__ == '__main__':
main()
运行结果
0.5143876000000001
[‘C’, ‘A’, ‘D’, ‘A’, ‘C’, ‘D’, ‘B’]