使用Qt和opencv

时间:2015-10-22 08:49:50

标签: c++ qt opencv arm cross-compiling

Raspberry Pi提供了cross-compile种方法,并且还发布了交叉编译Qtopencv的解决方案。

但是,我找不到任何使用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只有在使用相同的编译器进行编译时才能协同工作,我尝试使用相同的交叉编译器来实现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。)注意,{{1 }}是当前会话的用户名,以防其他初学者将来可能尝试这些方法。

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

  

CMake错误   /usr/share/cmake-3.0/Modules/CMakeTestCXXCompiler.cmake:54(消息):   C ++编译器
  &#34; /home//opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g ++&#34;   无法编译简单的测试程序。

     

它失败并显示以下输出:

     

更改目录:/ home // temp / CMakeFiles / CMakeTmp

     

运行Build命令:&#34; / usr / bin / make&#34; &#34; cmTryCompileExec117178613 /快&#34;

     

/ usr / bin / make -f CMakeFiles / cmTryCompileExec117178613.dir / build.make   CMakeFiles / cmTryCompileExec117178613.dir /构建

     

make 1:输入目录&#39; / home // temp / CMakeFiles / CMakeTmp&#39;

     

/ 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:In   function'int main()':

     

/home//temp/CMakeFiles/CMakeTmp/testCXXCompiler.cxx:4:10:   对不起,未实现:Thumb-1 hard-float VFP ABI

     

CMakeFiles / cmTryCompileExec117178613.dir / build.make:57:食谱   目标
  &#39; CMakeFiles / cmTryCompileExec117178613.dir / testCXXCompiler.cxx.o&#39;   失败

     

make 1:***
  [CMakeFiles / cmTryCompileExec117178613.dir / testCXXCompiler.cxx.o]错误   1

     

make 1:离开目录&#39; / home // temp / CMakeFiles / CMakeTmp&#39;

     

Makefile:118:目标配方&cm; cmTryCompileExec117178613 / fast&#39;   失败

     

make:*** [cmTryCompileExec117178613 / fast]错误2

我为编译器指定了一个绝对路径,但即使我没有指定它,只是将它添加到我的$ PATH中,它仍然会遇到同样的问题。

<user>

如果我输入

,则可以正确找到编译器本身
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/

成功找到:

  

使用内置规格。 COLLECT_GCC = / ARM-Linux的gnueabihf-C ++   COLLECT_LTO_WRAPPER = /家庭/ vszabi的/ opt / GCC-4.7-Linaro的-RPI-gnueabihf / bin中/../的libexec / GCC / ARM-Linux的gnueabihf / 4.7.2 / LTO-包装   目标: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 /构建/ ARM-Linux的gnueabihf Linux的/安装   --with-SYSROOT = /选择的/ dev / SRC /的crosstool-纳克/的crosstool-NG-Linaro的-1.13.1-2012.07-20120720 /建立/臂-Linux的gnueabihf-LINUX /安装/臂-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 =&#39; crosstool-NG linaro-1.13.1-2012.07-20120720 - Linaro GCC 2012.07&#39;   --with-bugurl = https://bugs.launchpad.net/gcc-linaro --enable -__ cxa_atexit --enable-libmudflap --enable-libgomp --enable-libssp --with-gmp = / opt / dev / src / crosstool-ng / crosstool- NG-Linaro的-1.13.1-2012.07-20120720 /建立/臂-Linux的gnueabihf-LINUX / .build /臂-Linux的gnueabihf /建造/静态   --with-MPFR = /选择的/ dev / SRC /的crosstool-纳克/的crosstool-NG-Linaro的-1.13.1-2012.07-20120720 /建立/臂-Linux的gnueabihf-LINUX / .build /臂-Linux的gnueabihf /建立/静   --with-MPC = /选择的/ dev / SRC /的crosstool-纳克/的crosstool-NG-Linaro的-1.13.1-2012.07-20120720 /建立/臂-Linux的gnueabihf-LINUX / .build /臂-Linux的gnueabihf /建立/静   --with-PPL = /选择的/ dev / SRC /的crosstool-纳克/的crosstool-NG-Linaro的-1.13.1-2012.07-20120720 /建立/臂-Linux的gnueabihf-LINUX / .build /臂-Linux的gnueabihf /建立/静   --with-cloog = /选择的/ dev / SRC /的crosstool-纳克/的crosstool-NG-Linaro的-1.13.1-2012.07-20120720 /建立/臂-Linux的gnueabihf-LINUX / .build /臂-Linux的gnueabihf /建立/静   --with-= libelf的/选择的/ dev / SRC /的crosstool-纳克/的crosstool-NG-Linaro的-1.13.1-2012.07-20120720 /建立/臂-Linux的gnueabihf-LINUX / .build /臂-Linux的gnueabihf /建立/静   --with宿主libstdcxx =&#39; -L /选择的/ dev / SRC /的crosstool-纳克/的crosstool-NG-Linaro的-1.13.1-2012.07-20120720 /建立/臂-Linux的gnueabihf-LINUX /。建立/ ARM-Linux的gnueabihf /建设/静态/ lib目录   -lpwl&#39; --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 /建立/臂-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)

我接下来可以尝试什么?打开带有arm-linux-gnueabihf-g++ -v 的cmake的gui版本显示的选项很少(只有ARM_LINUX_SYSROOT,CMAKE_BUILD_TYPE,CMAKE_CONFIGURATION_TYPES,CMAKE_INSTALL_PREFIX,GCC_COMPILER_VERSION和LIBRARY_OUTPUT_PATH_ROOT,但没有我可以使用BUILD_opencv_xyz禁用单个软件包),比为x86或x64平台构建opencv时的case要少得多。

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

1 个答案:

答案 0 :(得分: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,必须将以下选项传递给编译器:{{1 }}

因此,我们必须编辑-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")

再次运行cmake,配置成功完成!

使

在构建过程中,如果出现以下错误

  

CMakeFiles / opencv_core.dir / src / rand.cpp.o:重定位   R_ARM_THM_MOVW_ABS_NC针对“本地符号”时不能使用   制作共享对象;用-fPIC重新编译   CMakeFiles / opencv_core.dir / src / rand.cpp.o:无法读取符号:错误   值

只需将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文件中的-fPICCMAKE_C_FLAGS,然后再次运行make。

Deployement

使用Qt Creator进行部署,只需在CMAKE_CXX_FLAGS文件中设置标题和库,例如:

.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 中找到)复制到Raspberry Pi。使用USB记忆棒可能会弄乱符号链接,因此我建议使用<your build dir>/install/lib/复制文件。

如果您对Linux相对较新(就像我一样),请不要忘记,可执行文件不会像在Windows中那样自动查找动态库的自己的文件夹。

因此,您应该将图书馆复制到通常会搜索到的地方(例如scp),或者相应地更新您的/usr/local/bin

对于快速而肮脏的测试,要查看是否一切正常,您可以将库复制到部署可执行文件的同一文件夹中,然后使用

运行它。
LD_LIBRARY_PATH

测试

Opencv现在可以在Raspberry Pi上的Qt程序中使用。

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

但请注意,窗口管理可能仍存在一些问题。 尝试打开opencv窗口,例如,$ LD_LIBRARY_PATH=. ./your_program 可能会失败,并显示以下错误:

  

OpenCV错误:未指定错误(该功能未实现。   使用Windows,GTK + 2.x或Carbon支持重建库。如果你   在Ubuntu或Debian上,然后安装libgtk2.0-dev和pkg-config   在cvNamedWindow文件中重新运行cmake或配置脚本   /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或碳支持。如果您使用的是Ubuntu或Debian,请安装libgtk2.0-dev和pkg-config,然后重新运行cmake或配置脚本   function cvNamedWindow

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

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

(...如果我找到一个在窗口中运行Qt应用程序并使用cvNamedWindow

的良好解决方案,将会更新