• 最近老师让一个处理图像的小软件,用了大概一个星期出来了成品,MFC上我算是新手,一路摸索过来也算是收获不少吧,现在软件也完了,给自己总结一下在学习过程中的收获和不足。 首先放出一下软件的运行截图,...
    最近老师让做一个处理图像的小软件,用了大概一个星期做出来了成品,MFC上我算是新手,一路摸索过来也算是收获不少吧,现在软件也做完了,给自己总结一下在学习过程中的收获和不足。
    

    首先放出一下软件的运行截图,主要是做了灰度图像的几何变换、正交变换、图像增强、二值化处理、形态学处理、图像分割等功能。代码主要参考了《visual c++数字图象处理技术详解》以及网上的一些技术文章,完整的工程已上传至csdn:http://download.csdn.net/detail/zzucode/7672489

    灰度图像处理主要操作的是设备无关位图(DIB),由于mfc本身没有提供DIB的一个完整的类,只是提供了一些API接口和结构体,因此需要自己创建一个DIB类,主要实现位图的载入,保存,绘制及返回位图信息等操作。

    首先使用mfc向导创建一个单文档应用程序,不使用unicode编码,然后在源文件中添加DIB类的头文件Dib.h和Dib.cpp,具体的头文件如下:

    class CDib 
    {
    public:
    	CDib();
    	virtual ~CDib();
    	//operations
    	public:
    	// 用于操作DIB的函数声明
    	BOOL   DrawDib(HDC, LPRECT,HGLOBAL, LPRECT,CPalette*);//显示位图
    	BOOL   ConstructPalette(HGLOBAL,CPalette* );          //构造逻辑调色板
    	LPSTR  GetBits(LPSTR);                                //取得位图数据的入口地址
    	DWORD  GetWidth(LPSTR);                               //取得位图的宽度
    	DWORD  GetHeight(LPSTR);                              //取得位图的高度
    	WORD   GetPalSize(LPSTR);                             //取得调色板的大小
    	WORD   GetColorNum(LPSTR);                            //取得位图包含的颜色数目
    	WORD   GetBitCount(LPSTR);                            //取得位图的颜色深度
    	HGLOBAL CopyObject(HGLOBAL);                          //用于复制位图对象
    
    	BOOL      SaveFile(HGLOBAL , CFile&);                    //存储位图为文件
    	HGLOBAL   LoadFile(CFile&);                           //从文件中加载位图
    	BOOL      IsEmpty();
    	// 在对图像进行处理时,针对位图的字节宽度必须是4的倍数的这一要求,
    	//我们设计了函数GetRequireWidth,来处理这种比较特殊的情况
    	int     GetReqByteWidth(int );                     //转换后的字节数
    	long    GetRectWidth(LPCRECT );                    //取得区域的宽度
    	long    GetRectHeight(LPCRECT);                    //取得区域的高度
    public:
    	void ClearMemory();
    	void InitMembers();
    public:
    	LPBITMAPINFO        	lpbminfo;// 指向BITMAPINFO结构的指针
    	LPBITMAPINFOHEADER  	lpbmihrd;	//指向BITMAPINFOHEADER结构的指针
    	BITMAPFILEHEADER<span style="white-space:pre">	</span>bmfHeader;  //BITMAPFILEHEADER结构
    	LPSTR<span style="white-space:pre">			</span>lpdib;      //指向DIB的指针
    	LPSTR<span style="white-space:pre">			</span>lpDIBBits;  // DIB像素指针
    	DWORD<span style="white-space:pre">			</span>dwDIBSize;  //DIB大小
    	HGLOBAL<span style="white-space:pre">			</span>m_hDi       //DIB对象的句柄
    	RGBQUAD*<span style="white-space:pre">		</span>lpRgbQuag;  //指向颜色表的指针
    };
    
    DIB类的实现文件太长,就不再贴出来了,《visual c++数字图象处理技术详解》上有完整的源码,有感兴趣的朋友可以自己去看。

    将Dib的实现文件添加进来之后,接下来就需要载入图像并在文档客户区显示,首先在工程C**Doc类的头文件中声明一个Dib类的对象并定义一些操作:

    // 特性
    public:
    	CDib m_dib;	//声明一个DIB对象
    	CString m_szPathName;//图片文件路径
    // 操作
    public:
    	HGLOBAL GetHObject() const	//获取Dib对象的句柄
    	{ return m_hDIB;}
    	CPalette *GetDocPal() const	//获取调色板指针
    	{ return m_palDIB;}
    	CSize GetDocDimension() const	//
    	{ return m_sizeDoc;}
    	void UpdateObject(HGLOBAL hDIB);	//更新DIB对象
    // 实现
    public:
    	void SetDib();		//获取Dib对象
    public:
    	HGLOBAL m_hDIB;
    	CPalette *m_palDIB;
    	CSize m_sizeDoc;

    然后在C**Doc类的实现文件的构造函数中添加

    // TODO: 在此添加一次性构造代码
    	m_hDIB = NULL;
    	m_palDIB = NULL;
    	m_sizeDoc = CSize(1,1);
    在析构函数中添加

    if (m_hDIB != NULL)	//判断是否有dib对象
    	{
    		::GlobalFree(m_hDIB);
    	}
    
    	if (m_palDIB != NULL)	//判断是否有调色板
    	{
    		delete m_palDIB;
    	}
    然后重载C**Doc类的OnOpenDocument函数

    // TODO:  在此添加您专用的创建代码
    	CFile file;
    	if (!file.Open(lpszPathName,CFile::modeRead | CFile::shareDenyWrite))
    	{
    		//只读方式打开文件
    		return FALSE;
    	}
    	DeleteContents();//删除文档中数据,确保载入图像数据之前文档为空
    	m_hDIB = m_dib.LoadFile(file);
    
    	m_szPathName = lpszPathName;
    	if (m_hDIB == NULL)
    	{
    		return FALSE;
    	}
    	SetDib();
    	if (m_hDIB == NULL)
    	{
    		AfxMessageBox("读取图像时出错!");
    		return FALSE;
    	}
    	SetPathName(lpszPathName);//设置文件名称
    
    	return TRUE;
    其中setdib函数主要是在载入位图数据后创建调色板,具体代码如下

    void CImgProcessDoc::SetDib()
    {
    	LPSTR lpdib = (LPSTR) ::GlobalLock(m_hDIB);//保持图片数据内存一直有效
    	if (m_dib.GetWidth(lpdib) > INT_MAX ||m_dib.GetHeight(lpdib) > INT_MAX)// 判断图像是否过大
    	{
    		::GlobalUnlock((HGLOBAL) m_hDIB);				
    		::GlobalFree((HGLOBAL) m_hDIB);	// 释放DIB对象			
    		m_hDIB = NULL;// 设置DIB为空		
    		AfxMessageBox("初始化失败!"); 		
    		return;
    	}
    
    	m_sizeDoc = CSize((int)m_dib.GetWidth(lpdib), (int)m_dib.GetHeight(lpdib));// 设置文档大小	
    	::GlobalUnlock((HGLOBAL) m_hDIB);	
    	m_palDIB = new CPalette;// 创建新调色板		
    	if (m_palDIB == NULL)// 判断是否创建成功
    	{		
    		::GlobalFree((HGLOBAL) m_hDIB);	// 失败		
    		m_hDIB = NULL;// 设置DIB对象为空
    		return;
    	}	
    	// 调用CreateDIBPalette来创建调色板
    	if (m_dib.ConstructPalette(m_hDIB, m_palDIB) == NULL)
    	{				
    		delete m_palDIB;// 删除				
    		m_palDIB = NULL;// 设置为空	
    		return;// 返回空
    	}
    }
    这时候编译工程并运行,点击打开一个位图文件就可以将位图文件的信息和数据载入内存,但是打开之后并没有在客户区显示,这时候需要重载C**View类的OnDraw函数

    // TODO: 在此处为本机数据添加绘制代码
    	HGLOBAL hDIB = pDoc->GetHObject();
    
    	// 判断DIB是否为空
    	if (hDIB != NULL)
    	{
    		LPSTR lpDibSection = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
    
    		// 获取DIB宽度
    		int cxDIB = (int) pDoc->m_dib.GetWidth(lpDibSection);
    
    		// 获取DIB高度
    		int cyDIB = (int) pDoc->m_dib.GetHeight(lpDibSection);
    
    		::GlobalUnlock((HGLOBAL) hDIB);
    
    		CRect rcDIB;
    		rcDIB.top = rcDIB.left = 0;
    		rcDIB.right = cxDIB;
    		rcDIB.bottom = cyDIB;
    
    		CRect rcDest= rcDIB;	
    		// 输出DIB
    		pDoc->m_dib.DrawDib(pDC->m_hDC, &rcDest, pDoc->GetHObject(),
    			&rcDIB, pDoc->GetDocPal());
    	}
    编译工程并运行,就可以打开文件并显示到程序的客户区了。





    展开全文
  • <br />可以到这里下载源码:  http://download.csdn.net/source/1779188<br />P.S.:后面又添加了播放视频和捕获摄像头画面的功能,其中播放视频的功能只有 'Play' 和 'Stop',不能实现暂停,《A step-...
  • 基于MFC图像处理 2020-06-22 17:10:32
    用vc编程基于MFC图像处理。可以实现图片基本的处理。如二值化,放缩,平移,锐化……图像只能打开BMP格式的。
  • 数字图像处理作业用opencv + MFC图像处理界面设计与实现,点击按钮(Button)在Picture Control上显示处理前后的对比图像 // ImageprocessingDlg.cpp : 实现文件 // #include &quot;stdafx.h&quot; #...
  • 新建一个MFC工程,添加两个picture控件和一个按钮控件。 二、添加变量 1、为两个picture控件添加control变量,类型为CStatic,变量名分别为m_picture1和m_picture2. 2、添加保存图片路径和名称变量,CString类型,...
  • 最近想把以前过的数字图像处理实习写成一个教程,用的是CBmpFile类,武汉大学遥感信息工程学院的学生也许都会用这个类来实现图像处理,废话就不多说了,直接开始吧。。。  一、图像的显示  VC6.0工程向导创建MFC...
  • 主要详细介绍了BMP图片格式,同时使用C++和MFC显示BMP格式,主要结合自己的《数字图像处理》课程和以前的项目叙述讲解.一.BMP图片格式定义BMP文件格式是Windows操作系统推荐和支持的标准图像文件格式,是一种将内存或显...
  • MFC连续处理图像 2019-12-28 19:55:01
    问题背景:需要自动化的连续的处理500张图,一个一个地处理显然很幼稚,因此需要一个连续处理图像的函数。 CString m_strFileOut = _T(""); //初始化适应Unicode TCHAR szSelected[MAX_PATH];//用来存放文件夹...
  • 本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行讲解,主要通过MFC单文档视图实现显示BMP格式图片,并通过Bitmap进行灰度处理、图片采样和量化功能。...
  • 使用Windows编程进行各种图像图形的处理 内含全部源程序代码
  • OpenCV MFC 实现图像处理,在文档中直接进行图像处理,综合了边缘检测,Hough变换等等一些图像处理功能
  • 本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑、高斯平滑、不同算子的图像锐化知识...
  • MFC平台的图像处理 2020-07-06 16:27:38
    本次项目采用Opencv+MFC框架,通过对源代码的学习和借鉴,完成了对图像进行点处理、邻域处理、二值化、二值图像处理、形态学处理、彩色图像处理、综合处理、视频采集播放这些常用功能。
  • MFC图像处理 2020-06-03 23:32:19
    适合MFC 图像处理初学者,自己也是菜鸟级的。有基本的点运算
  • MFC实现opencv图像处理 2020-06-14 09:04:36
    使用MFC实现opencv中图像处理的部分函数功能: 实现的主要内容有主要包含有: 图像灰度化: 最大值灰度化: 单通道灰度化: 平均值灰度化: 加权平均灰度化: 图像缩放: 最近邻内插法: 双线性内插法: ...
  • 软件使用VC6.0+OpenCV+GDIPlus完成。   先看几张截图:   1、开始界面:     2、打开图片:     3、所有的菜单:     4、软件下载地址: ...另,不是我不讲人情,非特殊情况
  • 基于MFC图像处理和分析的基本算法的实现,是学习MFC编程和图像处理非常有用的代码,包括滤波,小波变换,图像分割,边缘检测以及霍夫变换等图像处理常用的技术
  • 本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行讲解,主要通过MFC单文档视图实现显示BMP图片空间几何变换,包括图像平移、图形旋转、图像反转倒置镜像和图像...
  • opencv+MFC图像处理程序 2020-06-03 23:32:55
    使用opncv2.49和VS2010,利用MFC框架图像处理软件
  • Opencv+MFC框架图像处理 2020-06-03 23:33:30
    本次项目采用Opencv+MFC框架,通过对源代码的学习和借鉴,完成了对图像进行点处理、邻域处理、二值化、二值图像处理、形态学处理、彩色图像处理、综合处理、视频采集播放这些常用功能。
1 2 3 4 5 ... 20
收藏数 14,696
精华内容 5,878