2,利用程序huff_enc和huff_dec进行以下操作(在每种情况下,利用由被压缩图像生成的码本)。
(a)对sena、sensin和omaha图像进行编码。
以sena图像为例(注:对图像进行编码时需要将该img文件移到HuffmanEnc文件夹内)
HuffmanEnc属性页——命令参数:
输入原始文件sena.img,输出编码后文件senai.img,输出码本storecode
输出的文件也都会在HuffmanEnc文件夹内。
设置完命令参数后启动本地Windows调试器即可完成对原始文件的编码。同理,可对sensin和omaha图像进行编码。
编码结果
文件名 | 文件大小 | 压缩后文件名 | 压缩后文件大小 | 压缩比 |
sena.img | 64.0kb(65,536字节) | senai.img | 54.9kb(56,223字节) | 1.166:1 |
sensin.img | 64.0kb(65,536字节) | sensini.img | 58.7kb(60,149字节) | 1.090:1 |
omaha.img | 64.0kb(65,536字节) | omahai.img | 55.7kb(57,095字节) | 1.149:1 |
三幅图像中sena压缩比最大,sinan压缩比最小。压缩比越大图像被压缩的程度越大,说明图像的冗余信息越多。
(b)编写一段程序,得到相邻像素之差,然后利用huffman对差值图像进行编码。
编写代码imgdiff.cpp生成每个图像所对应的残差图像。残差图像的生成采用后向的DPCM,并采用8bit量化。
DPCM代码:
图像文件放置在imgdiff.cpp所在文件夹内,生成的残差图像文件也会在该文件夹内。
/* Your codes here */
#include<stdio.h>
#include<math.h>
#include<iostream>
using namespace std;
#pragma warning(disable:4996);
void dpcm_diff(unsigned char* imagebuf, unsigned char* diffbuf, int width, int height, int bitdepth)
{
for (int i = 0; i < width; i++)
{
for (int j = 1; j < height; j++)
{
diffbuf[i * width + j] = (imagebuf[i * width + j] - imagebuf[i * width + j - 1] + 255) / pow(2, (9 - bitdepth));
}
}
for (int i = 0; i < width * height; i++)
{
if (diffbuf[i] > 255)
diffbuf[i] = 255;
if (diffbuf[i] < 0)
diffbuf[i] = 0;
}
}
void main()
{
FILE* image = NULL; FILE* qyuv = NULL; FILE* diff_image = NULL;
const int width = 256; const int height = 256;
int bitdepth = 8;
if (!(image = fopen("omaha.img", "rb")))
{
printf("open file error!");
exit(-1);
}
else
{
printf("open file success");
}
if (!(diff_image = fopen("omaha_diff.img", "wb")))
{
printf("open file error!");
exit(-1);
}
else
{
printf("open file success");
}
unsigned char* imagebuf = (unsigned char*)malloc(sizeof(unsigned char) * width * height);
unsigned char* diffbuf = (unsigned char*)malloc(sizeof(unsigned char) * width * height);
fread(imagebuf, sizeof(unsigned char), width * height, image);
dpcm_diff(imagebuf, diffbuf, width, height, bitdepth);
fwrite(diffbuf, sizeof(unsigned char), width * height, diff_image);
free(diffbuf); free(imagebuf);
fclose(image);
fclose(diff_image);
}
上述代码生成omaha_diff.img文件,同理,用该代码可生成sena_diff.img和sensin_diff.img文件。
生成残差图像文件后再对上述文件使用hu'ff_enc程序进行霍夫曼编码。
使用的命令参数:
对sena_diff.img和sensin_diff.img进行同样的操作,得到
文件名 | 文件大小 | 压缩后文件名 | 压缩后文件大小 | 压缩比 |
sena_diff.img | 64.0kb(65,536字节) | sena_diff_huff.img | 25.0kb(25,679字节) | 2.56:1 |
sensin_diff.img | 64.0kb(65,536字节) | sensin_diff_huff.img | 29.9kb(30,692字节) | 2.14:1 |
omaha_diff.img | 64.0kb(65,536字节) | omaha_diff_huff.img | 44.6kb(45,678字节) | 1.43:1 |
使用了DPCM后的霍夫曼编码与单独使用霍夫曼编码相比,压缩率大大提高。
3,利用程序huff_enc和huff_dec,并使用由sensin图像生成的码本,对bookshelf1和sena图像进行编码,将这一结果与使用被压缩图像生成码本的情况进行对比。
以bookshelf1图像为例,使用由sensin图像生成的码本进行编码
HuffmanEnc属性页——命令参数:
输入原始文件bookshelf1.img,输出编码后文件bookshelfa.img,输入码本storecode2(由sensin图像生成的码本——上一题中生成的输出码本)
设置完命令参数后启动本地Windows调试器即可完成对原始文件的编码。同理,可对sena进行编码。
编码结果
文件名 | 文件大小 | 本码压缩文件大小 | sensin码本压缩文件名 | sensin码本压缩文件大小 |
bookshelf1.img | 64.0kb(65,536字节) | 58.2kb(59.667字节) | bookshelfa.img | 70.8kb(72.543字节) |
sena.img | 64.0kb(65,536字节) | 54.9kb(56.223字节) | senaa.img | 59.2kb(60.719字节) |
从上述结果可以看出,采用不合适的码表进行编码,可能会造成编码后的文件大小比原文件大,或者比本码压缩的文件大小大,这是因为不同图像的亮度值的概率分布差别可能很大。