1、1第 1 章 位图基础本章要点: 数字图像的基本概念 与设备相关位图(DDB) 与设备无关位图(DIB) CDib 类库 的建立 数字图像处理的应用1.1 数字图像的基本概念计算机屏幕上显示出来的画面通常有两种描述方法:一种为图形,另一种为图像。图形、图像在存储结构和表示方法上有着根本的区别。图形是矢量结构的画面存储形式,是由指令集合组成的描述,这些指令描述构成一幅图的所有直线、圆、圆弧、矩形、曲线等的位置、维数和大小、形状、颜色,显示时需要相应的软件读取这些命令,并将其转变为屏幕上所显示的形状和颜色,图形记录的主要内容是坐标值或坐标值序列,对一般画面内容的颜色或亮度隐含且统一地描述,因此,矢
2、量结构显式地表现画面内容的坐标值。图像是以栅格结构存储画面内容,栅格结构将一幅图划分为均匀分布的栅格,每个栅格称为像素,显式地记录每一像素的光度值(亮度或彩色),所有像素位置按规则方式排列,像素位置的坐标值却是有规则地隐含。图像由数字阵列信息组成,用以描述图像中各像素点的强度与颜色,因此图像适合于表现含有大量细节(如明暗变化、场景复杂和多种颜色等) 的画面,并可直接、快速地在屏幕上显示出来。图像占用存储空间较大,一般需要进行数据压缩。色度学理论认为,任何颜色都可由红(Red)、绿(Green)、蓝(Blue)三种基本颜色按照不同的比例混合得到。红、绿、蓝被称为三原色,简称 RGB 三原色。在
3、PC 的显示系统中,显示的图像是由一个个像素组成的,每一个像素都有自己的颜色属性,像素的颜色是基于RGB 模型的,每一个像素的颜色由红,绿,蓝三原色组合而成。3 种颜色值的结合确定了在图像上看到的颜色。人眼看到的图像都是连续的模拟图像,其形状和形态表现由图像各位置的颜色所决定。因此,自然界的图像可用基于位置坐标的三维函数来表示,即:f(x,y,z)=f red(x,y,z) ,f green(x,y,z), f blue(x,y,z)其中 f 表示空间坐标为(x,y,z)位置点的颜色, f red 、f green、 f blue 分别表示该位置点的红、绿、蓝三种原色的颜色分量值。他们都是空间
4、的连续函数,即连续空间的每一点都有一个精确的值与之相对应。为了研究的方便,主要考虑平面图像。平面上每一点仅包括两个坐标值,因此,平面图像函数是连续的二维函数,即: f(x,y)=f red(x,y) ,f green(x,y), f blue(x,y)数字图像是连续图像 f(x,y)的一种近似表示,通常用由采样点的值所组成的矩阵来2表示:f(0,0) f(0,1). f(0,M-1)f(1,0) f(1,1). f(1,M-1)f(N-1,0) f(N-1,1). f(N-1,M-1) 每一个采样单元叫做一个像素(pixel),上式中,M、N 分别为数字图像在横、纵方向上的像素总数。在计算机内
5、通常用二维数组来表示数字图像的矩阵,把像素按不同的方式进行组织或存储,就得到不同的图像格式,把图像数据存成文件就得到图像文件。图像文件按其数字图像格式的不同一般具有不同的扩展名。最常见的图像格式是位图格式,其文件名以 BMP 为扩展名。图像数字化的精度包括两个部分,即分辨率和颜色深度。 分辨率指图像数字化的空间精细程度,有显示分辨率和图像分辨率两种不同的分辨率。图像分辨率是数字化图像时划分图像的像素密度,即单位长度内的像素数,其单位是每英寸的点数 DPI(Dots Per Inche) 。显示分辨率是把数字图像在输出设备(如显示屏或打印机等)上能够显示的像素数目和所显示像素之间的点距。显示分辨
6、率是用户在屏幕上观察图像时,所感受到的分辨率。一般显示分辨率是由计算机的显示卡所决定的。例如标准的 VGA 显示卡的分辨率是 640480,即宽 640 点(像素) ,高 480 点(像素) 。至于较高级的显示卡,通常可以支持 800600 或是 1024768 点以上。图像分辨率说明了数字图像的实际精细度,显示分辨率说明了数字图像的表现精细度。具有不同的图像分辨率的数字图像在同一输出设备上的显示分辨率相同。数字图像的颜色深度表示每一像素的颜色值所占的二进制位数。颜色深度越大则能表示的颜色数目越多。颜色深度的不同,就产生不同种类的图像文件,在计算机中常使用如下类型的图像文件。1单色图像单色图像
7、中每个像素点仅占一位,其值只有 0 或 1,0 代表黑,1 代表白或相反。因为图像中的每个像素仅需 1 位信息,常把单色图像称为是 1 位图像。单色图像具有比较简单的格式,一般由黑色区域和白色区域组成。2灰度图像灰度图像具有如下特征:(1) 灰度图像的存储文件带有图像颜色表,此颜色表共有 256 项,图像颜色表中每一表项由红、绿、蓝颜色分量组成,并且红、绿、蓝颜色分量值都相等,即:f red(x,y) =f green(x,y)= f blue(x,y)(2) 每个像素由 8 位组成,其值范围从 0255,表示 256 种不同的灰度级。每个像素的像素值 f(x,y)是图像颜色表的表项入口地址。
8、例如,某灰度图像(16x6)对应的数值矩阵如下:125,153,158,157,127, 70,103,120,129,144,144,150,150,147,150,160,133,154,158,100,116,120, 97, 74, 54, 74,118,146,148,150,145,157,155,163, 95,112,123,101,137,108, 81, 71, 63, 81,137,142,146,152,167, 69, 85, 59, 65, 43, 85, 34, 69, 78,104,101,117,132,134,149,54, 46, 38, 44, 38,
9、36, 44, 36, 25, 48,115,113,114,124,135,152,58, 30, 44, 35, 28, 69,144,147, 57, 60, 93,106,119,124,131,144,33伪彩色图像伪彩色图像与灰度图像相似,其存储文件中也带有图像颜色表,伪彩色图像具有如下特征:(1)图像颜色表中的红、绿、蓝颜色分量值不全相等,即:f red(x,y)f green(x,y) f blue(x,y)(2)整幅图像仅有 256 种颜色,要表示 256 种不同的颜色,像素必须由 8 位组成,每个像素值不是由每个基色分量的数值直接决定,而是把像素值当作图像颜色表的表项入口地
10、址。把具有 256 色的图像称为 8 位彩色图像。256 色图像有照片效果,比较真实。424 位真彩色图像具有全彩色照片表达能力的图像为 24 位彩色图像,24 位真彩色图像存储文件中不带有图像颜色表,其具有如下特征:(1)图像中每一像素由 RGB 三个分量组成,每个分量各占 8 位,每个像素需 24 位。(2)f red(x,y)、f green(x,y)、 f blue(x,y)取值范围为 0255。例如,某彩色图像(6x8)对应的数值矩阵如下: (207,137,130) (220,179,163) (215,169,161) (210,179,172) (210,179,172) (2
11、07,154,146)(217,124,121) (215,169,161) (216,179,170) (216,179,170) (207,137,120) (159, 51, 71)(213,142,135) (216,179,170) (221,184,170) (190, 89, 89) (204,109,113) (204,115,118)(216,179,170) (220,188,176) (190, 77, 84) (206, 95, 97) (217,113,113) (189, 85, 97)(222,192,179) (150, 54, 71) (177, 65, 73
12、) (145, 39, 65) (150, 47, 67) (112, 20, 56)(136, 38, 65) (112, 20, 56) (112, 20, 56) (109, 30, 65) (112, 20, 56) ( 95, 19, 64)(136, 38, 65) ( 91, 11, 56) (113, 25, 60) (103, 19, 59) ( 81, 12, 59) (126, 62, 94)(138, 46, 71) (103, 19, 59) (158, 65, 83) (124, 40, 70) (145, 62, 79) (130, 46, 73)由于 24 位真
13、彩色图像所需的存储空间很大,处理速度较慢,当需要存储空间不大,并且要求实时快速处理图像时,一般都要利用相应的 8 位位图对其进行近似处理,因此 8 位位图是图像技术中涉及范围比较广泛的一种图像表示方法。本书从第二章至第十章介绍 8位位图的处理技术。第十一章介绍 24 位位图的处理技术。1.2 与设备相关位图(DDB)与设备相关位图 DDB 是一种内部位图格式,它显示的图像依计算机显示系统的设置不同而不同,因此一般不存储文件。结构 BITMAP 定义了 DDB 位图的类型、宽度、高度、颜色格式和像素位值,该结构在 Windows.h 中定义如下:typedef struct tagBITMAPi
14、nt bmType; / 位图类型,必须设为 0int bmWidth; / 位图宽度int bmHeight; /位图高度int bmWidthBytes; /位图中每一扫描行中的字节数4BYTE bmPlanes; /颜色层数BYTE bmBitsPixel; /每一像素所占的位数Void FAR* bmBits; /存放像素值内存块的地址 BITMAP;DDB 中不包括颜色信息,显示时是以系统的调色板为基础进行各位的颜色映射的,Windows 只能保证系统调色板的前二十种颜色稳定不变,所以 DDB 只能保证正确显示色彩少于二十色的位图。Windows SDK 提供了标准的 DDB 位图操
15、作函数,MFC 中定义了CBitmap 类来说明 DDB 位图,其中封装了与 DDB 位图操作相关的数据结构和操作函数。表1-1 列出了 CBitmap 类封装的主要函数。表 1-1 CBitmap 类封装的主要函数函数名 功能LoadBitmap 从应用程序的资源中装入位图资源,并将其与 CBitmap 对象连接CreateBitmap 用指定了宽、高和位模式的内存位图来创建位图,并将其与 CBitmap对象连接CreatCompatibleBitmap创建与指定设备兼容的位图,并将其与 CBitmap 对象连接GetBitmap 从位图中获取信息,并填充 BITMAP 结构SetBitma
16、pBits 用指定的图像位来设置位图的位值1.3 与设备无关位图(DIB)与设备无关位图 DIB 可以在不同的机器或系统中显示位图所固有的颜色。与 DDB 相比而言,DIB 是一种外部的位图格式,经常存储以 BMP 为后缀的位图文件。DIB 位图还支持图像数据的压缩。1BMP 文件组成BMP 文件由文件头、位图信息头、颜色信息和图像数据四部分组成。位图结构如下所示:位图文件头结构 BITMAPFILEHEADER位图信息头结构 BITMAPINFOHEADER位图颜色表 RGBQUAD位图像素数据2. BMP 文件头 BMP 文件头数据结构含有 BMP 文件的类型、文件大小和位图起始位置等信息
17、。其结构定义如下: typedef struct tagBITMAPFILEHEADERWORD bfType; / 位图文件的类型,必须为 BMDWORD bfSize; / 位图文件的大小,以字节为单位WORD bfReserved1; / 位图文件保留5字,必须为 0WORD bfReserved2; / 位图文件保留字,必须为 0DWORD bfOffBits; / 位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位 BITMAPFILEHEADER;3. 位图信息头 BMP 位图信息头数据用于说明位图的尺寸等信息。typedef struct tagBITMAPINFO
18、HEADERDWORD biSize; / 本结构所占用字节数LONG biWidth; / 位图的宽度,以像素为单位LONG biHeight; / 位图的高度,以像素为单位WORD biPlanes; / 目标设备的级别,必须为 1WORD biBitCount; / 每个像素所需的位数 ,必须是 1(双色), 4(16 色),8(256 色)或 24(真彩色)之一DWORD biCompression; / 位图压缩类型,必须是 0(不压缩),1(BI_RLE8 压缩类型)或 2(BI_RLE4 压缩类型)之一DWORD biSizeImage; / 位图的大小,以字节为单位LONG b
19、iXPelsPerMeter; / 位图水平分辨率,每米像素数LONG biYPelsPerMeter; / 位图垂直分辨率,每米像素数DWORD biClrUsed; / 位图实际使用的颜色表中的颜色数DWORD biClrImportant; / 位图显示过程中重要的颜色数 BITMAPINFOHEADER;4. 颜色表 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个 RGBQUAD 类型的结构,定义一种颜色。RGBQUAD 结构的定义如下: typedef struct tagRGBQUADBYTE rgbBlue;/ 蓝色的亮度(值范围为 0-255)BYTE rgbGr
20、een; / 绿色的亮度(值范围为 0-255)BYTE rgbRed; / 红色的亮度(值范围为 0-255)BYTE rgbReserved;/ 保留,必须为 0 RGBQUAD;颜色表中 RGBQUAD 结构数据的个数有 biBitCount 来确定:当 biBitCount=1,4,8 时,分别有 2,16,256 个表项;当 biBitCount=24 时,没有颜色表项。位图信息头和颜色表组成位图信息,BITMAPINFO 结构定义如下:typedef struct tagBITMAPINFO BITMAPINFOHEADER bmiHeader; / 位图信息头6RGBQUAD b
21、miColors1; / 颜色表 BITMAPINFO;5. 位图数据 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数: 当 biBitCount=1 时,8 个像素占 1 个字节;当 biBitCount=4 时,2 个像素占 1 个字节;当 biBitCount=8 时,1 个像素占 1 个字节;当 biBitCount=24 时,1 个像素占 3 个字节。位图图素的位数可为 1、4、8 和 24,其图像的颜色数分别为 2、16、256 和真彩色。其中前三种具有对应的颜色表,而 24 位位图的颜色表为空,其像素值就是颜色
22、值。如果BITMAPINFOHEADER 的 biClrUsed 域不为 0,则其值为位图所使用的颜色数,也即是颜色表的表项数。如果该域为 0,则位图的颜色表的表项数是满的,即像素颜色位数为 1、4、8,则其颜色表项数分别为 2、16、256。颜色表中一般将最重要的颜色排在前面。DIB 位图的位数据紧跟在颜色表后面。数据可以是不压缩的,也可以是压缩的。对 4位和 8 位位图,可以采用 RLE(游程长度编码)压缩,分别称为 RLE4 和 RLE8 位图。位数据以行为单位存储,每行都被填充到一个四字节边界,即每行所占的存储长度总是四字节(32 位)的倍数,不足时将多余位用 0 填充。位图行的存储次
23、序是颠倒的,即位图文件中第一行数据对应的是位图的最底行。对于像素位数为 1 的 DIB 位图,其每个像素只占 1 位,每个字节存储 8 个像素。字节的最高位对应于最左边的像素。在像素位数为 24 的 DIB 位图中,每个像素占三字节,从左到右的每一字节分别存储蓝、绿、红的颜色值。每行用 0 填充到一个四字节边界。表 1-2 Windows 位图结构数据域的含义结构 数据域 含义BITMAPFILEHEADER bfType 字节“BM”bfSize 文件总字节数BfReserved1 0BfReserved1 0bfOffBits 位图数据距文件头的偏移量BITMAPINFOHEADER bi
24、Size 本结构大小的字节数biWidth 位图的宽度,单位为像素点biHeight 位图的高度,单位为像素点biPlanes 1biBitCount 像素的位数(1,4,8,24)biCompression 压缩方式(0 表示不压缩)bisizeImage 位图数据的字节数biXpelsPerMeter 水平分辨率(像素点/米)biYpelsPerMeter 垂直分辨率(像素点/米)biClrUsed 图像中使用的颜色数biClrImportant 图像中重要的颜色数RGBQUAD rgbBlue 蓝色的比例7rgbGreen 绿色的比例rgbRed 红色的比例rgbReserved 01.
25、4 CDib 类库的建立大多数图像处理都是基于与设备无关位图(DIB)来进行讨论的,由于 MFC 中没有处理DIB 位图的类,这就给编程带来了许多困难。所以需要定义一个处理 DIB 位图的专用类CDib 类,在其中封装必要而有效的 DIB 数据成员和处理函数。该类具有的功能如下。void LoadFile(CString m_fileName); -装载 BMP 位图文件BOOL SaveFile(const char *pszFilename);-存储 BMP 位图文件char* GetFileName(); -返回位图文件名DWORD GetSize();-返回位图文件的大小UINT Ge
26、tWidth();-返回位图的宽度UINT GetHeight();-返回位图的高度UINT GetNumberOfColors();-返回位图颜色数目RGBQUAD* GetRGB();-返回颜色表首地址BITMAPINFO* GetInfo();-返回图像信息结构首地址BYTE* GetData();-返回图像数据首地址1.CDib 类的设计目标用面向对象的方法处理位图的核心是设计一个处理 DIB 的类,称之为 CDib 类。本节从功能、父类、数据封装和继承等方面来分析 CDib 类的设计目标。(1)功能根据上节对 DIB 操作的分析,以及参照 CBitmap 的功能设计,CDib 类的基
27、本操作功能应包括:DIB 文件的读、写操作;提供位图宽度、高度、颜色数目等位图相关信息;提供有关位图占据内存空间的信息,包括:图像数据区首地址、颜色表首地址、位图信息结构首地址等信息。(2)父类由于 MFC 中已有一个支持 DDB 操作的 CBitmap 类,因此,很直观的想法是,以CBitmap 类为父类派生出 CDib 类。但是,从长远考虑,这样做并没有什么好处。首先,CBitmap 类是为 DDB 的操作而设计的,其中没有处理 DIB 的功能,因此 CDib 类不能从中继承任何可用的功能。其次,CBitmap 类是从 CGdiObject 中派生来的,CBitmap 类以及它从CGdiO
28、bject 类继承来的数据成员和功能函数对 CDib 类来说都是不合适的,也是多余的。此外,CBitmap 类没有提供有效的文件操作机制。而 DIB 主要是一种“外部”位图,即它主要以文件形式进行存储和交换,所以 CDib 类应该能很好地处理文件操作。MFC 中的 CObject 类是 MFC 中其他大多数类的根类和基类。它不但提供许多有用的特性,还包括对文件串行化的支持,运行时的类信息和对象诊断的输出等。如果从 CObject类派生类,则可继承该类的这些特性。另外,CObject 类具有最低限度的成员数据和函数,从 CObject 类派生类所花的代价是最低的。因此,采用 CObject 类作
29、为 CDib 类的父类是很8合理的。(3)数据封装面向对象方法的一个重要特征就是数据封装。即将类的成员数据隐藏在类中,外界只能通过类的成员函数来操作类的成员数据。这是面向对象方法的重要优点,它可以保护类中的数据不受外部的意外修改。但是,过分“纯粹”的数据封装,需要付出降低程序效率的代价。特别在设计像 CDib 这样需要大量使用 Win32 API 函数的类时,这种缺陷特别突出。因为操作 DIB 的 API 函大多需要一些 DIB 的属性作为参数。如果硬要将这些属性封装起来,则需要在类中重新实现许多 Win32 API 函数。这不但要花费很大的精力,而且还可能因此而产生错误和低效。所以,在设计
30、CDib 时应采用既尽可能保证数据的封装,又能保证效率的提高。(4)继承CDib 类的另一个设计目标应该考虑到,在程序中即要打开原图,又要对原图分别进行各种处理,为了能够对照显示,原图不做任何处理,可将原图定义为 CDib 类的对象或指向该对象的指针,而将需要处理的类定义为 CDib 类的派生类,由于派生类对基类中的保护或公有成员可以直接使用,不需要声明,因此,在派生类中仅仅定义各种处理图像数据区的函数即可。本书中所有实例都按这种结构设计,使不同处理功能归结在不同的 CDib 派生类中,结构简洁,请看附录及光盘上的实例。2.构造 CDib 类根据上节的分析,实现了 CDib 类,其接口文件和实
31、现文件分别为 DIB.H 和DIB.CPP。文件 DIB.H 包含了 CDib 类的类声明有关的所有信息。CDib 类的声明及实现细节如下。#ifndef _CDIB_H#define _CDIB_Hclass CDib : public CObjectpublic:RGBQUAD* m_pRGB;BYTE* m_pData;UINT m_numberOfColors;BOOL m_valid;BITMAPFILEHEADER bitmapFileHeader;BITMAPINFOHEADER* m_pBitmapInfoHeader;BITMAPINFO* m_pBitmapInfo;BYT
32、E* pDib;DWORD size;public:CDib();CDib();char m_fileName256;char* GetFileName();BOOL IsValid();DWORD GetSize();9UINT GetWidth();UINT GetHeight();UINT GetNumberOfColors();RGBQUAD* GetRGB();BYTE* GetData();BITMAPINFO* GetInfo();WORD PaletteSize(LPBYTE lpDIB);WORD DIBNumColors(LPBYTE lpDIB);void SaveFil
33、e(const CString filename);public:void LoadFile(const char* dibFileName);文件 DIB.CPP 中包含了 Cdib 类中各函数的实现,实现代码如下。#include “stdafx.h“#include “CDib.h“#include “windowsx.h“CDib:CDib()size=0;CDib:CDib()GlobalFreePtr(m_pBitmapInfo);void CDib:LoadFile(const char* dibFileName)strcpy(m_fileName,dibFileName);CF
34、ile dibFile(m_fileName, CFile:modeRead);dibFile.Read(void*)if (bitmapFileHeader.bfType = 0x4d42)DWORD fileLength = dibFile.GetLength(); size = fileLength -sizeof(BITMAPFILEHEADER);pDib =(BYTE*)GlobalAllocPtr(GMEM_MOVEABLE, size);dibFile.Read(void*)pDib, size);dibFile.Close();m_pBitmapInfo = (BITMAPI
35、NFO*) pDib;m_pBitmapInfoHeader = (BITMAPINFOHEADER*) pDib;m_pRGB = (RGBQUAD*)(pDib +m_pBitmapInfoHeader-biSize);int m_numberOfColors = GetNumberOfColors();10if (m_pBitmapInfoHeader-biClrUsed = 0)m_pBitmapInfoHeader-biClrUsed =m_numberOfColors;DWORD colorTableSize = m_numberOfColors *sizeof(RGBQUAD);
36、m_pData = pDib + m_pBitmapInfoHeader-biSize+ colorTableSize;if (m_pRGB = (RGBQUAD*)m_pData) / No color tablem_pRGB = NULL;m_pBitmapInfoHeader-biSizeImage = GetSize();m_valid = TRUE; elsem_valid = FALSE;AfxMessageBox(“This isnt a bitmap file!“);BOOL CDib:IsValid()return m_valid;char* CDib:GetFileName
37、()return m_fileName;UINT CDib:GetWidth()return (UINT) m_pBitmapInfoHeader-biWidth;UINT CDib:GetHeight()return (UINT) m_pBitmapInfoHeader-biHeight;DWORD CDib:GetSize()if (m_pBitmapInfoHeader-biSizeImage != 0)return m_pBitmapInfoHeader-biSizeImage;11elseDWORD height = (DWORD) GetHeight();DWORD width =
38、 (DWORD) GetWidth();return height * width;UINT CDib:GetNumberOfColors()int numberOfColors;if (m_pBitmapInfoHeader-biClrUsed = 0) break;case 4: numberOfColors = 16; break;case 8: numberOfColors = 256;elsenumberOfColors = (int) m_pBitmapInfoHeader-biClrUsed;return numberOfColors;BYTE* CDib:GetData()re
39、turn m_pData;RGBQUAD* CDib:GetRGB()return m_pRGB;BITMAPINFO* CDib:GetInfo()return m_pBitmapInfo;12WORD CDib:PaletteSize(LPBYTE lpDIB) return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE); WORD CDib:DIBNumColors(LPBYTE lpDIB) WORD wBitCount; / DIB bit count wBitCount = (LPBITMAPCOREHEADER)lpDIB)-bcBitCoun
40、t; switch (wBitCount) case 1: return 2; case 4: return 16; case 8: return 256; default: return 0; void CDib:SaveFile(const CString filename) /此函数只能保存经处理后宽度、高度均没有改变大小的图像strcpy(m_fileName,filename);CFile dibFile(m_fileName, CFile:modeCreate|CFile:modeWrite);dibFile.Write(void*)dibFile.Write(void*)pDib
41、, size);dibFile.Close();本书从第二章到第十章介绍 256 色的图像处理技术,在第十一章介绍 24 位真彩色图像的处理。在显示方面调用了调色板技术。设备无关位图读取及显示的方法,流程图如下所示:得到文件的完整路径名打开位图文件读取 BITMAPFILEHEADER 结构读取 BITMAPINFOHEADER 结构得到位图大小,并分配相应的内存空间文件是 BMP 格式?开始找到象素数据的起始位置,保存象素数据起始位置指针结束13NY图像显示的流程图NY从 DOC 对象中得到位图数据起始位置指针,并得到图象的宽、高等信息信息使用文件中颜色表数据创建调色板把新创建的调色板作为设
42、备环境的调色板,并保留原调色板设定显示参数,显示位图恢复原调色板 设定显示参数,显示位图是否带有颜色表 结束开始141.5 数字图像处理的应用1图像处理在实际应用中,系统获取的原始图像不是完美的,由于噪声、光照、拍摄角度不正等原因,图像的质量不高,所以需要进行图像处理,以有利于提取感兴趣的信息。所谓图像处理,就是对图像信息进行加工以满足人的视觉心理或应用需求的行为。数字图像处理的英文名称是“Digital Image Processing”。通常所说的数字图像处理是指用计算机进行的处理,因此也称为计算机图像处理。对于一个图像处理系统来说,可以将流程分为三个阶段,首先是图像处理阶段、第二是图像分
43、析阶段、第三是图像理解阶段。图像处理阶段主要是在像素级上进行处理,进行图像的几何校正,图像的灰度变换处理,图像噪声滤除的平滑处理,目标物体边界的锐化处理等,这些工作尤为重要,如果这阶段处理不好,后面的工作根本无法展开。图像分析阶段主要对图像里感兴趣的目标进行检测、分割、特征提取和测量,分析的结果能为用户提供描述图像目标特点和性质的数据,把原来以像素描述的图像转变成比较简洁的非图像方式的描述。图像理解阶段主要通过对图像里各目标的性质和它们之间相互关系的研究,对描述抽象出来的符号进行运算,了解把握图像内容并解释原来的客观场景,提供客观世界的信息,指导和规划行为,其处理过程和方法与人类的思维推理可以
44、有去多类似之处。图像处理就是用一系列的特定操作来改变图像的像素,以达到特定的目标,比如使图像更清晰,或从图像中提取某些特定的信息等。对含有噪声的图像,要除去噪声、滤去干扰,提高信噪比;对信息微弱的图像要进行灰度变换等增强处理;对已经退化的模糊图像要进行各种复原的处理;对失真的图像要进行几何校正等变换。除此之外,图像的合成、图像的编码与传送等技术也属于图像处理的内容。由此可见,图像处理就是为了达到改善图像的质量,将图像变换成便于人们观察、适于机器识别的目的。数字图像处理是现代图像处理的主要方法,具有再现性好、精度高、适用面广和灵活性大等优点。图像处理既可以在空间域实现,也可以在频域内实现,本书只
45、在第 9 章介绍了图像基于变换域的处理方法,其它部分主要介绍在空间域内对图像进行运算,它是一种既简单又重要的图像处理技术,能让用户改变图像上像素点的灰度值,产生一幅新图像。2图像处理中的常用技术数字图像处理的内容非常丰富,是现代计算机的重要应用方向。对图像像素的处理方式上可以划分为点处理和区域处理。点处理是一种输出像素值仅取决于输入像素值的图像处理方法;区域处理的输出像素值不仅与输入的像素值有关,而且与输入像素在一定的范围内的相邻像素值有关。区域处理在数字图像处理中占有重要地位。区域处理在处理某一像素时,利用与该像素相邻的一组像素,经过某种变换得到处理后图像中某点的的像素值。目标像素的邻域一般
46、是由像素组成的二维矩阵,该矩阵的大小为奇数,目标像素位于该矩阵的中央,即目标像素就是区域的中心像素。经过处理后,目标像素的值为经过特定算法计算后所得的结果。主要的区域处理算法有卷积、中值滤波和边缘检测。其中卷积算法的应用最广泛,大部分的区域处理都采用卷积算法来实现。15(1) 卷积 卷积可以简单的看成加权求和的过程。卷积时使用的权用一个很小的矩阵来表示,矩阵的大小是奇数,而且与使用的区域的大小相同。这种权矩阵叫做卷积核,区域中的每个像素分别与卷积核中的每个元素相乘,所有乘积之和即区域中心像素的新值。比如,对于一个 3*3 的区域 P 与卷积核 K, 其中:p1 p2 p3 k1 k2 k3 p
47、4 p5 p6 k = k4 k5 k6p7 p8 p9 k7 k8 k9P 与卷积核 K 卷积后,区域 P 的中心像素 p5 表示如下:p5=p1*k1+ p2*k2+ p8*k8+ p9*k9卷积核中各元素叫卷积系数。卷积核中卷积系数的大小、方向及排列次序决定了卷积的图像处理效果。大多数常用的卷积核都是 3*3 的,所有卷积核的行、列都是奇数。进行卷积时会遇到一些较复杂的问题,首先是图像边界的问题。当在图像上逐个移动卷积核时,只要卷积核移到了图像边界,即卷积核悬挂在图像边界上时,就会出现计算上的问题。这时在原图像上就不能完整找到与卷积核中卷积系数相对应的九个(对 3*3 卷积核)图像像素。
48、解决这一问题的两个简单方法是:或者忽略图像边界数据,或者在图像的四周复制图像的边界数据。卷积运算的第二个复杂问题是计算得到的中心像素的动态问题。使用大多数卷积核卷积得到的中心像素值都位于像素值的有效范围之内。但也有一些卷积核卷积的结果超出了像素的有效范围。这时要引用比例缩放操作,即对卷积结果进行指定次数的除以二操作。卷积运算的第三个复杂问题是卷积结果像素值的符号问题。当卷积核中包含负的卷积系数时,卷积结果像素值的符号可能为负。负的像素没有意义,也不能显示,必须进行适当的处理,常用的方法如下:将负的结果像素值置为 0;取负的结果像素值的绝对值作为像素的新值;将所有像素的值都加上一个常数,使所有负的像素值都大于等于 0。(2)循环像素点 因为在图像上逐个移动卷积核时,只要卷积核移到了图像边界,即卷积核悬挂在图像边界上,这时在原图像上就不能完整找到与卷积核中卷积系数相对应的九个(对 3*3 卷积核)图像像素。在处理图像时可以忽略图像边界。代