数据压缩之Huffman编码
數(shù)據(jù)壓縮之Huffman編碼
- 實驗介紹
- 實驗環(huán)境介紹和項目使用方法
- 1.對.img圖像文件進行Huffman編碼
- 2.編寫diff程序得到差值圖像,并進行Huffman編碼
- 3.使用其他圖像碼本對圖像進行Huffman編碼
實驗介紹
通過已有的HuffmanCodes項目,
1.對sena.img、omaha.img、sensin.img、Bookshelf1.img等raw圖像文件進行Huffman編碼;
2.自行編寫一段程序,對sena.img、omaha.img、sensin.img三者進行相鄰像素差值計算,并輸出差值圖像。然后分別對輸出的差值圖像進行Huffman編碼;
3.使用對sensin.img圖像進行Huffman編碼時生成的碼本(編碼樹),對Bookshelf1.img和sena.img圖像進行Huffman編碼,與自身計算得到的碼本的壓縮效果進行對比。
實驗環(huán)境介紹和項目使用方法
本次實驗使用的軟件為Visual Studio 2019(版本最好在2013以上);
具體安裝方式參考鏈接:VS2019安裝教程
安裝好VS2019后,打開HuffmanCodec項目文件,
即打開HuffmanCodec.sln文件。
帶參數(shù)調(diào)試VS項目的方法:
對具體需要使用的項目右鍵,設(shè)置為啟動項目;
下面以打開HuffmanEnc項目為例
如圖設(shè)置為啟動項目后,啟動項目會高亮顯示;
然后同樣對使用的項目右鍵,點擊最下面的屬性,選擇配置屬性下的調(diào)試
在命令參數(shù)部分寫入需要設(shè)置的命令即可。
以HuffEnc項目為例,從huff_enc.doc或huff_enc.c中的usage()函數(shù)中的內(nèi)容可以得知,本項目輸入?yún)?shù)包含四種:
-i 代表輸入文件,本次輸入的為.img格式的raw圖像文件;
-o 代表輸出文件,本程序的輸出為.huff或.huffenc后綴的Huffman編碼文件;
-c 代表編碼使用的碼本文件,依然以.huff或.huffenc為后綴,如果不設(shè)置,默認在編碼前計算出對應(yīng)圖像的碼本;
-s 代表碼本的存儲位置,以.huff或.huffenc為后綴,如果-c沒有被設(shè)置,則輸出由圖像自身計算出的碼本,如果-c被設(shè)置,則輸出和-c同樣的碼本;如果不設(shè)置,則默認寫入-o對應(yīng)的輸出文件的頭部;
所以,輸入?yún)?shù)的格式為:
-i 輸入文件路徑 -o 輸出.huff文件路徑 -c 輸入碼本路徑 -s 輸出碼本路徑
其中每一部分需要用空格間隔開。
(需要注意的是,這樣的輸入格式是因為項目中代碼使用了相應(yīng)的函數(shù)進行設(shè)置,并非所有項目的輸入都有同樣的參數(shù)設(shè)置格式,這里不再對這種函數(shù)進行介紹)
1.對.img圖像文件進行Huffman編碼
本次實驗所用的圖片大小皆為64KB,如圖所示:
編碼后結(jié)果如圖所示:
其中.huffenc為圖像編碼后結(jié)果
_code.huffenc為對應(yīng)的碼本文件
可以看到編碼后文件大小整體被壓縮了大概5~9KB
2.編寫diff程序得到差值圖像,并進行Huffman編碼
代碼如下:
#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <stdio.h> #include <string.h>int main(int argc, char** argv) {FILE* ifp, * ofp;unsigned char* file, * tmp, * tmp_diff;int size;char infile[80], outfile[80];strcpy(infile, argv[1]);strcpy(outfile, argv[2]);fopen_s(&ifp, infile, "rb");if (ifp == NULL) {printf("infile open error!");return 0;}fseek(ifp, 0, 2); /* 指針從文件末尾開始 */size = ftell(ifp); /* 獲取指針所在的位置,(這里就相當于獲取到了文件數(shù)據(jù)的個數(shù)) */++size;fseek(ifp, 0, 0); /* 指針從文件開頭開始 */file = (unsigned char*)malloc(size * sizeof(unsigned char) * 4); /* 開辟空間 */tmp = (unsigned char*)malloc(size * sizeof(unsigned char) * 4);tmp_diff = (unsigned char*)malloc(size * sizeof(unsigned char) * 4);if (file == NULL) {printf("Unable to allocate memory for file.\n");exit(1);}/* 獲取文件內(nèi)容 */fread(file, sizeof(unsigned char), size, ifp);fclose(ifp);fopen_s(&ofp, outfile, "wb");if (ofp == NULL) {printf("outfile open error!");return 0;}int i,j;for (i = 0;i < size;++i) {*(tmp + i) = *(file + i);}for (i = 0;i < 256;++i) {for (j = 0;j < 256;++j) {if (j == 0){*(tmp_diff + i * 256 + j) = (*(tmp + i * 256 + j) - 128);}else{*(tmp_diff + i * 256 + j) = (*(tmp + i * 256 + j) - *(file + i * 256 + j - 1));}}}fwrite(tmp_diff, sizeof(unsigned char), size, ofp);fclose(ofp);return 0; }(#define _CRT_SECURE_NO_WARNINGS為忽視老版本函數(shù)警告,
可根據(jù)具體情況進行刪減;
本項目在之前的大項目下會有傳參問題,
故需要在新的文件夾下另建一個項目;
本項目使用main函數(shù)進行傳參,
第一個參數(shù)為 輸入.img原圖像的路徑
第二個參數(shù)為 輸出.img差值圖像的路徑
輸出的路徑同樣需要先創(chuàng)建好文件夾)
本項目的差值壓縮方法:
通常情況下,當前位置與其左側(cè)位置的互信息最大,
即二者的相關(guān)性高,顧使用其與左側(cè)的差值代替當前位置;
使用當前像素值減去左側(cè)像素值得到當前位置的差值;
最左側(cè)像素則減去128得到最左側(cè)位置對應(yīng)的差值。
使用本程序?qū)ena.img、omaha.img、sensin.img三個圖像分別進行處理,
得到輸出的差值圖像;
之后再對輸出的差值圖像進行Huffman編碼;
結(jié)果如圖所示:
其中_diff.img為差值圖像文件;
_diff.huff對Huffman編碼后的文件;
_diffcode.huff為計算出的碼本文件;
可以看到,差值圖像普遍比原圖像增加了1KB,
是因為差值處理引入了負數(shù)導(dǎo)致整體大小變大了一點;
也可以看到
對差值圖像編碼后文件大小比原圖像的編碼后文件壓縮比更高;
其中sena.img和sensin.img壓縮提升多,但omaha.img壓縮提升不明顯。
3.使用其他圖像碼本對圖像進行Huffman編碼
首先使用對sensin.img圖像的碼本
即sensin_code.huffenc文件
對Bookshelf1.img和sena.img圖像進行Huffman編碼。
結(jié)果如下圖所示:
可以看到使用sensin碼本編碼的bookshelf1.img,
編碼后文件大小比使用自身碼本得到的文件更大,
甚至比原圖像文件更大;
而sena.img使用sensin碼本編碼后壓縮效果也不如使用原碼本。
總結(jié)
以上是生活随笔為你收集整理的数据压缩之Huffman编码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 赵山林c语言程序设计答案,c语言程序设计
- 下一篇: dede模板标签帮助[DedeCMS教程