游程编码和PCX格式

来源:互联网 发布:linux退出 编辑:程序博客网 时间:2024/05/06 00:54

游程编码和PCX格式的matlab实现

1、 编码

clear, clc%编码,逐行读入tic; %开始计时%预处理%以只读方式打开原文件%fopen()返回一个文件id值,-1表示打开文件失败fi = fopen('D:\Code\InformationTheory\PCX\lena1.raw', 'r');buf = fread(fi); %读取原文件数据至buf数组内,fread()默认以uchar(8bit)作为精度len = length(buf); %数据长度,即原图像有多少像素点fclose(fi); %关闭原文件%以写方式打开原文件,w后面的+表示清除所打开文件中原有的数据后再写入fo = fopen('D:\Code\InformationTheory\PCX\lena1.cmp', 'w+');idx = 1; %当前位置olen = 0; %写出数据长度while idx <= len    count = 1; %记录重复像素个数,无重复记为1        if buf(idx) ~= buf(idx + 1) %当前像素和后一个像素值不等        %孤立像素且像素值>=192        if buf(idx) >= 192            olen = olen + 1;            test(olen) = 193;% test数组存放写入lena1.cmp中的数据            fwrite(fo, 193, 'uchar'); %uchar==1Byte            olen = olen + 1;            test(olen) = buf(idx);            fwrite(fo, buf(idx), 'uchar');        else            %孤立像素且像素值介于0-191之间            olen = olen + 1;            test(olen) = buf(idx);            fwrite(fo, buf(idx), 'uchar');        end                idx = idx + 1;     else        %非孤立像素        i = idx; %当前位置        while buf(i) == buf(i + 1) %记录游程            count = count + 1;            i = i + 1;            if count == 63 || i == len %游程达到63或到达原图像最后一个像素                break; %结束当前游程            end        end        olen = olen + 1;        test(olen) = 128 + 64 + count;        fwrite(fo, 128 + 64 + count, 'uchar');        olen = olen + 1;        test(olen) = buf(idx);        fwrite(fo, buf(idx), 'uchar');                idx = idx + count; %起始新的游程    endendfclose('all');disp(['编码结束,用时', num2str(toc), '秒'])

2、 解码

clear, clc%解码,逐行写出tic;%预处理fi = fopen('D:\Code\InformationTheory\PCX\lena1.pcx', 'r');buf = fread(fi); %读取压缩文件数据至buf数组内,fread()默认以uchar(8bit)作为精度len = length(buf); %数据长度,即压缩文件字节数fclose(fi);fo = fopen('D:\Code\InformationTheory\PCX\lena1_rec.raw', 'w+');idx = 1; %当前位置olen = 0; %写出数据长度while idx < len    count = 1;    if buf(idx) > 192        if buf(idx) == 193            %孤立像素且像素值>=192,写出idx+1处的数据            olen = olen + 1;            test(olen) = buf(idx + 1);            fwrite(fo, buf(idx + 1), 'uchar');                        idx = idx + 2;        else            %非孤立像素            count = buf(idx) - 128 - 64; %像素值重复次数            for i = 1 : count                olen = olen + 1;                test(olen) = buf(idx + 1);                fwrite(fo, buf(idx + 1), 'uchar');            end            idx = idx + 2;        end    else        %孤立像素且像素值<192,写出idx处的数据        olen = olen + 1;        test(olen) = buf(idx);        fwrite(fo, buf(idx), 'uchar');                idx = idx + 1;    endendfclose('all');disp(['解码结束,用时', num2str(toc), '秒'])

运行以上两段代码后,生成了两个文件(编码压缩文件lena1.cmp以及解码恢复文件lena1_rec.raw),观察原文件lena1.raw及压缩文件lena1.cmp,可以发现,文件大小从262144字节减小至189847字节,减小了27.58%。

代码中使用了逐行读取原图像数据的方法(直接读取),利用Photoshop打开原图像可以看出原图像在竖直方向上有更多连续的像素,如果使用逐列读取的方法(以数组的形式读取原文件数据)的话可以将原文件压缩的更小(170038Byte)。

这里也可以得出fread()函数的一个特性,即如果以数组的形式读取一副图片的话,fread()函数是逐列读取的。


0 0
原创粉丝点击