天天看點

移植EMCV到DM6467(1)——C++工程測試1        在CCS中建立工程2        修改EMCV源檔案3        編寫測試程式4        測試結果分析

EMCV全稱為EmbeddedComputer Vision Library,是一個可在TI DM64x系列DSP上運作的計算機視覺庫。EMCV提供了跟OpenCV完全一緻的函數接口,通過EMCV,可以輕松地将原有的OpenCV算法移植到DSP,甚至不用改一行代碼。

目前EMCV已經支援IplImage,CvMat,CvSeq等基本資料結構,可使用cvCreateImage等建立和釋放圖像,以及contour檢測等。

考慮到OpenCV的複雜性,我們選用EMCV來替代OpenCV在DM6467上進行移植,在移植成功之後,如果需要使用某種圖像處理功能,隻需要将相關函數從OpenCV源代碼中移植到EMCV即可,非常友善。

1        在CCS中建立工程

1,下載下傳EMCV源碼。要建立調用EMCV算法的DSP工程,首先需要下載下傳EMCV源碼,下載下傳位址為https://emcv.svn.sourceforge.net/svnroot/emcv/,由于源碼使用SVN進行管理,是以需要使用SVN工具進行下載下傳,我選用的是TortoiseSVN,依照網絡上的教程進行checkout,成功将EMCV源碼下載下傳到本地。

2,建立工程。建立TMS320C6++系列DSP的工程,選擇out模式。

3,添加源檔案。将emcv源碼複制到建立工程的同級目錄,例如我的DSP路徑位于D:\OpenCV\projects,則将emcv源碼複制到該目錄下。由于暫時隻使用emcv的cv和cxcore兩部分,是以複制時可以隻選擇這兩個檔案夾。複制完畢之後,将cv和cxcore目錄下所有的.cpp檔案全部添加到工程中。然後,将C:\CCStudio_v3.3\C6000\cgtolls\lib\rts64plus.lib這個庫檔案添加到工程。

移植EMCV到DM6467(1)——C++工程測試1        在CCS中建立工程2        修改EMCV源檔案3        編寫測試程式4        測試結果分析

4,修改編譯選項。首先需要設定預處理時頭檔案的搜尋路徑,也即在compiler指令中添加-i"..\emcv\cv" -i"..\emcv\cxcore”。然後,在linker指令中添加 --no_sym_merge,如果不添加會編譯出錯。

5,編寫cmd檔案。接下來需要編寫cmd檔案配置設定存儲區域,考慮到EMCV函數很占用記憶體,是以将各個段都放在DDR2上面。另外,需要特别注意stack和heap的大小設定,如果設定得太小,程式在運作時空間不夠很可能發生無法預料的結果,是以這裡設定stack大小為0x00020000,heap大小為0x00800000,最終的linker.cmd檔案如下所示。

-heap                           0x00800000     

-stack                          0x00020000      

MEMORY

{

    VECS:       o = 0x00000000  l = 0x00000080

    IRAM:       o = 0x00000080  l = 0x00007f80 

    DRAM:       o = 0x00010000  l = 0x00008000 

    DDR2:       o = 0x80000000  l = 0x08000000 

}

SECTIONS

{

    .bss        >   DDR2

    .cinit      >   DDR2

    .cio        >   DDR2

    .const      >   DDR2

    .stack      >   DDR2

         .far            >       DDR2

         .switch              >       DDR2

         .tables               >       DDR2

    .sysmem     >   DDR2

    .text       >   DDR2

    .ddr2       >   DDR2

}

2        修改EMCV源檔案

由于EMCV中的源檔案是以C++格式編寫,很多地方與C不相容,在CCS中編譯時有些代碼無法編譯通過、或者即使編譯通過也無法運作,是以,需要修改EMCV中的一些檔案。到現在為止已經修改過的包括以下幾處。

1,cxmisc.h第259行

CV_INLINE  CvSize  cvGetMatSize( const CvMat* mat )

{

    CvSize size = { mat->width, mat->height };

    return size;

}

修改為

CV_INLINE  CvSize  cvGetMatSize( const CvMat* mat )

{

    //CvSize size = { mat->width, mat->height };

         CvSize size;

         size.width = mat->cols;

         size.height = mat->rows;

    return size;

}

2,cxmisc.h第247行

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) );

}

3,cxtypes.h第211行

CV_INLINE  int  cvRound( double value )

{

    if(value >= 0.0)

    {

        return int(floor(value + 0.5));

    }

    return int(ceil(value - 0.5));

}

CV_INLINE  int  cvFloor( double value )

{

         return int(floor(value));

}

CV_INLINE  int  cvCeil( double value )

{

         return int(ceil(value));

}

修改為

CV_INLINE  int  cvRound( double value )

{

         int a;

    if(value >= 0.0)

    {

        //return int(floor(value + 0.5));

                   a = floor(value + 0.5);

                   return a;

    }

    //return int(ceil(value - 0.5));

         a = ceil(value - 0.5);

         return a;

}

CV_INLINE  int  cvFloor( double value )

{

         //return int(floor(value));

         int a = floor(value);

         return a;

}

CV_INLINE  int  cvCeil( double value )

{

         //return int(ceil(value));

         int a = ceil(value);

         return a;

}

4,cxarray.cpp

将該檔案中所有出現if(!CvIPL.createHeader )的代碼按如下格式修改(紅色部分為添加的注釋符)。

        CV_CALL( img = (IplImage *)cvAlloc( sizeof( *img )));

        CV_CALL( cvInitImageHeader( img, size, depth, channels, IPL_ORIGIN_TL,

                                    CV_DEFAULT_IMAGE_ROW_ALIGN ));

到現在為止,修改的地方還很少,因為大部分函數都還沒有用到,後面如果想要使用OpenCV的其他功能時很可能還需要大量修改代碼。

3        編寫測試程式

修改完EMCV源碼之後,需要編寫測試程式進行測試。這裡編寫的程式隻完成幾個很簡單的任務:建立圖像,在其中添加一個矩形框,釋放圖像。雖然程式很簡單,但是它也包含了一部分OpenCV的基礎資料結構,包括CvPoint,CvScalar,CvSize和IplImage,以及幾個基本的函數,包括cvCreateImage,cvRectangle和cvReleaseImage。如果這些代碼能夠運作,那麼表明EMCV移植到DSP上的工作初步完成了。最終的程式代碼如下所示。

#include <stdio.h>

#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\n", *(img->imageData), *(img->imageData + 1), *(img->imageData + 2));

         cvRectangle(img, point1, point2, color, CV_AA, 0);

         printf("%d %d %d\n", *(img->imageData), *(img->imageData + 1), *(img->imageData + 2));

         cvReleaseImage(&img);

         return 0;

}

4        測試結果分析

對于編寫的測試程式可以現在VS2010中進行測試,如果運作無誤再移植到DSP。

将測試程式添加進工程,編譯通過之後下載下傳到開發闆運作,最終輸出結果如下所示。其中第一行為建立圖像的第一個像素點的BGR三個分量值,第二行為将第一個像素點置為綠色之後的值,0 -1 0表示的是BGR(0, 255, 0),也即綠色,表明程式運作無誤,EMCV在DSP上的移植取得初步成功。

移植EMCV到DM6467(1)——C++工程測試1        在CCS中建立工程2        修改EMCV源檔案3        編寫測試程式4        測試結果分析