posts - 112, comments - 215, trackbacks - 0, articles - 34
  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

一、引言
   Visual C++ 是一种可视化编程语言。它集成了功能强大的编辑器、编译器、链接器、调试器、 App Wizard Class Wiz? ard AppStudio 等多种多样的可视化编程工具,利用它可以完成各种应用程序的开发。此外 Visual C++ 语言与其它高级语言相比有很高的代码执行效率。但是在编写例如数字图像处理方面的程序时就需要比较复杂的算法,编写得不好就会影响程序的运行速度。
   Matlab 是一种高性能的数值计算和可视化编程软件,在数值分析、信号处理、系统辨识、特殊函数和图形处理等方面具有广泛的应用。它将数值计算与图形可视化功能完美结合,具有开放的设计理念,提供了多个与外部程序的接口,而且提供多个面向不同领域扩展的工具箱支持,这些都使得 Matlab 在许多学科领域中成为计算机辅助设计与分析、算法研究和应用开发的基本工具和首选平台。特别是 Matlab 在图像处理方面更具有明显的优势。它支持多达 15 种不同格式的图像文件;具有强大的矩阵运算功能,在进行一些简单的图像变换时可以避免很多繁琐的计算;图形显示方便,甚至在调试过程中也能随时观察图形的变化;带有丰富的图像处理函数库。
  由上可见,如果把 Matlab Visual C++ 在图像处理的应用中结合起来,将会大大提高编程效率。本文通过在 Visual C++ 中调用 Matlab 引擎的方法进行图像处理混合编程,这样既方便了调用 Matlab 工具箱中的图像处理函数,又精简了源程序代码,还保留了 Visual C++ 面向对象及可视化等 Win? dows 程序风格和快速处理数据的能力。
  二、 Visual C++ Matlab 混合编程环境
  (一) Matlab 引擎
   Matlab 引擎采用客户机 / 服务器( C/S )计算模式。实际应用过程中,用户编写的高级语言的程序作为前端客户机程序, Matlab 引擎接收它传来的数据信息,并给引擎传递执行命令所需要的信息。
   Matlab engine 提供了一组 Matlab API 函数( Application Program Interface ),我们通过一种专门的对象类型 ———Matlab 数组 (mxArray) 来完成 Matlab 引擎与 Visual C++ 之间的数据交换。我们不必关心 Matlab Engine 是如何实现的,只要调用这些 API 函数即可。
  下面是几个常用的 Matlab API 函数:
      1
EngOpen :打开 / 开启 Matlab 引擎;
      2
Engclose :关闭 Matlab 引擎;
      3
EngGetArray :从 Matlab engine 中获得一个 Matlab 矩阵,用于数据交换
      4
EngEvalString :在 Matlab 引擎中执行输入的 Matlab 命令;
   5 EngPutVariable :从应用程序向 Matlab 引擎发送一个 Matlab 矩阵( mxArray 类型),用于数据交换;
      6
EngOutputBuffer :创建字符缓冲区以获取 Matlab 文本输出
  (二) Matlab Visual C++ 混合编程环境
  操作系统: Windows XP
  软件环境: Visual C++6.0 中文版
Matlab7.0
  工程属性设置:

      1.
Visual C++ 环境下新建一个基于对话框的 MFC EXE )类型的工程
      2.
设置工程属性在工具栏的 工程 菜单中选择 设置 子菜单,然后:
  ( 1 )在 “C/C++” 标签下的 分类 下拉列表框中选择 预处理器 ,在 附加包含路径 文本框中加入 Matlab 软件的 “in? clude” 文件夹安装路径。
  ( 2 )在 连接 标签下的 分类 下拉列表框里选择 常规 选项,在 对象 / 库模块 文本框里添加 Matlab 库文件 libeng.lib libmx.lib libmat.lib matlab.lib
  ( 3 )在 连接 标签下的 分类 下拉列表框里选择 输入 选项,在 附加库路径 文本框里面添加以上四个库文件所在文件夹的路径。
  ( 4 )若用的是旧版本的 Matlab ,且没有自带以上所需的库文件,则需要将 Matlab 软件的 libeng.def libmx.def 等文件生成相应的库文件。
  三、 Visual C++ Matlab 混合编程方法
  在 Visual C++ 中新建一个 MFC AppWizard(EXE) 类型的工程,命名为 mypro Visual C++ 为这种类型的工程提供了 单文档 多文档 基于对话框 等三种不同的界面,我们选择 基于对话框 这一选项,并以图像的边缘提取处理为例,来说明 Visual C++ Matlab 混合编程处理图像的方法。建立好的对话框界面如图 1 所示。在 确定 按钮的响应函数中添加如下代码:
   Void CmyproDlg::OnOK()
  {/*Cstring MFC 工程中特有的数据类型定义 name suanzi 两变量用来接收对话框传来的数据
*/
   CString name

   CString suanzi
   UpdateData(true) // 将数据存入前面所定义的变量中
   name=pic_name // 存入图像文件名
suanzi=pic_suanzi;//
存入边缘提取算子
   /*name,suanzi Visual C++ 中的 Cstring 型变量,而 Mat? lab 引擎使用的变量是 Char 型,所以要转化 */
  
char name1[20] = {0};
  
char suanzi1[20] = {0};
  
char szTemp[100] = {0};
  
for(int i=0;i<=name.GetLength()-1;i++){name1[i]=name.GetAt(i);}
   name1[i]='\0';// 添加字符串结束符

for(int j=0;j<=suanzi.GetLength()-1;j++){suanzi1[j]=suanzi.GetAt(j);}
   suanzi1[j]='\0';
   Engine *ep; // 创建 Matlab 引擎指针

   if(!(ep=engOpen(NULL)))
  
{fprintf(stderr,"\nCan not start  Matlab engine\n");
     return;
   }// 判断引擎是否成功打开

   mxArray *t=NULL; //Matlab 引擎中用的是 mxArray 型的数据
   mxArray *s=NULL;
   t=mxCreateString(name1);// 建立 MATLAB 字符串数组

   s=mxCreateString(suanzi1);
   engPutVariable(ep,"t",t); // 把数组放到 Matlab 工作区

engPutVariable(ep,"s",s);                                  
       strcpy(szTemp,"l=imread('");
   strcat(szTemp,name1);
  
strcat(szTemp,"');");
   engEvalString(ep,szTemp);// 变成灰度图

   engEvalString(ep,"k=rgb2gray(l);");
   engEvalString (ep,"imshow(k);");// 显示灰度图

   strcpy(szTemp,"bw=edge(k,'");
   strcat(SzTemp,suanzi1); // 边缘提取

   strcat(szTemp,"');");
  
engEvalString(ep,szTemp);
  
engEvalString(ep,"figure;");
   engEvalString(ep,"imshow(bw);");// 显示边缘提取后的图像

   mxDestroyArray(t); // 释放数组内存
   mxDestroyArray(s);
   engClose(ep);// 关闭引擎

   }
  注意:在添加以上代码前,首先在该对话框源文件 (CmyproDlg.cpp) 的开头部分引入 Matlab 的两个头文件:

      #include “engine.h”
     
#include “matrix.h”
     
然后编译并执行 chuangkou 工程。在图 1 所显示的对话框中输入图像文件和边缘提取算子 , 然后点击 确定 按钮,原图像如图 2 所示,程序执行后显示的灰度图如图 3 所示,显示的边缘提取后的图像如图 4
所示。
  四、应用实例
  某广告公司欲制作一喷有中国地图的大型广告牌,如图 2 所示。在采用计算机自动完成广告牌总制造费用的计算过程中,因单位面积喷绘费用随颜料不同而有所差别,故需首先计算相同颜色不同省份的总面积,再计算出每种颜料总面积进而求出其单项总费用后,那么就可以方便地求出整个地图的总喷绘费用。在这一过程中,我们采用 VC++ Matlab 混合编程的方法,求出了地图的边缘提取后的图像,如图 4 所示,得出了各个省份的轮廓曲线,再求出每一块的面积,然后就可以计算广告牌的喷绘费用了。
  结果表明,在图像处理过程中使用 Visual C++ 调用 MatLAB 引擎的方法,大大地简化了图像处理的各种操作。此外,本例是采用对图像的边缘提取处理来说明这种混合编程的。然而实际应用过程中, Matlab Visual C++ 混合编程的应用范围要更加广泛。例如,我们可以通过调用 Matlab 图像处理工具箱中的 wiener2 函数在 Visual C++ 中对图像进行二维适应性去噪过滤处理,还可以调用 Matlab 图像处理工具箱中的 subimage 函数在 Visual C++ 中实现在一幅图像中显示多个图像的操作,或者调用 imwrite 函数把图像写入图形文件,等等。此外, Matlab 图像显示工具提供了对所显示的图像的一系列操作,如打印、保存等,方便了用户对处理结果的操作。
  五、结语
  通过调用 Matlab 引擎,在 Visual C++ 中很方便地实现了对图像的处理操作。由于 Matlab 的图形图像工具箱提供了功能强大的图形图像处理函数 , 通过在 Visual C++ 中调用它们可以很方便而且高效地处理图像。这种混合编程的方法具有很强的实用性。

【参考文献】
   [1] 罗军辉,冯平,哈力旦 A MATLAB 7.0 在图像处理中的应用 [M] .北京:机械工业出版社, 2005
      [2]
阮沈勇. MATLAB 程序设计 [M] .北京:电子工业出版社, 2004
   [3] 郝文化,田蕾,董秀芳. MATLAB 图形图像处理应用教程 [M] .北京:中国水利水电出版社, 2004
   [4] 网冠科技. Visual C++ 6.0 MFC 时尚编程百例 [M] .北京:机械工业出版社, 2004

只有注册用户登录后才能发表评论。