1、第 16 章 图像处理综合系统 友情制作本章导读本章介绍以下 2 个综合系统: 画笔系统 综合图像处理系统16.1 画笔系统综合 前 面 所 学 过 的 有 关 图 像 处 理 特 效 的 知 识 , 编 写 图 像 处 理 综 合 系 统 。 此 系 统 能 够 实现 图 片 的 浏 览 、 放 大 和 缩 小 、 旋 转 、 灰 暗 化 , 以 及 在 图 片 上 画 出 能 够 设 置 颜 色 和 线 条 宽 度的 线 。16.1.1 实例原理应用通用对话框控制文件的打开,选取预设格式的图片加载到图片框中进行浏览。在 VB 中 Form,PictureBox 和 Printer 都有 P
2、aintPicture 方法,它们可以满足按一定比例对图片的大小进行缩小与放大的要求。这个方法的功能是复制图像,其基本语法如下:object.PaintPicture picture, x1, y1, width1, height1, x2, y2,_ width2, height2, opcode 这里的 Picture 来自 Form 等的 Picture 属性,而 x1,y1 是目标区域的左上角坐标,而x2,y2 是源区域的左上角坐标,width1 和 height1 是目标区域的宽度和高度,而 width2和 height2 是源区域的宽度和高度,如果 width1=width2 且
3、height1=height2,那么就是等比例复制,只需要选择适当的参数就可以实现图片的缩小与放大。参数 opcode 是操作码,其含义可以参考 Windows API 中关于 BitBlt 和 StretchBlt 函数的介绍。对图像的旋转我们采用的是逐点计算法。图像是由多个点组成的,如果将每一个点都按一定的角度进行旋转,整幅图像也就进行了旋转。因此,图像的旋转就变为点的旋转,利用逐点计算的方法就可以实现整幅画面的旋转。在图片上画图应用了鼠标的 MouseDown,MouseUp 和 MouseMove 事件,通过逻辑Visual Basic 编程从基础到实践(第 2 版) 560 变量来控
4、制画笔和橡皮是否可用,使用 PictureBox 控件的 Line 方法用鼠标点击相应的图标即可设置线条宽度 DrawWidth 属性。16.1.2 实例演示运行该程序可看到如图 16-1 所示的图像处理综合系统界面。在程序的主界面中,有两个 PictureBox,左面的为“操作区域” ,右面的为“对比区域” , “对比区域”用来与在“操作区域”载入图片进行放大、缩小等处理时的对比。操作区域同时也具有画板的功能。在“工具”栏中选择画笔工具,然后在“颜色”框中选择画笔颜色,接着在“线宽”栏中选择画笔的线宽,当在“操作区域”按下鼠标左键并移动鼠标时就可以实现画图功能了,橡皮工具可以把需要擦除的区域
5、设置成背景色,以实现擦除的效果。图像综合处理中的画图如图 16-2 所示。图 16-1 图像处理综合系统界面图 16-2 图像综合处理中的画图载入图片后,画图工具仍然可用,你可以在图片上进行画图操作。在“编辑”栏中点击“打开”命令按钮,选择图片载入程序,选择的图片将同时载第 16 章 图像处理综合系统 561 入“操作区域”和“对比区域” , “操作区域”将根据图片的大小显示和隐藏滚动条,以便浏览图片,如图 16-3 所示。载入图像后就可以对图片进行相应的操作,点击“编辑”栏中的“放大”命令按钮,“操作区域”中的图片行对于“对比区域”将被放大,你可以拉动水平或垂直滚动条来浏览放大后的图像(如图
6、 16-4 所示)和缩小后的图像(如图 16-5 所示) 。在前面的多媒体学习中我们已经学习了图片的旋转,和这里的图片旋转完全相同。点击“左旋”或“右旋”命令按钮,就能够使整副图片向左(如图 16-6)或向右(如图16-7)旋转 90,如果想旋转更大的角度只需要多点击几次就可以实现,不过旋转的角度要是 90 的整数倍。除了对调整图像大小和旋转图像,本程序还提供了画面变暗的效果,单击“编辑”栏中的“变暗”命令按钮, “操作区域”中的图片将会变暗,与“对比区域”形成鲜明的对比,如图 16-8 所示。图 16-3 将图片载入程序 图 16-4 浏览放大后的图像图 16-5 浏览缩小后的图像 图 16
7、-6 向左旋转图片Visual Basic 编程从基础到实践(第 2 版) 562 图 16-7 向右旋转图片 图 16-8 图片变暗如果在图片上使用了画图工具或者将图片变暗后,当单击“编辑”栏中的“恢复”命令按钮后, “操作区域”就会恢复到图 16-3 时的载入状态。单击“退出”按钮结束程序。16.1.3 实例实现由于篇幅有限,本案例代码被省略其代码请查看光盘,路径: chap16ex_01。16.2 综合图像处理系统本节将介绍一个功能强大的数字图像处理系统。通常,对于要求很高的数字图像处理,一般都是通过 Visual C+来实现,在 Visual Basic 中,如果要进行大规模的图像处理
8、,可以调用通过 C+编译的动态链接库来实现。但是很多时候,只需要使用到部分图像处理功能,或者对图像处理速度要求不是很高的时候,通过 Visual Basic 本身也能够进行各种数字图像的处理。 本节介绍的系统将提供以下功能:(1)能够显示各种文件类型的图片;(2)能够保存成多种文件格式的图片;(3)能够实现图像漫游, 浏览大图片的时候,可以通过鼠标拖动图片或者通过键盘方向键来移动大图片;(4)能够选取图像;(5)能够进行图像的复制粘贴;(6)能够放大、缩小图像、查看原始图像大小、以及自适应显示图像即随着窗体的大小将图像全部显示在窗体中;(7)能够撤销或者重复上一步的操作;(8)当前编辑图像的状
9、态显示;(9)能够进行多种颜色之间的转化,如黑白图、16 色灰度图、256 色灰度图等;第 16 章 图像处理综合系统 563 (10)能够改变图像的大小;(11)能够旋转图像;(12)能够镜像图像;(13)常用的图像参数调整,如饱和度调整、亮度调整、 对比度调整;(14)能够选取图像中任一像素的颜色值;(14)常用的各种图像处理技术,如 Greys、Negative、Sepia、Colorize、Replace HS、 Replace L、Shift、Blur、Soften、Sharpen、Diffuse、Pixelaze、Despeckle、Contour、Emboss 、Outline、
10、 Relieve、 Noise、Scanlines、Dilate、Erode、Texturize 等;(15)各种常见的图像特效效果,如百叶窗效果、马赛克效果、翻页效果等;(16)快速查看放大图像的局部位置; Visual Basic 编程从基础到实践(第 2 版) 564 16.2.1 编程原理本系统文件很多,设计了很多的编程技术和原理,下面就重点介绍其中的一些比较重要的编程技术和原理。1自定义控件开发本系统中,使用了 4 个自定义的控件,分别是 ucCanvas、 ucInfo、ucProgress 以及ucToolbar,这些控件都不是 Visual Basic 自带的,也不是第三方控件
11、,而是通过 Visual Basic 提供的工具来开发的。很多时候为了实现某个功能,或者实现代码的管理,自己开发一个控件是一个很好的选择。开发自定义控件,很多语言都可以实现,如 Visual C +、Visual Basic、Delphi 等,在 Visual Basic 中开发控件,非常简单方便,下面简单介绍自定义开发组件的过程。 (1)创建或者添加自定义控件工程 如果是创建一个单独的控件,则需要创建一个自定义控件工程,如果已经创建了一个工程,则可以添加自定义控件,下面介绍如何开发一个自定义控件工程。启动 Visual Basic,如图 16-9 所示。在图 16-9 中,选择“AciveX
12、 控件” ,然后单击【打开】按钮,创建后界面如图 16-10 所示。 图 16-9 创建 AcitiveX 控件 图 16-10 控件界面从图 16-10 中可以看到,自定义控件的开发界面同普通的 Visual Basic 应用程序窗体开发一样,因此大部分的 Visual Basic 自带的控件,都可以被加入到控件容器中。编者手记如果已经创建了一个工程,需要在该工程中添加控件,则可以通过菜单【工程】【添加用户控件】 ,来添加自定义控件。第 16 章 图像处理综合系统 565 (2)添加属性和方法为了能够让用户能够使用该控件,总是需要为该控件添加一些属性和方法,下面介绍为控件添加属性和方法。在控
13、件中添加属性主要是通过“Public Property Let”和“ Public Property Get”两个方法来实现,下面来看看控件“ucInfo ”的“TextFile ”属性定义过程。以下两个函数定义了属性 TextFile该函数用于设定属性 TextFile 的值Public Property Let TextFile(ByVal New_TextFile As String)m_TextFile = New_TextFileCall RefreshEnd Property 该函数用于获得属性 TextFile 的值Public Property Get TextFile() A
14、s StringTextFile = m_TextFile End Property而在控件中定义方法则比较简单,直接通过关键词“Public ”定义一个函数或者过程即可,如在“ucToolbar ”控件中定义的 “BuildToolbar”方法如下:Public Function BuildToolbar(Image As StdPicture, ByVal MaskColor As OLE_COLOR, ByVal IconSize As Integer, Optional ByVal FormatMask As String) As Boolean省略代码End Function因此如果
15、在其他工程中引用了该控件,则可以同使用其他控件一样使用这些定义的属性和方法,如下所示:ucInfo. TextFile=“hello“myText= ucInfo. TextFileucToolbar.BuildToolbar(LoadResPicture(“BITMAP_TBQUICK“, vbResBitmap), &HFF00FF, 16, “NNN|NN|OO|NNN|C|NN|NNN|NNN|NN“)(3)编译成 OCX 控件如果是在当前工程中使用该控件,则不需要编译,而如果为了让其他用户或者工程能够方便的使用该工程,则需要将控件编译成 OCX 控件,编译的过程很简单,选择菜单【文件
16、】【生成 工程 1.OCX】 ,其中“工程 1”为创建的自定义控件工程的名称,用户可以通过工程属性修改。2API 的应用由于本系统是进行图像处理,众所周知,数字图像一般都比较大,如果使用 Visual Basic 自带的一些图像控件来进行各种图像处理,则会极大的影响速度。为了加快速度,本系统中了很多的 API 函数,下面解释一些本系统中比较重要的 API 函数。 (1)CreateDIBSection 函数创建一个存储 DIB 位的内存区域,既可以执行相应的GDI 操作,又可以直接通过指向 DIB 位区域的指针方位 DIB 位区域。这是一个非常有用的函数,通过它我们可以用 DIB 替代 DDB
17、。Private Declare Function CreateDIBSection Lib “gdi32“ (ByVal hDC As Long, Visual Basic 编程从基础到实践(第 2 版) 566 lpBitsInfo As BITMAPINFOHEADER, ByVal wUsage As Long, lpBits As Long, ByVal handle As Long, ByVal dw As Long) As Long(2)CreateCompatibleDC 函数创建一个与特定设备场景一致的内存设备场景Private Declare Function Create
18、CompatibleDC Lib “gdi32“ (ByVal hDC As Long) As Long(3)CreateCompatibleBitmap 函数创建一幅与设备有关位图,它与指定的设备场景兼容Private Declare Function CreateCompatibleBitmap Lib “gdi32“ (ByVal hDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long(4)DeleteDC 函数删除专用设备场景或信息场景,释放所有相关窗口资源。Private Declare Function D
19、eleteDC Lib “gdi32“ (ByVal hDC As Long) As Long(5)GetObject 函数取得对指定对象进行说明的一个结构。windows 手册建议用GetObject 这个名字来引用该函数。Private Declare Function GetObject Lib “gdi32“ Alias “GetObjectA“ (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long(6)GetObjectType 函数判断由指定句柄引用的 GDI 对象的类型Private Decl
20、are Function GetObjectType Lib “gdi32“ (ByVal hgdiobj As Long) As Long(7)SelectObject 函数用于选择对象。每个设备场景都可能有选入其中的图形对象。其中包括位图、刷子、字体、画笔以及区域等等。一次选入设备场景的只能有一个对象。选定的对象会在设备场景的绘图操作中使用。例如,当前选定的画笔决定了在设备场景中描绘的线段颜色及样式。Private Declare Function SelectObject Lib “gdi32“ (ByVal hDC As Long, ByVal hObject As Long) As
21、Long(8)DeleteObject 函数删除 GDI 对象,比如画笔、刷子、字体、位图、区域以及调色板等等。对象使用的所有系统资源都会被释放。Private Declare Function DeleteObject Lib “gdi32“ (ByVal hObject As Long) As Long(9)BitBlt 函数将一幅位图从一个设备场景复制到另一个。源和目标 DC 相互间必须兼容。Private Declare Function BitBlt Lib “gdi32“ (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Lon
22、g, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long(10)StretchBlt 函数将一幅位图从一个设备场景复制到另一个。源和目标 DC 相互间必须兼容。这个函数会在设备场景中定义一个目标矩形,并在位图中定义一个源图像。第 16 章 图像处理综合系统 567 源矩形会根据需要进行伸缩,以便与目标矩形的大小相符。Private Declare Function Stretc
23、hBlt Lib “gdi32“ (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long(11)SetStretchBltMode 函数指定 StretchBlt 和 Str
24、etchDIBits 函数的伸缩模式。这种伸缩模式定义了 Windows 如何对伸缩过程中剔除的扫描线进行控制。对于 VB 窗体和控件,倘若在 API 绘图过程中使用这个函数,建议恢复原来的 StretchBlt 模式。Private Declare Function SetStretchBltMode Lib “gdi32“ (ByVal hDC As Long, ByVal nStretchMode As Long) As Long(12)GetDIBColorTable 函数选入设备场景的 DIBSection 中取得颜色表信息Private Declare Function GetDI
25、BColorTable Lib “gdi32“ (ByVal hDC As Long, ByVal un1 As Long, ByVal un2 As Long, lpRGBQuad As Any) As Long(13)GetDIBits 函数将来自一幅位图的二进制位复制到一幅与设备无关的位图里Private Declare Function GetDIBits Lib “gdi32“ (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As
26、 Any, lpbi As Any, ByVal wUsage As Long) As Long(14)SetRect 函数设置指定矩形的内容Private Declare Function SetRect Lib “user32“ (lpRect As RECT2, ByVal x1 As Long, ByVal y1 As Long, ByVal x2 As Long, ByVal y2 As Long) As Long(15)FillRect 函数用指定的刷子填充一个矩形Private Declare Function FillRect Lib “user32“ (ByVal hDC A
27、s Long, lpRect As RECT2, ByVal hBrush As Long) As Long(16)CreateSolidBrush 函数用纯色创建一个刷子Private Declare Function CreateSolidBrush Lib “gdi32“ (ByVal crColor As Long) As Long(17)CreatePalette 函数创建调色板 Private Declare Function CreatePalette Lib “gdi32“ (lpLogPalette As Any) As Long(18)GetDC 函数获取指定窗口的设备场景
28、Private Declare Function GetDC Lib “user32“ (ByVal hWnd As Long) As Long(19)GetDesktopWindow 函数获得代表整个屏幕的一个窗口(桌面窗口)句Private Declare Function GetDesktopWindow Lib “user32“ () As Long(20)ReleaseDC 函数释放由调用 GetDC 或 GetWindowDC 函数获取的指定设备场景。它对类或私有设备场景无效Visual Basic 编程从基础到实践(第 2 版) 568 Private Declare Funct
29、ion ReleaseDC Lib “user32“ (ByVal hWnd As Long, ByVal hDC As Long) As Long(21)OpenClipboard 函数打开剪贴板Private Declare Function OpenClipboard Lib “user32“ (ByVal hWnd As Long) As Long(22)CloseClipboard 函数关闭剪贴板 Private Declare Function CloseClipboard Lib “user32“ () As Long(23)SetClipboardData 函数设定剪贴板的数据
30、Private Declare Function SetClipboardData Lib “user32“ (ByVal wFormat As Long, ByVal hMem As Long) As Long(24)EmptyClipboard 函数清空剪贴板 Private Declare Function EmptyClipboard Lib “user32“ () As Long(25)DeleteObject 函数删除 GDI 对象,比如画笔、刷子、字体、位图、区域以及调色板等等。对象使用的所有系统资源都会被释放Private Declare Function DeleteObje
31、ct Lib “gdi32“ (ByVal hObject As Long) As Long本系统中还使用了其他一些 API 函数,读者可以参考相关的资料。3常用图像处理原理本系统实现了很多的图像处理的功能,但是每种图像处理都有一定的理论基础,下面介绍一些常用的图像处理的原理。(1)图像的灰度处理图像由彩色转化为灰度的过程叫做灰度化,由于位图为点阵图像,它的每一个像素点有 R、 G、B 三个分量组成, R、G 、B 的变化可以产生 1600 多万种颜色,Delphi 中灰度化有几种方法可以实现:方法一:求出每一个像素点的 R、G、B 的平均值,然后把这个平均值赋给该像素点的 R、G 、B 三个
32、分量。方法二:求出每一个像素点 R、G、B 三个分量的最大值,然后把这个最大值赋给原来像素点的 R、G、B 三个分量。方法三:根据 YUV 的颜色空间, Y 分量的物理含义就是亮度,它含了灰度图的所有信息,只用 Y 分量就完全能够表示出一幅灰度图来。 YUV 和 RGB 之间有着如下的对应关系: 10.437.01.528956BGRVU第 16 章 图像处理综合系统 569 利用上式,可以求出:Y0.299R+0587G+0.114B根据 R,G,B 的值求出 Y 值后,将 R,G,B 值都赋值成 Y,就能表示出灰度图来,这就是 24 位真彩色图转灰度图的原理。(2)图像的二值化 图像的二值
33、化的具体办法是:通过设定阈值(Threshold) ,把灰度图像变换成仅用两个值(0 或 1)来分别表示的图像目标和图像背景的二值图像,其中目标取值为 1,背景值取值为 0。实际的位图(Bitmap)中,0 对应于 RGB 值均为 0,1 对应于 RGB 值均为255,二值化图像的方法很多,阈值的选择是二值化图像的关键。阈值的选择主要可以分为两类:全局阈值和局部阈值。全局阈值是对整个图像采用一个阈值进行划分,例如固定阈值法二值化、判断分析法二值化、基于灰度差直方图的阈值法等。不同的灰度图像,其灰度深度是存在差异的。同一幅灰度图像,不同部位其明暗分布可能是不同的。因此,在对灰度图像进行二值化的过
34、程中,如果选用全局阈值法显然是不合适的。局部阈值是将图像分成一些子块,对于每一子块选定一个阈值。其中动态阈值法是一个变换方法,即在一个 nn 的子块中,所有具有灰度级超过平均灰度值到 255 数据点变换 1(即黑色) ,而另一些低于平均灰度值的数据点则变换到 1(即白色) 。具体作法如下:图像分为 nn 的方块,对每一个子块计算其平均灰度值,然后将方块中每个像素点的灰度值与平均灰度值进行比较,若大于平均灰度值,则将该像素点灰度值置为 255;反之则置为 0。一般采用 88 的分块大小的动态阈值二值化方法能取得的效果最佳。(3)图像对比度图像对比度 是 指 图 像 上 两 点 问 信 号 的 差
35、 异 。 在 一 幅 灰 阶 图 像 上 , 信 号 的 差 异 是 通 过 灰度 ( 或 亮 度 ) 的 明 暗 来 体 现 的 , 高 对 比 度 意 思 是 图 像 上 两 个 不 同 观 察 点 一 个 非 常 暗 , 另 一个 非 常 亮 , 而 低 对 比 度 表 示 两 点 的 相 对 亮 度 差 别 较 小 , 当 在 提 高 对 比 度 时 , 图 像 中 的 暗 色调 变 得 更 暗 , 亮 色 区 域 变 得 更 亮 , 而 人 眼 在 辩 认 一 件 事 物 时 , 更 多 地 是 从 色 彩 的 差 错 对 比中 得 出 结 论 , 因 此 更 大 的 对 比 度 会
36、 带 来 更 为 醒 目 的 效 果 。 对 比 度 的 改 变 , 往 往 使 暗 色 调 损失 细 节 , 因 此 , 在 几 乎 所 有 位 图 处 理 软 件 中 , 都 将 明 暗 度 ( Brightness) 调 整 功 能 与 对 比 度调 整 功 能 集 中 放 在 一 起 以 便 于 使 用 。 适 当 地 进 行 一 些 明 暗 调 整 , 会 让 整 个 图 像 显 得 更 加 自然 。 在 Delphi 程 序 设 计 中 , 一 个 简 化 的 方 法 是 : 区 间 调 节 即 首 先 设 定 一 个 阈 值 , 通 常 是128; 然 后 判 断 像 素 点 的
37、 R, G, B 值 , 凡 是 大 于 128 的 , 增 加 一 个 值 , 小 于 128 的 , 减 少一个值。(4)图像平移初始坐标为(x0,y 0)的点经过平移(tx ,ty) (以向右,向下为正方向)后,坐标变为(x1,y1) 。这两点之间的关系是 x1=x0+tx;y1=y0+ty.以矩阵的形式表示为 :Visual Basic 编程从基础到实践(第 2 版) 570 101xytxy它的逆变换: 0101xytxy由于我们想知道的是平移后的图像中每个像素的颜色。很显然,该点是原图中的某一点经过平移后得到的,这两点的颜色肯定是一样的,所以只要知道了原图那点的 RGB值即可。那么
38、到底新图中的左上角点对应原图中的哪一点呢?将左上角点的坐标(0,0)代入逆变换,得到 x0=-tx;y 0=-ty;所以新图中的( 0,0)点的颜色和原图中(-tx, -ty)的一样。也就是通过平移后的像素点的位置返回去求出原始点的像素位置,这样就存在一个问题:如果新图中有一点(x1,y1) ,如果变化得到的(x0,y0)不在原图中则把该点的 RGB 值统一设成白色(255,255,255) ,平移后的图像没有缩放,移出的部分被截断。(5)图像的旋转图像的旋转其实就是图像上像素点的坐标变换,假如旋转前某一点的坐标位x,y ,1,旋转后的坐标为 ,在二维平面上点绕原点顺时针旋转 角,则其变换矩阵
39、为:*,1xy cosin0i01坐标的变换公式: *,1,cosin,sicos,1csin0i0xyxy 旋转前的图像上的点如果用上述变换矩阵,则有可能多个点映射到同一个点,为此我们采用坐标的反变换公式,先求出旋转后的图像的点对应的旋转前的图像上的点,此时只需把旋转前的点的像素值赋给旋转后的相应的点,这种方法可以保证旋转后的每一个点都能被赋值。反变换公式如下:第 16 章 图像处理综合系统 571 *,1,cosin,sicos,1csin00xyxy 此时的旋转的中心点在图像的原点,也就是客户区坐标的左上角,如果要求旋转的中心点为图像的中心,则反变换公式修改如下: *,1icentr,j
40、t,0,jter,1cosin01xyit 其中 icenter 和 jcenter 分别是旋转前图像的宽度和高度的一半,此时在内存中动态创建两个位图对象 TempBmp 和 NewBmp,一个用于存放旋转前的位图(TempBmp ) ,另一个则是存放旋转后的位图(NewBmp ) ,位图格式为 24 位真彩色。(6)图像镜像所谓的镜像显示,就是好像一幅图像放在镜头里面,形成两幅绝对对称的图像,具体操作时具有水平镜向和垂直镜像之分,这其中包括两幅图像的显示过程,即正面图像和反面图像,正面图像的显示方法非常简单,关键之处是反面图像的显示过程,这其中涉及图像的变形操作;实现图像变形的一种简单方法是
41、重新安排像素位置,比如左面和右面的像素条一一对换,即可得到水平方向的反面图像,同样通过上下像素条的对换则可得到垂直方向的反面图像。为了得到更美观的镜像显示效果,具体操作时不能先显示一幅正常图像,然后再显示反面图像,而需要两个图像时从交叉点向外显示,这样将形成特殊的屏幕效果。(7)图像扭曲图像扭曲的原理为将位图图像中的每一个像素点按照一定的半径进行逆时针旋转到新的位置,旋转的角度由该点的原始坐标以及图像的原始大小决定,整体效果就好像被扭曲了一样。(8)图像波浪效果与图像的扭曲类似,在处理此类问题的时候一般用反向求取法,即假如对一幅经过波浪处理过的图像上的一个像素点 Pixelsi, j,通过坐标
42、的反变换,我们可以求出这个点所对应的是原始位图上的哪一个点,求出原始图上该点的坐标,例如波浪处理过的图像上的一点为 PixelsXSrc,YSrc,而经过坐标反变换后得到对应的点为 Pixelsi,j,则只需Pixelsi, j=PixelsXSrc,YSrc,就实现像素点的颜色赋值。(9)颜色空间转换对于任何 3 个单位化到0,1范围内得 R、G 、B 值,其对应的 HSL 模型中的H、S、L 可由下面的计算:Visual Basic 编程从基础到实践(第 2 版) 572 1()3LRGBmin(,()S公式(10)122)arcos()(HRGBHSL 转换 RGB,要先把 S、 L 单
43、位化,R、G 、B 也在0,1之间。当 H 在0 0,1200时: (1)S06CosH3()GIBR当 H 在1200,2400 时:(1)LS028CosH3()BIGR当 H 在2400,3600 之间时: (1)LS0243CosH()RIGB(10)图像锐化在图像系统中由于摄影系统的聚焦不良和信号传输系统信号频带过窄,造成图像中目标轮廓的模糊是必然的。图像的模糊实际上是由于颁率高的空间频率成分低于频率低的空间频率成分而造成的,这一影响表现于均匀灰度区域间的边界部分(边缘) ,如图16-11 所示。因此要消除模糊,必须增强图像中频率高的空间频率成分,即图像的锐化(或细微层次强调) 。第
44、 16 章 图像处理综合系统 573 1 2图 16-11 模糊边缘带来的影响图像锐化(Image Sharpening)是一种使图像具有的信息让人们易于观察的图像质量改善方法,从数学角度上讲就是对图像进行微分化处理。在图像中,边缘是由灰度级和相邻域点不同的像素点构成的。因而,若想增强边缘,就应该突出相邻点间的灰度级的变化。微分运算可用来求信号的变化率,因而具有加强高频分量的作用。如果将其应用在图像上,可使图像的轮廓清晰。由于常常无法事先确定轮廓的取向,因而挑选用于轮廓增强的微分算子时,必须选择那些不具备空间方向性的和具有旋转不变的线性微分算子。用这种方法可以去掉引起图像质量劣化的原因之一“
45、模糊“ ,并把图像变得轮廓分明。卷积是实现锐化的一个很好的变通。卷积可以看成是加权求和的过程,卷积时使用一个很小的矩阵来表示,矩阵的维数为奇数,该矩阵体现在程序中就是模板概念,区域中的每个像素分别与模板中相应的元素相乘,相乘之和即为区域中心像素新值,例如一个 33的区域 A 和模板 P 卷积后,区域 A 的中心像素 A5 像素值表示为:591=iP其中, 123123456456789789AP不同的模板可以得到不同的效果,一般所用模板采用 33 矩阵,在采用模板操作时必须解决两个问题,即边界点问题,一般可以忽略第一列和最后一列像素的操作,或者直接进行边界像素的拷贝,还有一个问题即是越界问题,
46、必须保证中心像素点的各分量在 0255 范围。锐化的常用模板如下:, , , 10519125129(11)图像平滑在输入图像的过程中,图像可能存在各种寄生效应,如可能受到各种噪声源的干扰,Visual Basic 编程从基础到实践(第 2 版) 574 混入各种高频噪声。另外如光电转换过程中的噪声、照片颗粒噪声和信息传输中的误差等,从而不能保证正确地求出数字图像的密度信息。要求得正确的图像信息则必须消除噪声。此外在印刷彩色复制过程中为了保证诸如肤色、丝绸质感之类的复制及艺术再现需要,亦需要图像平 滑 、 柔 和 、 降 低 锐 度 。 因 此 这 种 消 除 图 像 的 噪 声 及 满 足
47、彩 色 复 制 特 殊需 要 的 方 法 , 在 图 像 处 理 中 称 为 图 像 平 滑 。 亦 即 采 用 依 据 小 区 域 平 均 化 方 法 的 滤 波 , 从 数学 上 讲 就 是 采 用 一 种 具 有 能 够 除 去 高 频 成 分 性 质 的 积 分 运 算 。 图 像 平 滑 亦 分 为 空 间 域 处 理和 频 谱 域 处 理 两 种 。 主 要 有 邻 域 平 均 法 , 低 通 滤 波 法 , 和 多 图 像 滤 波 法 等 , 本 节 主 要 介 绍邻 域 平 均 法。邻域平均法是一种在空间域上对图像进行平滑处理的最常用方法。该方法的核心是求出图像中以某点为中心的
48、一个邻域范围内的图像像素之平均值,并以此平均值来作为该中心点的灰度值,假定一幅 个像素的图像 ,平滑后处理得到一幅图像N(,)fxy,则:(,)gxy (,)1(,)(,)mnsgxyfM式中 ,S 是 点邻域中心的点的集合,但是其中不包括,01,23.xy,点,M 是集合内点的总数。一般的邻域有四点邻域和八点邻域,八点邻域效果要好(,)于四点邻域,和锐化一样,采用模板来编制程序。图像平滑的模板大致有以下几个:, ,1z=9算 子 核 12z=10算 子 核 214z=16算 子 核(12)中值滤波中值滤波是把数字图像中的一点的值用该点的一个领域的各个点的值的中值代替,中值的定义如下:一组数 假如排序如下:1234,nxx123iiiinxx1()21234()(),ninniiyMedxxA其 中 奇其 中 偶y 称为 的中值,加入一个序列(10,20,30,40,50,60,70)则1234,n中值为 40。把一个点的特定长度或形状的邻域称作窗口,在一维的时候,中值滤波器是一个奇数个像素的滑动窗口,窗口正中间的值用窗口内各个像素的中值代替。设输入为 ,则滤