在DSP_6748上移植OpenCV EMCV全称为EmbeddedComputer Vision Library,是一个可在TI C6000系列DSP上运行的计算机视觉库。EMCV提供了跟OpenCV完全一致的函数接口,通过EMCV,你可以轻松的将你的OpenCV算法移植到DSP,甚至不用改一行代码。目前EMCV已经支持IplImage,CvMat,CvSeq等基本数据结构,可使用cvCreateImage等创建和释放图像,以及contour检测等。1、在以建好的CCS工程中添加相关文件①、下载EMCV源码,②、分组添加源文件:将emcv源码复制到工程目录下。建立两个文件夹:src和include,将原OpenCV中的cv和cxcore的h文件全部拷贝到include文件中,将原OpenCV中cv和cxcore的cpp文件全部拷贝到src目录下。注:DSP上不需要HighGUI模块。③、添加头文件和CPP文件到工程中。2、修改EMCV源文件(也就是处理一些移植错误)
我总结一下错误 一共我遇到的有四处:问题一、在cxmisc.h的第 233行 编译器对c语言标准的支持不同造成的。出现这个错误 error: expression must have a constant valueCvSize cvGetMatSize(const CvMat* mat)
{
CvSize size = {mat->width,mat->height}; return size;
} CV_INLINE CvSize cvGetMatSize( const CvMat* mat ) { CvSize size = cvSize( mat->cols, mat->rows ); return size; } CvMat在C语言中只定义了为rows和cols,采用rows和cols访问应该是最好的。
问题二、在cxtypes.h的第192行 出现这个错误 error: expected an expressionCV_INLINE int cvFloor( double value )
{
return int(floor(value));} CV_INLINE int cvFloor( double value )
{
int a = floor(value); return a;
} 问题三、在cxmisc.h中 line 219函数名那块是 219行出现了个这样的错误error: expected a ")",CV_INLINE void* cvAlignPtr( const void* ptr, int align=32)
{
assert( (align & (align-1)) == 0 );
return (void*)(((size_t)ptr + align - 1) & (~(size_t)(align-1)) );
} CV_INLINE void* cvAlignPtr( const void* ptr, int align CV_DEFAULT(32)) { //assert( (align & (align-1)) == 0 ); return (void*)( ((size_t)ptr + align - 1) & ~(size_t)(align-1) ); } CV_INLINE int cvAlign( int size, int align ) { // assert( (align & (align-1)) == 0 && size < INT_MAX ); return (size + align - 1) & -align; } //把那个 align 的缺省值删掉就正确了。 问题四、有些EMCV里会有重复定义的函数,去掉就OK//typedef CvStatus (CV_STDCALL *CvFunc2DnC_1A1P)( void* arr, int step, CvSize size, // int cn, int coi, void* param ); //typedef CvStatus (CV_STDCALL *CvFunc2DnC_2A1P)( void* arr0, int step0, // void* arr1, int step1, // CvSize size, int cn, // int coi, void* param ); 3、编写cmd文件
接下来需要编写cmd文件分配存储区域,考虑到EMCV函数很占用内存,所以将各个段都放在DDR2上面。另外,需要特别注意stack和heap的大小设置,如果设置得太小,程序在运行时空间不够很可能发生无法预料的结果,所以这里设置stack大小为0x00020000,heap大小为0x00800000,最终的linker.cmd文件-heap 0x00800000
/* Stack Size */ -stack 0x00020000
/* Heap Size */ MEMORY { VECS: o = 0x00000000 l = 0x00000080 IRAM: o = 0x00000080 l = 0x00007f80 /* 32 kBytes */
DRAM: o = 0x00010000 l = 0x00008000 /* 32 kBytes */
/*DDR2: o = 0x80000000 l = 0x10000000*//* 256 MBytes */
DDR2: o = 0x80000000 l = 0x08000000 /* 128 MBytes */ } SECTIONS { .bss > DDR2
.cinit > DDR2
.cio > DDR2
.const > DDR2
.stack > DDR2
.far > DDR2
.switch > DDR2
.tables > DDR2
.sysmem > DDR2
.text > DDR2
.ddr2 > DDR2
} 4、在CCS环境下编写测试程序
修改完EMCV源码之后,需要编写测试程序进行测试。这里编写的程序只完成几个很简单的任务:创建图像,在其中添加一个矩形框,释放图像。虽然程序很简单,但是它也包含了一部分OpenCV的基础数据结构,包括CvPoint,CvScalar,CvSize和IplImage,以及几个基本的函数,包括cvCreateImage,cvRectangle和cvReleaseImage。如果这些代码能够运行,那么表明EMCV移植到DSP上的工作初步完成了。最终的程序代码如下所示。
#include #include "cv.h" int main() { CvPoint point1, point2; point1.x = 0; point1.y = 0; point2.x = 10; point2.y = 10; CvScalar color = CV_RGB(0, 255, 0); CvSize size; size.height = 40; size.width = 40; IplImage* img; img = cvCreateImage(size, IPL_DEPTH_8U, 3); printf("%d %d %d
", *(img->imageData), *(img->imageData + 1), *(img->imageData + 2)); cvRectangle(img, point1, point2, color, CV_AA, 0,0); printf("%d %d %d
", *(img->imageData), *(img->imageData + 1), *(img->imageData + 2)); cvReleaseImage(&img); return 0; } 5、测试结果分析
对于编写的测试程序可以在VS2010中进行测试,如果运行无误再移植到DSP。将测试程序添加进工程,编译通过之后下载到开发板运行,最终输出结果如下所示。其中第一行为创建图像的第一个像素点的BGR三个分量值,第二行为将第一个像素点置为绿 {MOD}之后的值,0 -1 0表示的是BGR(0, 255, 0),也即绿 {MOD},表明程序运行无误,EMCV在DSP上的移植取得初步成功。