一、設計題目
對一幅BMP格式的灰度圖像(個人證件照片)進行二元霍夫曼編碼和譯碼
二、算法設計
(1)二元霍夫曼編碼:
①:圖像灰度處理:
利用python的PIL自帶的灰度圖像轉換函數,首先將彩色圖片轉為灰度的bmp圖像,此時每個像素點可以用單個像素點來表示。
②:二元霍夫曼編碼:
程序流程圖:

詳細設計:
- 統計像素點頻率,首先通過python自帶的PIL庫的圖像像素點讀取函數read()獲取灰度圖像的所有像素點,通過循環遍歷每個像素點,將每個出現的像素點值以及其次數以鍵值對的形式放入到python的字典中。
①:首先構造用以表示節點的類,其中每個節點包括一下成員屬性:
self.left = left
self.right = right
self.parent = parent
self.weight = weight
self.code = code
②:遍歷已經保存好的像素點頻率字典,將圖片中出現的像素點全部定義為葉子節點,通過類的code以及weight來表示對應的像素點值和該像素點出現的次數。
③:此時葉子結點中的權值為亂序,此時依據每個葉子結點的權重所有的葉子結點進行從小到大的排序;
④:每次取權值最小的兩個節點最為要被替換的節點,將這兩個節點的權值進行相加,然后生成新的節點,同時將這兩個節點從葉子結點列表中去除,同時將新生成的節點放入葉子節點列表,同時對列表進行排序;
⑤:重復步驟④,直到列表中還剩下一個節點,此時這個節點便為頭節點。
3.
①:根據已經構造好的二元霍夫曼編碼樹,由葉子節點開始遍歷整棵樹,左邊賦予碼字1,右邊賦予碼字0,每次向下遍歷一次,若節點為非根節點,則依次將碼符號放在碼字左邊,若遍歷到根節點,則將該葉子結點所表示的像素值以及對應編成的碼字放到碼字字典中;
②:重復步驟①,直到所有的葉子節點都有其對應的二元霍夫曼碼字。
③:經過步驟②,此時像素的碼字字典已經生成,此時回歸到原圖片,根據遍歷原圖片的像素點,依次在碼字列表中查找其對應的碼字,將所有像素點對應的碼字拼接在一起。
4.此時由於為二元霍夫曼編碼,則編碼結果為01字符串,此時為了對信息量進行壓縮,采用將8個string類似的值轉為一個byte,首先填充編碼結果使其長度為8的倍數,並增加冗余位數保存原使編碼結果最后多余位數的值以及其長度。填充完畢后,只需每次取編碼結果的八位轉為一個byte存入到txt中即可。
(2)二元霍夫曼譯碼:

詳細設計:
1.每次讀取txt中的一個字節,將其還原為字符串,直到txt中的所有字節被讀取結束 ,則所得到的字符串則為霍夫曼編碼的結果。
2.
①遍歷霍夫曼編碼的結果,根據霍夫曼編碼已經生成的碼字列表,對原始像素點進行還原,並根據還原后的像素點生成原始bmp圖片。
②:對於每一個被遍歷到的字符均在碼字列表中進行查找,若未找到則加上后續一個字符,繼續查找;
③:重復步驟③,直到在碼字列表中找到該碼字對應的像素點,將其碼字對應的像素值放入到像素點列表中,重復以上查找還原像素值的步驟直到所有字符串均被遍歷完。
三、模塊划分
(1)二元霍夫曼編碼部分:
①:類:
class node:
def __init__(self, right=None, left=None, parent=None, weight=0, code=None):
self.left = left
self.right = right
self.parent = parent
self.weight = weight
self.code = code
功能:表示葉子節點的類
②:函數:
def picture_convert():
功能:此函數完成彩色圖轉為灰度圖的功能
③:函數:
def pin_lv_tong_ji(list):
功能:統計每個像素出現的次數
④:函數
def gou_zao_ye_zi(xiang_su_zhi):
功能:此函數主要為生成葉子結點,將每個節點賦予權值與像素值
⑤:函數
def sort_by_weight(list_node):
功能:根據每個葉子結點的權重對葉子結點列表進行排序
⑥:函數
def huo_fu_man_shu(listnode):
功能:根據葉子結點列表,生成對應的霍夫曼編碼樹
⑦:函數
def er_yuan_huo_fu_man_bian_ma(picture):
功能:此函數為進行二元霍夫曼編碼的主函數,通過對其他函數的調用完成對像素點的編碼
⑧:函數
def zi_jie_xie_ru():
功能:由於霍夫曼編碼結果為string類型,此時應將其轉為byte保存,此函數完成將編碼結果的字節存入
(2)二元霍夫曼譯碼部分:
①:函數:
def zi_jie_du_qu(qqqq):
功能:根據霍夫曼編碼生成的txt文件讀取其中的字節恢復為字符串形式的編碼結果
②函數:
def er_yuan_huo_fu_man_yi_ma(kuan,gao)
功能:此為二元霍夫曼譯碼的主函數,通過調用其他函數來還原原始的bmp圖像
四、測試數據
測試采取圖片像素點個數大小兩種bmp圖進行:
圖片1信息:
名稱:new.bmp

大小: 255 KB (261,366 字節)
像素點個數為: 260288
灰度圖寬為448像素
灰度圖高為581像素
圖片2信息:
名稱:test1.bmp

大小:12.7 KB (13,078 字節)
像素點個數: 12000
灰度圖寬:96像素
灰度圖高:125像素
六、測試情況及結果分析:
(一)二元霍夫曼編碼過程:
圖片1測試結果:

程序運行后將會生成霍夫曼編碼表,並且將最終的編碼結果存入到當前程序運行目錄下的huo_fu_man_compress.txt中
由於存入為字節形式,以txt形式查看會顯示亂碼,屬於正常情況。



原始圖像大小為255kb,經過霍夫曼編碼最終大小為218kb,大小縮減了接近15%。
圖片2測試結果:

由程序運行結果可得出二元霍夫曼游程編碼結果保存到
er_yuan_huo_fu_man_youcheng_compress.txt中

由於存入為字節形式,以txt形式查看會顯示亂碼,屬於正常情況。

原始圖片大小為12.7kb,編碼結果文件為9.5kb,大小縮減了接近26%。
(二)二元霍夫曼譯碼過程:
圖一測試結果:

根據編碼生成的huo_fu_man_compress.txt還原原始bmp圖片並保存為
er_yuan_huo_fu_man_huan_yuan.bmp

還原后的圖片與原始圖片相符合,譯碼成功
圖片2測試結果:

根據編碼生成的huo_fu_man_compress.txt還原原始bmp圖片並保存為
er_yuan_huo_fu_man_huan_yuan.bmp

還原后的圖片與原始圖片相符合,譯碼成功
結果分析:
Bmp灰度圖片經過二元霍夫曼編碼后,文件大小總能夠縮小,即所占空間減小,即達到了壓縮的效果,壓縮效率會由像素點出現頻率的影響。
等長碼編碼位數的影響。
