数字图像处理论文1.docx
《数字图像处理论文1.docx》由会员分享,可在线阅读,更多相关《数字图像处理论文1.docx(14页珍藏版)》请在冰豆网上搜索。
![数字图像处理论文1.docx](https://file1.bdocx.com/fileroot1/2023-4/1/c0a12c9c-c6ce-4275-af0a-77761a41009a/c0a12c9c-c6ce-4275-af0a-77761a41009a1.gif)
数字图像处理论文1
数字图像处理论文
院系:
信息工程学院
班级:
学号:
姓名:
侯聪
任课教师:
严红平
时间:
2010-6-20
数字图像处理
第一部分、前言
本学习我选修了严红平老师的数字图像处理这门课程,经过一个学期的学习,我对这门课程也有了一定的了解。
数字图像处理,就是利用数字计算机或者其他数字硬件,对从图像信息转换而得到的电信号进行某些数学运算,以提高图像的实用性。
学会了如何将图像进行平移,锐化,反色,膨胀,缩小等功能。
一般来讲,对图像进行处理的主要目的有三个方面:
(1)提高图像的视感质量,如进行图像的亮度、彩色变换,增强、抑制某些成分,对图像进行几何变换等,以改善图像的质量。
(2)提取图像中所包含的某些特征或特殊信息,这些被提取的特征或信息往往为计算机分析图像提供便利。
提取特征或信息的过程是模式识别或计算机视觉的预处理。
提取的特征可以包括很多方面,如频域特征、灰度或颜色特征、边界特征、区域特征、纹理特征、形状特征、拓扑特征和关系结构等。
(3)图像数据的变换、编码和压缩,以便于图像的存储和传输。
本学期学习的图像处理技术主要是针对BMP位图所进行的操作,首先介绍一些什么是BMP图像以及什么是位图操作:
BMP文件是Windows操作系统所推荐和支持的图像文件格式,是一种将内存或显示器的图像数据不经过压缩而直接按位存盘的文件格式,所以称为位图(bitmap)文件,因其文件扩展名为BMP,故称为BMP文件格式,简称BMP文件。
首先,位图文件可看成由4个部分组成:
1.位图文件头(bitmap-fileheader)
2.位图信息头(bitmap-informationheader)
3.彩色表(colortable)
4.定义位图的字节阵列,它具有如下所示的形式。
<位图文件的组成><结构名称><符号>
位图文件头(bitmap-fileheader)BITMAPFILEHEADERbmfh
位图信息头(bitmap-informationheader)BITMAPINFOHEADERbmih
彩色表(colortable)RGBQUADaColors[]
图像数据阵列字节BYTEaBitmapBits[]
其次,处理位图时要根据文件的这些结构得到位图文件大小、位图的宽、高、实现调色板、得到位图像素值等等。
这里要注意的一点是在BMP位图中,位图的每行像素值要填充到一个四字节边界,即位图每行所占的存储长度为四字节的倍数,不足时将多余位用0填充。
第二部分、解释各功能的实现过程及核心代码
总揽图
1.图像的反色
反色又叫补色,红的补色是绿色,蓝的补色是橙色,黄的补色是紫色,由这三种对比关系可引出很多对比的反色。
图像反色是图像灰度的线性变换的一种,即通过线性灰度变换函数使得输出图像的灰度正好是输入图像的灰度的反转。
。
对于彩色图像的R、G、B各彩色分量取反的技术就是图像的反色处理,这在处理二值化图像的连通区域选取的时候非常重要。
算法是这样进行设计的:
线性灰度变换函数:
灰度变换方程为:
其中:
fA为线性函数斜率。
fB为线性函数在y轴上的截距,
表示输入图像的灰度,
表示输出图像的灰度。
当fA=1,fB=0时,输出图像和输入图像相同;当fA=-1,fB=255时,输出图像的灰度正好反转,也就实现了图像反色。
以下是实现反色的关键代码:
image_s[(height-i-1)*www*3+3*j]=255-image_s[(height-i-1)*www*3+3*j];
image_s[(height-i-1)*www*3+3*j+1]=255-image_s[(height-i-1)*www*3+3*j+1];
image_s[(height-i-1)*www*3+3*j+2]=255-image_s[(height-i-1)*www*3+3*j+2];
2.图像的黑白化
图像的黑白化也就是图像的二值化,是图像灰度处理的一种特殊情况。
图像的二值化处理就是将图像上的像素点的灰度值设置为0或255,使得整幅图像只有黑白两种颜色效果。
将256个亮度等级的灰度图像通过适当的阀值选取而获得仍然可以反映图像整体和局部特征的二值化图像。
在数字图像处理中,二值图像占有非常重要的地位,首先,图像的二值化有利于图像的进一步处理,使图像变得简单,而且数据量减小,能凸显出感兴趣的目标的轮廓。
其次,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像。
关键代码如下:
image_s[(height-i-1)*www*3+3*j]=image_s[(height-i-1)*www*3+3*j+1]=image_s[(height-i-1)*www*3+3*j+2]=(image_s[(height-i-1)*www*3+3*j]+image_s[(height-i-1)*www*3+3*j+1]+image_s[(height-i-1)*www*3+3*j+2])/3;
只需令R=G=B即可实现。
3.图像的旋转
图像旋转是指把定义的图像绕某一点以逆时针或顺时针方向旋转一定的角度,通常是指绕图像的中心以逆时针方向旋转。
首先根据旋转的角度、图像对角线的长度计算旋转后的图像的最大宽度、高度,根据旋转后图象最大的宽度、高度生成新的缓冲区,假设图像的左上角为(left,top),右下角为(right,bottom),则图像上任意点(x,y)绕其中心(xcenter,ycenter)逆时针旋转angle角度后,新的坐标位置(x1,y1)的计算公式为:
xcenter=(width+1)/2+left;
ycenter=(height+1)/2+top;
x1=(x-xcenter)cosθ-(y-ycenter)sinθ+xcenter;
y1=(x-xcenter)sinθ+(y-ycenter)cosθ+ycenter;
与图像的镜像变换相类似,然后就是把原图中的(x,y)处象素的灰度值读入新缓冲区的(x1,y1)点处。
注意在新缓冲区中与原图没有对应的象素点的值用白色或指定的灰度代替。
在选转之前,需要将画布扩大,这样可以防止出现信息丢失的情况,即部分画面看不到。
画布扩大的原则是:
以最小的面积承载全部的画面信息。
图像旋转的关键代码为:
image_t[((hmax-height)/2+ch+int(sin(angle1)*(q-cw))+int(cos(angle1)*(p-ch)))*wmax*3+((wmax-width)/2+cw+int(cos(angle1)*(q-cw))-int(sin(angle1)*(p-ch)))*3]=image_s[p*www*3+3*q];
image_t[((hmax-height)/2+ch+int(sin(angle1)*(q-cw))+int(cos(angle1)*(p-ch)))*wmax*3+((wmax-width)/2+cw+int(cos(angle1)*(q-cw))-int(sin(angle1)*(p-ch)))*3+1]=image_s[p*www*3+3*q+1];
image_t[((hmax-height)/2+ch+int(sin(angle1)*(q-cw))+int(cos(angle1)*(p-ch)))*wmax*3+((wmax-width)/2+cw+int(cos(angle1)*(q-cw))-int(sin(angle1)*(p-ch)))*3+2]=image_s[p*www*3+3*q+2];
4.图像的平移
图像平移就是将图像中所有点都按照指定的平移量水平、垂直移动。
设(x0,y0)为原图像上的一点,图像水平平移量为tx,垂直平移量为ty,则平移后点(x0,y0)坐标变为(x1,y1)。
显然(x0,y0)(x1,y1)的关系如下:
用矩阵表示如下:
对该矩阵求逆,可以得到逆变换:
即
这样,平移后的图像上的每一点都可以在原图像中找到对应的点。
例如,对于新图中的(0,0)像素,代入上面的方程组,可以求出对应原图中的像素(-tx,-ty)。
如果tx或ty大于0,则(-tx,-ty)不在原图中。
对于不在原图中的点,可以直接将它的像素值统一设置为0或255。
同样,若有点不在原图中,也就是说原图中有点被移出了显示区域。
如果不想丢失被移出的部分图像,可以将新生成的图像宽度扩大|tx|,|高度扩大ty|。
平移的算法:
for(j=0;j<1Width;j++)
{
lpDst=(char*)lpNewDIBBits+1LineBytes*(1Height-1-i)+j;
i0=i-1XOffset;
j0=j-1YOffset;
if(j0>=)&&(j0=0)&&(i0{
lpSrc=(char*)lpDIBBits+lLineBytes*(lHeight-1-i0)+j0;
*lpDst=*lpSrc;
}
else
{
*((unsignedchar*)lpDst)=255;
}}}
由于每行像素是连续放置的,可以直接逐行地来复制图像。
首先计算出移出后可视的区域。
对于X轴方向,当tx<=-width时,图像完全移出了屏幕,不做任何处理;
当-width=width时,图像完全移出了屏幕,不做任何处理。
Y轴方向同理。
关键代码如下:
for(i=bi.biHeight-1;i>=0;i--)
for(j=0;j{
imgDataMove[i+K1][3*(j+K2)]=imgData[i][3*j];
imgDataMove[i+K1][3*(j+K2)+1]=imgData[i][3*j+1];
imgDataMove[i+K1][3*(j+K2)+2]=imgData[i][3*j+2];
}
其中,K1,K2这两个参数用来控制平移,通过K1,K2值的改变,来完成平移量的变化。
5.图像的锐化
锐化滤波能减弱或消除图像中的低频率分量,但不影响高频率分量。
因为低频分量对应图像中灰度值缓慢变化的区域,因而与图像的整体特性,如整体对比度和平均灰度值等有关。
锐化滤波将这些分量滤去可使图像反差增加,边缘明显。
在实际应用中,锐化滤波可用于增强被模糊的细节或者低对比度图像的目标边缘。
图像锐化的主要目的有两个:
一是增强图像边缘,使模糊的图像变得更加清晰,颜色变得鲜明突出,图像的质量有所改善,产生更适合人眼观察和识别的图像;二是希望经过锐化处理后,目标物体的边缘鲜明,以便于提取目标的边缘、对图像进行分割、目标区域识别、区域形状提取等。
图像锐化一般有两种方法:
一是微分法,二是高通滤波法。
锐化的部分代码如下:
for(i=bi.biHeight-1;i>=0;i--)//
for(j=0;j{
if((i!
=bi.biHeight-1&&i!
=0)&&(j!
=0&&j!
=width_s-1))
{
imgDataSharp[i][3*j]=(matrixImg(imgData,H,i,j,0))+125;
imgDataSharp[i][3*j+1]=(matrixImg(imgData,H,i,j,1))+125;
imgDataSharp[i][3*j+2]=(matrixImg(imgData,H,i,j,2))+125;
}
else
{
imgDataSharp[i][3*j]=imgData[i][3*j];
imgDataSharp[i][3*j+1]=imgData[i][3*j+1];
imgDataSharp[i][3*j+2]=imgData[i][3*j+2];
}
}
其中,函数abs(matrixImg(imgData,H,i,j,0))取得是锐化差值的绝对值,因为锐化差值基本上都趋近于0,所以锐化后的图像的颜色会显得比较暗。
对于(matrixImg(imgData,H,i,j,1))+125,为了使锐化后的图像的颜色显得比较亮,使锐化效果闲的较为明显,就加了125。
6.图像的放大
图像放大从字面上看,是图像缩小的逆操作,但是,从信息处理的角度来看,则难易程度完全不一样。
图像缩小是从多个信息中选出所需要的信息,而图像放大则是需要对多出的空位填入适当的值,是信息的估计。
最简单的思想是,如果需要将原图像放大为k倍,则将原图像中的每个像素值,填在新图像中对应的k*k大小的子块中。
实现方法为:
设原图像大小为M*N,放大为k1M*k2N,
(k1>1,k2>1)。
算法步骤如下:
①.设旧图像是F(i,j),i=1,2,…,M,j=1,2,…,N.
新图像是G(x,y),x=1,2,…,k1M,y=1,2,…,k2N.
②.G(x,y)=F(c1*i,c2*j)
c1=1/k1c2=1/k2
在实际的操作过程中我发现这种方法会带来明显的失真。
部分代码如下:
for(i=height_s;i>=1;i--)
{
height[i-1]=(int)(i/K1+0.5)-1;
}
for(j=1;j<=width_s;j++)
{
width[j-1]=(int)(j/K2+0.5)-1;
}
这段代码是把所要保留的行数和列数进行了保存和注释。
把需要的行和列风别放进了两个数组height[]和width[]里面。
在这里K1>1且K2>1。
for(i=height_s-1;i>=0;i--)
for(j=0;j{
imgDataBig[i][3*j]=imgData[height[i]][3*(width[j])];
imgDataBig[i][3*j+1]=imgData[height[i]][3*(width[j])+1];
imgDataBig[i][3*j+2]=imgData[height[i]][3*(width[j])+2];
}
这段代码是将height[]和width[]这两个数组中所对应的每个像素的RGB的值依次的放入imgDataBig[][]的数组中,这样就完成了对数据的扩大,也就实现了图像的放大。
7.图像的缩小
图像的缩放不同于图像的其他变换,缩放操作会改变图像的大小,产生的图像中像素可能在原图中找不到相应的像素点,需要进行必要的近似处理。
一般的方法是直接赋值为和它最相近的像素值,也可以通过一些插值算法来计算。
图像缩小的具体算法:
假设图像X轴方向缩放比例为X1,Y轴缩放比例为Y1,那么原图中点(x0,y0)对应与新图中的点(x1,y1)的转换矩阵为:
其逆矩阵为:
即
举一个例子来说明:
当X1=Y1=0.5时,图像被缩放到一半大小,此时缩小后的图像的(0,0)像素点对应于原图像中的(0,0)像素;(0,1)像素对应于原图像中的(0,2)像素点,以此类推。
在原图基础上,每隔一个像素点读取一个像素点。
每隔一行进行操作。
部分程序代码如下:
for(i=height_s;i>=1;i--)
{
height[i-1]=(int)(i/K1+0.5)-1;
}
for(j=1;j<=width_s;j++)
{
width[j-1]=(int)(j/K2+0.5)-1;
}
这段代码是把所要保留的行数和列数进行了保存。
把需要的某行和某列分别放进了两个数组height[]和width[]中。
for(i=height_s-1;i>=0;i--)
for(j=0;j{
imgDataSmall[i][3*j]=imgData[height[i]][3*(width[j])];
imgDataSmall[i][3*j+1]=imgData[height[i]][3*(width[j])+1];
imgDataSmall[i][3*j+2]=imgData[height[i]][3*(width[j])+2];
}
将数组height[]和width[]中所对应的像素RGB的值依次的放入imgDataSmall[][]的数组中,这样就完成了对数据的压缩,即实现了图像的缩小。
8.图像的镜像转化
镜像就是指在镜子中所成的像。
其特点是左右颠倒或者是上下颠倒。
图像的镜像分为水平镜像和垂直镜像。
1.水平镜像:
水平镜像计算公式如下(图像大小为M*N)
由于表示图像的矩阵坐标不能为负,因此需要在进行镜像计算之后,再进行坐标的平移。
程序的部分代码:
for(i=bi.biHeight-1;i>=0;i--)//产生镜像数据
for(j=0;j{
imgDataMirror[i][3*j]=imgData[i][3*(width_s+1+-j)];
imgDataMirror[i][3*j+1]=imgData[i][3*(width_s+1+-j)+1];
imgDataMirror[i][3*j+2]=imgData[i][3*(width_s+1+-j)+2];
}
在这段代码中,通过变量J的变化来逐步产生镜像数据。
在imgData中J的取值是负的,这样就可以在同一行里把每个像素的RGB的值按颠倒的顺序进行排放。
2.垂直镜像
水平镜像计算公式如下(图像大小为M*N)
由于表示图像的矩阵坐标不能为负,因此需要在进行镜像计算之后,再进行坐标的平移。
部分代码如下:
for(i=bi.biHeight-1;i>=0;i--)
for(j=0;j{
imgDataMirror[i][3*j]=imgData[height_s-1-i][3*j];
imgDataMirror[i][3*j+1]=imgData[height_s-1-i][3*j+1];
imgDataMirror[i][3*j+2]=imgData[height_s-1-i][3*j+2];
}
在这段代码中与上面的水平镜像所不一样的地方是,本程序中是通过i的变化来产生镜像数据的。
同样在imgData中i也是是负的,也能实现在同一列中将每个像素的RGB值倒序排列。
第三部分、课程总结
经过一学期的学习与机房的实践,我掌握了一些对图像的基本操作,虽然会使用,但是用的很不熟练,有一些关键性的代码还没有真正掌握。
在本文中,我介绍了图像的反色,图像的二值化,图像旋转,图像平移,图像锐化,图像放大,图像缩小以及对图像的镜像转化等功能的实现算法以及核心代码。
在撰写的过程中发现了如下几个问题,在对图像进行锐化的时候往往不能达到很好的效果,在参数的设定上还比较模糊,对锐化函数还不是很懂。
这些都是我平时上课的时候遗留下来的问题,在今后的学习中,我会逐步的解决这些问题,数字图像处理是一门很有用的学科,涉及面很广,虽然我只略懂皮毛,但也了解了它强大的功能。
我没有将各个功能聚合起来,形成一个程序,是因为能力有限,处理不好各个函数之间的相互影响,所以是将每个功能分开来写,一个程序实现一个功能。
由于时间有限,在很多地方还存在不足之处,希望严老师多多批评指正。
感谢一学期以来严老师的辛苦工作,再次感谢!
!
!