数字图像处理与机器视觉:Visual C++与Matlab实现(第2版)
上QQ阅读APP看书,第一时间看更新

2.4 DIPDemo工程

DIPDemo工程位于本书配套光盘中的根目录下的同名文件夹中,它是本书中涉及的所有Visual C++数字图像处理算法的一个综合测试平台。通过它读者可以方便地查看多幅图像,通过菜单命令处理图像并观察效果,还可以对同一幅图像处理前后的效果进行对比。本节主要介绍DIPDemo工程的界面、主要框架结构和一些最常用的基本功能,更多其他的内容将分散在本书后面各章节中随需要来阐述。

2.4.1 DIPDemo主界面

DIPDemo是一个基于多文档的Visual C++程序,运行后主界面如图2.2所示。

图2.2 DIPDemo程序主界面

通过菜单命令“文件→打开”,打开一幅或多幅图像后,将会出现如图2.3所示的程序界面,此时便可以通过相应处理菜单下的命令对当前选中的图像进行需要的处理。

图2.3 打开图像后的DIPDemo程序主界面

2.4.2 图像操作和处理类——CImg和CImgProcess

CImg和CImgProcess是DIPDemo中的两大核心类,它们肩负着几乎所有的图像操作和处理大任。2.3节已经对CImg类进行了比较全面的介绍,这里对其派生类CImgProcess做一个简要的说明。CImgProcess的类定义片断如下,可以看到其中封装了本书中将要出现的绝大部分图像处理算法,本书将在随后各章中给出这些算法的原理和实现。

      // CImgProcess封装了各种图像处理的标准算法
      class CImgProcess : public CImg
      {
      public:
            CImgProcess();
            virtual~CImgProcess();

            //***************第3章 图像的点运算*****************
            BOOL GenHist(double * hist, int n = 256); // 生成灰度直方图
            BOOL ParLinTran(CImgProcess * pTo, BYTE x1, BYTE x2, BYTE y1, BYTE y2); //分段线性
      变换
            BOOL LinTran(CImgProcess * pTo, double dFa, double dFb); //线性变换
            BOOL LogTran(CImgProcess * pTo, double C); //对数变换
            BOOL GammaTran(CImgProcess * pTo, double gamma, double comp=0); //伽玛变换
            BOOL WindowTran(CImgProcess * pTo, BYTE lowThre, BYTE highThre); //窗口变换
            BOOL Histeq(CImgProcess * pTo); //灰度均衡化
            BOOL Histst(CImgProcess * pTo, double* pdStdHist); //直方图规定化,直接匹配直方图
            BOOL Histst(CImgProcess * pTo, CImgProcess* pStd); //直方图规定化,匹配标准图像的直方图

            //***************第4章 图像的几何变换*****************
            void ImMove(CImgProcess* pTo, int x, int y); //图像平移
            void HorMirror(CImgProcess* pTo); //图像水平镜象
            void VerMirror(CImgProcess* pTo); //图像垂直镜象
            void Transpose(CImgProcess* pTo); //图像转置
            void Scale(CImgProcess* pTo, double times); //图像缩放
            void Rotate(CImgProcess* pTo, float ang); //图像旋转

            ……
            ……

      }; //class CImgProcess

2.4.3 文档类——CDIPDemoDoc

DIPDemo使用了文档和视图分离的结构,文档类中保存了两个CImgProcess类的实例m_Image和m_OImage,分别用于保存当前显示的前台图像和后台备份的图像;此外还提供了对图像读、写的有力支持,将在2.5节中随示例一起介绍。

以下是DIPDemoDoc类定义中的一段相关代码。

      ……
      public:
        // 对应的CImgProcess对象(前台显示)
        CImgProcess m_Image;
        // 对应的CImgProcess对象(后台备份)
        CImgProcess m_OImage;
      ……

提示

打开一幅图像并显示后,它就成为当前图像,在经过算法处理后,输出图像将成为前台图像显示出来,但此时原图像并没有被丢弃,而是将它保存在文档类的后台对象m_OImage中。用户可以使用文件菜单下面的“与后台图像交换”功能或工具栏中的按钮随时切换这两幅图像,对图像处理前后的效果进行对比。

2.4.4 视图类——CDIPDemoView

视图类提供了对全部图像处理菜单命令的响应功能、客户重绘功能,以及交换前、后台图像的功能。下面给出重绘事件OnDraw和前后台图像交换函数OnFileRotate的实现细节,在2.5节中将给出一个图像清空操作的视图类响应函数实例。

1.重绘事件的响应代码

      void CDIPDemoView::OnDraw(CDC* pDC)
      {
            // 显示等待光标
            BeginWaitCursor();

            // 获取文档
            CDIPDemoDoc* pDoc = GetDocument();
            ASSERT_VALID(pDoc);

            if(pDoc->m_Image.IsValidate())
            {
                CPalette* pOldPalette;
                CPalette* pPalette = pDoc->GetDocPalette();

                if(pPalette! =NULL)
                {
                      pOldPalette = pDC->SelectPalette(pPalette, FALSE);
                      pDC->RealizePalette(); //更新系统调色板
                }

                pDoc->m_Image.Draw(pDC); //绘制图像

                if(pPalette! =NULL)
                      pDC->SelectPalette(pOldPalette, FALSE);
            }
            // 恢复正常光标
            EndWaitCursor();
      }

每次客户区需要重绘时,OnDraw函数都会调用文档类中m_Image对象的Draw方法将m_Image对象绘制到pDC指定的平面上。

2.交换前、后台图像的响应代码

文件菜单下面的“与后台图像交换”功能的响应函数实现如下。

      void CDIPDemoView::OnFileRotate()
      {
            // 切换前、后台图像
            CDIPDemoDoc * pdoc = GetDocument();

            std::swap(pdoc->m_Image, pdoc->m_OImage); //交换前、后台图像

            pdoc->SetModifiedFlag(true);
            pdoc->UpdateAllViews(NULL);
      }