1、 数字图像处理第一次作业姓名:班级:学号:提交日期:2015 年 3 月 13 日摘要本次报告首先简单阐述了 BMP 图像格式及其相关数据结构,随后主要完成了作业要求中关于图像处理与计算的各项任务。本次作业以 Matlab 2014 为平台,通过对lena.bmp,elain.bmp 图像文件的编程处理,分别得到了 lena.bmp 图像的 8 到 1 级灰度逐级递减显示,lena.bmp 图像的均值和方差,通过近邻、双线性和双三次插值法对 lena.bmp 进行4 倍放大后得到的 20482048 尺寸图像,和对 lena.bmp、elain.bmp 图像分别进行水平偏移变换和旋转变换后的图
2、像及其 4 倍插值放大图像。以上任务完成后均得到了预期的结果。1.Bmp 图像格式简介。1.1 BMP 格式概述BMP(全称 Bitmap)是 Windows 操作系统中的标准图像文件格式,可以分成两类:设备相关位图(DDB)和设备无关位图(DIB ),使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP 文件所占用的空间很大。BMP文件的图像深度可选 lbit、4bit、8bit 及 24bit。BMP 文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。1.2 BMP 格式组成典型的 BMP 图像文件由四部分组成:(1)位图头文件数据结构,它包含
3、 BMP 图像文件的类型、显示内容等信息;(2)位图信息数据结构,它包含有 BMP 图像的宽、高、压缩方法,以及定义颜色等信息;(3)调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的 BMP)就不需要调色板;(4)位图数据,这部分的内容根据 BMP 位图使用的位数不同而不同,在 24 位图中直接使用 RGB,而其他的小于 24 位的使用调色板中颜色索引值。1.3 BMP 格式对应数据结构BMP 文件由文件头、位图信息头、颜色信息和图形数据四部分组成。1.3.1 BMP 文件头(14 字节)BMP 文件头数据结构含有 BMP 文件的类型、文件大小和位图起始位置等 信
4、息。其结构定义如下:typedef struct tagBITMAPFILEHEADERWORD bfType; / 位图文件的类型,必须为 BM(1-2 字节)DWORD bfSize; / 位图文件的大小,以字节为单位(3-6 字节)WORD bfReserved1; / 位图文件保留字,必须为 0(7-8 字节)WORD bfReserved2; / 位图文件保留字,必须为 0(9-10 字节)DWORD bfOffBits; / 位图数据的起始位置,以相对于位图(11-14 字节)/ 文件头的偏移量表示,以字节为单位 BITMAPFILEHEADER;1.3.2 位图信息头(40 字节
5、)BMP 位图信息头数据用于说明位图的尺寸等信息。typedef struct tagBITMAPINFOHEADERDWORD biSize; / 本结构所占用字节数( 15-18 字节)LONG biWidth; / 位图的宽度,以像素为单位(19-22 字节)LONG biHeight; / 位图的高度,以像素为单位( 23-26 字节)WORD biPlanes; / 目标设备的级别,必须为 1(27-28 字节)WORD biBitCount;/ 每个像素所需的位数,必须是 1(双色),(29-30 字节)/ 4(16 色),8(256 色)16(高彩色) 或 24(真彩色)之一DW
6、ORD biCompression; / 位图压缩类型,必须是 0(不压缩),(31-34 字节)/ 1(BI_RLE8 压缩类型)或 2(BI_RLE4 压缩类型)之一DWORD biSizeImage; / 位图的大小( 其中包含了为了补齐行数是 4 的倍数而添加的空字节) ,以字节为单位( 35-38 字节)LONG biXPelsPerMeter; / 位图水平分辨率,每米像素数(39-42 字节)LONG biYPelsPerMeter; / 位图垂直分辨率,每米像素数(43-46 字节)DWORD biClrUsed;/ 位图实际使用的颜色表中的颜色数(47-50 字节)DWORD
7、 biClrImportant;/ 位图显示过程中重要的颜色数(51-54 字节) BITMAPINFOHEADER;1.3.3 颜色表颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是 RGBQUAD 类型的结构,定义一种颜色。RGBQUAD 结构的定义如下:typedef struct tagRGBQUAD BYTE rgbBlue;/ 蓝色的亮度(值范围为 0-255)BYTE rgbGreen; / 绿色的亮度(值范围为 0-255)BYTE rgbRed; / 红色的亮度(值范围为 0-255)BYTE rgbReserved;/ 保留,必须为 0 RGBQUAD;颜色表中 R
8、GBQUAD 结构数据的个数有 biBitCount 来确定:当 biBitCount=1,4,8 时,分别有 2,16,256 个表项;当 biBitCount=24 时,没有颜色表项。位图信息头和颜色表组成位图信息,BITMAPINFO 结构定义如下:typedef struct tagBITMAPINFO BITMAPINFOHEADER bmiHeader; / 位图信息头RGBQUAD bmiColors1; / 颜色表 BITMAPINFO;1.3.4 位图数据位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右, 扫描行之间是从下到上。位图的一个像素值所占的字节数:当
9、 biBitCount=1 时,8 个像素占 1 个字节;当 biBitCount=4 时,2 个像素占 1 个字节;当 biBitCount=8 时,1 个像素占 1 个字节;当 biBitCount=24 时,1 个像素占 3 个字节,按顺序分别为 B,G,R;Windows 规定一个扫描行所占的字节数必须是 4 的倍数(即以 long 为单位), 不足的以 0 填充。 2.把 lena512*512 图像灰度级逐级递减 8-1 显示。(1)问题分析:本题中对图像进行的操作是直接灰度变换。首先利用 imread 函数读入 lena512.bmp,得到图像的灰度矩阵 I,之后对灰度矩阵中的每
10、个元素进行操作,即阵列操作。将灰度矩阵的每个元素值除以二,取整后将结果转换为无符号 8 位数,既得到灰度级为 7 的图像,最后利用 imshow 函数输出显示图像。同理可得到灰度级为 6-1的图像。对应源程序 lena.m(2)MATLAB 函数:A=imread(filename)用 imread 函数读取图像文件,文件格式可以是 TIFF、JPEG、GIF、BMP 、PNG。读进来的是一个二维数组,存放在矩阵 A 中。调用格式:A=imread(filename,fmt)X,map=imread(filename,fmt)imshow(A)imshow 是 matlab 中显示图像的函数。
11、调用格式:imshow(I,n)imshow(I,low high)用指定的灰度范围 low high显示灰度图像 I。显示结果,图像中灰度值等于或低于 low 的都将用黑色显示,而灰度值大于等于 high 的都显示为白色,介于 low 和 high 之间的用其灰度级的默认值的中间色调显示。(3)处理结果:8 灰度级:7 灰度级:6 灰度级:5 灰度级:4 灰度级:3 灰度级:2 灰度级:1 灰度级:(4)结果分析:对一幅 512*512,256 个灰度级的具有较多细节的图像,保持空间分辨率不变,仅将灰度级数依次递减为 128、64、32、16、8、4、2,比较得到的结果就可以发现灰度级数对图
12、像的影响。 前四张图灰度级数较高,图像基本看不出什么变化。当灰度级数继续降低,则在灰度缓变区常会出现一些几乎看不出来的非常细的山脊状结构。灰度级数越低,越不能将图像的细节刻画出来。对比实验中处理过的图像,可以发现,虽然都是灰度图,但是灰度范围越大则图像显示出的色彩越丰富。3.计算 lena512 图像的均值方差。(1)问题分析:首先通过 imread()函数读入图像文件到灰度矩阵 A 中,然后利用mean2()函数和 std2()函数计算灰度矩阵(即图像)的均值和标准差,再由标准差平方得到方差。对应源程序:lena2.m(2)MATLAB 函数:mean2()MATLAB 中提供均值计算函数
13、mean()和 mean2()。 mean2( A ),用于对整一个矩 阵求像素平均值。调用格式:u=mean2(A)std2()MATLAB 中提供标准差计算函数 std()和 std2()。调用格式:s=std2(A)(3)处理结果:均值 u=95.6564 方差 s2=1.9273e+03(4)结果分析:经过 MATLAB 运算,得到图像 lena512.bmp 的均值约为 95.6564,标准差约为 43.9012,方差是标准差的平方,约为 1927.3。方差越大,图像的对比度越大,可以显示的细节就越多。4.把 lena 图像用近邻、双线性和双三次插值法 zoom 到 2048*204
14、8。(1)问题分析:插值算法是估计在图象像素间的某个位置的像素的取值方法。最近邻点插值法:在待插像素的周围四邻像素中,距离待求插像素最近的像素灰度赋给待插像素。该方法最简单,但校正后存在灰度不连续性,图像有明显锯齿状。双线性插值算法:双线性插值算法输出的图像的每个像素都是原图中四个像素()运算的结果,这种算法极大地消除了锯齿现象。双三次插值算法: 双三次插值算法是上一种算法的改进算法, 它输出图像的每个像素都是原图个像素()运算的结果。这种算法是一种很常见的算法,普遍用在图像编辑软件、打印机驱动和数码相机上。本题先通过 imread()函数读入图像文件,然后利用 imresize()函数将图像
15、分别利用三种插值方法放大到2048*2048。对应源程序:lena3.m(2)MATLAB 函数:imresize()函数用于对图像做缩放处理。调用格式:B = imresize(A, numrows numcols,method)其中,numrows 和 numcols 分别指定目标图像的高度和宽度。 显而易见,由于这种格式允许图像缩放后长宽比例和源图像长宽比例不相同,因此所产生的图像有可能 发生畸变。method 参数用于指定在改变图像尺寸时所使用的算法,可以为一下几种:nearest: 这个参数也是默认的, 即改变图像尺寸时采用最近邻插值算法;bilinear:采用双线性插值算法;bic
16、ubic: 采用双三次插值算法;(3)处理结果:原始图像:最近邻插值法:双线性插值法:双三次插值法:(4)结果分析:最近邻插值、双线性插值与双三次差值这三种方法之间的区别主要在于点周围像素序列的取法不同。对于最近邻插值,输出像素的值指定为点所属像素的值,不考虑 其他像素;对于双线性插值,输出图像的值是最近的 2*2 邻域内像素值得加权平均值;对于双三次差值,输出图像的值是最近的 4*4 邻域内像素值得加权平均值。所以,双线性插值法花费的时间比最近邻法的要长一些,而双三次法花费的时间比双线性法的又要长一些。但是,参与计算的时间越多,计算结果越精确,通常双线性插值和双三次差值这两种方法比最近邻法得
17、到的效果更好。从得到的图像我们可以看到,最近邻内插产生了最大的锯齿边缘,尤其是在对应图像中的肩膀的边缘部位,产生了很明显的锯齿,而双线性内插得到了明显改进的结果使用双三次内插产生了稍微清晰一些的结果。5.把 lena 和 elain 图像分别进行水平 shear(参数可设置 1.5,或者自行选择)和旋转 30 度,并采用近邻、线性和双三次插值法 zoom 到 2048*2048。(1)问题分析:采用仿射变换来进行水平裁剪。仿射变换是空间直角坐标变换的一种,它是一种二维坐标到二维坐标的线性变换,即用图像的矩阵去乘仿射变换的矩阵 T,把图像上的像素重新定位到一个新位置,并为这些新位置赋灰度值,而这
18、个任务可以用灰度内插的方法完成,选择最近邻内插法、双线性插值法和双三次插值法三种方法。对于水平偏移变换,运算后,坐标变为 x=v,y=shv+w。在本题中, 参数 shv 根据题中要求设为 1.5。 对于旋转变换,运算后,坐标变为 x=vcos- wsin ,y=vsin +wcos 。在本题中,运用旋转函数,就不在程序中重新设置矩阵值了,而是函数根据参数自行设置矩阵 T ;使用 imrotate 函数旋转图像。该函数接受两个主要的变量,即要旋转的图像和旋转的角度,旋转角度的单位为度。如果指定一个正值,imrotate 函数按逆时针方向旋转函数;如果指定一个负值,imrotate 函数按顺时针
19、方向旋转图像。作为可选变量,还可以给 imrotate 函数指定产值方法和图像的大小;使用 imtransform 函数完成一般的二维空间转换。其语法格式如下:B=imtransform(A,TFORM,paraml,vall,param2,val2)。该函数接受两个主要变量,既要变换的图像和 TFORM 空间变换结构。 创建一个 TFORM 结构有两种方法,即使用makeform 函数和 cp2tform 函数。使用 makeform 函数,可指定变换类型。在本次实验中,指定的是仿射变换“affine”类型,即进行平移,旋转,比例,拉伸和错切等功能。仿射变换要求变换矩阵的最后一列除最后一个元
20、素为 1 之外,其它的均为 0。对应源程序;lena4.m和 lena5.m(2)MATLAB 函数:图像二维仿射变换 MATLAB 使用 imtransform 函数完成图像空间变换。 调用格式:imtransform(A,T)其中参数 A 是要变换的图像, T 是由 makeform 函数产生的变换结构 .在 maketform(P,)函数中,参数 P 可以以一下形式:affine:仿射变换形式;projective:投影变换形式;cusyom:自定义函数变换;box:利用函数中的另外参数产生仿射变换结构;composite:该参数是实现多次调用 tformfwd 功能;maketform
21、 函数就是利用给定的参数建立变换结构,然后把该变换结构赋予结构变量T。 根据得到的结构体变量 T,调用 imtransform(A,T)函数进行变换。(3)处理结果:Lena 水平偏移:Elaine 水平偏移:Lena 旋转 30 度:Elaine 旋转 30 度:(4)结果分析:在数字图像处理中几何变换由两个基本操作组成:(1)坐标的空间变化;(2)灰度内插,即对空间变换后的像素赋灰度值。最常用的空间坐标变换之一是仿射变换。最近邻内插产生了最大的锯齿边缘,双线性内插得到了明显的改进结果,使用双三次内插产生了稍微清晰一些的结果。 旋转是保持直线特性方面最苛求的几何变换之一,与上一实验结果相同,
22、最近邻内插产生了最大的锯齿边缘,双线性内插得到了明显的改进结果,使用双三次内插产生了稍微清晰一些的结果。附录【参考文献】1 冈萨雷斯.数字图像处理(第三版)北京:电子工业出版社,20112 周品.MATLAB 数字图像处理 北京:清华大学出版社,20123 杨杰.数字图像处理及 MATLAB 实现 北京:电子工业出版社,2010【源代码】lena.mclose all;clear all;clc;I=imread(lena512.bmp);figure(1)imshow(I)title(8 灰度级 );x,y=size(I);%读取 lena.bmp 的长宽img7=zeros(x,y);im
23、g6=zeros(x,y);img5=zeros(x,y);img4=zeros(x,y);img3=zeros(x,y);img2=zeros(x,y);img1=zeros(x,y);for i=1:xfor j=1:yimg7(i,j)=floor(I(i,j)/2); %floor 为向下取整endendfigure(2)imshow(uint8(img7),0,127) %unit8 为 8 位二进制数title(7 灰度级 );for i=1:xfor j=1:yimg6(i,j)=floor(I(i,j)/4);endendfigure(3)imshow(uint8(img6),
24、0,63)title(6 灰度级 );for i=1:xfor j=1:yimg5(i,j)=floor(I(i,j)/8);endendfigure(4)imshow(uint8(img5),0,31)title(5 灰度级 );for i=1:xfor j=1:yimg4(i,j)=floor(I(i,j)/16);endendfigure(5)imshow(uint8(img4),0,15)title(4 灰度级 );for i=1:xfor j=1:yimg3(i,j)=floor(I(i,j)/32);endendfigure(6)imshow(uint8(img3),0,7)tit
25、le(3 灰度级 );for i=1:xfor j=1:yimg2(i,j)=floor(I(i,j)/64);endendfigure(7)imshow(uint8(img2),0,3)title(2 灰度级 );for i=1:xfor j=1:yimg1(i,j)=floor(I(i,j)/128);endendfigure(8)imshow(uint8(img1),0,1)title(1 灰度级 );lena2.mA=imread(lena512.bmp);B=mean2(A);C=std2(A);D=C2;lena3.mA=imread(lena512.bmp);figure(1);
26、imshow(A); title(原始图像);B1=imresize(A,2048 2048,nearest);figure(2);imshow(B1);title(最近邻插值法);B2=imresize(A,2048 2048,bilinear);figure(3);imshow(B2);title(双线性插值法);B3=imresize(A,2048 2048,bicubic);figure(4); imshow(B3);title(双三次插值法); lena4.m%Lena 图像:transformtype=affine; transformmatrix=1 1.5 0;0 1 0;0
27、0 1; T=maketform(transformtype,transformmatrix);I=imread(lena512.bmp);nI=imtransform(I,T);figure(1); imshow(I);title(原始图像);B1=imresize(nI,2048 2048,nearest);subplot(1,3,1);imshow(B1);title(水平偏移 最近邻内插 );B2=imresize(nI,2048 2048,bilinear); subplot(1,3,2);imshow(B2); title(水平偏移 双线性内插 ); B3=imresize(nI,
28、2048 2048,bicubic); subplot(1,3,3);imshow(B3);title(水平偏移 双三次内插 ); %Elain 图像:transformtype=affine;transformmatrix=1 1.5 0;0 1 0;0 0 1; T=maketform(transformtype,transformmatrix); I=imread(elaine512.bmp); nI=imtransform(I,T); figure(5);imshow(I); title(原始图像);B1=imresize(nI,2048 2048,nearest);subplot(1
29、,3,1);imshow(B1); title(水平偏移 最近邻内插 );B2=imresize(nI,2048 2048,bilinear);subplot(1,3,2); imshow(B2);title(水平偏移 双线性内插 ); B3=imresize(nI,2048 2048,bicubic);subplot(1,3,3); imshow(B3);title(水平偏移 双三次内插 );lena5.m%Lena 图像:I=imread(lena512.bmp);figure(1);imshow(I);title(原始图像);I1=imrotate(I,30,nearest);B1=im
30、resize(I1,2048 2048,nearest);subplot(1,3,1);imshow(B1);title(旋转 30 度 最近邻内插 );I2=imrotate(I,30,bilinear);B2=imresize(I2,2048 2048,bilinear);subplot(1,3,2);imshow(B2); title(旋转 30 度 双线性内插 ); L3=imrotate(I,30,bicubic);B3=imresize(L3,2048 2048,bicubic);subplot(1,3,3);imshow(B3);title(旋转 30 度 双三次内插 ); %E
31、laine 图像:L=imread(elaine512.bmp); figure(5);imshow(L); title(原始图像);L1=imrotate(L,30,nearest);C1=imresize(L1,2048 2048,nearest);subplot(1,3,1);imshow(C1); title(旋转 30 度 最近邻内插 );L2=imrotate(L,30,bilinear);C2=imresize(L2,2048 2048,bilinear);subplot(1,3,2); imshow(C2);title(旋转 30 度 双线性内插 ); L3=imrotate(L,30,bicubic);C3=imresize(L3,2048 2048,bicubic);subplot(1,3,3);imshow(C3);title(旋转 30 度 双三次内插 );