程序源码:http://download.csdn.net/detail/jsgaobiao/9456641
Ø 【作业要求】
1. Get your matlab platform ready. Payspecial attention to the image processing toolbox.
2.Use matlab functions to convert the attached image from .jpg to binary .ppm format. Save it as greens.ppm.
3. Write your own imread(‘*.ppm’) functioncode to read the newly generated .ppm file.
4. Submit your code, result, and report.
选做:尝试设计你的 .pgm和.pbm读写程序。
Ø 【文件说明】
jpg2ppm.m:
Use matlab functions to convert theattached image from .jpg to binary .ppm format. Save it as greens.ppm
imread_pxm.m:
Myown imread() function code to read .ppm/.pgm/.pbm file which can beencoding ineither ASCII or Binary.
imwrite_pxm.m:
Myown imwrite() function code to write .ppm/.pgm/.pbm file which canbe encoding ineither ASCII or Binary.
test_imread_pxm.m:
Use imread_pxm() to readgreens.ppm/.pgm/.pbm && greens1.ppm/.pgm/.pbm, then show them to checkthe correctness of function imread_pxm().
test_imwrite_pxm.m:
Use imwrite_pxm to write .ppm/.pgm/.pbmencoding in ASCII/Binary mode, then show them to check the correctness offunction imwrite_pxm().
greens.ppm/.pbm/.pgm(Encoding in Binary) :
Images for imread_pxm() function to load.
greens1.ppm/.pbm/.pgm(Encoding in ASCII) :
Images for imread_pxm() function to load.
Ø 【作业思路】
一、 将jpg文件转化成二进制编码的.ppm文件
通过MATLAB自带的函数imread()载入jpg的图像数据部分,再使用imwrite()将上一步的结果写成.ppm文件,’encoding’选项可以选择’rawbits’和’ASCII’分别是二进制和ASCII编码。
二、 手写imread()实现读取.ppm/.pgm/.pbm图像的功能
我的imread_pxm()函数可以读取二进制或ASCII编码的.ppm/.pgm/.pbm文件。主要思路和注意点如下:
1、 图像的头部统一处理,都是由ASCII编码的图像类型(P1..P6)、宽、高和像素值范围。其中.pbm没有最后一个像素值范围(因为.pbm的像素值只可能是0/1);
2、 根据图像类型(P1..P6)读取图像的数据部分,全部按uint8的类型读入。需要注意P3和P6每个像素都有RGB信息,所以需要存入3维矩阵,其他类型存入二维矩阵;
3、 每种类型的图像读入后的矩阵具有不同的数据类型,fread读入的结果默认是doublele类型,所以保存时需要强制转换:.pgm/.ppm的数据转换为uint8,.pbm的数据转换为logical;
4、 ASCII编码的数据要处理数据间的空格和换行符;
5、 .pbm的图像数据在保存时需要0/1取反,否则显示出来的结果会反色;
6、 .pbm的二进制编码数据每行会按照8bit对齐,每行最后一个8bit数据的末尾会用0补齐,需要注意处理一下。
使用test_imread_pxm.m脚本可以测试P1..P6的图像读入并显示,以检测imread_pxm()函数的正确性,结果如下图:
三、 手写imwrite()实现将像素值矩阵写成.ppm/.pgm/.pbm图像的功能
我的imwrite_pxm(im, ptype, filename)函数可以将图像数据矩阵im写入二进制或ASCII编码的.ppm/.pgm/.pbm文件,ptype指定了图像和编码的类型(P1..P6),filename指定了保存文件名,例如imwrite_pxm(im,6, ‘output.ppm’).
实现的主要思路和注意点如下:
1、 统一处理图像的头部,写入ASCII编码的图像类型(P1..P6)、宽、高和像素值范围。其中.pbm没有最后一个像素值范围(因为.pbm的像素值只可能是0/1);
2、 根据图像类型(P1..P6)写入图像的数据部分,以’wb’格式打开输出文件后,直接使用fwrite()函数写入即可。需要注意P3和P6每个像素都有RGB信息,所以需要写入3维矩阵,其他类型写入二维矩阵;
3、 .pbm的图像数据在保存时需要0/1取反,否则显示出来的结果会反色;
4、 .pbm的图像数据是由0/1组成的,但是在写入时,需要将它们合成8bit的数后,再写入文件。和上文中提到的一样,要特殊处理每行最后8bit的对齐。
使用test_imwrite_pxm.m脚本可以测试P1..P6的图像写出并显示,以检测imwrite_pxm()函数的正确性,结果如下图:
Ø 【问题】
在手写imread()函数中处理.pbm二进制编码的图像时,我首先尝试了使用fread(fid, 1, ‘ubit1’),每次读入1bit,这样可以直接获取0/1的数据而不需要每次读一个uint8,再拆成8个0/1。
但是,我发现在读入的过程中,每8个bit数据的开头一个bit的读入结果都是空(0*0的矩阵)。当我忽略空的结果后,总的数据量比正确结果要少——也就是说1bit为单位读入会丢失部分数据,而8bit为单位读入就没问题。
我查阅了一些资料并没有找到原因。记录在此,希望日后可以解决。
上期谜语:日行七千里(二字数字图像术语)—— 量化