OpenCV中文网站

 找回密码
 立即注册
搜索
热搜: 安装 配置
查看: 9074|回复: 5

OpenCV在基于FPGA的嵌入式系统中的移植研究

[复制链接]
发表于 2010-6-27 02:17:56 | 显示全部楼层 |阅读模式
可能很少有人会把OpenCV移植到FPGA器件上的uClinux中用吧
自己本科的毕设也只是为了学习研究才这么干的
做毕设之时
已经搜遍自己会用的各种途径
依旧查不到成功的先例
碍于自己的水平
自己移植成功也是费了些时间

不知道自己是不是头一个做这事情的人
趁着这几天空闲
顺带整理了下资料
以便日后有人也做相同的事情时有个参考
自己的博客文章原地址在此
[url:pmbu0z89]http://www.tyreal.net/port-opencv-to-niosii.html[/url:pmbu0z89]

本科四年
认真努力的时间太少
水平有限
有所谬误的地方还望诸位能指正下
论坛中的ARM平台下的移植文章与讨论给我了很大帮助
在此谢过了


移植整体步骤
    [li]1.配置交叉编译开发环境,移植uClinux系统
    2.获取OpenCV源码,配置并编译,生成目标平台的静态链接库
    3.自行编写文件读写以及图片显示函数,摒除对Highgui库的调用依赖
    4.将改写后的程序与生成的静态链接库链接一起,下载到目标平台上测试运行[/li]


对于第一步,给个自己写的文章当参考——[url=http://www.tyreal.net/port-uclinux-to-niosii.html:pmbu0z89]《uClinux在Nios II平台上的移植》[/url:pmbu0z89],我将从第二步开始说起
值得注意的是:
Highgui是造成移植程序运行不稳定的一个原因,毕竟不同嵌入式硬件平台之间都有诸多区别,更何况与Pc的差异。所以要移植OpenCV程序到Nios II的嵌入式系统中,请修改源程序,摒除对Highgui库的调用依赖,自行编写文件读写以及对IplImage这种OpenCV特有数据结构的初始化。

本文使用nios2-gcc-3.4.6 + OpenCV 1.1 pre测试,OpenCV的1.0、2.0版本我也尝试过编译,均告失败,只有1.1测试通过。


配置编译OpenCV

获取OpenCV源码
你可以从[url=http://sourceforge.net/projects/opencvlibrary/files/:pmbu0z89]http://sourceforge.net/projects/opencvlibrary/files/[/url:pmbu0z89]这里下载OpenCV的源码
点击View all files那个按钮,然后下载opencv-unix 1.1pre1,在终端输入
  1. tar -zxvf opencv-1.1pre1.tar.gz
复制代码
解压供后面使用
如果你还尝试了别的版本并且也成功了,请不吝告诉在下

配置OpenCV编译信息
进入刚才解压出来的源码文件夹,输入配置命令
  1. $ ./configure --host=nios2-linux --without-gtk --without-carbon --without-quicktime --without-1394libs --without-ffmpeg --without-python --without-swig --enable-static --disable-shared --disable-apps CXX=nios2-linux-g++ --prefix=/home/lee/uccv
复制代码
--host 指定要编译的目标平台

--witout-* 禁用各种函数库,一是uClinux本来就不支持这里的大部分库,除了gtk,其他的其实你不填也是一样不会编译进去;二是出于精简的需要,说不定日后真支持某个库了,这些我们不需要的东西还是明令去除的好

--enable-static --disable-shared 启动静态链接库,禁用动态链接,因为嵌入式系统对内核的大小要求很看重,不适合将OpenCV库编译成动态链接库,因为这样生成的库都是完整且较为庞大,所以在移植程序数量较少的情况下,通过静态链接库,只将程序用到的部分与程序编译链接到一起,是相对比较理想的选择。另外一个原因是我曾经想使用动态链接库来运行,可是编译出错,暂时无解。

--disable-apps 禁止编译范例程序,因为要编译可以在FPGA上的uClinux系统运行的OpenCV程序,需要在编译的时候额外添加参数,而且我们等会还要自行测试编译,这里一定得禁用掉,否则会导致之后make出错。

CXX 指定编译器。其实这个可以不加,只要host里面指定的平台系统能识别,最后生成的makefile里面的编译器配置信息都是一样的,之所以还保留是因为之前参考ARM下的移植文章,在此留着给大家之后编译若有错误当做一个切入点。

--prefix 可以设置OpenCV编译结果想要安装的路径,这里设置为笔者Fedora中用户所在的个人文件夹。

然后经过一堆输出信息刷新,你可以看到如下信息:



v4l那是因为我毕设要做双目测距程序,需要用到摄像头,所以我留着(不过最后还是失败了,西奈……uClinux下摄像头驱动的移植又是个头痛的问题)。

一切正常的话,我们就开始编译
  1. $ make
复制代码
如果make没有出错,就开始安装目标平台上的OpenCV函数库吧
  1. $ make install
复制代码
然后在我们设置的路径下找到lib文件夹,进入就可以看到编译好的静态链接库了


摒除Highgui的依赖
由于不能再用Highgui库了,如果你的程序有用到Highgui,我们就得自己重写文件读写以及图片显示函数,这里着重讲下如何对图片文件读取以及之后如何使用自己读取的图片数据来初始化IplImage,以此为例,其他部分按照这样的思路同样去修改。

1.删除所有Highgui的头文件引用
为了对原来写好的程序进行最低程度的修改,我们只删除Highgui的头文件引用,然后自行添加个头文件与源文件,在其中加入的图片读取函数的名称,跟原来一样为IplImage* cvLoadImage(char* filename, int iscolor = 1)

2.读取图片函数的编写,将图像数据存在BYTE*指针指向的内存空间
在自行编写cvLoadImage()函数中,根据要读取的图片格式不同,对应自己编写读取算法,唯一相同的步骤是,最后将图片数据读取到一个BYTE指针指向的空间

3.使用读取的图像数据初始化OpenCV的IplImage数据结构
读取好图片,可以使用OpenCV的cxcore中的两个函数来初始化IplImage
  1. IplImage* cvLoadImage(char* fileName, int iscolor = 1)
  2. {
  3.         /*...省略其他代码...*/
  4.         //创建IplImage变量的信息头
  5.         IplImage* img = cvCreateImageHeader(cvSize(width,height), depth, channel);
  6.         //利用BYTE指针数据初始化IplImage
  7.         cvSetData(img, (void *)blocks, lineByte);
  8.         /*...省略其他代码...*/
  9.         return img;
  10. }
复制代码
width、height是要创建IplImage图像的宽度与高度
depth是图像的位深
channel是图像的通道数
blocks是读取来的图像数据的BYTE*指针

lineByte是OpenCV中图像每一行的数据宽度,OpenCV规定图像的每一行数据宽度都必须是4的倍数,但是图像不同位数、不同宽度,不一定满足这个条件,所以这个变量之前需要额外进行一个简单的计算处理
  1. lineByte = (width * biBitCount/8)/4*4;
  2. //biBitCount是图像一个像素占用的位宽大小
复制代码
以上width、height、biBitCount等int变量的值都可以从图片的文件头读取得知,具体方法请查阅不同图片格式的资料说明。

需要说清楚,我们只是自己简单的写了一个读取特定图片格式的函数,比不上原来的highgui原来的API那么好用,各种格式都支持,不过一般应用的时候,格式都比较固定,这点相对不是什么大问题。

4.最后对IplImage的释放就不像原来一句cvReleaseImage()就搞定,要分2次完成
  1. delete[] img->imageDataOrigin;
  2. cvReleaseImageHeader(&img);
复制代码
至此,我们就完成了脱离Highgui自行完成图片文件读取函数,至于文件写入乃至图片显示,限于篇幅原因就不详细讲解,基本思想掌握,剩下的就是自由发挥了。
等我工作定下之后,闲暇再找机会补写看看。

这里留下一个自己写的BMP读取的源码,供大家参考下,写的很搓很随意,而且只读取彩色图像,随意瞥下了解就好。
[url=http://www.tyreal.net/wp-content/plugins/download-monitor/download.php?id=5:pmbu0z89]<---------点击下载--------->[/url:pmbu0z89]

链接整合程序
弄到这里,有了OpenCV的静态函数库,也有脱离Highgui的源码,就可以开始编译链接目标平台的程序了
  1. #先编译文件读取程序
  2. $ nios2-linux-g++ -c bmpDecoder.cpp bmpDecoder.o -I/home/lee/uccv/include/opencv
  3. #再编译测试OpenCV程序
  4. $ nios2-linux-g++ -c test.cpp test.o -I/home/lee/uccv/include/opencv
  5. #最后与函数库链接在一起
  6. $ nios2-linux-g++ -o test bmpDecoder.o test.o -L/home/lee/uccv/lib -lcv -lcvaux -lcxcore -lml -lpthread -elf2flt
复制代码
-I 指定源码中的头文件引用库位置

-L 指定静态链接函数库位置

-lcv -lcvaux -lcxcore -lml 是需要链接的OpenCV的几个静态链接库,顺序很重要,更改顺序很可能导致undefined reference,需要根据自己编写的程序微调这个参数列表的顺序。

-lpthread 支持多线程程序,我是根据错误提示信息加上这个参数,更深入的理由我并未深究。

-elf2flt 编译为flt格式程序,uClinux默认没有MMU,只支持绝对内存地址的二进制格式,这个记得一定要加上

假如没有什么意外的话,你就会获得最后编译出来的目标平台的OpenCV程序文件

最后唠叨
编译好了,链接成功了,按照我之前给的那篇文章的说明,再烧写下载程序到目标板上测试运行。

虽然我觉得以Cyclone II级别的FPGA器件运行OpenCV的效率,还不能到实际应用的程度,不过以现在FPGA的发展势头,多尝试新的SoPC应用开发,待硬件资源足够之时,也未必不是一大优势。

至于一些目前其他高端的FPGA的运行表现,由于自己没有条件测试,在此就不妄加评价了。
回复

使用道具 举报

 楼主| 发表于 2010-7-11 13:57:52 | 显示全部楼层

OpenCV在基于FPGA的嵌入式系统中的移植研究

今天重新整理了下帖子
可能帖子太简单,说得又有点繁琐,只是想起自己当初初学的时候也很多问题不知道怎么解决,所以细节唠叨得比较多,高手们别在意
回复 支持 反对

使用道具 举报

发表于 2010-9-2 15:24:51 | 显示全部楼层

OpenCV在基于FPGA的嵌入式系统中的移植研究

今天重新整理了下帖子
可能帖子太简单,说得又有点繁琐,只是想起自己当初初学的时候也很多问题不知道怎么解决,所以细节唠叨得比较多,高手们别在意
这个工作很有意义。有移植好的源文件吗。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-9-10 09:31:53 | 显示全部楼层

OpenCV在基于FPGA的嵌入式系统中的移植研究

[quote=&quot;Tyreal&quot;:1tva79tr]今天重新整理了下帖子
可能帖子太简单,说得又有点繁琐,只是想起自己当初初学的时候也很多问题不知道怎么解决,所以细节唠叨得比较多,高手们别在意
这个工作很有意义。有移植好的源文件吗。[/quote:1tva79tr]

倒是有编译成功的静态链接库
源代码那些网上都有的下,只是要配置下而已,如果是Highgui的部分我自己的文章里有小写了一点点图形读取的代码
回复 支持 反对

使用道具 举报

发表于 2011-1-21 15:34:00 | 显示全部楼层

OpenCV在基于FPGA的嵌入式系统中的移植研究

先顶一个!我毕设也要这么做,关注中~
回复 支持 反对

使用道具 举报

发表于 2011-5-8 10:12:38 | 显示全部楼层

OpenCV在基于FPGA的嵌入式系统中的移植研究

终于看到了同道中人了,我最近也在做这个 有点焦头烂额了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|OpenCV中文网站

GMT+8, 2024-4-29 10:10 , Processed in 0.013629 second(s), 16 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表