日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据压缩之Huffman编码

發布時間:2023/12/31 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据压缩之Huffman编码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數據壓縮之Huffman編碼

  • 實驗介紹
    • 實驗環境介紹和項目使用方法
    • 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編碼,與自身計算得到的碼本的壓縮效果進行對比。

實驗環境介紹和項目使用方法

本次實驗使用的軟件為Visual Studio 2019(版本最好在2013以上);
具體安裝方式參考鏈接:VS2019安裝教程

安裝好VS2019后,打開HuffmanCodec項目文件,
即打開HuffmanCodec.sln文件。

帶參數調試VS項目的方法:
對具體需要使用的項目右鍵,設置為啟動項目;
下面以打開HuffmanEnc項目為例
如圖設置為啟動項目后,啟動項目會高亮顯示;
然后同樣對使用的項目右鍵,點擊最下面的屬性,選擇配置屬性下的調試

在命令參數部分寫入需要設置的命令即可。
以HuffEnc項目為例,從huff_enc.doc或huff_enc.c中的usage()函數中的內容可以得知,本項目輸入參數包含四種:
-i 代表輸入文件,本次輸入的為.img格式的raw圖像文件;
-o 代表輸出文件,本程序的輸出為.huff或.huffenc后綴的Huffman編碼文件;
-c 代表編碼使用的碼本文件,依然以.huff或.huffenc為后綴,如果不設置,默認在編碼前計算出對應圖像的碼本;
-s 代表碼本的存儲位置,以.huff或.huffenc為后綴,如果-c沒有被設置,則輸出由圖像自身計算出的碼本,如果-c被設置,則輸出和-c同樣的碼本;如果不設置,則默認寫入-o對應的輸出文件的頭部;

所以,輸入參數的格式為:
-i 輸入文件路徑 -o 輸出.huff文件路徑 -c 輸入碼本路徑 -s 輸出碼本路徑
其中每一部分需要用空格間隔開。

(需要注意的是,這樣的輸入格式是因為項目中代碼使用了相應的函數進行設置,并非所有項目的輸入都有同樣的參數設置格式,這里不再對這種函數進行介紹)

1.對.img圖像文件進行Huffman編碼

本次實驗所用的圖片大小皆為64KB,如圖所示:

編碼后結果如圖所示:
其中.huffenc為圖像編碼后結果
_code.huffenc為對應的碼本文件

可以看到編碼后文件大小整體被壓縮了大概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); /* 獲取指針所在的位置,(這里就相當于獲取到了文件數據的個數) */++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);}/* 獲取文件內容 */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為忽視老版本函數警告,
可根據具體情況進行刪減;
本項目在之前的大項目下會有傳參問題,
故需要在新的文件夾下另建一個項目;
本項目使用main函數進行傳參,
第一個參數為 輸入.img原圖像的路徑
第二個參數為 輸出.img差值圖像的路徑
輸出的路徑同樣需要先創建好文件夾)

本項目的差值壓縮方法:
通常情況下,當前位置與其左側位置的互信息最大,
即二者的相關性高,顧使用其與左側的差值代替當前位置;

使用當前像素值減去左側像素值得到當前位置的差值;
最左側像素則減去128得到最左側位置對應的差值。
使用本程序對sena.img、omaha.img、sensin.img三個圖像分別進行處理,
得到輸出的差值圖像;
之后再對輸出的差值圖像進行Huffman編碼;
結果如圖所示:

其中_diff.img為差值圖像文件;
_diff.huff對Huffman編碼后的文件;
_diffcode.huff為計算出的碼本文件;
可以看到,差值圖像普遍比原圖像增加了1KB,
是因為差值處理引入了負數導致整體大小變大了一點;

也可以看到
對差值圖像編碼后文件大小比原圖像的編碼后文件壓縮比更高;
其中sena.img和sensin.img壓縮提升多,但omaha.img壓縮提升不明顯。

3.使用其他圖像碼本對圖像進行Huffman編碼

首先使用對sensin.img圖像的碼本
即sensin_code.huffenc文件
對Bookshelf1.img和sena.img圖像進行Huffman編碼。

結果如下圖所示:

可以看到使用sensin碼本編碼的bookshelf1.img,
編碼后文件大小比使用自身碼本得到的文件更大,
甚至比原圖像文件更大;
而sena.img使用sensin碼本編碼后壓縮效果也不如使用原碼本。

總結

以上是生活随笔為你收集整理的数据压缩之Huffman编码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。