图像处理的开闭运算_第1页
图像处理的开闭运算_第2页
图像处理的开闭运算_第3页
图像处理的开闭运算_第4页
图像处理的开闭运算_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、图像处理的开运算与闭运算0.前言腐蚀和膨胀是依据数学形态学集合论方法发展起来的图像处理方法,起源于岩相对岩石结构 的定量描述工作,在数字图像处理和机器视觉领域中得到了广泛的应用,形成了一种独特的 数字图像分析方法和理论。数学形态学是图像处理和模式识领域的新方法,其基本思想是: 用具有一定形态的结构元素去量度和提取图像中的对应形状,以达到图像分析和识别的目的。 优势有以下几点:有效滤除噪声,保留图像中原有信息,算法易于用并行处理方法有效实现, 基于数学形态学的边缘信息提取处理优于基于微分运算的边缘提取算法,提取的边缘比较平 滑,提取的图像骨架也比较连续,断点少腐蚀:是一种消除边界点,使边界向内部

2、收缩的过程。可以用来消除小且无意义的物体。膨胀:是将与物体接触的所有背景点合并到该物体中,使边界向外部扩张的过程。可以用来 填补物体中的空洞。开运算:先腐蚀后膨胀的过程开运算。用来消除小物体、在纤细点处分离物体、平滑较大物 体的边界的同时并不明显改变其面积。开运算通常是在需要去除小颗粒噪声,以及断开目标 物之间粘连时使用。其主要作用与腐蚀相似,与腐蚀操作相比,具有可以基本保持目标原有 大小不变的优点。闭运算:先膨胀后腐蚀的过程称为闭运算。用来填充物体内细小空洞、连接邻近物体、平滑 其边界的同时并不明显改变其面积。原因:虽然腐蚀处理可以将粘连的目标物进行分离,膨胀处理可以将断开的目标物进行接续,

3、但同时都存在一个问题,就是经过腐蚀处理后,目标物的面积小于原有面积,而经过 膨胀处理之后,目标物的面积大于原有面积。开、闭运算就是为了解决这个问题而被提出的。 数学形态学中二值图像的形态变换是一种针对集合的处理过程。其形态算子的实质是表达物 体或形状的集合与结构元素间的相互作用,结构元素的形状就决定了这种运算所提取的信号 的形状信息。形态学图像处理是在图像中移动一个结构元素,然后将结构元素与下面的二值 图像进行交、并等集合运算。1 .系统分析系统功能需求(1)位图图像文件的导入、转换、显示、保存、关闭模块在该功能模块中提供:位图图像文件的导入功能;把32位或8位位图文件转换为24 位位图文件的

4、功能;显示经过导入和转换后的24位位图文件的功能;图像保存(提供保存 为8位和24位位图的功能)和关闭图像的功能。这一模块主要对图像进行后续处理及其操 作的基础。(2)基于膨胀和腐蚀的图像处理模块该模块主要的功能是用膨胀和腐蚀算法,得到对应的参数图像(图像增强), 结合膨胀和腐蚀,做出开闭运算的图像(3)图像控制模块该模块主要功能是实现对原始图像另存;分形图像、分割结果图像保存的操作 场景分析和开发场景 名称参与 执行者前置 条件事件流后置条件1、打开系统主界面2、选择文件菜单中的“打开”命令,选择文件1、图像导入2、在图像显示图像系统3、对图像类型进行合法性检查,合则4,否则2界面上显示(三

5、信息用户已4、清除上一次数据组图像及其直导入打开5、把图像转换为24位位图文件6、提取图像像素数据,并保存三份7、将用户所要处理的图像导入系统中方图)3、用户可以作其他的处理基于用户系统1、选择“图像处理”菜单1、得到处理后腐蚀已打2、根据用户需要选择需要的处理类型图像(增强);和膨开图3、系统对图像作相应的处理2、在图像显示胀图像已4、将处理后图像保存并显示给用户(中间组和右边界面上显示(中像的 开闭 处理导入组:包括图像、直方图)间组和右边 组);3、用户 可以作其他的 处理处理用户系统1、选择“文件”菜单1、得到分形结结果已打2、选择“另保存”菜单,路径+文件名果图像;2、用图像 保存

6、场景开,图 像已 导入, 并作 相应 的处 理3、将分形结果图像保存。户可以作其他 的处理抽象用例对应活动图用例图根据功能分析和用例分析,我们得到“图像处理开闭运算”的用例图。(1)图像信息的导入用例图(2)基于腐蚀膨胀图像处理用例图(3)原始图像另存用例(4)处理结果图像保存用例(5)总的用例图用户退出系统匕原始图像另存图像导入图像开闭处理CD 处理后图像保存建立系统总体架构及领域概念模型系统总体架构系统总体架构用于描述整个软件的体系结构,包括对各个功能模块的划分、功能定义、软件的层次结构等。根据前面建立的系统用例图,我们选用分层架构模式。下面我们用包图来描界面层各种操作界面I图像基本操 作

7、模块图像开闭处理模块业务逻慢处理层数据服务层、述总体结构。系统领域概念模型领域概念模型用于描述用户需求和相关业务领域中全局性的概念及其相互之间的关系。 它在系统总体架构的基础上,进一步从概念上帮助开发人员理清系统结构及系统各组成部分 之间的相互作用。领域概念模型使用UML的类图来表示,但不需要标出每个类的属性和方 法,只需根据以上所作的场景开发和建立的用例,提取关键的概念并以类的形式表示出来即 可。领域概念模型可以理解为类图的草图本系统拟采用MFC支持的文档视图结构中的单文档界面(SDI)结构。大部分Windows应用程序都相当复杂。典型的情况是,它们均包含业务逻辑处理层和 界面层(程序框架)

8、,在MFC中对应于两个代表性的类:“文档”和“视图”。MFC将文档 和视图有机地组成一个整体的框架,提供给程序编写者,这就是我们通常所说的文档/视图 结构。通常,当创建一个SDI应用程序时,如果不考虑About对话框窗口类的话,SDI应用程 序将创建 4 个特定的类,即 CC*APP 类、CMainFrame 类、CC*DOC 类、CC*VIEW 类,每个类在程序运行时都有自己的特殊用途。其中:(1) CC*APP类:创建所有其它组件。该类接收所有的事件消息,然后将这些消息传递给CMainFrame类、CC*DOC类、CC*VIEW。在编程中几乎 不需要修改和添加代码。(2) CMainFra

9、me类:它包括菜单、工具栏、滚动条、状态栏、和所有其他与该 框架相关联的显示对象。在编程中几乎不需要修改和添加代码。(3) CC*DOC类:它是关于文档存储的类。可以在这个类中创建数据结构,并利用这些数据结构存储和处理构成文档的数据。(注意:一般通过在该类中 定义一个用户类的对象作为该类的成员变量,以此来创建数据结构,在程序 中通过该成员变量来调用用户类的各种成员函数【方法】)。该类从用户自己定义的类或CC*VIEW类得到输入并将要显示的信息输出到CC*VIEW 类。该类还负责存盘和从文件中检索文档数据的工作。(4) CC*VIEW类:它用于向用户显示可视化文档,并将用户输入的信息传送 到CC

10、*DOC类,然后从CC*DOC类接收显示信息。在该类中所需要的 大部分代码工作包括绘制用户的文档、处理用户的输入、调用用户自定义类 中的方法(通过CC*DOC类的指针)。CC*DOC类有几个子类,包括 CEditView、CFormView、CHtmlView、CListView、CRichEditView、CScrollView、 CTreeView等,但大部分子类和CC*VIEW类的属性和使用方法区别不大。在系统需求分析阶段,通过建立系统总体结构、领域概念模型,已经确定了系 统的基本结构。在系统设计阶段主要内容有:设计用例实现方案、数据设计、用户界面设计, 建立组件图、配置图、生成系统代码

11、框架等几部分工作提取边界类、实体类、控制类(1)提取边界类边界类主要描述目标软件系统和外部环境的交互,复杂界面控制、外部接口和环境隔 离,处理目标软件系统与用户、其他软件系统及操作系统和其他设备之间的交互。根据已建 立系统总体结构、领域概念模型,可以提取以下边界类:1)CMainFrame 类、CC*VIEW 类、CC*APP 类、CC*DOC 类中的涉及数据输入 以及界面变化的方法(成员函数)2)CDlg*类3)CImg类中的涉及数据输入以及显示的方法(成员函数)(2)提取实体类实体类表示目标软件系统中具有持久意义的信息项和操作,它向目标软件系统的其他 部分提供读取信息项内容的必要接口,不涉

12、及业务逻辑处理。根据已建立系统总体结构、领 域概念模型,可以提取以下边界类:1)CC*DOC类中的涉及数据保存的方法(成员函数)2)CImg类中的涉及数据保存的方法(成员函数)(3)提取控制类和辅助类控制类作为完成用例任务的责任承担者,主要用于协调、控制其他类共同完成用例规定的功能或行为。它一般不处理具体的任务细节,但它应该能够分解任务并将子任务分派给 适当的辅助类,同时在辅助类之间进行消息传递和协调。MFC中采用消息映射机制实现处 理来自操作面板接收的各种用户指令,并将这些命令分派给适当的辅助类。辅助类用于辅助控制类完成用例规定的功能或行为。可提取以下的辅助类:1)CImg类中的用于完成用例

13、规定的功能或行为的各种方法(成员函数)2)CC*VIEW类、CC*DOC类、CDlg*类中的用于完成用例规定的功能或行为 的各种方法(成员函数)或消息响应函数。基于所提取的边界类、实体类和构建的控制类和辅助类,我们将在已提取的各种类的 基础上,构造系统的交互图、协作图等动态视图,为设计生成系统类图做准备。通过建立系统的顺序图和协作图-构造交互图顺序图和协作图是反映用户和系统动态交互的两种视图。顺序图按时间顺序描述系统 元素之间的交互,而协作图则按照时间和空间顺序描述系统元素(包括系统用户)之间的交 互和它们之间的动态关系。二者都是表示对象间的交互作用,前者强调时间顺序,但没有明 确的表达对象间

14、的关系;后者描述对象之间的关系,但时间顺序必须从序号获得。顺序图和 协作图都是来自UML模型的相同信息,语义上是等价的,二者可以相互转换而不丢失任何 信息。实际使用中,常用时序图,即在顺序图的基础上,加入表示时间顺序的序号。(1)图像导入时序图:CMainFrame:CC*DOCm clsImg : CImg:CC*VIEWUser1.启动1. CImg:CImg()2.“打开”3. OnOpenDocument()4. CImg:Initial()5. CImg:Clean()6. CImg:F8to24()7. CImg:F32to24()8. 复制三份图像9. OnDraw()10. C

15、Img:Show()12.显示图像及宜方图(2)开闭运算计算时序图11. CImg:DrawIntensity()(3)原始图像另存时序图类图的生成类图(Class Diagram)是在系统的领域概念模型基础上进一步添加对象的属性和方法生成的,它描述类、接口、协作、以及它们之间的关系,是系统设计的核心部分。类图是系统 静态视图的一部分,主要用于描述软件系统的静态结构,主要支持系统的功能需求,也即系 统要提供给最终用户的服务。类图也是面向对象系统建模中最常用的图,是定义其他图的基 础。在类图基础上,我们可以定义组件图、配置图,为代码生成做好准备。在系统实现部分,表述,加入!类名: CImgImg

16、.h 和 Img.cpppublic:void Close();void Open();void Dilate();void GrayDilate(BYTE *pData);void Erosion();void GrayErosion(BYTE *pData);void Sort(int *pBuf, int l, int r);void MidFilter(int nWidth, int nHeight);void GrayErosion(int D);void Save8(LPCTSTR lpszPathName);void Save24(LPCTSTR lpszPathName);vo

17、id Save(LPCTSTR lpszPathName, int nType);void DrawIntensity(CDC *pDC, BYTE *lpSrc,血 nType);void Show(CDC *pDC, int x=0, int y=0, char *pStr=NULL);void F24to8(const BYTE *pSrc, BYTE *pDest);void F32to24(BYTE *lpBit);void F8To24(BYTE *lpBit);BOOL Initial(LPCTSTR lpszPathName);void Clean();CImageProces

18、s();virtual -CImageProcess();private:BYTE *m_lpSrcBit;BYTE *m_lpModifyBit1;BYTE *m_lpModifyBit2;图像像素数据(原始图像,左边图像)处理后的图像像素数据(中间图像)处理后的图像像素数据(右边图像)BITMAPINFO *m_lpBmif;图像信息头文件char *m_sImgPath;图像的路径int m_nWidth;图像宽度int m_nHeight;图像高度BOOL m_bGray;int m_nLineByte;/图像每行占的字节数(24位图像)int m_nLineByte8;/图像每行占的

19、字节数(8位图像)int m_nImgByteSize;图像的所占的字节大小BYTE *m_lpSrcBit8;/8位位图数据BYTE *m_lpModifyBit8;/8位位图数据总体框架和界面设计人机界面也称为用户界面,它是交互式应用软件系统的门面。(1)用户打开系统主界面-系统功能的外部模型运行可执行程序后,首先进入系统的主界面。界面要求简单,符合用户习惯如 Untitled - Image文件此能看看业群助的图蟋遁口能日甚甯噌|哥|(2)用户导入图像界面文件名mr查我范围红):匚卓面皿3西 c a9回二三2溺三望5总rRniszT文件翘j g . 而不177石FIM G_2014060

20、4.G&5 34E,jp gKanLan JPEG 能8OCYE2QD&Da3S_8ca 2 6993 5 c3dd 3 5.f *M"kan SMP若告293/打开虫)取消(3)基于腐蚀膨胀的开闭图像处理界面329312200腐蚀.292882020822585开运算口onn2U2UB23263'1 1 I ' H I if1 i nri ieinnri Rri i mi inn ,图像像素数据(原始图像,左边图像)处理后的图像像素数据(中间图像)(处理后为分形处理后的图像像素数据(右边图像)(处理后为分割数据存储设计设计数据存储的目的是将目标软件系

21、统中依赖于系统运行环境的数据存取部分与其他 部分相分离。在本软件中,需要将处理后的图像保存到指定位置、指定格式、指定文件名。3.系统设计3.1 建立工程(1)New-Projects-Mfc Appwizard-工程名(2)Single Document(3)CScrollView.Finish.3.2 建立用户类CImg(1)New Class.1)右击“工程名”2)双击 C*Doc 类,添加头文件 #include "ImageProcess.h"(2)添加成员变量private:BYTE *m_lpSrcBit;BYTE *m_lpModifyBit1;图像)BYTE

22、 *m_lpModifyBit2;图像)BITMAPINFO *m_lpBmif; / 图像信息头文件char *m_sImgPath;int m_nWidth;int m_nHeight;int m_nLineByte;int m_nLineByte8;int m_nImgByteSize;int m_nMse;图像的路径图像宽度图像高度图像每行占的字节数(24位图像)图像每行占的字节数(8位图像)图像的所占的字节大小图像方差(计算图像直方图时使用)BOOL m_bGray;(3)依次添加成员函数并完成代码1)CImg:CImgeProcess() 构造函数:用于对成员变量进行初始化;m_l

23、pSrcBit = NULL;m_lpBmif = NULL;m_lpModifyBit1 = NULL;m_lpModifyBit2 = NULL;m_nLineByte =1;m_nLineByte8 =1;m_nHeight = 1;m_nWidth = 1;m_nImgByteSize = 1;m_sImgPath = NULL;m_nMse = 0;m_pD = NULL;m_pa = NULL;m_pe = NULL;m_Rmax = 0;m_Rmax2 = 0;m_lpSrcBit8 = NULL;m_lpModifyBit8 = NULL;m mes = m_sCodeTime

24、 =""2)CImageProcess: CImageProcess () 析构函数;用于释放内存,避免内存泄露! Clean();3)void CImageProcess:Clean()实际的释放内存函数if ( m_lpSrcBit != NULL)(delete m_lpSrcBit;m_lpSrcBit = NULL;)if ( m_lpModifyBit1 != NULL)(delete m_lpModifyBit1;m_lpModifyBit1 = NULL;if ( m_lpModifyBit2 != NULL) (delete m_lpModifyBit2;

25、m_lpModifyBit2 = NULL; ) if ( m_lpBmif != NULL) (delete m_lpBmif;m_lpBmif = NULL;)if ( m_sImgPath != NULL) (delete m_sImgPath; m_sImgPath = NULL;)if ( m_pD != NULL)(delete m_pD;m_pD = NULL;) if ( m_pa != NULL) (delete m_pa;m_pa = NULL; )if ( m_pe != NULL) (delete m_pe;m_pe = NULL; ) if ( m_lpSrcBit8

26、 != NULL) (delete m_lpSrcBit8;m_lpSrcBit8 = NULL; ) if ( m_lpModifyBit8 != NULL) (delete m_lpModifyBit8; m_lpModifyBit8 = NULL;)打开图像及其初始化工作4) BOOL Initial(LPCTSTR lpszPathName);初始化函数功能:进行一系列的初始化操作,初始化位图的基本数据,如长、宽,信息头等。/Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx

27、Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx /BOOL CImageProcess:Initial(LPCTSTR IpszPathName) (读取图像文件数据CFile file(lpszPathName, CFile:modeRead); 使用 MSDN 讲解DWORD len = file.GetLength();BYTE *pTemp = new BYTElen;if ( (file.ReadHuge(pTemp, len) != len) (AfxMessag

28、eBox("文件读取失败!");delete pTemp;return FALSE;)if ( ( (BITMAPFILEHEADER *)pTemp )->bfType != *(WORD *)"BM")(AfxMessageBoxC'目前只支持BMP格式!)delete pTemp;return FALSE;)清除上一次数据Clean();取得文件头指针BITMAPFILEHEADER *lpbmfh = (BITMAPFILEHEADER *)pTemp;取得信息头指针BITMAPINFO *lpBMheader = (BITMAPI

29、NFO *)( lpbmfh + 1 );取得像素指针BYTE *lpBit = (BYTE *)lpbmfh+lpbmfh->bfOffBits;/初始化图像信息int nBitNum = lpBMheader->bmiHeader.biBitCount;m_nWidth = lpBMheader->bmiHeader.biWidth;m_nHeight = lpBMheader->bmiHeader.biHeight;m_nLineByte = (m_nWidth*3*8+31)/32*4;m_nLineByte8 = (m_nWidth*8+31)/32*4;m_

30、nImgByteSize = m_nLineByte*m_nHeight;为像素数据申请存储空间m_lpSrcBit = new BYTEm_nHeight*m_nLineByte;m_lpSrcBit8 = new BYTEm_nLineByte8*m_nLineByte;m_lpModifyBit8 = new BYTEm_nLineByte8*m_nLineByte;/颜色数转换 if ( nBitNum = 8)(F8To24(lpBit);)else if ( nBitNum = 32 )F32to24(lpBit);)else if (nBitNum = 24) (memcpy(m

31、_lpSrcBit, IpBit, m_nHeight*m_nLineByte); else (AfxMessageBox("不支持的 BMP 格式!)delete pTemp;Clean();return FALSE;保存图像文件的路径m_sImgPath = new charMAX_PATH;strcpy(m_sImgPath, lpszPathName);/把信息头该为24位,8, 32位统一按24位处理lpBMheader->bmiHeader.biBitCount = 24;m_lpBmif = new BITMAPINFO;memcpy(m_lpBmif, lpBM

32、header, sizeof(BITMAPINFO);delete pTemp;m_lpModifyBit1 = new BYTEm_nHeight*m_nLineByte;memcpy(m_lpModifyBit1, m_lpSrcBit, m_nHeight*m_nLineByte);m_lpModifyBit2 = new BYTEm_nHeight*m_nLineByte;memcpy(m_lpModifyBit2, m_lpSrcBit, m_nHeight*m_nLineByte);F24to8(m_lpSrcBit, m_lpSrcBit8);return TRUE;5)/8位灰

33、度图像转24位void CImageProcess:F8To24(BYTE *lpBit) (int nLineByte = (8*m_nWidth+31)/32*4;for (int i=0; i<m_nHeight; i+) (for (int j=0; j<m_nWidth; j+)(BYTE *pTemp = m_lpSrcBit + i*m_nLineByte +j*3;* pTemp = *(lpBit + i*nLineByte + j);* (pTemp+1) = *pTemp;* (pTemp+2) = *pTemp;6)/32位灰度图像转24位void CIma

34、geProcess:F32to24(BYTE *lpBit) (int nLineByte = m_nWidth*4;for (int i=0; i<m_nHeight; i+) (for (int j=0; j<m_nWidth; j+)(BYTE *pTemp = m_lpSrcBit + i*m_nLineByte +j*3;BYTE *pTemp2 = IpBit + i*nLineByte + j*4;* pTemp = *pTemp2;* (pTemp+1) = *(pTemp2+1);* (pTemp+2) = *(pTemp2+2);)7) 画直方图void CIm

35、ageProcess:DrawIntensity(CDC *pDC, BYTE *lpSrc, int nType) (if ( m_lpSrcBit = NULL II IpSrc = NULL)(return;)int anCount256;for (int k=0; k<256; k+)(anCountk = 0;)统计直方图for (int i=0; i<m_nHeight; i+) (for (int j=0; j<m_nWidth; j+)(BYTE *pTemp = lpSrc + i*m_nLineByte +j*3; anCount*pTemp+;)/字符串

36、CString str;/最大计数LONG lMaxCount = 0;/计算最大计数值for (i = 0; i <= 255; i +)(/判断是否大于当前最大值if (anCounti > IMaxCount) (/更新最大值IMaxCount = anCounti;)pDC->Rectangle(10+310*nType, m_nHeight+20, 310+310*nType, m_nHeight+350 );/创建画笔对象CPen* pPenRed = new CPen;/红色画笔pPenRed->CreatePen(PS_SOLID,1,RGB(255,0

37、,0);/创建画笔对象CPen* pPenBlue = new CPen;/蓝色画笔pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0, 255);/创建画笔对象CPen* pPenGreen = new CPen;/绿色画笔pPenGreen->CreatePen(PS_DOT,1,RGB(0,255,0);/选中当前红色画笔,并保存以前的画笔CGdiObject* pOldPen = pDC->SelectObject(pPenRed);/绘制坐标轴pDC->MoveTo(20+310*nType, m_nHeight+30);/垂直轴pD

38、C->LineTo(20+310*nType, m_nHeight+320);/水平轴pDC->LineTo(300+310*nType, m_nHeight+320)/绘制丫轴箭头pDC->MoveTo(15+310*nType, m_nHeight+40);pDC->LineTo(20+310*nType, m_nHeight+30);pDC->LineTo(25+310*nType, m_nHeight+40);/绘制X轴箭头pDC->MoveTo(290+310*nType, m_nHeight+315);pDC->LineTo(300+310

39、*nType, m_nHeight+320);pDC->LineTo(290+310*nType, m_nHeight+325);/写X轴刻度值for (k=0; k<251; k+=50)(str.Format("%d", k);pDC->TextOut(12+310*nType+k, m_nHeight+330, str);)/绘制X轴刻度for (i = 0; i < 256; i += 5) (if (i & 1) = 0)(/ 10的倍数pDC->MoveTo(i+20+310*nType, m_nHeight+320);pD

40、C->LineTo(i+20+310*nType, m_nHeight+326);)else (/ 10的倍数 pDC->MoveTo(i+20+310*nType, m_nHeight+320);pDC->LineTo(i+20+310*nType, m_nHeight+323);)if ( i%50 = 0)(pDC->MoveTo(i+20+310*nType, m_nHeight+320);pDC->LineTo(i+20+310*nType, m_nHeight+329);)/输出最大计数值pDC->MoveTo(20+310*nType, m_n

41、Height+45);pDC->LineTo(25+310*nType, m_nHeight+45);str.Format("%d", lMaxCount);pDC->TextOut(22+310*nType, m_nHeight+50, str);/更改成蓝色画笔pDC->SelectObject(pPenBlue);/判断是否有计数if (lMaxCount > 0)(/绘制直方图 for (i = 0; i <= 255; i +) (pDC->MoveTo(i+20+310*nType, m_nHeight+320);pDC-&g

42、t;LineTo(i+20+310*nType, m_nHeight+320 - (int) (anCounti * 260 / lMaxCount);)/恢复以前的画笔pDC->SelectObject(pOldPen);/删除新的画笔delete pPenRed;delete pPenBlue;delete pPenGreen;) 1 /显示函数功能:显示原图像和处理后的图像/Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx

43、Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx Tx /void CImageProcess:Show(CDC *pDC, int x, int y, char *pStr) (if (m_lpSrcBit = NULL)(return;)if (m_lpSrcBit != NULL)(显示位图:SetDIBitsToDevice(pDC->m_hDC,10,10, m_nWidth, m_nHeight, 0, 0, 0, m_nHeight, m_lpSrcBit, m_lpBmif, DIB_RGB_COLORS);

44、 画直方图 DrawIntensity(pDC, m_lpSrcBit, 0);)if ( m_lpModifyBit1 != NULL)( :SetDIBitsToDevice(pDC->m_hDC, 20+m_nWidth, 10, m_nWidth, m_nHeight, 0, 0, 0, m_nHeight, m_lpModifyBit1, m_lpBmif,DIB_RGB_COLORS);DrawIntensity(pDC, m_lpModifyBit1, 1);if ( m_lpModifyBit2 != NULL)(:SetDIBitsToDevice(pDC->m_

45、hDC, 30+2*m_nWidth, 10, m_nWidth, m_nHeight, 0, 0, 0, m_nHeight, m_lpModifyBit2, m_lpBmif,DIB_RGB_COLORS);DrawIntensity(pDC, m_lpModifyBit2, 2);)if ( pStr != NULL) (pDC->TextOut(x, y, pStr);)pDC->TextOut(m_nWidth*3/2, m_nHeight+11, m_mes);pDC->TextOut(m_nWidth*3/2, m_nHeight+25, m_sCodeTime

46、); )9) 保存处理后的图像void CImageProcess:Save(LPCTSTR lpszPathName, int nType) (/* if ( m_lpModifyBit1 = NULL)(AfxMessageBox("图像还没有处理过不需要保存) return ;)*/根据选择的文件类型来保存switch(nType) case 1:Save24(lpszPathName);break;case 2:Save8(lpszPathName);break;default:/MessageBox("未知的文件类型!)break;)10) void CImage

47、Process:Save24(LPCTSTR IpszPathName) (构造24位文件头并保存数据CFile file(lpszPathName, CFile:modeCreate | CFile:modeWrite);BITMAPFILEHEADER bmheader;bmheader.bfSize = sizeof(BITMAPFILEHEADER);bmheader.bfType = *(WORD *)"BM"bmheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO);bmheader.bf

48、Reserved1 = 0;bmheader.bfReserved2 = 0;file.Write( (const void *)&bmheader, sizeof(BITMAPFILEHEADER);file.Write( (const void *)m_lpBmif, sizeof(BITMAPINFO);file.WriteHuge( (const void *)m_lpModifyBit1, m_nHeight*m_nLineByte); file.Close();)void CImg:Save8(LPCTSTR lpszPathName)(构造8位文件头BITMAPFILEH

49、EADER bmfd;bmfd.bfSize = sizeof(BITMAPFILEHEADER);bmfd.bfType = *(WORD *)"BM"bmfd.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD);bmfd.bfReserved1 = 0;bmfd.bfReserved2 = 0;BITMAPINFOHEADER bmif = m_lpBmif->bmiHeader;构造信息头int nWidth = bmif.biWidth;int

50、nHeight = bmif.biHeight;int nLineBytes = (nWidth*8+31)/32*4;int cbImage = nLineBytes*nHeight;bmif.biBitCount = 8;bmif.biSizeImage = cbImage;BYTE *lp8Bit = new BYTE cbImage ;memset(lp8Bit , 255, cbImage);BYTE *pTemp = NULL;把24位转化为8位for (int i=0; i<nHeight; i+) (for (int j=0; j<nWidth; j+) (pTem

51、p = m_lpModifyBit1 + i*m_nLineByte + j*3; *(lp8Bit + i*nLineBytes + j) = *pTemp;)构造灰度调色板RGBQUAD *pPalette = new RGBQUAD256;for (int k=0; k<256; k+) (pPalettek.rgbBlue = k;pPalettek.rgbGreen = k;pPalettek.rgbRed = k;pPalettek.rgbReserved = 0;)/写数据TRY(CFile file(lpszPathName, CFile:modeCreate | CFi

52、le:modeWrite); file.Write(const void*)&bmfd, sizeof(BITMAPFILEHEADER); file.Write( (const void*)&bmif, sizeof(BITMAPINFOHEADER); file.Write( (const void*)pPalette, 256*sizeof(RGBQUAD); file.WriteHuge( (const void*)lp8Bit, cbImage);file.Close();)CATCH(CFileException, e)(switch(e->m_cause)(

53、case CFileException:badPath:AfxMessageBox("无效的路径!"); break;case CFileException:invalidFile:AfxMessageBox("invalid File!");break;default:AfxMessageBox("other error!"); break;)END_CATCHdelete lp8Bit;灰度腐蚀:delete pPalette; ) void CImageProcess:GrayErosion(BYTE *pData)(if (

54、pData = NULL II m_lpSrcBit = NULL)(return;)for (int i=1; i<m_nHeight-1; i+)(for (int j=1; j<m_nWidth-1; j+) (int min = 255;for (int m=-1; m<=1; m+) (for (int n=-1; n<=1; n+)(BYTE *pSrc = pData+(i+m)*m_nLineByte+(j+n)*3; if ( *pSrc < min ) (min = *pSrc;) )*(m_lpModifyBit1+i*m_nLineByte+j*3) = min;*(m_lpModifyBit1+

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论