文档详情

利用游程编码实现二值图像压缩

M****1
实名认证
店铺
DOC
53.50KB
约10页
文档ID:471089982
利用游程编码实现二值图像压缩_第1页
1/10

. . . . 算术编码、游程编码都属于无损压缩算术编码(Arithmetic coding)算术编码是一种无损数据压缩方法,也是一种熵编码的方法和其它熵编码方法不同的地方在于,其他的熵编码方法通常是把输入的消息分割为符号,然后对每个符号进行编码而算术编码是直接把整个输入的消息编码为一个数,一个满足(0.0 ≤ n < 1.0)的小数n算术编码用到两个基本的参数:符号的概率和它的编码间隔信源符号的概率决定压缩编码的效率,也决定编码过程源符号的间隔,而这些间隔包含在0到1之间算术编码的算法思想如下:(1)对一组信源符号按照符号的概率从大到小排序,将[0,1)设为当前分析区间按信源符号的概率序列在当前分析区间划分比例间隔2)检索“输入消息序列”,锁定当前消息符号(初次检索的话就是第一个消息符号)找到当前符号在当前分析区间的比例间隔,将此间隔作为新的当前分析区间并把当前分析区间的起点(即左端点)指示的数“补加”到编码输出数里当前消息符号指针后移3)仍然按照信源符号的概率序列在当前分析区间划分比例间隔然后重复第二步。

直到“输入消息序列”检索完毕为止4)最后的编码输出数就是编码好的数据在算术编码中需要注意几个问题:(1)由于实际计算机的精度不可能无限长,运算中出现溢出是一个明显的问题,但多数与其都有16位,32位或者64位的精度,因此这个问题可以使用比例缩放方法解决2)算术编码器对整个消息只产生一个码字,这个码字是在间隔[0,1)中的一个实数,因此译码器在承受到表示这个实数的所有位之前不能进行译码3)算术编码是一种对错误很敏感的编码方法,如果有一位发生错误就会导致整个消息译错算术编码可以是静态的或者是自适应的在静态算术编码中,信源符号的概率是固定的在自适应算术编码中,信源符号的概率根据编码时符号出现的频率动态地进行修改,在编码期间估算信源符号概率的过程叫做建模需要开发动态算术编码的原因是因为事前知道精确的信源概率是很难的,而且不切实际当压缩消息时,不能期待一个算术编码器获得最大的效率,所能做的最有效的方法是在编码过程中估算概率因此动态建模就成为确定编码器压缩效率的关键游程编码(RLE编码——Run Length Encoding)游程编码又称“运行长度编码”或“行程编码”,是一种统计编码,该编码属于无损压缩编码。

对于二值图有效 行程编码的基本原理是:用一个符号值或串长代替具有相同值的连续符号(连续符号构成了一段连续的“行程”行程编码因此而得名),使符号长度少于原始数据的长度 例如:21111111 行程编码为:(5,6)(7,5)(3,3)(2,4)(l,7)可见,行程编码的位数远远少于原始字符串的位数 在对图像数据进行编码时,沿一定方向排列的具有相同灰度值的像素可看成是连续符号,用字串代替这些连续符号,可大幅度减少数据量 行程编码分为定长行程编码和不定长行程编码两种类型 行程编码是连续精确的编码,在传输过程中,如果其中一位符号发生错误,即可影响整个编码序列,使行程编码无法还原回原始数据游程编码所能获得的压缩比有多大,主要取决于图像本身的特点如果图像中具有相同颜色的图像块越大,图像块数目越少,获得的压缩比就越高反之,压缩比就越小利用游程编码实现二值图像压缩文章出处:.diybl./course/3_program/c++/cppjs/2008331/107771.html编码方案设计:按位进行压缩,对二进制流进行超前扫描,判断是否值得压缩,如果压缩有意义,则压缩;否则保持原始数据系统实现方案:总体思想:将图像文件以二进制方式读入缓冲区,把二进制位转制为整数,对缓冲区数据进行编码,以特定的格式(unsigned short)写入输出文件;解压缩过程反过来即可。

压缩文件存储格式:以每两个字节为单位储存(即每次写入16位unsigned short类型) 0 1 2~15 ... 第0位 存储压缩信息(1压缩;0不压缩,原始数据)第1位 如果第0位为1(压缩),此位标明字符类别(0或1);如果第0位为0(原始数据),此位无意义,默认为0后14位 存储字符数量或者原始数据的值算法实现:缓冲区:定义缓冲区为一维char数组,因为只用14位来统计数量,所以缓冲区总字符量即维数应小于或等于214(16384)判断可压缩性:对当前指针位置,超前扫描16位,如果这16位全相同(例:111或000),那么可压缩性为真,从当前位置开始计数并指针前移,直到相同序列终止或到达缓冲区边界为止将统计数量写入unsigned short类型后14位,第0位置1,第0位置为当前字符;如果16位中有不相同数据(例:011)或缓冲区中有效数据不足16位,那么可压缩性为假,从当前位置开始读14位(如果缓冲区中剩余不足14位,有多少位读多少位)把原始数位写入unsinged short类型后14位,前两位置0解压缩:每次从压缩文件读取16位到short类型,根据第0位和第1位的数值进行相应的解码处理,直到缓冲区满,每次从缓冲区中取8位,写入文件。

源码(gcc或C++编译器)Bmpheader.htypedef unsigned char BYTE;typedef unsigned short WORD;typedef unsigned long DWORD;typedef long LONG;typedef struct ...{ /**//* BITMAPFILEHEADER*/ BYTE bfType[2];// 位图文件的类型,必须为BM DWORD bfSize;//位图文件的大小,以字节为单位 WORD bfReserved1;// 位图文件保留字,必须为 WORD bfReserved2;// 位图文件保留字,必须为 DWORD bfOffBits;// 位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位 /**//* BITMAPINFOHEADER*/ DWORD BiSize;// 本结构所占用字节数 LONG BiWidth;// 位图的宽度,以像素为单位 LONG BiHeight;// 位图的高度,以像素为单位 WORD BiPlanes;// 目标设备的级别,必须为 WORD BiBitCount;//每个像素所需的位数,必须是 DWORD BiCompression;// 位图压缩类型,必须是0(不压缩), 1(BI_RLE8压缩类型)或(BI_RLE4压缩类型)之一 DWORD BiSizeImage;// 位图的大小,以字节为单位 LONG BiXpelsPerMeter;// 位图水平分辨率,每米像素数 LONG BiYpelsPerMeter;// 位图垂直分辨率,每米像素数 DWORD BiClrUsed;// 位图实际使用的颜色表中的颜色数 DWORD BiClrImportant;// 位图显示过程中重要的颜色数} BITMAPHEADER;/**//*************颜色表**************/typedef struct...{ unsigned char blue;// 蓝色的亮度(值围为-255) unsigned char green; unsigned char red; char reserved;// 保留,必须为} RGBQUAD;/**//*********压缩字符流结点**********/Main.cpp /**//*黑白点二值位图游程编码压缩程序*/ /**//*2008.3.20 付闯 */ #include #include #include #include #include"bmpheader.h" const unsigned short MaxSize=16384;//14字节最大数 void compress(FILE *,FILE *);//压缩 void decompress(FILE *,FILE *);//解压缩 void wbuffer(FILE *,char *,int);/**//*将像素信息写入缓冲区*/ void buf_init(char *,int);//缓冲初始化 void rbuffer(FILE *,char *,int);//读缓冲到文件 unsigned long RLE(FILE *,char *,int,unsigned long);//游程压缩,并返回写入字节数 void decode(FILE *,char *,int);//解码,逆运算 / /void bufdisplay(char *,char *,int);//打印缓冲,测试用 DWORD getBMPsize(FILE *ifp);//获取位图大小 int IsFeasible(char *,char *,int);//判断压缩可行性,可行 int main() ...{ FILE *ifp,*ofp,*ffp; char choic; char *ifilename,*ofilename; ifilename=(char *)malloc(1); ofilename=(char *)malloc(1); printf("a.压 缩 b.解压缩 "); choic=getch(); if(choic==''a'') ...{ printf("请输入压缩(Compress)源文件名:"); scanf("%s",ifilename); printf("请输入压缩(Compress)输出文件名:"); scanf("%s",ofilename); if((ifp=fopen(ifilename,"rb"))==NULL) ...{ printf("无法打开文件!"); getch(); return 1; } if((ofp=fopen(ofilename,"wb"))==NULL) ...{ printf("无法创。

下载提示
相似文档
正为您匹配相似的精品文档