信源编码技术-作业2-哈夫曼编码
1. 哈夫曼编码实验
针对所给的Sena、Sensin和Omaha三幅图像的说明(参见项目readme):
每张图像均为256x256的灰度图。
Sena | Sensin | Omaha |
---|---|---|
![]() | ![]() | ![]() |
*使用YUV Player打开源图像,下载地址:https://github.com/latelee/YUVPlayer
针对所给程序命令参数的说明:

1.1 利用自身码本对源图像进行编码
在调试->调试属性->配置属性->调试->命令参数中输入
-i ..\images\sensin.img -o .\out\sensin.huff
编码后文件大小差异如下图所示:
源图像大小 | 编码后大小 | 压缩率 | |
---|---|---|---|
sena | 64.0 KB | 56.1 KB | 87.66 % |
sensin | 64.0 KB | 58.7 KB | 91.72 % |
omaha | 64.0 KB | 57.0 KB | 89.06 % |
1.2 对差值图像进行编码
1)将源图像转换为差值图像
图中每行的第一个像素保留原值,其余像素使用后向差分计算。对差值进行8bit量化,得到的差值图像如下图所示(以sena为例)。
差值图像

DPCM程序
/* Your codes here */
#include <iostream>
#include <fstream>
using namespace std;
#define Width 256
#define Height 256
int main()
{
// 打开要读入的文件
ifstream File_in;
File_in.open("../images/sensin.img", ios::in | ios::binary);
if (!File_in) {
cout << "Can't open the input imgage!";
return 0;
}
// 打开要输出的差值文件
ofstream File_out;
File_out.open("out/sensin_diff.img", ios::out | ios::binary);
if (!File_in) {
cout << "Can't open the output imgage! ";
return 0;
}
unsigned char* grey_buff = NULL;
unsigned char* diff_buff = NULL;
grey_buff = new unsigned char[Width * Height];
diff_buff = new unsigned char[Width * Height];
// 读入每个像素点的灰度
File_in.read((char*)grey_buff, Width * Height);
//第一列直接赋值
for (int i = 0; i < Width * Height; i = i + Width) {
diff_buff[i] = grey_buff[i];
}
// 其余列求差赋值
for (int i = 0; i < Height; i++) {
for (int j = 1; j < Width; j++) {
int diff = grey_buff[i * Width + j] - grey_buff[i * Width + j - 1];
// 对差值进行8bit量化
diff = (int)(diff + 255) / 2.0;
diff = diff > 255 ? 255 : diff;
diff = diff < 0 ? 0 : diff;
// 赋值
diff_buff[i * Width + j] = (unsigned char)diff;
}
}
File_out.write((char*)diff_buff, Width * Height);
File_in.close();
File_out.close();
delete[] grey_buff;
delete[] diff_buff;
return 0;
}
2)编码
在调试->调试属性->配置属性->调试->命令参数中输入
-i ..\images\sensin_diff.img -o .\out\sensin_diff.huff
编码后文件大小差异如下图所示:
残差图像大小 | 残差图像编码后大小 | 压缩比 | 源图像压缩-压缩比 | |
---|---|---|---|---|
sena | 64.0 KB | 25.2 KB | 39.38 % | 87.66 % |
sensin | 64.0 KB | 30.1 KB | 41.03 % | 91.72 % |
omaha | 64.0 KB | 44.6 KB | 69.69 % | 89.06 % |
1.3 利用Sensin图像生成的码本给其他文件进行编码
1)生成码本
在调试->调试属性->配置属性->调试->命令参数中输入
-i ..\images\sensin.img -o .\out\sensin.huff -s .\out\sensin.code
2)编码
在调试->调试属性->配置属性->调试->命令参数中输入
-i ..\images\bookshelf1.img -o .\out\bookshelf1_by_sensin_code.huff -c .\out\sensin.code
源图像大小 | 编码后大小(自身码本) | 编码后大小(sensin码本) | |
---|---|---|---|
bookshelf1 | 64.0 KB | 59.5 KB | 70.8 KB |
sena | 64.0 KB | 25.2 KB | 59.2 KB |
利用sensin码本编码的文件大小远高于利用自身码本编码的文件大小。