资源描述
毕业设计
题 目 彩色颗粒显微图像识别系统
---图像采集与处理模块
学 院 机械工程学院
专 业 机械工程及其自动化
班 级 机自0706
学 生 郑朋辉
学 号 20070403284
指导教师 王玉增
二〇一一年五月三十日
济南大学毕业设计
1 前言
1.1 选题背景及意义
人们在利用显微镜生物的分析检测的过程中,一个最基本的问题我们展现在面前,就是如何获取所检测微生物的各种定量测量信息。因为微生物检测的环节较多,所以只要有一个环节失误就可能会影响检验结果。对于传统的人工检测方法,经常存在有以下几个问题:
(1)对于同一微生物标本,不同的观测者就可以得出不同的结论,因为传统的检验并没有明确的客观标准,每个人对于实验的判断也就不会相同;
(2)即使同一微生物标只由同一个观察者观察,当间隔若干天后本人进行再次观察时,结论也可能不一样;
(3)众所周知,人的视觉有一定的限制,对于实际存在的较小差异更本察觉不出来,所以用肉眼来观察,在实际意义上就已经丢失了许多可贵的信息。为了客观的获取微生物标本中的各种定量信息及其有效特征,人工检测方法就难以准确掌握有效信息。
所以,传统的检测方式就应该被改变,寻求更加有效且便捷的方式,由此本课题就应运而生了,它的出现就是解决人眼难以触及的难题。
传统的图像采集具有很大的局限性,主要表现在采集的实时性。
本课题将传统的显微技术与计算机技术相结合,显微镜图像采用摄像头进行采集,当采集的视频信号进行模数转换后,会经过经过基本处理后,在传入计算机进行观测,记录,分析和后期处理,为了便于观测者进行进一步的观测,就需要进行一定的预处理,这也是课题重要的一部分。
这样既满足了实时记录观测的要求,可以让显微图像的分析方法更加的高效。显微图像的采集与处理在医学,生物学等领域占有重要地位,它的研究发展对各个行业的发展有着极其重要的推动作用。
同时它也是整个图像识别系统的关键之一,它决定着未来识别的走向。
1.2课题目的
本课题的目的是完成彩色颗粒显微镜图像识别系统---图像采集与处理模块的设计,主要涉及图像采集和图像预处理等技术。图像预处理包括图像的几何变换、颜色转换、图像压缩和图像存储等内容。
在数字化发展迅速的今天,传统的图像采集与处理的方式已远远不能满足现实生活的需要,在航空、生物、医学和农业等各个领域,都需要它的存在。设计的课题就将满足其一定的要求。
作为彩色颗粒显微图像识别系统的第一步,所做的就是采集所需图像,并对其进行一定的预处理,改变图像的画面,为分析等步骤打下良好的基础。
2 课题内容
本课题设计的是关于图像采集与处理方面的问题,主要是图像的采集系统。图像采集与处理模块是彩色颗粒显微图像识别系统中的一部分,其他模块包括颗粒图像的识别模块,自动对焦模块和打印输出模块每一块都有自己的重要作用。
本设计所需设备包括显微镜、摄像头和计算机等。对图像采集和处理分为两部分进行讲述。
2.1 图像采集
图像采集是整个图像识别系统的基础,摄像头和显微镜通过一个光学接口连接在一起, 而此该光学接口的上端与镜头相连, 可通过微机屏幕观察视频图像, 即时拍摄,并且将拍摄图像传到微机进行分析和处理。
图像采集是一个非常重要的的环节,它将对象的可视化图像和其特征进行一定的转换,成为能够被计算机处理的一系列数据。但由于机器视觉系统强调采集的精度和速度,所以就需要图像采集部分可以及时、准确的提供清晰地图像,只要这样以后,图像处理才能在较短时间内得出正确的结果。由此可了解,图像采集部分的性能作用将会直接影响到整个机器视觉系统的性能作用。
图像采集部分一般是由光源、摄像头和图像采集卡组成的。采集的过程中可简单描述成在光源提供有效地照明后,摄像头拍摄目标物体后并将其转化为图像信号,在最后过程中,用过图像采集卡传输给图像处理部分。
2.1.1 显微镜简介
显微镜是由一个透镜或几个透镜组合构成的光学仪器,是人类进入原子时代的标志。主要用于放大微小物体并使人的肉眼所能看见。显微镜分为光学显微镜和电子显微镜,光学显微镜是由荷兰的杨森父子在1950年所发明的。现在的光学显微镜可以把物体放大1600倍,并且分辨的最小极限也已经可以达到0.1微米。
显微镜以显微原理可分为光学显微镜和电子显微镜;如果按照以可移动性来划分,可分为台视显微镜和便携式显微镜。
光学显微镜通常皆有光学部分、照明部分和机械部分组成。而光学部分是最为关键的,是有目镜和物镜组成。
光绪显微镜结构为:目镜,镜筒,转换器,物镜,载物台,通光孔,遮光器,反光镜,压片夹,镜座,细准焦螺旋,粗准焦螺旋,镜臂,镜柱。
电子显微镜与光学显微镜有着十分相似的基本结构特征,但它对物体的放大及分辨本领比光学显微镜要高得多,它将电子流作为一种新的光源,从而使物体成像。
虽然电子的显微镜的分辨本领远胜于光学显微镜,但电子显微镜因需在真空条件下工作,所以很难观察活动的生物,而且电子束的照射也会使生物样品受到辐照损伤。其他的问题,如电子枪亮度和电子透镜质量的提高等问题也有待继续研究。
2.1.2 摄像头简介
摄像头(WEBCAM)又称为电脑相机和电脑眼等,它是一种视频输入设备,而被广泛的运用于到视频会议,远程医疗及实时监控等各个方面。普通的人也可以彼此通过摄像头在网络进行有影像、且有声音的交谈和沟通。
摄像头可以分为数字摄像头和模拟摄像头两大类。数字摄像头可以将视频采集设备产生的模拟视频信号亲轻松地转换为数字信号,进而将其储存在计算机里。模拟摄像头捕捉到的视频信号必须经过特定的视频捕捉卡将模拟视频信号换成数字模式,并将数字信号压缩后才可以转换到计算机上运用。
数字摄像头可以直接捕捉影像,然后通过串并的接口或者USB接口传到计算机里。现在电脑市场上的摄像头基本以数字摄像头为主,而数字摄像头中又以使用新型数据传输接口的USB数字摄像头为主,目前市场上可见的大部分都是这种产品。除此之外一种与视频采集卡配合使用的产品,但目前还不是主流。由于个人电脑的迅速普及,模拟摄像头的整体成本较高等原因,由于USB接口的传输速度远远高于串口、并口的速度,因此现在市场热点主要是USB接口的数字摄像头。
摄像头的主要部件:
镜头:透镜结构,是由几片透镜组成,有塑胶透镜或玻璃透镜。
图像传感器:分为CCD 电荷耦合器件,COMS互补金属氧化半导体。
电源:摄像机内部需要两种工作电压,3.3V和2.5V,最新的工艺芯片用到1.8V。
摄像头的工作原理可以简述为:所拍景物透过镜头生成光学图像投射到图像传感器表面上,然后转换为电信号,在由A/D(模数转换)转换为数字图像信号,再经过数字信号处理芯片的加工处理,通过USB接口传输到电脑中处理,通过显示器就可以看见图像了。
图像采集的程序要有通用性,适用于各种摄像头,鉴于USB接口的广泛使用,使用USB接口的数字摄像头。
2.1.3 图像采集卡简介
图像采集卡在整个系统中起着重要作用,是图像采集部分和图像处理部分的接口。由于图像信号的传输需要的传输速度很高,通用的传输接口就无法满足其要求,这也就是为什么需要图像采集卡的原因所在。
图像采集卡的选择要考虑以下的几个方面:
(1)数据传输率与视频输入的格式
当摄像头用较高的速度拍摄高分辨率的图像后,会产生很高的传输速率,在这时,摄像头一般情况下会使用多路信号同时输出的形式,所以图像采集卡就必须可支持多路输入及摄像机的输出速率。
(2)数据的吞吐量
当图像采集卡的图像信号的输入速率比较高时,就要考虑图像采集卡与图像处理之间的宽带问题。但在实际使用中, 多数计算机上的PCI 接口平均数据传输率为50~90MB/ s,所以有可能在瞬间高传输率时就不能满足传输的需要。
为了避免与其他PCI 设备产生冲突得过程中丢失数据, 图像采集卡上应该有一定的数据缓存。在一般情况下, 有2MB的板载存储器可以满足大部分的任务要求。
(3)数字的I/O控制
在系统中,输入输出的控制是非常重要的,在一些系统中,由于需要设定一定的拍摄频率,就应该有像素时钟发生器。外同步是指不同的视频设备之间可以用同一同步信号来保证视频信号的同步, 同时它可以保证不同设备输出的视频信号也具有相同的帧行起止时间
2.2 图像处理
图像采集后传输到计算机中,要对图像进行一定的处理,在此的处理指的是图像的预处理,主要内容是图像的颜色转换,几何变换,图像存储,图像压缩等,目的是改变图像质量,使图像变得更加清晰,为图像识别打下良好的基础。
对图像要进行一定的增强和恢复,图像的增强是按照特定的要求,去得到一幅图像的许多信息,与此同时,消弱或者是去除一些不需要的信息的处理方式,它的目的是将图像进行处理后,对于一些特定的应用来说,比原图像更加的适用,是为了一些目的去改善图像的质量,使图像更加的适合在人的视觉特性或者是机器的识别系统。
现在常见的图像增强的方法主要有直方图均衡化、图像的平滑处理、图像的锐化处理及伪彩色处理等几项技术。
由于各种图像增强算法的特点有些不同, 对图像增强的侧重点也就会不同. 在对图像进行处理时, 首先要分析不同图像增强方法会造成的优缺点, 再对具体图像问题再进行具体分析, 然后选择几种增强方法相互结合着使用, 也许就可能达到预期的增强效果。
2.2.1 颜色转换
(1)彩色图像转灰度图
我们在处理图像的过程中,会发现常见的颜色模式主要有HSB模式(色相、饱和度、亮度)、RGB模式(红、绿、蓝)、CMKY模式(青、洋红、黄、黑)、位图模式和Grayscale灰度模式等。
图像采集的图像采用的RGB模式,灰度图的图像处理速度要远高于彩色图像,要采用Grayscale模式,所以要将彩色图像转换为灰度图像。
在颜色转换的过程后,会损失部分的颜色信息,所以在颜色转换前最好为其保存一个备份的文件,以便在必要的时候可以做到恢复图像颜色。真彩图转灰度图,一般情况下,真彩图的每一个像素是由三个字节表示的,每个字节会对应着R、G、B分量的亮度(红、绿、蓝),转换后的灰度图的每一个像素都是用一个字节来表示该点的灰度值,灰度值的范围在0-255之间,数值越大,该点的亮度就越高,就越白,数值越小越黑。
颜色转换的转换公式为:
其中R(x,y),G(x,y),B(x,y)为彩色图像在(x,y)点的红、绿、蓝的亮度,Gray(x,y)为转换后灰度图在(x,y)点处的灰度值。
观察该公式,可以发现绿色所占的比重最大,红色所占的比重最小,说明绿色在彩色图像中的作用最大。
(2)灰度图转彩色图像
灰度图转换为彩色图像,技术上被称为灰度图像的伪彩色处理,这是一种视觉效果明显而且技术又不是很复杂的图像增强技术。在灰度图像中,如果相邻的像素点灰度值相差不大时,但包含了丰富的信息的话,人眼是无法从图像中提取相应的信息的,因为人眼的分辨灰度的能力较差,一般来说也只有几十个数量级而已,但是人眼对彩色信号的分辨率却是很强的,所以将灰度图转换成彩色图像的话,人眼就可以提取更多的信息量。
在转换过程中,经常被采用的技术是灰度向彩色转换,简单来说,驾驶对灰度图上的每一像素,获取改点的灰度值并送入三个通道,经过转换得到相应的R、G、B的亮度值。
2.2.2 直方图均衡化
直方图均衡化是图像处理领域中利用图像直方图对对比度进行调整的方法。图像直方图均衡化的中心思想可以表达为把原始图像的灰度直方图从比较集中的某个灰度区间变为在全部灰度范围内的分布均匀。
直方图均衡化是对图像进行非线性的拉伸,并且重新分配图像的像素,使一定范围中的像素数量大致相同。这种方法会提高图像的局部对比度,对背景和前景都太亮或太暗的图像非常有用。
直方图均衡化的缺点:
① 变换后图像的灰度级减少,某些细节消失;
② 某些图像,若直方图有高峰,经过处理后对比度会不自然的过分增强;
③ 它对处理的数据不加以选择,它可能会增加背景中杂讯的对比度并降低有用信号的对比度。
举例说明直方图均衡的方法,以下是一个3*2像素的简单图像。
图 1
① 统计每一灰度级的像素个数,设i为某一灰度值,n[i]为其的像素个数。
② 求出每一灰度在总像素中所占的概率,N为总的像素数。
③ 直方图的累计归一化,所谓累计归一化是指当前灰度值与前面灰度值的像素个数占所有像素的概率。
④ 转换灰度值,灰度值的范围为(0,255),所以累计概率要乘以255,得到的就是均衡后的灰度值。
表格 1
原灰度值
像素个数
概率
归一化
均衡后灰度值
50
3
3/6
3/6
128
100
2
2/6
5/6
212
200
1
1/6
1
255
对于图1来说,128替换50,212替换100,255替换200.这样直方图均衡化就完成了。
图2直方图均衡化
2.2.3 几何变换
图像的几何变换:包括图像的平移、图像的镜像变换、图像的缩放、图像的颠倒等。
(1)图像的平移只是改变了图像在显示屏中的位置,图像本身并不发生变化。假设原图的某点坐标为(X,Y),将图像分别沿X轴和Y轴平移dx和dy,则坐标平移变换的公式为:
(2)镜像变换是指将指定区域内的图像左右翻转的显示在屏幕上。分析镜像变换的过程中就可以发现:每行图像的信息的处理方法是相同的,并且行顺序不发生变化,只是每一行的像素信息按照从左向右的顺序进行了左右的颠倒,从而实现了镜像变换。因此,可以采用按行逐点变换的方法实现图像的镜像。
原图中点(X,Y)镜像变换后的新坐标(X1,Y1)的坐标变换公式:
根据以上公式,将原图的灰度值读入点(X1,Y1)中。
(3)图像颠倒是指把定义好的图像区域进行上下翻转的显示在屏幕上。分析图像颠倒的过程中,就可以发现每行图像信息都保持不变,只是改变了行的顺序,将第一行与最后的第n行相互交换,而第二行与第n-1行交换,以此类推,就能实现图像的颠倒。
原图中点(X,Y),图像颠倒后为点(X1,Y1).
图像颠倒公式为:
(4)图像缩放 上面几种图像几何变换都是1:1的变换,而图像的缩放操作将会改变图像的大小,产生的图像中的像素可能在原图中找不到相应的像素点,这样就必须进行近似处理。一般的方法是直接赋值为和它最相近的像素值,也可以通过一些插值算法来计算。
2.2.4 图像黑白求反
所谓图像求反,就是将图像中的灰度翻转过来,简单来说,就是是原图像中的黑点变为白点,白点变为黑点。设某点的灰度值为n,求反后,。
2.2.5 图像锐化
图像锐化是用来补偿图像的轮廓,增强图像的边缘及其灰度发生跳变的部分,结果会使图像变得清晰,可以分为空余处理和频域处理两种。
图像的平滑会使图像的边界、轮廓变得比较模糊,这样的话,就会有许多不利的影响,就需要图像锐化。图像锐化的处理的目的是为了使图像的轮廓、边缘以及图像的细节变得更加的清晰。
3 课题方案
3.1系统硬件设计
(1)显微镜:选择光学显微镜,光学显微镜的功能已经完全可以满足课题的需要,电子显微镜的性能虽远超过光学显微镜,但其价格昂贵,要求环境比较苛刻,故在此选择光学显微镜。
(2)摄像头:课题的设计要做到通用性,市场上USB接口的摄像头站主导地位,所以摄像头要选用USB接口的摄像头。
如果从摄像头输出的颜色上来分的话,就有彩色摄像头和黑白摄像头之分。彩色摄像头提供了更多的信息,也就因此,在处理时就需要更大的空间和更多的时间。
3.1系统软件设计
(1)人机交互界面
人机交互界面包括显示图像窗体和功能按钮设置两大部分。
显示图像窗体: 为连续采集的AVI文件窗体和获取的单个图像文件窗体。
功能按钮: 准备设备,运行摄像头,抓图,停止,图像处理,打开图像和保存图像等功能按钮。
(2).图像采集
有单次采集和连续采集两种工作模式。单次采集是在连续采集的AVI文件上进行抓图 , 采集一幅8位真彩色BMP图像文件, 可设置一定频率对图像抓取,也可进行手动抓取。
(3)图像预处理
AVI转换为BMP:把连续的AVI文件单次采集为一副BMP位图文件。
颜色变换:彩色图像转变为黑白图,加快图像处理速度。
直方图均衡:改变图像的亮度,增强图像对比度。
图像求反:将黑白两色交换。
几何变换:对图像的位置和大小进行改变,获取最佳图像。
图像存储:保存处理后的多幅BMP文件。
(4) 编程所需软件及其依赖项
包括Microsoft visual studio 2010 软件、CxImage类库和DirectShow开发包等。
Microsoft visual studio 2010软件是微软公司发行的专门进行程序编写的,应对所有的编程方式,包括C++、C#和C basic等。
CxImage类库是一个优秀的图像操作类库。它可以快捷地存取、显示、转换各种图像。与CxImage库相连,作为编辑程序的依赖,使编程更加的简单。CxImage类库是完全免费的。CxImagel类库在平台方面做的非常好,完全公开了源代码。
DirectShow是微软公司在ActiveMovie和Video for Windows的基础上推出的新一代基于COM(Component Object Model)的流媒体处理的开发包,与Direct开发包一起发布。DirectShow使用一种叫Filter Graph的模型来管理整个数据流的处理过程,运用DirectShow,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。这样使在多媒体数据库管理系统(MDBMS)中多媒体数据的存取变得更加方便。它广泛地支持各种媒体格式,包括Asf、Mpeg、Avi、Dv、Mp3、Wave等,为多媒体流的捕捉和回放提供了强有力的支持。
4 程序设计
本程序设计采用的是C++编程方式,在Microsoft visual studio 2010 软件的环境下编程。
4.1 图像采集代码及其结果
4.1.1 获取视频采集设备代码
void vcGetCaptureDevices(CComboBox& adaptersBox)
{
adaptersBox.ResetContent();
//创建系统设备枚举器
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,
CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void **) & pSysDevEnum);
if (FAILED(hr)) {
Msg(TEXT("CoCreateInstance() hr=0x%x"), hr);
return;
}
//获取一个为视频压缩的类枚举器
IEnumMoniker *pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&pEnumCat, 0);
if (hr == S_OK) {
//枚举名称
IMoniker *pMoniker = NULL;
ULONG cFetched;
while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) {
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **) & pPropBag);
if (SUCCEEDED(hr)) {
// 要检索过滤器的友好名称,执行以下操作:
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr)) {
adaptersBox.AddString(varName.bstrVal);
}
VariantClear(&varName);
// 要创建一个过滤器实例,执行以下操作:
IBaseFilter *pFilter;
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
(void **) & pFilter);
// 现在向图像添加过滤器:
//记住,过滤后释放.
pPropBag->Release();
}
pMoniker->Release();
}
pEnumCat->Release();
}
pSysDevEnum->Release();
adaptersBox.SetCurSel(0);
}
结果:运行此代码后,在界面上显示摄像头的类型,例如我的界面显示的是Lenovo easy camera。
4.1.2 运行视频采集设备代码
void CVidCapDlg::OnBnClickedRunButton()
{
UpdateData();
HRESULT hr; //定义变量
if (m_nTimer == 0) {
//执行采集
hr = vcCaptureVideo(m_hWnd, m_PrvStatic.m_hWnd, m_AdapterCombo.GetCurSel() + 1);
if (hr != S_OK) {
vcStopCaptureVideo();
return;
}
CString str; //定义字符串
//设置输出视频的宽,高和数据
str.Format(L"Video output: %dx%d %dbpp", sgGetDataWidth(), sgGetDataHeight(), 8 * sgGetDataChannels());
m_VideoFormat.SetWindowTextW(str);
//设置按钮显示为停止时,在采集图像
m_RunButton.SetWindowTextW(L"停止");
m_nTimer=1;
} else {
//关闭定时器
//设置按钮为运行时,不采集图像
m_RunButton.SetWindowTextW(L"运行");
m_nTimer=0;
m_VideoFormat.SetWindowTextW(L"Video output");
//停止采集
vcStopCaptureVideo();
}
}
结果:运行之后,摄像头的显示灯点亮,采集视频信息,在视频的窗口上显示摄像头采集的视频。
4.1.3 捕获图像代码及其结果
void CVidCapDlg::OnBnClickedTestGetimage()
{
SYSTEMTIME SystemTime; //定义系统时间
GetLocalTime(&SystemTime); 获取本地时间
//设置时间显示类型
TRACE(L" %d:%d:%d\n", SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond);
unsigned char* pData = sgGrabData();//定义数据
if (pData != 0) {
DrawData(sgGetBitmap());
//定义图像宽和高
extern unsigned int gWidth,gHeight;
if(image) //判断是否已存在图像
{ image->Destroy(); delete image; image=NULL;} //删除原图
//更新新图
image = new CxImage;
image->CreateFromArray(pData,gWidth,gHeight,24,3*gWidth,true);
ReDraw();
}
}
结果:显示图像,如图3所示
图3 原图
4.2 图像处理代码及其结果
4.2.1 打开图像代码
void CVidCapDlg::OnBnClickedTestOpen()
{
CFileDialog dlgFile(TRUE);
CString fileName; //定义文件名
const int c_cMaxFiles = 100; //设置最大文件数
const int c_cbBuffSize = (c_cMaxFiles * (MAX_PATH + 1)) + 1;
dlgFile.GetOFN().lpstrFile = fileName.GetBuffer(c_cbBuffSize);
dlgFile.GetOFN().nMaxFile = c_cMaxFiles;
//设置打开窗口名称
dlgFile.m_ofn.lpstrTitle = _T(“打开图像文件”);
//设置打开图像的类型
dlgFile.m_ofn.lpstrFilter =_T(“BMP 文件(*.bmp)\0*.bmp\0JPG 文件(*.jpg)\
0*.jpg\0\0”);
if(dlgFile.DoModal()!=IDOK)
{
fileName.ReleaseBuffer();
return;
}
//定义文件类型
int FileType=CxImage::GetTypeIdFromName(dlgFile.GetFileExt());
if(image) {
image->Destroy(); delete image; image=NULL;} //删除原图
image = new CxImage(fileName, FileType); //设置新图
//检测图像是否有效
if (!image->IsValid()){
CString s(image->GetLastError());
AfxMessageBox(s);
delete image; //删除图像
image = NULL;
}
ReDraw();
fileName.ReleaseBuffer(); //释放缓冲区
}
4.2.2 图像保存代码
void CVidCapDlg::OnBnClickedtestsave()
{CFileDialog dlgFile(FALSE);
CString fileName; //定义文件名
const int c_cMaxFiles = 100; //设置最大文件数
const int c_cbBuffSize = (c_cMaxFiles * (MAX_PATH + 1)) + 1;
dlgFile.GetOFN().lpstrFile = fileName.GetBuffer(c_cbBuffSize);
dlgFile.GetOFN().nMaxFile = c_cMaxFiles;
dlgFile.m_ofn.Flags |= OFN_EXPLORER | OFN_EXTENSIONDIFFERENT;
//设置保存窗口名称
dlgFile.m_ofn.lpstrTitle = _T(“保存图像文件”);
//设置保存图像的类型
dlgFile.m_ofn.lpstrFilter =_T(“BMP 文件(*.bmp)\0*.bmp\0JPG文件(*.Jpg)\
0*.jpg\0\0”);
if(dlgFile.DoModal()==IDOK) //判断函数是否成功
{
int FileType=CxImage::GetTypeIdFromName(dlgFile.GetFileExt());
image->Save(fileName,FileType); //保存图像
}
fileName.ReleaseBuffer();//释放缓冲区
}
4.2.3 彩色图转灰度图代码及其结果
void CVidCapDlg::OnBnClickedTestGrayscale()
{
int x,y,w,h; //定义变量
w=image->GetWidth(); //获取图像宽
h=image->GetHeight(); //获取图像高
//设置新图
CxImage *Img = new CxImage(w,h,8);
Img->SetGrayPalette(); //设置调色板
for(y=0;y<h;y++)
for(x=0;x<w;x++)
{
int R,G,B; //定义三原色
//获取图像的亮度
RGBQUAD rgb = image->GetPixelColor(x,y);
R = rgb.rgbRed;
G=rgb.rgbGreen;
B=rgb.rgbBlue;
//公式计算灰度值
int gray=(30*R+59*G+11*B)/100;
Img->SetPixelIndex(x,y,(BYTE)gray);//设置像素索引
}
image->Destroy(); //删除原图
image=Img;//更新新图
ReDraw();
}
转灰度图结果:如图4所示,(a)为原图,(b)为灰度图。
(a)
(b)
图4 颜色转换 求灰度图
4.2.4 直方图均衡化代码及其结果
void CVidCapDlg::OnBnClickedtexthiseq()
{ int x,y,w,h,i,j; //定义变量
image->GrayScale(); //转灰度图
w=image->GetWidth(); //获取图像宽
h=image->GetHeight(); //获取图像高
//设置新图
CxImage *Img = new CxImage(w,h,8);
Img->SetGrayPalette(); //设置灰度调色板
int WH=w*h; //定义像素
int n[256];
double p[256]; //定义数组变量
//获取每一灰度级的像素个数//
for(i=0; i<=255;i++) n[i]=0;
for(y=0;y<h;y++)
for(x=0;x<w;x++) n[image->GetPixelIndex(x,y)]++;
//灰度概率统计
for(i=0;i<=255;i++) p[i]=1.0*n[i]/WH;
double c[256];
c[0]=p[0];
//累计归一化
for(i=1;i<=255;i++) c[i]=c[i-1]+p
展开阅读全文