版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
图像处理的开运算与闭运算0.前言腐蚀和膨胀是依据数学形态学集合论方法开展起来的图像处理方法,起源于岩相对岩石结构的定量描述工作,在数字图像处理和机器视觉领域中得到了广泛的应用,形成了一种独特的数字图像分析方法和理论。数学形态学是图像处理和模式识领域的新方法,其根本思想是:用具有一定形态的结构元素去量度和提取图像中的对应形状,以到达图像分析和识别的目的。优势有以下几点:有效滤除噪声,保存图像中原有信息,算法易于用并行处理方法有效实现,基于数学形态学的边缘信息提取处理优于基于微分运算的边缘提取算法,提取的边缘比拟平滑,提取的图像骨架也比拟连续,断点少腐蚀:是一种消除边界点,使边界向内部收缩的过程。可以用来消除小且无意义的物体。膨胀:是将与物体接触的所有背景点合并到该物体中,使边界向外部扩张的过程。可以用来填补物体中的空洞。开运算:先腐蚀后膨胀的过程开运算。用来消除小物体、在纤细点处别离物体、平滑较大物体的边界的同时并不明显改变其面积。开运算通常是在需要去除小颗粒噪声,以及断开目标物之间粘连时使用。其主要作用与腐蚀相似,与腐蚀操作相比,具有可以根本保持目标原有大小不变的优点。闭运算:先膨胀后腐蚀的过程称为闭运算。用来填充物体内细小空洞、连接邻近物体、平滑其边界的同时并不明显改变其面积。原因:虽然腐蚀处理可以将粘连的目标物进行别离,膨胀处理可以将断开的目标物进行接续,但同时都存在一个问题,就是经过腐蚀处理后,目标物的面积小于原有面积,而经过膨胀处理之后,目标物的面积大于原有面积。开、闭运算就是为了解决这个问题而被提出的。数学形态学中二值图像的形态变换是一种针对集合的处理过程。其形态算子的实质是表达物体或形状的集合与结构元素间的相互作用,结构元素的形状就决定了这种运算所提取的信号的形状信息。形态学图像处理是在图像中移动一个结构元素,然后将结构元素与下面的二值图像进行交、并等集合运算。1.系统分析系统功能需求〔1〕位图图像文件的导入、转换、显示、保存、关闭模块在该功能模块中提供:位图图像文件的导入功能;把32位或8位位图文件转换为24位位图文件的功能;显示经过导入和转换后的24位位图文件的功能;图像保存〔提供保存为8位和24位位图的功能〕和关闭图像的功能。这一模块主要对图像进行后续处理及其操作的根底。〔2〕基于膨胀和腐蚀的图像处理模块该模块主要的功能是用膨胀和腐蚀算法,得到对应的参数图像〔图像增强〕,结合膨胀和腐蚀,做出开闭运算的图像〔3〕图像控制模块该模块主要功能是实现对原始图像另存;分形图像、分割结果图像保存的操作场景分析和开发场景名称参与执行者前置条件事件流后置条件图像信息导入用户系统已翻开1、翻开系统主界面2、选择文件菜单中的“翻开〞命令,选择文件3、对图像类型进行合法性检查,合那么4,否那么24、去除上一次数据5、把图像转换为24位位图文件6、提取图像像素数据,并保存三份7、将用户所要处理的图像导入系统中1、图像导入2、在图像显示界面上显示〔三组图像及其直方图〕3、用户可以作其他的处理基于腐蚀和膨胀图像的开闭处理用户系统已翻开图像已导入1、选择“图像处理〞菜单2、根据用户需要选择需要的处理类型3、系统对图像作相应的处理4、将处理后图像保存并显示给用户〔中间组和右边组:包括图像、直方图〕1、得到处理后图像〔增强〕;2、在图像显示界面上显示〔中间组和右边组〕;3、用户可以作其他的处理处理结果图像保存场景用户系统已翻开,图像已导入,并作相应的处理1、选择“文件〞菜单2、选择“另保存〞菜单,路径+文件名3、将分形结果图像保存。1、得到分形结果图像;2、用户可以作其他的处理抽象用例对应活动图用例图根据功能分析和用例分析,我们得到“图像处理开闭运算〞的用例图。〔1〕图像信息的导入用例图〔2〕基于腐蚀膨胀图像处理用例图〔3〕原始图像另存用例〔4〕处理结果图像保存用例〔5〕总的用例图建立系统总体架构及领域概念模型系统总体架构系统总体架构用于描述整个软件的体系结构,包括对各个功能模块的划分、功能定义、软件的层次结构等。根据前面建立的系统用例图,我们选用分层架构模式。下面我们用包图来描述总体结构。系统领域概念模型领域概念模型用于描述用户需求和相关业务领域中全局性的概念及其相互之间的关系。它在系统总体架构的根底上,进一步从概念上帮助开发人员理清系统结构及系统各组成局部之间的相互作用。领域概念模型使用UML的类图来表示,但不需要标出每个类的属性和方法,只需根据以上所作的场景开发和建立的用例,提取关键的概念并以类的形式表示出来即可。领域概念模型可以理解为类图的草图本系统拟采用MFC支持的文档视图结构中的单文档界面〔SDI〕结构。大局部Windows应用程序都相当复杂。典型的情况是,它们均包含业务逻辑处理层和界面层〔程序框架〕,在MFC中对应于两个代表性的类:“文档〞和“视图〞。MFC将文档和视图有机地组成一个整体的框架,提供应程序编写者,这就是我们通常所说的文档/视图结构。通常,当创立一个SDI应用程序时,如果不考虑About对话框窗口类的话,SDI应用程序将创立4个特定的类,即CC***APP类、CMainFrame类、CC***DOC类、CC***VIEW类,每个类在程序运行时都有自己的特殊用途。其中:CC***APP类:创立所有其它组件。该类接收所有的事件消息,然后将这些消息传递给CMainFrame类、CC***DOC类、CC***VIEW。在编程中几乎不需要修改和添加代码。。CMainFrame类:它包括菜单、工具栏、滚动条、状态栏、和所有其他与该框架相关联的显示对象。在编程中几乎不需要修改和添加代码。CC***DOC类:它是关于文档存储的类。可以在这个类中创立数据结构,并利用这些数据结构存储和处理构成文档的数据。〔注意:一般通过在该类中定义一个用户类的对象作为该类的成员变量,以此来创立数据结构,在程序中通过该成员变量来调用用户类的各种成员函数【方法】〕。该类从用户自己定义的类或CC***VIEW类得到输入并将要显示的信息输出到CC***VIEW类。该类还负责存盘和从文件中检索文档数据的工作。CC***VIEW类:它用于向用户显示可视化文档,并将用户输入的信息传送到CC***DOC类,然后从CC***DOC类接收显示信息。在该类中所需要的大局部代码工作包括绘制用户的文档、处理用户的输入、调用用户自定义类中的方法〔通过CC***DOC类的指针〕。CC***DOC类有几个子类,包括CEditView、CFormView、CHtmlView、CListView、CRichEditView、CScrollView、CTreeView等,但大局部子类和CC***VIEW类的属性和使用方法区别不大。2系统设计在系统需求分析阶段,通过建立系统总体结构、领域概念模型,已经确定了系统的根本结构。在系统设计阶段主要内容有:设计用例实现方案、数据设计、用户界面设计,建立组件图、配置图、生成系统代码框架等几局部工作提取边界类、实体类、控制类〔1〕提取边界类边界类主要描述目标软件系统和外部环境的交互,复杂界面控制、外部接口和环境隔离,处理目标软件系统与用户、其他软件系统及操作系统和其他设备之间的交互。根据已建立系统总体结构、领域概念模型,可以提取以下边界类:1〕CMainFrame类、CC***VIEW类、CC***APP类、CC***DOC类中的涉及数据输入以及界面变化的方法〔成员函数〕2〕CDlg***类3〕CImg类中的涉及数据输入以及显示的方法〔成员函数〕〔2〕提取实体类实体类表示目标软件系统中具有持久意义的信息项和操作,它向目标软件系统的其他局部提供读取信息项内容的必要接口,不涉及业务逻辑处理。根据已建立系统总体结构、领域概念模型,可以提取以下边界类:1〕CC***DOC类中的涉及数据保存的方法〔成员函数〕2〕CImg类中的涉及数据保存的方法〔成员函数〕〔3〕提取控制类和辅助类控制类作为完成用例任务的责任承当者,主要用于协调、控制其他类共同完成用例规定的功能或行为。它一般不处理具体的任务细节,但它应该能够分解任务并将子任务分派给适当的辅助类,同时在辅助类之间进行消息传递和协调。MFC中采用消息映射机制实现处理来自操作面板接收的各种用户指令,并将这些命令分派给适当的辅助类。辅助类用于辅助控制类完成用例规定的功能或行为。可提取以下的辅助类:1〕CImg类中的用于完成用例规定的功能或行为的各种方法〔成员函数〕2〕CC***VIEW类、CC***DOC类、CDlg***类中的用于完成用例规定的功能或行为的各种方法〔成员函数〕或消息响应函数。基于所提取的边界类、实体类和构建的控制类和辅助类,我们将在已提取的各种类的根底上,构造系统的交互图、协作图等动态视图,为设计生成系统类图做准备。通过建立系统的顺序图和协作图---构造交互图顺序图和协作图是反映用户和系统动态交互的两种视图。顺序图按时间顺序描述系统元素之间的交互,而协作图那么按照时间和空间顺序描述系统元素〔包括系统用户〕之间的交互和它们之间的动态关系。二者都是表示对象间的交互作用,前者强调时间顺序,但没有明确的表达对象间的关系;后者描述对象之间的关系,但时间顺序必须从序号获得。顺序图和协作图都是来自UML模型的相同信息,语义上是等价的,二者可以相互转换而不丧失任何信息。实际使用中,常用时序图,即在顺序图的根底上,参加表示时间顺序的序号。〔1〕图像导入时序图〔2〕开闭运算计算时序图〔3〕原始图像另存时序图〔4〕开闭处理后图像保存时序图类图的生成类图〔ClassDiagram〕是在系统的领域概念模型根底上进一步添加对象的属性和方法生成的,它描述类、接口、协作、以及它们之间的关系,是系统设计的核心局部。类图是系统静态视图的一局部,主要用于描述软件系统的静态结构,主要支持系统的功能需求,也即系统要提供应最终用户的效劳。类图也是面向对象系统建模中最常用的图,是定义其他图的根底。在类图根底上,我们可以定义组件图、配置图,为代码生成做好准备。在系统实现局部,表述,参加!类名:CImg-----------Img.h和Img.cpppublic: voidClose(); voidOpen(); voidDilate(); voidGrayDilate(BYTE*pData); voidErosion(); voidGrayErosion(BYTE*pData); voidSort(int*pBuf,intl,intr); voidMidFilter(intnWidth,intnHeight); voidGrayErosion(intD); voidSave8(LPCTSTRlpszPathName); voidSave24(LPCTSTRlpszPathName); voidSave(LPCTSTRlpszPathName,intnType); voidDrawIntensity(CDC*pDC,BYTE*lpSrc,intnType); voidShow(CDC*pDC,intx=0,inty=0,char*pStr=NULL); voidF24to8(constBYTE*pSrc,BYTE*pDest); voidF32to24(BYTE*lpBit); voidF8To24(BYTE*lpBit); BOOLInitial(LPCTSTRlpszPathName); voidClean(); CImageProcess(); virtual~CImageProcess();private: BYTE*m_lpSrcBit;//图像像素数据〔原始图像,左边图像〕 BYTE*m_lpModifyBit1;//处理后的图像像素数据〔中间图像〕 BYTE*m_lpModifyBit2;//处理后的图像像素数据〔右边图像〕 BITMAPINFO*m_lpBmif;//图像信息头文件 char*m_sImgPath;//图像的路径 intm_nWidth;//图像宽度 intm_nHeight;//图像高度 BOOLm_bGray; intm_nLineByte;//图像每行占的字节数〔24位图像〕 intm_nLineByte8;//图像每行占的字节数〔8位图像〕 intm_nImgByteSize;//图像的所占的字节大小 BYTE*m_lpSrcBit8;//8位位图数据 BYTE*m_lpModifyBit8;//8位位图数据总体框架和界面设计人机界面也称为用户界面,它是交互式应用软件系统的门面。〔1〕用户翻开系统主界面---系统功能的外部模型运行可执行程序后,首先进入系统的主界面。界面要求简单,符合用户习惯〔2〕用户导入图像界面〔3〕基于腐蚀膨胀的开闭图像处理界面腐蚀膨胀开运算闭运算数据存储设计设计数据存储的目的是将目标软件系统中依赖于系统运行环境的数据存取局部与其他局部相别离。在本软件中,需要将处理后的图像保存到指定位置、指定格式、指定文件名。3.系统设计3.1建立工程〔1〕New---Projects---MfcAppwizard---工程名〔2〕SingleDocument…〔3〕CScrollView…Finish.3.2建立用户类CImg〔1〕NewClass… 1〕右击“工程名〞… 2〕双击C***Doc类,添加头文件#include"ImageProcess.h"〔2〕添加成员变量…private: BYTE*m_lpSrcBit;//图像像素数据〔原始图像,左边图像〕 BYTE*m_lpModifyBit1;//处理后的图像像素数据〔中间图像〕〔处理后为分形图像〕 BYTE*m_lpModifyBit2;//处理后的图像像素数据〔右边图像〕〔处理后为分割图像〕 BITMAPINFO*m_lpBmif;//图像信息头文件 char*m_sImgPath;//图像的路径 intm_nWidth;//图像宽度 intm_nHeight;//图像高度 intm_nLineByte;//图像每行占的字节数〔24位图像〕 intm_nLineByte8;//图像每行占的字节数〔8位图像〕 intm_nImgByteSize;//图像的所占的字节大小 intm_nMse;//图像方差〔计算图像直方图时使用〕BOOLm_bGray;〔3〕依次添加成员函数并完成代码 1〕CImg::CImgeProcess()//构造函数:用于对成员变量进行初始化; m_lpSrcBit=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=""; 2〕CImageProcess::~CImageProcess()//析构函数;用于释放内存,防止内存泄露!Clean(); 3〕voidCImageProcess::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;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!=NULL){delete[]m_lpSrcBit8;m_lpSrcBit8=NULL;} if(m_lpModifyBit8!=NULL){ delete[]m_lpModifyBit8; m_lpModifyBit8=NULL;}4〕BOOLInitial(LPCTSTRlpszPathName);//翻开图像及其初始化工作/*******************************************************初始化函数功能:进行一系列的初始化操作,初始化位图的根本数据,如长、宽,信息头等。*******************************************************/BOOLCImageProcess::Initial(LPCTSTRlpszPathName){ //读取图像文件数据 CFilefile(lpszPathName,CFile::modeRead);//使用MSDN讲解 DWORDlen=file.GetLength(); BYTE*pTemp=newBYTE[len]; if((file.ReadHuge(pTemp,len))!=len) { AfxMessageBox("文件读取失败!"); delete[]pTemp; returnFALSE; } if(((BITMAPFILEHEADER*)pTemp)->bfType!=*(WORD*)"BM") { AfxMessageBox("目前只支持BMP格式!"); delete[]pTemp; returnFALSE; }//去除上一次数据 Clean();//取得文件头指针 BITMAPFILEHEADER*lpbmfh=(BITMAPFILEHEADER*)pTemp;//取得信息头指针 BITMAPINFO*lpBMheader=(BITMAPINFO*)(lpbmfh+1);//取得像素指针 BYTE*lpBit=(BYTE*)lpbmfh+lpbmfh->bfOffBits;;/初始化图像信息 intnBitNum=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_nImgByteSize=m_nLineByte*m_nHeight;//为像素数据申请存储空间 m_lpSrcBit=newBYTE[m_nHeight*m_nLineByte]; m_lpSrcBit8=newBYTE[m_nLineByte8*m_nLineByte]; m_lpModifyBit8=newBYTE[m_nLineByte8*m_nLineByte];//颜色数转换 if(nBitNum==8) { F8To24(lpBit); } elseif(nBitNum==32) { F32to24(lpBit); } elseif(nBitNum==24) { memcpy(m_lpSrcBit,lpBit,m_nHeight*m_nLineByte);} else { AfxMessageBox("不支持的BMP格式!"); delete[]pTemp; Clean(); returnFALSE; }//保存图像文件的路径 m_sImgPath=newchar[MAX_PATH]; strcpy(m_sImgPath,lpszPathName);//把信息头该为24位,8,32位统一按24位处理 lpBMheader->bmiHeader.biBitCount=24; m_lpBmif=newBITMAPINFO; memcpy(m_lpBmif,lpBMheader,sizeof(BITMAPINFO)); delete[]pTemp; m_lpModifyBit1=newBYTE[m_nHeight*m_nLineByte]; memcpy(m_lpModifyBit1,m_lpSrcBit,m_nHeight*m_nLineByte); m_lpModifyBit2=newBYTE[m_nHeight*m_nLineByte]; memcpy(m_lpModifyBit2,m_lpSrcBit,m_nHeight*m_nLineByte); F24to8(m_lpSrcBit,m_lpSrcBit8); returnTRUE;}5〕//8位灰度图像转24位voidCImageProcess::F8To24(BYTE*lpBit){ intnLineByte=(8*m_nWidth+31)/32*4; for(inti=0;i<m_nHeight;i++) { for(intj=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位voidCImageProcess::F32to24(BYTE*lpBit){ intnLineByte=m_nWidth*4; for(inti=0;i<m_nHeight;i++) { for(intj=0;j<m_nWidth;j++) { BYTE*pTemp=m_lpSrcBit+i*m_nLineByte+j*3; BYTE*pTemp2=lpBit+i*nLineByte+j*4; *pTemp=*pTemp2; *(pTemp+1)=*(pTemp2+1); *(pTemp+2)=*(pTemp2+2); } }}7〕//画直方图voidCImageProcess::DrawIntensity(CDC*pDC,BYTE*lpSrc,intnType){if(m_lpSrcBit==NULL||lpSrc==NULL) { return; }intanCount[256]; for(intk=0;k<256;k++) { anCount[k]=0; } //统计直方图 for(inti=0;i<m_nHeight;i++) { for(intj=0;j<m_nWidth;j++) { BYTE*pTemp=lpSrc+i*m_nLineByte+j*3; anCount[*pTemp]++; } } //字符串 CStringstr; //最大计数 LONGlMaxCount=0; //计算最大计数值 for(i=0;i<=255;i++) { //判断是否大于当前最大值 if(anCount[i]>lMaxCount) { //更新最大值 lMaxCount=anCount[i]; } } pDC->Rectangle(10+310*nType,m_nHeight+20,310+310*nType,m_nHeight+350); //创立画笔对象 CPen*pPenRed=newCPen; //红色画笔 pPenRed->CreatePen(PS_SOLID,1,RGB(255,0,0)); //创立画笔对象 CPen*pPenBlue=newCPen; //蓝色画笔 pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0,255)); //创立画笔对象 CPen*pPenGreen=newCPen; //绿色画笔 pPenGreen->CreatePen(PS_DOT,1,RGB(0,255,0)); //选中当前红色画笔,并保存以前的画笔 CGdiObject*pOldPen=pDC->SelectObject(pPenRed); //绘制坐标轴 pDC->MoveTo(20+310*nType,m_nHeight+30); //垂直轴 pDC->LineTo(20+310*nType,m_nHeight+320); //水平轴 pDC->LineTo(300+310*nType,m_nHeight+320) //绘制Y轴箭头 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*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); pDC->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_nHeight+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->LineTo(i+20+310*nType,m_nHeight+320-(int)(anCount[i]*260/lMaxCount)); } } //恢复以前的画笔 pDC->SelectObject(pOldPen); //删除新的画笔 deletepPenRed; deletepPenBlue; deletepPenGreen;}8〕/*******************************************************显示函数功能:显示原图像和处理后的图像*******************************************************/voidCImageProcess::Show(CDC*pDC,intx,inty,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); //画直方图 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_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);}9〕//保存处理后的图像voidCImageProcess::Save(LPCTSTRlpszPathName,intnType){/* if(m_lpModifyBit1==NULL) { AfxMessageBox("图像还没有处理过不需要保存"); return; }*/ //根据选择的文件类型来保存 switch(nType){ case1: Save24(lpszPathName); break; case2: Save8(lpszPathName); break; default:// MessageBox("未知的文件类型!"); break; }}10〕voidCImageProcess::Save24(LPCTSTRlpszPathName){ //构造24位文件头并保存数据 CFilefile(lpszPathName,CFile::modeCreate|CFile::modeWrite); BITMAPFILEHEADERbmheader; bmheader.bfSize=sizeof(BITMAPFILEHEADER); bmheader.bfType=*(WORD*)"BM"; bmheader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO); bmheader.bfReserved1=0; bmheader.bfReserved2=0; file.Write((constvoid*)&bmheader,sizeof(BITMAPFILEHEADER)); file.Write((constvoid*)m_lpBmif,sizeof(BITMAPINFO)); file.WriteHuge((constvoid*)m_lpModifyBit1,m_nHeight*m_nLineByte); file.Close();}voidCImg::Save8(LPCTSTRlpszPathName){ //构造8位文件头 BITMAPFILEHEADERbmfd; bmfd.bfSize=sizeof(BITMAPFILEHEADER); bmfd.bfType=*(WORD*)"BM"; bmfd.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) +256*sizeof(RGBQUAD); bmfd.bfReserved1=0; bmfd.bfReserved2=0; BITMAPINFOHEADERbmif=m_lpBmif->bmiHeader; //构造信息头 intnWidth=bmif.biWidth; intnHeight=bmif.biHeight; intnLineBytes=(nWidth*8+31)/32*4; intcbImage=nLineBytes*nHeight; bmif.biBitCount=8; bmif.biSizeImage=cbImage; BYTE*lp8Bit=newBYTE[cbImage]; memset(lp8Bit,255,cbImage); BYTE*pTemp=NULL; //把24位转化为8位 for(inti=0;i<nHeight;i++) { for(intj=0;j<nWidth;j++) { pTemp=m_lpModifyBit1+i*m_nLineByte+j*3; *(lp8Bit+i*nLineBytes+j)=*pTemp; } } //构造灰度调色板 RGBQUAD*pPalette=newRGBQUAD[256]; for(intk=0;k<256;k++) { pPalette[k].rgbBlue=k; pPalette[k].rgbGreen=k; pPalette[k].rgbRed=k; pPalette[k].rgbReserved=0; } //写数据 TRY { CFilefile(lpszPathName,CFile::modeCreate|CFile::modeWrite); file.Write((constvoid*)&bmfd,sizeof(BITMAPFILEHEADER)); file.Write((constvoid*)&bmif,sizeof(BITMAPINFOHEADER)); file.Write((constvoid*)pPalette,256*sizeof(RGBQUAD)); file.WriteHuge((constvoid*)lp8Bit,cbImage); file.Close(); } CATCH(CFileException,e) { switch(e->m_cause) { caseCFileException::badPath: AfxMessageBox("无效的路径!"); break; caseCFileException::invalidFile: AfxMessageBox("invalidFile!"); break; default: AfxMessageBox("othererror!"); break; } } END_CATCH delete[]lp8Bit; delete[]pPalette;}灰度腐蚀:voidCImageProcess::GrayErosion(BYTE*pData){if(pData==NULL||m_lpSrcBit==NULL) { return; } for(inti=1;i<m_nHeight-1;i++) { for(intj=1;j<m_nWidth-1;j++) { intmin=255; for(intm=-1;m<=1;m++) { for(intn=-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+i*m_nLineByte+j*3+1)=min; *(m_lpModifyBit1+i*m_nLineByte+j*3+2)=min; } }}腐蚀voidCImageProcess::Erosion(){if(m_lpSrcBit==NULL||m_lpModifyBit1==NULL) { return; } if(m_bGray) { GrayErosion(m_lpSrcBit); } else { }}灰度膨胀voidCImageProcess::GrayDilate(BYTE*pData){if(pData==NULL|
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025 高中信息技术数据与计算之数据在在线娱乐社交互动分析中的应用课件
- 2025 高中信息技术数据与计算之数据可视化的玫瑰图设计课件
- 2026年含氟含磷等特征污染物废水处理专用装备开发
- 2026年纳芯微车规级温度传感器智驾域控电池热管理应用方案
- 2026年数字孪生技术在源网荷储协同调度系统中的应用
- 2026年设施农业采摘机器人商业化应用难点
- 2026年智能体加快推广与重点行业规模化应用指南
- 2026年差分隐私数学可证明隐私保护技术应用指南
- 2026年锂电光伏行业智能制造机器人工艺适配方案
- 2026年海上风电直连制氢:阳江模式技术解析与推广
- 初中英语中考短文填空题型考点精析与知识清单
- 城市公共交通运营与服务规范
- 2026年1月浙江省高考首考英语试卷真题完整版(含答案+听力)
- 2026年国轩高科行测笔试题库
- 2025年研究生政治复试笔试题库及答案
- 水利三防培训课件
- 2026届新高考高中英语语法填空题66篇(含答案解析)
- 2026年时事政治测试题库附参考答案(培优)
- 锅炉满水培训课件
- 2026春教科版(新教材)小学科学一年级下册(全册)教学设计(附教材目录)
- 小儿股静脉抽血课件
评论
0/150
提交评论