共8条
1/1 1 跳转至页
opencv移植到DSP的过程
首先我们了解一下如何使用emcv,emcv是OpenCV针对C6000系列DSP的移植版本,目前只完成了我们工作中用到的部分。
下面对如何使用emcv做个简单的介绍:
1. 找到一个可用的demo
我们使用的是video_loopback例子,这个程序中DSP只是简单地将摄像头采集到的图像
显示出来。显示的过程是将采集帧缓冲的数据复制到显示帧缓冲中。
2. 将demo工程改为C++工程
简单的说,就是将工程中所有的*.c文件改为*.cpp文件。
因为C++基本兼容C,所以在cpp中还可以按照C语言的方式来开发。
如果开发板带的demo写的够规范,从C迁移到C++应该不会有任何问题。
不过实际的代码可能会出现一点。以videoloopback为例,在将工程改为C++之后
出现了15个错误:
代码: ---------------------- seedvpm642_vedioloop.pjt - LOOP2 ----------------------
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../LOOP2.lkf" "appData.cpp"
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../LOOP2.lkf" "boot.asm"
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../LOOP2.lkf" "seedvpm642main.cpp"
"C:/work/test/video_loopback/include/edc.h", line 48: error: expected a declaration
"seedvpm642main.cpp", line 41: warning: return type "int" omitted in declaration of function "main"
1 error detected in the compilation of "seedvpm642main.cpp".
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../../LOOP2.lkf" "seedvpm642_vcapparamsPAL_EMBEDDED.cpp"
"C:/work/test/video_loopback/include/edc.h", line 48: error: expected a declaration
"C:/work/test/video_loopback/include/tvp51xx.h", line 43: error: identifier "TVP51XX_Mode" is undefined
"C:/work/test/video_loopback/include/tvp51xx.h", line 44: error: identifier "TVP51XX_AnalogFormat" is undefined
"seedvpm642_vcapparamsPAL_EMBEDDED.cpp", line 71: error: identifier "TVP51XX_MODE_PAL601" is undefined
"seedvpm642_vcapparamsPAL_EMBEDDED.cpp", line 72: error: identifier "TVP51XX_AFMT_COMPOSITE" is undefined
At end of source: error: expected a "}"
6 errors detected in the compilation of "seedvpm642_vcapparamsPAL_EMBEDDED.cpp".
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../../LOOP2.lkf" "seedvpm642_vdisparamsPAL.cpp"
"C:/work/test/video_loopback/include/edc.h", line 48: error: expected a declaration
"seedvpm642_vdisparamsPAL.cpp", line 109: error: a value of type "void *" cannot be used to initialize an entity of type "EDC_Fxns *"
"seedvpm642_vdisparamsPAL.cpp", line 118: error: a value of type "void *" cannot be used to initialize an entity of type "I2C_Handle"
At end of source: error: expected a "}"
4 errors detected in the compilation of "seedvpm642_vdisparamsPAL.cpp".
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../LOOP2.lkf" "tskloopback.cpp"
"C:/work/test/video_loopback/include/edc.h", line 48: error: expected a declaration
At end of source: error: expected a "}"
2 errors detected in the compilation of "tskloopback.cpp".
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../LOOP2.lkf" "tskvideocapturevp1.cpp"
"C:/work/test/video_loopback/include/edc.h", line 48: error: expected a declaration
At end of source: error: expected a "}"
2 errors detected in the compilation of "tskvideocapturevp1.cpp".
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"LOOP2.lkf" "seedvpm642cfg.s62"
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"LOOP2.lkf" "seedvpm642cfg_c.c"
Build Complete,
15 Errors, 1 Warnings, 0 Remarks.
错误虽然感觉很多,其实只有简单的几类。首先看看第一个错误:
代码: "C:/work/test/video_loopback/include/edc.h", line 48: error: expected a declaration
找到对应的代码:
代码: // edc.h
#ifdef __cplusplus
{
#endif
#endif /* _EDC_H */
这是一个简单的笔误,作者将'}'误写为'{'了。C++中函数正规的写法是:
代码: #ifndef _EDC_H
#define _EDC_H
#ifdef __cplusplus
extern "C" {
#endif
// 这是C++实现的函数
// 但是C语言中也可以使用
// 对应汇编过程名字为 _cpp_fun,和C语言的编译规则一直
void cpp_fun();
#ifdef __cplusplus
}
#endif
#endif /* _EDC_H */
添加extern "C" {语句的原因是,C++中由于支持函数重载,一个函数的名字可能有几个;
在编译到汇编的时候,这些函数可能被重新命名(不是简单的在开头添加下划线'_'),
这样C语言或汇编在链接由C++实现的函数的时候就会找不到具体位置。
关键词: opencv 移植 过程 video loopba
将第一个错误修改之后重新编译,现在只有2个错误:
代码: ---------------------- seedvpm642_vedioloop.pjt - LOOP2 ----------------------
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../LOOP2.lkf" "seedvpm642main.cpp"
"seedvpm642main.cpp", line 41: warning: return type "int" omitted in declaration of function "main"
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../../LOOP2.lkf" "seedvpm642_vcapparamsPAL_EMBEDDED.cpp"
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../../LOOP2.lkf" "seedvpm642_vdisparamsPAL.cpp"
"seedvpm642_vdisparamsPAL.cpp", line 109: error: a value of type "void *" cannot be used to initialize an entity of type "EDC_Fxns *"
"seedvpm642_vdisparamsPAL.cpp", line 118: error: a value of type "void *" cannot be used to initialize an entity of type "I2C_Handle"
2 errors detected in the compilation of "seedvpm642_vdisparamsPAL.cpp".
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../LOOP2.lkf" "tskloopback.cpp"
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../LOOP2.lkf" "tskvideocapturevp1.cpp"
Build Complete,
2 Errors, 1 Warnings, 0 Remarks.
将第一个错误修改之后重新编译,现在只有2个错误:
代码: ---------------------- seedvpm642_vedioloop.pjt - LOOP2 ----------------------
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../LOOP2.lkf" "seedvpm642main.cpp"
"seedvpm642main.cpp", line 41: warning: return type "int" omitted in declaration of function "main"
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../../LOOP2.lkf" "seedvpm642_vcapparamsPAL_EMBEDDED.cpp"
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../../LOOP2.lkf" "seedvpm642_vdisparamsPAL.cpp"
"seedvpm642_vdisparamsPAL.cpp", line 109: error: a value of type "void *" cannot be used to initialize an entity of type "EDC_Fxns *"
"seedvpm642_vdisparamsPAL.cpp", line 118: error: a value of type "void *" cannot be used to initialize an entity of type "I2C_Handle"
2 errors detected in the compilation of "seedvpm642_vdisparamsPAL.cpp".
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../LOOP2.lkf" "tskloopback.cpp"
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../LOOP2.lkf" "tskvideocapturevp1.cpp"
Build Complete,
2 Errors, 1 Warnings, 0 Remarks.
找到出现错误的代码(2个错误在一起):
代码: VPORT_PortParams EVMDM642_vDisParamsPort = {
FALSE, /* enableDualChan; */
VPORT_POLARITY_ACTIVE_HIGH, /* vport control pin 1 polarity */
VPORT_POLARITY_ACTIVE_HIGH, /* vport control pin 2 polarity */
VPORT_POLARITY_ACTIVE_HIGH, /* vport control pin 3 polarity */
&SAA7105_Fxns,
INV,
};
SAA7105_ConfParams EVMDM642_vDisParamsSAA7105 = {
SAA7105_AFMT_SVIDEO,
SAA7105_MODE_PAL720,
SAA7105_IFMT_YCBCR422_INTERLACED,
TRUE,
TRUE,
INV, /*handleI2C */
};
都是提示类型不匹配。这个错误的产生原因是C++编译器对类型的检测更加严格。
在C语言中void*指针可能方便的和其他指针转换,但是C++中可能需要手工强制转换。
INV的定义可能和NULL类似,是一个无效值:
代码: csl_stdinc.h(39): #define INV ((void*)(-1))
我们将INV增加一个强制类型转换来遍面编译器的错误:
代码: VPORT_PortParams EVMDM642_vDisParamsPort = {
FALSE, /* enableDualChan; */
VPORT_POLARITY_ACTIVE_HIGH, /* vport control pin 1 polarity */
VPORT_POLARITY_ACTIVE_HIGH, /* vport control pin 2 polarity */
VPORT_POLARITY_ACTIVE_HIGH, /* vport control pin 3 polarity */
&SAA7105_Fxns,
(EDC_Fxns *)INV
};
SAA7105_ConfParams EVMDM642_vDisParamsSAA7105 = {
SAA7105_AFMT_SVIDEO,
SAA7105_MODE_PAL720,
SAA7105_IFMT_YCBCR422_INTERLACED,
TRUE,
TRUE,
(I2C_Handle)INV /*handleI2C */
};
2个结构中类型分别为(EDC_Fxns *)和 (I2C_Handle)。
然后在重新编译。编译已经没有错误,但是出现2个link错误:
代码: ---------------------- seedvpm642_vedioloop.pjt - LOOP2 ----------------------
"c:\ti\c6000\cgtools\bin\cl6x" -g -fr"C:/work/test/video_loopback/LOOP2" -i"C:/work/test/video_loopback/include" -d"_DEBUG" -d"CHIP_DM642" -d"_LOOP2_" -mv6400 -@"../../LOOP2.lkf" "seedvpm642_vdisparamsPAL.cpp"
"c:\ti\c6000\cgtools\bin\cl6x" -@"LOOP2.lkf"
undefined first referenced
symbol in file
--------- ----------------
_tskVideoCaptureVp1 C:\work\test\video_loopback\LOOP2\seedvpm642cfg.obj
_tskVideoLoopback C:\work\test\video_loopback\LOOP2\seedvpm642cfg.obj
error: symbol referencing errors - './LOOP2/seedvpm642_vedioloop.out' not
built
Build Complete,
1 Errors, 0 Warnings, 0 Remarks
_tskVideoCaptureVp1和_tskVideoLoopback对应C++函数编译后的汇编名字。
C语言中规则是添加“_”前缀表示函数在汇编中的名称,例如main函数在汇编中为_main。
但是C++不行,原因在之前已经说过,C++有重载。比如有以下函数:
代码: void fun(const char* msg)
{
printf("%s\n", msg);
}
void fun(int val)
{
printf("%d\n",val);
}
int main()
{
fun("hello");
fun(123);
return 0;
}
函数fun有2个,如果将fun简单用_前缀的话,就会出现2个不同的函数,但是名字都是_fun。
C++的处理方法是重命名,第一个可能被命名为_fun_const_char_XCC1,第二个可能为_fun_int_SXX。
名字中除了参数信息,可能还有一些随机字串(这样是为了避免冲突)。
现在如果想将void fun(int val)函数导出为C语言接口怎么办?这就要在声明的时候添加extern "C"修饰。
这2个的函数声明在"seedvpm642_tskvp1.h"头文件中,打开"seedvpm642_tskvp1.h",发现里面没有
代码:
#ifdef __cplusplus
extern "C" {
#endif
之类的代码。这说明这个demo的"seedvpm642_tskvp1.h"头文件写的不标准,只能在C语言中用,
不能在C++中使用,修改的方式可以参考ti标准的头文件(例如):
代码: /*
* Copyright 2004 by SEED Incorporated.
* All rights reserved. Property of SEED Incorporated.
* Restricted rights to use, duplicate or disclose this code are
* granted through contract.
*
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* ======== tskVideoCaptureVp1Init ========
* video capture function init.
*/
void VideoCaptureVp1Init();
/*
* ======== tskVideoCaptureVp1Start ========
* video capture function start.
*/
void VideoCaptureVp1Start();
/*
* ======== tskVideoCaptureVp1 ========
* video capture function.
*/
void tskVideoCaptureVp1();
#ifdef __cplusplus
}
#endif
之前的头文件缺少void tskVideoCaptureVp1();函数声明,现在补上。另外,缺少头文件重复包含的控制,
也应该补上,类似方法如下:
代码: #ifndef **_H
#define **_H
#ifdef __cplusplus
extern "C" {
#endif
// 放各种声明
#ifdef __cplusplus
}
#endif
#endif // **_H
重新build,link错误还剩1个:
代码: undefined first referenced
symbol in file
--------- ----------------
_tskVideoLoopback C:\work\test\video_loopback\LOOP2\seedvpm642cfg.obj
error: symbol referencing errors - './LOOP2/seedvpm642_vedioloop.out' not
built
Build Complete,
1 Errors, 3 Warnings, 0 Remarks.
同样的方法解决。
另外需要注意一下:
由于是移植到Davinci系列的6437内核上,所以需要注意要添加的库为rts64plus.lib.
写测试程序时不要忘了添加需要用的的头文件,如#include "_cv.h"等.下面是一个测试程序,用来读入Lena.bmp并将其二值化(目前我移植的emcv 还支持bmp).
#include
#include
#include "_cv.h"
#include "_cxcore.h"
int main()
{
FILE* f_in = NULL;
FILE* f_out = NULL;
long len = 0;
char* buf=NULL;
//声明IplImage指针
IplImage* pImg = NULL;
IplImage* pBinImg = NULL;
if( (pImg = cvLoadImage("../Lena_Little8.bmp", 1)) != 0 )
{
//为canny边缘图像申请空间
pBinImg = cvCreateImage(cvGetSize(pImg),
IPL_DEPTH_8U,
1);
cvThreshold(pImg,pBinImg,91, 255.0, CV_THRESH_BINARY);
cvSaveImage("../Lena_Little8_Bin.bmp",pBinImg);
cvReleaseImage( &pImg );
cvReleaseImage( &pBinImg );
}
return 0;
您好,我想请教个问题。在移植的过程中我遇到这样的错误:
unresolved symbol _cvConvertScale, first referenced in ./src/quwu.objunresolved symbol _cvGet2D, first referenced in ./src/quwu.obj
unresolved symbol _cvGetReal2D, first referenced in ./src/quwu.obj
unresolved symbol _cvSet2D, first referenced in ./src/quwu.obj
unresolved symbol _VPCapChaAIsr, first referenced in ./src/ves_dm642.obj
unresolved symbol _VPDispIsr, first referenced in ./src/ves_dm642.obj
unresolved symbol GuidedFilter_Color(CvMat, first referenced in *,
参照您上面的帮助,我看到CXCORE.H里有加ifndef **_H #define **_H #ifdef __cplusplus extern "C" { #endif // 放各种声明 #ifdef __cplusplus } #endif #endif //这样的声明,请问我这要怎么解决呢?
共8条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 | |
【分享评测,赢取加热台】使用8051单片机驱动WS2812被打赏40分 |