编译到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_FLAGSCMAKE_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

    链接地址: http://www.djcxy.com/p/86913.html

    上一篇: compiling to Raspberry Pi, using Qt and opencv

    下一篇: How to install a specific version of gcc