Board logo

标题: 移植OpenCV库至eBox-II [打印本页]

作者: rise_ming    时间: 2013-1-11 23:53     标题: 移植OpenCV库至eBox-II

1.     背景简介
1.1 eBox-II简介
eBox-II采用Vortex86 System-On-Chip(SoC)设计和制造。Vortex86 的架构类似于兼容x86 的CEPC架构。eBox-II包括几乎所有桌面电脑的通用接口:VGA,PS/2 Keyboard,PS/2 Mouse,Ethernet, Parallel, Serial, USB, Audio input and output, Microphone input。eBox-II 内部设有支持嵌入式IDE flash 存储器或2.5 吋笔记本硬盘的IDE 设备接口。eBox-II内置AMI BIOS,使用Boot Loader支持DOS、Windows 98、WindowsXP、Windows XP Embedded 和Windows CE的启动。eBox-II 由ICOP Technology Inc.设计制造,更多信息访问公司网站:http://www.icoptech.com
1.2  OpenCV简介
OpenCV的全称是:Open Source Computer Vision Library。OpenCV于1999年由Intel建立,现在由Willow Garage提供支持。OpenCV是一个基于BSD许可证授权(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。最新版本是2.3。
2.     移植过程
2.1准备工作
      首先需要安装Visual Studio 2005,然后到OpenCV China的官方网站[1]下载OpenCV库1.0。由于OpenCV库十分庞大,而且像highgui这样的库与运行环境联系比较密切,移植起来有较大难度,所以我们只选择了其中的两个核心库cvcore和cv进行移植的尝试。
        完成上述工作后需要在VS2005中安装供ebox用的SDK,具体的安装方法见清华大学嵌入式系统课程的基础实验指导书,在此不作冗述。新的SDK安装完成后我们新建了一个编译静态库用的工程,开始对cxcore和cv库中的代码进行修改。
2.2修改代码
cxmisc.h,
line 125:
#elif defined WIN32 || defined WIN64 || defined WINCE

cxswitcher.cpp
line 57:
#if defined WIN32 || defined WIN64 || defined WINCE
line 90:
#if defined WIN32 && !defined  WIN64 && !defined WINCE
line 137:
#ifndef WINCE
           “HARDWARE//DESCRIPTION//SYSTEM//CentralProcessor//0//”,
#else
           L”HARDWARE//DESCRIPTION//SYSTEM//CentralProcessor//0//”,
#endif
line 140:
#ifndef WINCE
          “~MHz”,
#else
          L”~MHz”,
#endif
     line 435:
#ifdef WINCE
           size_t origsize = strlen(name) + 1;
           WCHAR wname[100];
           MultiByteToWideChar(CP_ACP,0,name,origsize,wname,100);
             addr = (uchar*)GetProcAddress( plugins[idx].handle, wname );
#else
             addr = (uchar*)GetProcAddress( plugins[idx].handle, name );
#endif
line 600: ......修改方法同line 435

cxerror.cpp
line 45:
#if defined WIN32 || defined WIN64 || defined WINCE
line 92 加入
#define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
line with DllMain to
#if defined WIN32 || defined WIN64
BOOL WINAPI DllMain(
#ifdef WINCE
  HANDLE
#else
  HINSTANCE
#endif
  , DWORD  fdwReason, LPVOID )

a fragment in cvGuiBoxReport to
        sprintf( message, “%s (%s)/nin function %s, %s(%d)/n/n”
                  “Press /”Abort/” to terminate application./n”
                  “Press /”Retry/” to debug (if the app is running under debugger)./n”
                  “Press /”Ignore/” to continue (this is not safe)./n”,
                  cvErrorStr(code), err_msg ? err_msg : “no description”,
                  func_name, file, line );
        sprintf( title, “OpenCV GUI Error Handler” );
#ifdef WINCE
        WCHAR wmsg[2048];
        MultiByteToWideChar(CP_ACP,0,title,strlen(message),wmsg,2048);
        int answer = MessageBox( NULL, wmsg, L”OpenCV GUI Error Handler”,
MB_ICONERROR|MB_ABORTRETRYIGNORE);
#else
        int answer = MessageBox( NULL, message, title,
MB_ICONERROR|MB_ABORTRETRYIGNORE|MB_SYSTEMMODAL );
#endif

cvtypes.h的#include <emmintrin.h>的宏定义改为:
  #if defined WIN32 && (!defined WIN64 || defined EM64T) &&(!defined WINCE)&& /
      (_MSC_VER >= 1400 || defined CV_ICC) /
      || (defined __SSE2__ && defined __GNUC__ && __GNUC__ >= 4)

    _cvkdtree.hpp的accum_type maxvar = -std::numeric_limits < accum_type >::max(); 加上#undef max

    对于错误131 error LNK2001: 无法解析的外部符号 "const type_info::`vftable'" ([email=??_7type_info@@6B]??_7type_info@@6B[/email]@)  cvsmooth.obj.
引入Ccrtrtti.lib解决
2.3重新编译
在Soution Platforms中选择之前新安装的SDK :eBox2300_WinCE600_SDK(x86),如果不存在则点选Configuration Manager,在Active solution platform下拉列表中选择<New ..>新建一个eBox2300_WinCE600_SDK(x86),Copy settings from Win32就可以。另外还需要设置为Debug模式。
注意要先编译cvcore工程再编译cv工程,因为cv工程中有对cvcore生成的依赖。
最后我们可以得到cvcored.lib,cvd.lib两个供Debug模式用的静态库。
3.     测试
       由于highgui移植难度较高,我们并没有成功完成移植,但是highgui里面涵盖了Opencv库的图形界面功能,所以导致无法写出输入输出比较直观的测试程序。在这里我们选择编写一个Laplace变换的测试程序,使用了cv和cvcore里提供的API。
         为了完成测试,首先我们在vs2005中新建一个空项目opencvTest,添加新的源文件opencvTest.cpp。选择Tools>Options>Projects and Solutions>VC++ Directories,添加你编译完成的库的include目录和lib目录到eBox2300的Platform。
         然后打开工程属性,Configuration Properties>C/C++>Preprocessor,将Preprocessor Definitions改成_WIN32_WCE。另外,在Linker>Input中,将Additonal Dependencies改为cvcored.lib cvd.lib。
        编译工程后,拷贝生成的exe文件到ebox中运行得到计算结果,经手工验算后可知Laplace变换是正确的。下面给出opencvTest.cpp的源代码。

#include <stdlib.h>
#include <cv.h>
#include <cvcore.h>

int main(){
    IplImage* pimg = cvCreateImage(cvSize(10,10),IPL_DEPTH_32F,3);
    IplImage* pimg1 = cvCreateImage(cvSize(10,10),IPL_DEPTH_32F,3);
    printf("input array:\n");
    for(int i=0;i<10;i++)
    {
       for(int j=0;j<10;j++)
       {
             CvScalar s;

             s.val[0]=i+2*j;        
             s.val[1]=0;
             s.val[2]=0;
            printf("%d ",i+2*j);















cvSet2D(pimg,i,j,s);//set the (i,j) pixel value
       }
       printf("\n");
    }
    printf("\n");
    printf("output array:\n");
    cvLaplace( pimg, pimg1,3 );
    for(int i=0;i<10;i++)
    {
       for(int j=0;j<10;j++)
       {
             CvScalar s;
             s=cvGet2D(pimg1,i,j); // get the (i,j) pixel value
            printf("%f ",s.val[0]);
       }


printf("\n");
    }
     printf("\n");
     system("pause");
    return 0;
}















4.     总结
本文介绍了如何抑制OpenCV的两个核心库cvcore和cv至ebox/wince平台上,移植的关键是宏定义部分和字符编码部分,代码修改也基本是围绕这两点进行的。目前移植得到的版本是静态库,这是出于程序运行的方便性考虑的。如果改为动态库应用程序可以轻量化,但是同时也需要在ebox上做额外的配置。在使用我们编译出来的库时请注意设置好include和lib目录的路径、预编译宏和链接库等。
参考文献




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0