首页 文章

使用Qt和opencv交叉编译到Raspberry Pi

提问于
浏览
3

有多种方法可以cross-compile到Raspberry Pi,并且还有针对交叉编译Qtopencv的解决方案 .

但是,我找不到任何与Qt交叉编译程序的解决方案,Qt也使用opencv .

我在64位PC上使用debian尝试了以下操作:

  • 我使用this tutorial编译并设置Qt作为ARM7的交叉编译器 . 虽然没有问题但它没有用,here is an answer我贴了哪个解决了它 . 我现在可以在Raspberry Pi上使用图形GUI运行我的Qt程序(尽管只是全屏,但这是一个完全不同的问题)

  • 我在官方opencv网站上关注the guide来构建opencv . 它失败了 No CMAKE_CXX_COMPILER could be found.

  • 从经验中知道(我在Windows和Linux上使用了Qt和opencv)Qt和opencv只有在使用相同的编译器编译时才能一起工作,我试图使用相同的交叉编译器来解决我成功编译Qt的opencv : gcc-4.7-linaro-rpi-gnueabihf

  • 我指定了 gnueabihf 我以前用来编译Qt,作为编译器:

我创建了目录 ~/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 /我最近使用成功为x64平台编译opencv,使用我的Qt安装附带的g编译器 . )注意,<user>是用户名当前 Session ,以防其他初学者将来可能尝试这些方法 .

这失败并出现以下错误(其中 <user> 是我的用户名)

/usr/share/cmake-3.0/Modules/CMakeTestCXXCompiler.cmake:54中的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-sections -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 / Build /臂-Linux的gnueabihf-LINUX / .build /臂-Linux的gnueabihf /建造/静态--with-PPL = /选择的/ dev / SRC /的crosstool-纳克/的crosstool-NG-Linaro的-1.13.1-2012.07-20120720 / Build /臂-Linux的gnueabihf-LINUX / .build /臂-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-libstdcxx =' - L / 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 / lib -lpwl'-- enable-threads = posix --disable-libstdcxx-pch --enable-linker-build-id --enable-gold --with本地前缀= /选择的/ dev / SRC /的crosstool-纳克/的crosstool-NG-Linaro的-1.13.1-2012.07-20120720 / Build /臂-Linux的gnueabihf-LINUX /安装/臂-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)

What could I try next?opencv/platforms/linux/arm-gnueabi.toolchain.cmake 打开cike的gui版本显示的选项很少(只有ARM_LINUX_SYSROOT,CMAKE_BUILD_TYPE,CMAKE_CONFIGURATION_TYPES,CMAKE_INSTALL_PREFIX,GCC_COMPILER_VERSION和LIBRARY_OUTPUT_PATH_ROOT,但没有一个BUILD_opencv_xyz我可以禁用单独的包),远远少于case当我构建opencv时对于x86或x64平台 .

我担心搜索不同的编译器可能会导致Qt出现问题,因为据我所知,要使opencv在Qt中工作,必须使用与用于构建Qt库的编译器相同的编译器进行编译 . Build 我的计划 . 每当我在过去尝试它而不小心这三件事(Qt libs,opencv,我的程序)需要使用相同的编译器编译时,我总是遇到奇怪的崩溃,只要我包含任何opencv头,或者每当我从opencv调用任何函数 .

1 回答

  • 3

    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 工具链的创建者workgroup page时,似乎支持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_FLAGSCMAKE_CXX_FLAGS ,然后再次运行make .

    部署

    使用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现在应该在Raspberry Pi上的Qt程序中运行 .

    除非我的google-fu非常弱,否则这可能是第一个在使用opencv工作的Raspberry Pi上运行Qt GUI应用程序的案例 . :)

    但请注意,窗口管理可能仍存在一些问题 . 尝试打开opencv窗口,例如 cv::namedWindow("image"); 可能会失败,并显示以下错误:

    OpenCV错误:未指定错误(该功能未实现 . 使用Windows,GTK 2.x或Carbon支持重建库 . 如果您使用的是Ubuntu或Debian,请安装libgtk2.0-dev和pkg-config,然后重新运行cvke或配置脚本)在cvNamedWindow,文件/usr/dev/opencv/modules/highgui/src/window.cpp,第516行终止在抛出'cv :: Exception'的实例后调用what():/ usr / dev / opencv / modules / highgui / src / window.cpp:516:错误:( - 2)该函数未实现 . 使用Windows,GTK 2.x或Carbon支持重建库 . 如果您使用的是Ubuntu或Debian,请安装libgtk2.0-dev和pkg-config,然后在cvNamedWindow函数中重新运行cmake或configure脚本

    我想我们应该这样做,但 cvNamedWindow 在Qt GUI应用程序中不是很有用,因为它通常只需要调试 . 因此,如果必须在应用程序中显示图像,则将其转换为QImage可能比打开独立窗口更好 .

    然而,其他一切似乎都有效,我成功地在Raspberry Pi上运行了复杂的图像匹配算法 .

    (...如果我找到一个在窗口中运行Qt应用程序并使用 cvNamedWindow 的良好解决方案,将会更新)

相关问题