编译到Raspberry Pi,使用Qt和opencv
有多种方式可以交叉编译到Raspberry Pi,并且还有用于交叉编译Qt或opencv的解决方案。
然而,我找不到任何解决方案与使用opencv的Qt交叉编译程序。
我尝试了以下方法,在64位PC上使用debian:
我使用本教程编译并设置了Qt作为ARM7的交叉编译器。 它没有工作没有问题,虽然,这是我发布的答案,它为我解决了。 我现在可以在Raspberry Pi上使用图形化GUI来运行我的Qt程序(尽管只是全屏,但这是一个完全不同的问题)
我遵循官方opencv网站上的指南来构建opencv。 它失败了, No CMAKE_CXX_COMPILER could be found.
从经验中得知(我在Windows和Linux上使用Qt与opencv),Qt和opencv只有在使用相同的编译器编译时才能一起工作,我尝试使用相同的交叉编译器来编译Qt: gcc-4.7-linaro-rpi-gnueabihf
我指定了我以前用来编译Qt的gnueabihf
,作为编译器:
我创建了~/opt/opencv_build_arm7/
目录,并且在其中尝试了:
sudo cmake -DCMAKE_CXX_COMPILER=/home/<user>/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++ -DCMAKE_C_COMPILER=/home/<user>/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-gcc -DCMAKE_TOOLCHAIN_FILE=/usr/dev/opencv/platforms/linux/arm-gnueabi.toolchain.cmake /usr/dev/opencv/
(其中下载的opencv源文件位于/usr/dev/opencv/
,我最近成功地使用了我的Qt安装附带的g ++编译器编译x64平台的opencv。)注意, <user>
是用户名当前会话,以防其他初学者可能在将来尝试这些方法。
这失败了以下错误(其中<user>
是我的用户名)
/usr/share/cmake-3.0/Modules/CMakeTestCXXCompiler.cmake:54(message)处的CMake错误:C ++编译器
“/home//opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++”不能编译一个简单的测试程序。
它失败,输出如下:
更改目录:/ home // temp / CMakeFiles / CMakeTmp
运行构建命令:“/ usr / bin / make”“cmTryCompileExec117178613 / fast”
/ usr / bin / make -f CMakeFiles / cmTryCompileExec117178613.dir / build.make CMakeFiles / cmTryCompileExec117178613.dir / build
make1:进入目录'/ home // temp / CMakeFiles / CMakeTmp'
/ usr / bin / cmake -E cmake_progress_report
/ home // temp / CMakeFiles / CMakeTmp / CMakeFiles 1
构建CXX对象
CMakeFiles / cmTryCompileExec117178613.dir / testCXXCompiler.cxx.o
/home//opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++ -mthumb -fdata-sections -Wa, - noexecstack -fsigned-char -Wno-psabi -mthumb -fdata-部分-Wa, - noexecstack -fsigned-char -Wno-psabi -o CMakeFiles / cmTryCompileExec117178613.dir / testCXXCompiler.cxx.o -c /home//temp/CMakeFiles/CMakeTmp/testCXXCompiler.cxx
/home//temp/CMakeFiles/CMakeTmp/testCXXCompiler.cxx:在函数'int main()'中:
/home//temp/CMakeFiles/CMakeTmp/testCXXCompiler.cxx:4:10:对不起,未实现:Thumb-1硬浮点VFP ABI
CMakeFiles / cmTryCompileExec117178613.dir / build.make:57:目标配方
'CMakeFiles / cmTryCompileExec117178613.dir / testCXXCompiler.cxx.o'失败
make1:***
[CMakeFiles / cmTryCompileExec117178613.dir / testCXXCompiler.cxx.o]错误1
make1:离开目录'/ home // temp / CMakeFiles / CMakeTmp'
Makefile:118:目标'cmTryCompileExec117178613 / fast'的配方失败
make:*** [cmTryCompileExec117178613 / fast]错误2
我为编译器指定了一个绝对路径,但即使我没有指定它,只是将它添加到我的$ PATH中,它仍然有同样的问题。
export PATH=$PATH:/home/<user>/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/
sudo cmake -DCMAKE_TOOLCHAIN_FILE=/usr/dev/opencv/platforms/linux/arm-gnueabi.toolchain.cmake /usr/dev/opencv/
如果我键入,编译器本身就可以正确找到
arm-linux-gnueabihf-g++ -v
它被成功发现:
使用内置规格。 COLLECT_GCC =。/ arm-linux-gnueabihf-c ++ COLLECT_LTO_WRAPPER = / home / vszabi / opt / gcc-4.7-linaro-rpi-gnueabihf / bin /../ libexec / gcc / arm-linux-gnueabihf / 4.7.2 / lto -wrapper目标:arm-linux-gnueabihf配置:/opt/dev/src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/.build/ src / gcc-linaro-4.7-2012.07 / configure --build = i686-build_pc-linux-gnu --host = i686-build_pc-linux-gnu --target = arm-linux-gnueabihf --prefix = / opt / dev /src/crosstool-ng/crosstool-ng-linaro-1.13.1-2012.07-20120720/builds/arm-linux-gnueabihf-linux/install --with-sysroot = / opt / dev / src / crosstool-ng / crosstool -ng-linaro-1.13.1-2012.07-20120720 / builds / arm-linux-gnueabihf-linux / install / arm-linux-gnueabihf / libc --enable-languages = c,c ++,fortran --enable-multilib - with-arch = armv6zk --with-tune = arm1176jzf-s --with-fpu = vfp --with-float = hard --with-pkgversion ='crosstool-NG linaro-1.13.1-2012.07-20120720 - Linaro GCC 2012.07'--with-bugurl = https://bugs.launchpad.net/gcc-linaro --enable -__ cxa_ate xit --enable-libmudflap --enable-libgomp --enable-libssp --with-gmp = / opt / dev / src / crosstool-ng / crosstool-ng-linaro-1.13.1-2012.07-20120720 / builds / arm -linux-gnueabihf-linux / .build / arm-linux-gnueabihf / build / static --with-mpfr = / opt / dev / src / crosstool-ng / crosstool-ng-linaro-1.13.1-2012.07-20120720 / builds / arm-linux-gnueabihf-linux / .build / arm-linux-gnueabihf / build / static --with-mpc = / opt / dev / src / crosstool-ng / crosstool-ng-linaro-1.13.1-2012.07 -20120720 / builds / arm-linux-gnueabihf-linux / .build / arm-linux-gnueabihf / build / static --with-ppl = / opt / dev / src / crosstool-ng / crosstool-ng-linaro-1.13。 1-2012.07-20120720 / builds / arm-linux-gnueabihf-linux / .build / arm-linux-gnueabihf / build / static --with-cloog = / opt / dev / src / crosstool-ng / crosstool-ng-linaro -1.13.1-2012.07-20120720 / builds / arm-linux-gnueabihf-linux / .build / arm-linux-gnueabihf / build / static --with-libelf = / opt / dev / src / crosstool-ng / crosstool- ng-linaro-1.13.1-2012.07-20120720 / builds / arm-linux-gnueabihf-linux / .build / arm-linux-gnueabihf / build / static --with-host-l ibstdcxx =' - L /选择的/ dev / SRC /的crosstool-纳克/的crosstool-NG-Linaro的-1.13.1-2012.07-20120720 /建立/臂-Linux的gnueabihf-LINUX / .build /臂-Linux的gnueabihf /构建/ static / lib -lpwl'--enable-threads = posix --disable-libstdcxx -pch --enable-linker-build-id --enable-gold --with-local-prefix = / opt / dev / src / crosstool-ng / crosstool-ng-linaro-1.13.1-2012.07-20120720 / builds / arm-linux-gnueabihf-linux / install / arm-linux-gnueabihf / libc --enable-c99 --enable-long-long线程型号:posix gcc版本4.7.2 20120701(预发布)(crosstool-NG linaro-1.13.1-2012.07-20120720 - Linaro GCC 2012.07)
接下来我可以尝试什么? 使用opencv/platforms/linux/arm-gnueabi.toolchain.cmake
打开cmake的gui版本opencv/platforms/linux/arm-gnueabi.toolchain.cmake
显示很少的选项(只有ARM_LINUX_SYSROOT,CMAKE_BUILD_TYPE,CMAKE_CONFIGURATION_TYPES,CMAKE_INSTALL_PREFIX,GCC_COMPILER_VERSION和LIBRARY_INTPALL_PATH_ROOT,但没有一个BUILD_opencv_xyz可以禁用单个软件包),比我为x86或x64平台构建opencv的情况少得多。
恐怕搜索不同的编译器可能会导致Qt问题,因为据我所知,为了使opencv在Qt中工作,必须使用与用于构建Qt库的编译器相同的编译器进行编译,并且建立我的程序。 每当我在过去尝试过,但没有注意到这三件事(Qt库,opencv,我的程序)需要使用相同的编译器进行编译时,只要我包含任何opencv头文件,或者只要我从opencv调用任何函数。
http://docs.opencv.org/doc/tutorials/introduction/crosscompilation/arm_crosscompile_with_cmake.html中的教程似乎是错误的或过时的。
下载opencv 3.0的源代码, opencv/platforms/linux/arm-gnueabi.toolchain.cmake
似乎没有为Raspberry Pi配置。
配置
访问arm-linux-gnueabihf
工具链创建者的工作组页面,似乎要支持Raspberry Pi中的ARM7,必须将以下选项传递给编译器: -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=vfpv4
所以,我们必须编辑opencv/platforms/linux/arm-gnueabi.toolchain.cmake
文件并更改
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi")
至
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=vfpv4")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=vfpv4")
再次运行cmake,配置成功完成!
使
在构建过程中,如果出现以下错误
CMakeFiles / opencv_core.dir / src / rand.cpp.o:在创建共享对象时,不能使用针对“本地符号”的R_ARM_THM_MOVW_ABS_NC; 使用-fPIC CMakeFiles / opencv_core.dir / src / rand.cpp.o重新编译:无法读取符号:值不正确
只需将-fPIC
标志添加到cmake文件中的CMAKE_C_FLAGS
和CMAKE_CXX_FLAGS
并再次运行make。
Deployement
使用Qt Creator进行部署,只需在.pro
文件中设置头文件和库文件,例如:
INCLUDEPATH += <your build dir>/install/include/opencv2/
INCLUDEPATH += <your build dir>/install/include/
LIBS += -L "<your build dir>/install/lib/"
LIBS += -lopencv_calib3d
LIBS += -lopencv_core
#... and so on
您还必须将已编译的库(可在<your build dir>/install/lib/
)复制到Raspberry Pi。 使用USB棒可能会混淆符号链接,所以我会建议使用scp
来复制文件。
如果你对Linux比较陌生(就像我一样),不要忘记,可执行文件不会像在Windows中那样自动在动态库中查找自己的文件夹。
因此,您应该将库复制到通常搜索它们的位置(如/usr/local/bin
),或者相应地更新LD_LIBRARY_PATH
。
对于快速而脏的测试,为了确定一切是否正常,可以将库复制到可执行文件所在的文件夹中,然后使用
$ LD_LIBRARY_PATH=. ./your_program
测试
Opencv现在可以在你的Qt程序中运行在Raspberry Pi上。
除非我的google-fu非常弱,否则这可能是第一个在Raspberry Pi上运行Qt GUI应用程序并记录opencv的案例。 :)
但是请注意,窗口管理可能仍然存在一些问题。 尝试打开一个opencv窗口,例如, cv::namedWindow("image");
可能会因以下错误而失败:
OpenCV错误:未指定的错误(该功能未实现,用Windows,GTK + 2.x或Carbon支持重建库如果您在Ubuntu或Debian上,请安装libgtk2.0-dev和pkg-config,然后重新运行cmake或者配置脚本)在cvNamedWindow中,文件/usr/dev/opencv/modules/highgui/src/window.cpp,在抛出'cv :: Exception'实例后终止调用第516行what():/ usr / dev / opencv /modules/highgui/src/window.cpp:516:错误:(-2)该函数未实现。 用Windows,GTK + 2.x或Carbon支持重建库。 如果您在Ubuntu或Debian上,请安装libgtk2.0-dev和pkg-config,然后重新运行cmake或在函数cvNamedWindow中配置脚本
我想我们应该cvNamedWindow
它说的去做,但cvNamedWindow
在Qt GUI应用程序中并不是非常有用,因为它通常只用于调试。 因此,如果图像必须显示在您的应用程序中,将其转换为QImage可能比打开独立窗口更好。
然而,其他一切似乎都奏效,我成功地在Raspberry Pi上运行了复杂的图像匹配算法。
(...将更新,如果我找到一个很好的解决方案,在窗口中运行Qt应用程序并使用cvNamedWindow
)