做网站销售好吗西安公司网站建设服务商
做网站销售好吗,西安公司网站建设服务商,福州网站建设资讯,企业建设高端网站的目的Linux下编译、链接、加载运行C OpenCV的两种方式及常见问题的解决
在Linux下安装完OpenCV C之后#xff08;还没有安装的读者请参考Ubuntu 18.04 安装OpenCV C#xff09;#xff0c;本文将探索Linux下编译、链接C OpenCV的两种方式#xff0c;并且给出笔者在初次尝试时遇…Linux下编译、链接、加载运行C OpenCV的两种方式及常见问题的解决
在Linux下安装完OpenCV C之后还没有安装的读者请参考Ubuntu 18.04 安装OpenCV C本文将探索Linux下编译、链接C OpenCV的两种方式并且给出笔者在初次尝试时遇到的一些问题的解决方法。一般来看不只是OpenCV其实本文已经囊括了大部分Linux下C链接库文件、运行时链接动态库文件的常见问题。各位读者如果链接时遇到其他问题也可留言讨论。
注意我们这里并不采用简单的包含进opencv的头文件然后再main函数中打印个hello world的测试方式。这种测试方式只能测试头文件的正常包含即只能保证编译通过我们需要实际地调用一些opencv中的图像处理接口来保证链接和运行时的正确性。这里我们调用Canny算子来提取图像的边缘信息。如果这个测试用例能够正常地编译、链接、运行的话那整个opencv的运行测试才能算是完整通过了。
首先我们准备一个测试源码demo.cpp和测试图像demo.jpg把它们放到测试文件夹demo/下。即一开始我们有目录树如下
├── demo
│ ├── demo.cpp
│ └── demo.jpg方法一CMake
CMake链接的使用方法笔者已经在安装OpenCV的文章中介绍过这里再复述一遍这种方法基本不会遇到什么问题。我们先准备一个CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project( demo )
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( demo demo.cpp )
target_link_libraries( demo ${OpenCV_LIBS} )具体的含义笔者就不在这里赘述了这需要一些cmake的相关知识总之按照这个CMakeLists.txt是可以正常编译链接运行包含opencv库的源代码的。我们来试一下
cmake .
make过程输出
$ cmake .
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c
-- Check for working CXX compiler: /usr/bin/c -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenCV: /usr/local (found version 4.5.4)
-- Configuring done
-- Generating done
-- Build files have been written to: /home/song/hello/demo/demo
$ make
Scanning dependencies of target demo
[ 50%] Building CXX object CMakeFiles/demo.dir/demo.cpp.o
[100%] Linking CXX executable demo
[100%] Built target dem经过这两步后我们直接运行生成的可执行文件demo
./demo会得到一张Canny算子提取的图像边缘信息Canny.jpg整个过程没有报错的话则测试成功。
方法二通过g直接命令行编译
笔者在使用这种方法时遇到了不少问题会记录在后面的常见问题及解决一节读者在编译过程中遇到问题可以去后面看一下如果后面也没有你遇到的问题欢迎留言讨论。
我们回到最初的测试目录的内容只有demo.cpp和demo.jpg。
我们先尝试直接编译链接
g demo.cpp -o demo这样是肯定不行的会报一大堆undefined reference因为这样是没有链接我们的opencv库的。但是只这样编译其实是可以的即
g -c demo.cpp除非你的头文件都找不到否则上述-c选项的仅编译的命令是会通过的会得到一个demo.o可重定向文件。头文件找不到保存请看下面的问题一。
下面我们来解决链接时undefined reference的问题未定义引用究其原因无非就是opencv的库文件没有链接进来。对于动态链接库我们通常使用-l[lib]的选项来链接但是opencv中要包含的库文件太多了我们难道要一个一个写吗
当然不用我们通常会借助pkg-config工具来生成链接时的库文件选项。如果还没有安装请参考问题二。我们要在pkgconfig的目录下添加opencv.pc来让它帮助生成我们的opencv链接选项。opencv.pc应该是在opencv安装时直接生成的。
但默认是不生成的笔者当时安装的时候不知道要用到这个就没有配置笔者就自己从Stack Overflow抄了个opencv.pc文件但是弄了大半天都不行最后才发现是版本太老了不适合现在的opencv版本了。最终无奈自己写了个脚本把lib目录下opencv的动态链接库名称都提取出来放到opencv.pc里才成功。不然这篇博客应该会早几小时出来本段小吐槽勿怪
笔者把自己提取到的opencv.pc放到问题三了可能与官网安装时生成的不同但是亲测使用正常有需要的小伙伴自取版本是4.5.4。
将适合自己版本的opencv.pc放到/usr/local/lib/pkgconfig目录下。然后命令行执行pkg-config opencv --libs --cflags应当会得到如下链接选项
-I/usr/include/opencv -I/usr/include/opencv2 -L/usr/local/lib -lopencv_aruco -lopencv_barcode -lopencv_bgsegm -lopencv_bioinspired -lopencv_calib3d -lopencv_ccalib -lopencv_core -lopencv_datasets -lopencv_dnn_objdetect -lopencv_dnn -lopencv_dnn_superres -lopencv_dpm -lopencv_face -lopencv_features2d -lopencv_flann -lopencv_freetype -lopencv_fuzzy -lopencv_gapi -lopencv_hfs -lopencv_highgui -lopencv_imgcodecs -lopencv_img_hash -lopencv_imgproc -lopencv_intensity_transform -lopencv_line_descriptor -lopencv_mcc -lopencv_ml -lopencv_objdetect -lopencv_optflow -lopencv_phase_unwrapping -lopencv_photo -lopencv_plot -lopencv_quality -lopencv_rapid -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_shape -lopencv_stereo -lopencv_stitching -lopencv_structured_light -lopencv_superres -lopencv_surface_matching -lopencv_text -lopencv_tracking -lopencv_videoio -lopencv_video -lopencv_videostab -lopencv_wechat_qrcode -lopencv_xfeatures2d -lopencv_ximgproc -lopencv_xobjdetect -lopencv_xphoto这时我们就可以正常地链接测试源码demo.cpp了
g demo.cpp pkg-config opencv --libs --cflags -o demo注意是反引号。
关于以上链接选项的稍微详细一些的介绍可以参考gcc参数 -i, -L, -l, -include。
这时我们就应该得到可执行文件demo了运行它我们可以得到一张Canny算子提取的图像边缘信息Canny.jpg整个过程没有报错的话则测试成功。
如果已经得到了可执行文件demo但是运行时报错找不到共享库请参考问题四。
常见问题及解决
问题一默认安装的头文件路径与搜索的头文件路径不匹配
找不到头文件报错通常是因为默认安装的头文件路径与搜索的头文件路径不匹配。opencv默认安装的头文件路径是/usr/local/include而我们搜索的默认路径在/usr/include。
遇到这种找不到头文件的报错请先到/usr/local/include/opencv4/opencv2路径下确认有自己的头文件然后直接软链接就行了
sudo ln -s /usr/local/include/opencv4/opencv2 /usr/include/关于软链接用法Linux软链接的使用详解Linux中的硬链接和软链接。
或者通过gcc的-I参数来指定头文件的搜索路径
g -c demo.cpp -I/usr/local/include问题二pkg-config的安装
下载、解压、安装、验证一气呵成
# 下载
wget https://pkg-config.freedesktop.org/releases/pkg-config-0.29.2.tar.gz
# 解压
tar -zxvf pkg-config-0.29.2.tar.gz
# 安装
cd pkg-config-0.29.2/
./configure
make
make check
sudo make install
# 验证
pkg-config --version
# 输出0.29.2 安装成功问题三OpenCV 4.5.4 可行的opencv.pc文件
这个是笔者自己写脚本提取的opencv.pc文件可能与官网安装时生成的不同但是亲测使用正常放到/usr/local/lib/pkgconfig目录下即可。
prefix/usr
exec_prefix${prefix}/local
includedir${prefix}/include
libdir${exec_prefix}/libName: opencv
Description: The opencv library
Version: 2.x.x
Cflags: -I${includedir}/opencv -I${includedir}/opencv2
Libs: -L${libdir} -lopencv_aruco -lopencv_barcode -lopencv_bgsegm -lopencv_bioinspired -lopencv_calib3d -lopencv_ccalib -lopencv_core -lopencv_datasets -lopencv_dnn_objdetect -lopencv_dnn -lopencv_dnn_superres -lopencv_dpm -lopencv_face -lopencv_features2d -lopencv_flann -lopencv_freetype -lopencv_fuzzy -lopencv_gapi -lopencv_hfs -lopencv_highgui -lopencv_imgcodecs -lopencv_img_hash -lopencv_imgproc -lopencv_intensity_transform -lopencv_line_descriptor -lopencv_mcc -lopencv_ml -lopencv_objdetect -lopencv_optflow -lopencv_phase_unwrapping -lopencv_photo -lopencv_plot -lopencv_quality -lopencv_rapid -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_shape -lopencv_stereo -lopencv_stitching -lopencv_structured_light -lopencv_superres -lopencv_surface_matching -lopencv_text -lopencv_tracking -lopencv_videoio -lopencv_video -lopencv_videostab -lopencv_wechat_qrcode -lopencv_xfeatures2d -lopencv_ximgproc -lopencv_xobjdetect -lopencv_xphoto问题四可执行文件运行时找不到共享库
由于我们Linux默认是动态链接的即有些共享库是在可执行文件运行时才链接进来的关于链接、装载与库可参考Linux下的ELF文件、链接、加载与库含大量图文解析及例程。因此我们正确地链接生成可执行文件demo之后并不能保证正确地运行可能会找不到共享库报错
./demo: error while loading shared libraries: libopencv_core.so.4.5: cannot open shared object file: No such file or directory我们还可以通过ldd命令来查看可执行文件所需要的共享库
$ ldd demolinux-vdso.so.1 (0x00007ffdd25b5000)libopencv_core.so.4.5 not foundlibopencv_imgcodecs.so.4.5 not foundlibopencv_imgproc.so.4.5 not foundlibstdc.so.6 /usr/lib/x86_64-linux-gnu/libstdc.so.6 (0x00007fdf87e92000)libgcc_s.so.1 /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fdf87c7a000)libc.so.6 /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdf87889000)libm.so.6 /lib/x86_64-linux-gnu/libm.so.6 (0x00007fdf874eb000)/lib64/ld-linux-x86-64.so.2 (0x00007fdf8841f000确实opencv相关的库都找不到但是这时我们到共享库目录/usr/local/lib/下去查看其实是有这个共享库的
$ ls -l /usr/local/lib/ | grep core
lrwxrwxrwx 1 root root 21 10月 7 19:55 libopencv_core.so - libopencv_core.so.4.5
lrwxrwxrwx 1 root root 23 10月 7 19:55 libopencv_core.so.4.5 - libopencv_core.so.4.5.4
-rw-r--r-- 1 root root 5247960 10月 7 11:42 libopencv_core.so.4.5.4既然有这个库还报找不到文件的错误那这就提醒我们是不是系统不知道要到这个目录下去找共享库。这时我们就应该通过指定环境变量LD_LIBRARY_PATH来告诉系统我们想要搜索的共享库目录。即通过以下命令将/usr/local/lib添加到共享库搜索目录的环境变量中
export LD_LIBRARY_PATH/usr/local/lib:$LD_LIBRARY_PATH添加之后我们可以直接先ldd来查看一下是否已经能够找到共享库
$ ldd demolinux-vdso.so.1 (0x00007ffc15975000)libopencv_core.so.4.5 /usr/local/lib/libopencv_core.so.4.5 (0x00007fb271fde000)libopencv_imgcodecs.so.4.5 /usr/local/lib/libopencv_imgcodecs.so.4.5 (0x00007fb271b1f000)libopencv_imgproc.so.4.5 /usr/local/lib/libopencv_imgproc.so.4.5 (0x00007fb271283000)libstdc.so.6 /usr/lib/x86_64-linux-gnu/libstdc.so.6 (0x00007fb270efa000)libgcc_s.so.1 /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fb270ce2000)libc.so.6 /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb2708f1000)libdl.so.2 /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fb2706ed000)libpthread.so.0 /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb2704ce000)librt.so.1 /lib/x86_64-linux-gnu/librt.so.1 (0x00007fb2702c6000)libz.so.1 /lib/x86_64-linux-gnu/libz.so.1 (0x00007fb2700a9000)libm.so.6 /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb26fd0b000)libjpeg.so.8 /usr/lib/x86_64-linux-gnu/libjpeg.so.8 (0x00007fb26faa3000)libpng16.so.16 /usr/lib/x86_64-linux-gnu/libpng16.so.16 (0x00007fb26f871000)libtiff.so.5 /usr/lib/x86_64-linux-gnu/libtiff.so.5 (0x00007fb26f5fa000)/lib64/ld-linux-x86-64.so.2 (0x00007fb27282d000)liblzma.so.5 /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007fb26f3d4000)libjbig.so.0 /usr/lib/x86_64-linux-gnu/libjbig.so.0 (0x00007fb26f1c6000)我们看到所需的共享库已经全部能够找到了。这时我们再运行即可得到正确结果。
其实总的来说这里的问题一对应的是编译时期头文件包含的问题问题二三对应的是链接时期使用pkg-conifg生成对应库文件的链接选项的问题而问题四对应的则是运行时期共享库搜索的环境变量配置的问题。所以说本文的这一节将一个动态链接的C库在Linux下编译、链接、加载运行各个阶段会出现的常见问题都涵盖到了。
总之以上就是笔者在编译、链接、加载运行含有OpenCV库的源代码时遇到的一些问题及解决方案了若有错误遗漏或读者如果有其他问题不能解决欢迎留言讨论。
Ref
https://blog.csdn.net/Charliewolf/article/details/101273248
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/92187.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!