- UID
- 864567
|
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目录的路径、预编译宏和链接库等。
参考文献 |
|