嵌入式linux学习之opencv交叉编译/移植并使用CmakeList编译demo

1.下载opencv源码

OpenCV官方源码下载链接为https://opencv.org/releases/,选择3.4.16版本下载。放在ubuntu系统~/opencv文件夹中,解压缩,opencv文件夹中新建build和install文件夹用于存放编译文件和安装文件:
在这里插入图片描述

2. 安装编译工具

  • 安装 cmake 和 cmake-gui 工具
    sudo apt-get install cmake cmake-qt-gui cmake-curses-gui
  • 安装交叉编译器arm-none-linux-gnueabihf

3.安装opencv前安装环境依赖

sudo apt-get install build-essential
sudo apt-get install libopenblas-dev
sudo apt-get install git pkg-config libavcodec-dev libavformat-dev libswscale-dev

处理图像所需的包

sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff5-dev libdc1394-22-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev liblapacke-dev

处理视频所需的包

sudo apt-get install libxvidcore-dev libx264-dev

优化opencv功能

sudo apt-get install libatlas-base-dev gfortran
sudo apt-get install ffmpeg

4. 编译

进入build文件夹
命令cmake-gui
执行完成后会出现图形化工具 cmake-gui,选择源代码目录,buid目录
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在 CMAKE_EXE_LINKER_FLAGS 处添加上-lpthread -lrt -ldl。添加这些是是指定依赖库的链接
在这里插入图片描述
CMAKE_INSTALL_PREFIX 处指定安装目录,我们在上面已经新建了 install 安装目录。
我们直接指定到该目录即可。如果不指定,它会默认安装到 Ubuntu 系统目录/usr/local 下。
在这里插入图片描述
BUILD_TESTS取消勾选
在这里插入图片描述
在源码目录 opencv-3.4.1/3rdparty/protobuf/src/google/protobuf/stubs/common.cc 这个文件下添加#define HAVE_PTHREAD 宏定义才可以编译的过。具体原因是 HAVE_PTHREAD 宏定义了 pthread 库。
在这里插入图片描述
进入 build 目录下,可以看到 bulid 目录下已经准备了构建文件。我们直接输入 make 构建即可。结束后make nstall
编译完成如下图,如果有出错,先删除 build 目录下的所有文件,cmake-gui开始重新再来一次!
在这里插入图片描述
这是可以将这个文件夹中的文件用于程序编写并和可执行文件一同传输至开发板

问题汇总:

问题1:

/arm-none-linux-gnueabihf/libc/usr/include/features.h:311:52: error: operator ‘&&’ has no right operand
#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64

解决1:

在#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64前面 加上
#define _FILE_OFFSET_BITS 64

问题2

make[1]: *** [modules/core/CMakeFiles/opencv_test_core.dir/all] Error 2
Makefile:160: recipe for target ‘all’ failed
make: *** [all] Error 2

解决2

configure配置中取消BUILD_TESTS

问题3

usr/lib/gcc-cross/aarch64-linux-gnu/8/…/…/…/…/aarch64-linux-gnu/bin/ld: …/…/lib/libopencv_imgcodecs.so.4.2.0: undefined reference to `png_riffle_palette_neon’
collect2: error: ld returned 1 exit status
make[2]: *** [apps/annotation/CMakeFiles/opencv_annotation.dir/build.make:89:bin/opencv_annotation] 错误 1
make[1]: *** [CMakeFiles/Makefile2:3746:apps/annotation/CMakeFiles/opencv_annotation.dir/all] 错误 2

解决3:

./opencv-3.3.1/3rdparty/libpng/pngpriv.h

/*# if (defined(ARM_NEON) || defined(__ARM_NEON)) && */
#if defined(PNG_ARM_NEON) && (defined(ARM_NEON) || defined(__ARM_NEON)) &&
如上所示,把上面的一行注释掉,增加下面一行。删除build文件夹内容,在cmake-gui再次生成文件,再次make即可。
在这里插入图片描述

问题4

arm-linux-gnueabihf/bin/ld: …/…/lib/libopencv_imgcodecs.so: undefined reference to png_do_expand_palette_rgb8_neon' ./../../../arm-linux-gnueabihf/bin/ld: ../../lib/libopencv_imgcodecs.so: undefined reference to png_init_filter_functions_neon’
…/lib/libopencv_imgcodecs.so: undefined reference to `png_init_filter_functions_neon’

解决4:

在最上面加上添加如下语句:
SET(ARM 1)
SET(ENABLE_NEON 1)
添加完成后在root权限下重新运行cmake-gui,重新配置和生成。

问题5

想用opencv v4l调用usb/csi摄像头的话,需要cmake-gui中勾选WITH_V4L和WITH_LIBV4L
但是使用常规编译器GCC和G++才会出现上面两个选项,使用交叉编译器不会出现。

解决5

这里名字为Linux,L大写即可出现选项,不用v4l随便命名即可

在这里插入图片描述

问题6

交叉编译4.9.0版本opencv是,在cmake-gui中出现error in configuration process,project files may be invalid

解决6

根据上面的错误定位到libjpeg-turbo的CmakeLists.txt中,${CMAKE_SYSTEM_PROCESSOR} 无输出
在这里插入图片描述
在这行之前输入:
set(CMAKE_SYSTEM_NAME Linux) #设置目标系统名字
set(CMAKE_SYSTEM_PROCESSOR arm) #设置目标处理器架构

移植

1. 编译完成在install目录中有bin/include/lib等文件其中include存放的头文件,lib存放的libopencv*.so库文件在这里插入图片描述

2.在任何位置创建一个文件夹demo,编写测试程序gpio.cpp\CMakeLists.txt、rv1103.cmake,完成功能:从板内读取一张图片,转为灰度图片并保存。

(1) gpio.cpp:

#include <opencv2/opencv.hpp>  
#include <iostream>  
using namespace cv;  
using namespace std;  
int main() {  	
	// 读取图片  
    cv::Mat image = cv::imread("result.jpg");  
    // 检查图片是否成功读取  
    if (image.empty()) {  
        std::cout << "Could not read the image: " << "path_to_your_image.jpg" << std::endl;  
        return -1;  
    }  
    // 创建灰度图像矩阵  
    cv::Mat grayImage;  
    // 将彩色图像转换为灰度图像  
    cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);  
    cv::imwrite("reshui.jpg",grayImage);
	 // 等待按键,如果按下'q'键则退出循环  
	waitKey(1);  
    }  
    return 0;  
}

(2) CMakeLists.txt:

cmake_minimum_required(VERSION 3.0)
project(opencv)
set(include_DIR /home/tao/opencv/opencv-rv1103/install/include)# 设置OpenCV的include路径
set(lib_DIR /home/tao/opencv/opencv-rv1103/install/lib)# 设置OpenCV的lib路径
include_directories(${include_DIR})# 设置包含的头文件路径
link_directories(${lib_DIR})# 设置库文件路径
add_executable(gpio gpio.cpp)# 将源文件添加到此项目的可执行文件。
file(GLOB LIBRARIES ${lib_DIR}/*.so) #链接 lib 文件夹下所有的库文件 假设是 .so 文件,如果是其他格式,请相应调整
target_link_libraries(gpio ${LIBRARIES})

(3)rv1103.cmake

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(tools /home/tao/linux/luckfox/luckfox-pico-main/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/)#交叉编译器目录
set(CMAKE_C_COMPILER ${tools}/bin/arm-rockchip830-linux-uclibcgnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-rockchip830-linux-uclibcgnueabihf-g++)
set(CMAKE_AR ${tools}/bin/arm-rockchip830-linux-uclibcgnueabihf-ar)
set(CMAKE_RANLIB ${tools}/bin/arm-rockchip830-linux-uclibcgnueabihf-ranlib)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

(4)创建一个空目录build用于存放编译生成文件
结果如下:
在这里插入图片描述

有些编译器出现对‘pthread_create’未定义,对‘dladdr’未定义的引用

则CMakeLists.txt最后改为:链接上pthread和dl库
在这里插入图片描述

如果想包含多个路径下的头文件和库文件:定义其它路径变量,在include_directories内添加多个变量即可,中间空格隔开。

在这里插入图片描述

如果出现cpp程序报错:invalid conversion from ‘void*’ to ‘short unsigned int*’ [-fpermissive]

则可以在CMakeLists.txt中添加编译选项:target_compile_options(gpio PRIVATE -fpermissive)
在这里插入图片描述

3.交叉编译

(1) cmake -DCMAKE_TOOLCHAIN_FILE=…/rv1103.cmake …#两个…不是…
(2)make
(3)如果失败,修改问题后需要删除build文件夹内容再cmake指令
在这里插入图片描述

4.传输至开发板子

将build文件夹内生成的gpio可执行文件及最开始opencv编译生成的install文件夹内的东西复制到开发板(可以不在同一个文件夹):
在这里插入图片描述

5. chmod -r 777 ./*赋予权限

此时运行会报错找不到库,需要指定库路径:export LD_LIBRARY_PATH=/home/root/install/lib:$LD_LIBRARY_PATH指定opencv编译生成的lib文件夹路径临时有效,也可以修改/etc/ld.so.conf文件永久生效,如果export后仍然报错…/…/lib*so找不到,那就是可执行文件与库的位置与虚拟机中的相对位置不同。

6. ./gpio执行,如果gpio所在文件夹内存放有result.jpg则会读取图片生成灰度图像

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值