UbuntuX86_64交叉编译opencv为arm64架构

目录


简介

通过在ubunbu上编写编写程序可以打开工程文件下的一个视频,通过交叉编译可以使这个程序可以在树莓派上运行出来,即在树莓派上可以运行可执行文件打开视频。
这是我做好成品链接

一、在 Ubuntu X86_64 的主机上安装 OpenCV

1.安装make

sudo apt-get install  make

2.安装cmake

2.1获取安装包

wget https://cmake.org/files/v3.18/cmake-3.18.0-Linux-x86_64.tar.gz

2.2解压压缩包

tar zxvf cmake-3.18.0-Linux-x86_64.tar.gz

2.3安装

sudo mv cmake-3.18.0-Linux-x86_64 /opt/cmake-3.18.0
sudo ln -sf /opt/cmake-3.18.0/bin/*  /usr/bin/

2.4安装检测

cmake -version
cmake-gui -version
ccmake -version
cpack -version
ctest -version


3.安装依赖环境

sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev
sudo apt-get install libcanberra-gtk-module
sudo apt-get install pkg-config


4.通过官网下载opencv源码解压到ununtu的目录中

下载地址:https://opencv.org/releases/
在这里插入图片描述点击sources下载源码,我下载的4.5.5的源码
将下载完成的源码解压到ubuntu中


5.编译源码以及安装

5.1进入opencv源码目录中,新建build文件夹

cd /home/yunyu/opencv-4.5.5 #路径一般默认/usr/local可以根据自己喜好在解压的时候选择自己喜欢的路径
mkdir build 

在这里插入图片描述

5.2进入build文件夹,打开终端cmake生成makefile

cd /home/yunyu/opencv-4.5.5
cmake -D CMAKE_BUILD_TYPE=Release -D OPENCV_GENERATE_PKGCONFIG=ON -D CMAKE_INSTALL_PREFIX=/usr/local/opencv4.5.5 #路径自己选择需要下载安装到哪里.. 

5.3等待编译完成之后执行make

sudo make

这段时间编译时间较长

5.4代码完成编译后,进行安装

sudo make install

6.配置环境变量

6.1打开文件 /etc/ld.so.conf,在最后一行加上 /usr/local/opencv4.5.5/lib

注解:/etc/ld.so.conf 此文件记录了编译时使用的动态库的路径,也就是加载so库的路径。默认情况下,编译器只会使用/lib和 /usr/lib 这两个目录下的库文件,而通常通过源码包进行安装时,如果不指定 --prefix会将库安装在 /usr/local 目录下,而又没有在件/etc/ld.so.conf中添加/usr/local/lib这个目录>。这样虽然安装了源码包,但是使用时仍然找不到相关的.so库,就会报错。也就是说系统不知道安装了源码包。

sudo gedit /etc/ld.so.conf

在这里插入图片描述对于此种情况有2种解决办法:
1)在用源码安装时,用–prefix指定安装路径为/usr/lib。这样的话也就不用配置PKG_CONFIG_PATH
2) 直接将路径/usr/local/lib路径加入到文件/etc/ld.so.conf文件的中。在文件/etc/ld.so.conf中末尾直接添加:/usr/local/lib

(这个路径根据自己安装的opencv位置来更改)

6.2运行ldconfig

作用:它的作用是将文件/etc/ld.so.conf列出的路径下的库文件缓存到/etc/ld.so.cache以供使用,因此当安装完一些库文件,或者修改/etc/ld.so.conf增加了库的新的搜索路径,需要运>行一下ldconfig,使所有的库文件都被缓存到文件/etc/ld.so.cache中,如果没做,可能会找不到刚安装的库。

sudo ldconfig

6.3修改bash.bashrc

sudo gedit /etc/bash.bashrc 

注解:PKG_CONFIG_PATH这个环境变量,它是在安装了pkg-config后出现的,其实pkg-config就是向configure程序提供系统信息的程序,比如软件的版本,库的版本,库的路径
PKG_CONFIG_PATH 指明 xxx.pc 文件(包配置文件,保存了库的头文件,库所在的路径信息比如编译某个工程用到glib-2.0这个库,pkg-config会按照PKG_CONFIG_PATH中的路径行搜索glib-2.0.pc,然后把lib-2.0.pc作为参数传给GCC,那么GCC就可以找到该库了)的路径。

文件末尾添加

PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opencv4.5.5/lib/pkgconfig
export PKG_CONFIG_PATH

6.4检测opencv是否安装成功

pkg-config opencv --modversion

如果显示还是没有成功可能是因为没有opencv.cv这个文件,就手动创建这个文件放在opencv路径下lib文件中的pkgconfig文件下

cd /usr/local/opencv4.5.5/lib/pkgconfig
touch opencv.pc
sudo gedit opencv.pc

文件内容

prefix=/usr/local/opencv4.5.5#opencv的安装路径
exec_prefix=${prefix}
includedir=/usr/local//opencv4.5.5include
libdir=/usr/local//opencv4.5.5lib
 
Name: OpenCV
Description: Open Source Computer Vision Library
Version: 4.4.0
Libs: -L${exec_prefix}/lib -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dpm -lopencv_face -lopencv_photo -lopencv_freetype -lopencv_fuzzy -lopencv_hdf -lopencv_hfs -lopencv_img_hash -lopencv_line_descriptor -lopencv_optflow -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_surface_matching -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_dnn -lopencv_plot -lopencv_xfeatures2d -lopencv_shape -lopencv_video -lopencv_ml -lopencv_ximgproc -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_flann -lopencv_xobjdetect -lopencv_imgcodecs -lopencv_objdetect -lopencv_xphoto -lopencv_imgproc -lopencv_core
Libs.private: -ldl -lm -lpthread -lrt
Cflags: -I${includedir}


7.通过具体的程序来检测opencv是否安装成功

7.1创建工程文件demo,在其中创建build,src,include,lib文件夹以及CMakeLists.txt文件(检测的时候可以暂时不用直接创建include和lib,直接用系统本身的)

  1. List item1.src文件夹放.c/.cpp文件;
  2. include文件夹放.h文件;
  3. lib文件夹放库文件.a/.so;
  4. build文件夹用于放cmake运行产生的多个文件,这个文件名可以是其他,如my_build。因为还没有cmake CMakeLists.txt,所以build文件夹下还没有任何文件。
cd /home/yunyu/文档/cpp
mkdir demo
cd demo
mkdir build src && touch CMakelists.txt

7.2把图片放在demo文件下

在这里插入图片描述

7.3编写一个opencv程序

cd src && gedit zzing.cpp
//进入src文件夹后创建并编辑zzing.cpp

代码

#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"

using namespace std;
using namespace cv;

int main() {
    Mat img = imread("../1.png");
    if (img.empty()) {
	cout <<"error,unable to open picture"<< endl;
	return -1;
    }    
	imshow("img", img);
	waitKey(0);    
    return 0;
}

7.4编写CMakeLists.txt文件

cd ../ && gedit CMakeLists.txt
// 返回上一级后编辑CMakeLists.txt

打开文件写入命令

cmake_minimum_required(VERSION 2.8)	#声明cmake需要的最低版本
project(Demo)	#声明cmake项目的名称

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

find_package(OpenCV REQUIRED)

include_directories(${OpenCV_INCLUDE_DIRS})	#添加OpenCV头文件
add_executable(${PROJECT_NAME} src/zzing.cpp)	#生成可执行文件,这里我把可执行文件名称定义成项目名称
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})	#链接OpenCV库文件到cmake项目上

  • cmake_minimum_required() 需要的最低cmake版本
  • List item
  • project() 生成的项目名称
  • set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
    这两个命令指定编译类型为C++
  • 如果是CMAKE_C_STANDARD则为C
  • find_package(OpenCV REQUIRED)
    这个命令会在系统内寻找OpenCV的路径,找前文提到的OpenCVConfig.cmake,注意大小写。
  • ${OpenCV_INCLUDE_DIRS}和 ${OpenCV_LIBS}分别是OpenCV的头文件和库文件包含路径,来自find_package(OpenCV REQUIRED)。

7.5完成CMakeLists.txt编写后进行cmake

cd build
cmake ..	//注意是空格后..  是camke前面目录中的CMakeLists.txt
make -j8	//-j8和进程有关,可以是make/make -4/make -j6

出现下面的情况就是成功了
在这里插入图片描述在这里插入图片描述

7.6运行程序

./Demo

二、对opencv进行交叉编译(cmake-gui)

1.打开安装好的opencv目录,创建文件夹build和install(用来放交叉编译好的opencv文件)

cd /home/yunyu/opencv-4.5.5
mkdir build install

2.下载交叉编译工具aarch64

  • 下载需要的版本到默认文件夹下一般就在/usr/bin下

3.用cmake-gui配置

3.1打开cmake-gui,如果没有就安装

sudo apt-get install
cmake-gui

3.2 where is the source code填写opencv源码路径,where to build the binaries填写opencv源码文件夹中创建的build路径

在这里插入图片描述

3.3点击Configure

在这里插入图片描述

3.4选择如下

在这里插入图片描述

3.5进入后配置

  • Target System →Operating System 填写Linux (L大写,填入其他如:linux-arm,后面configure会出现错误);
  • Compliers → C and Complier → C++填入对应交叉编译工具链gcc和g++路径;
  • Target Root: 交叉编译工具链bin目录路径
  • Finish; 无报错
    在这里插入图片描述安装路径
    在这里插入图片描述

4.开始编译

4.1进入build目录,进行编译(时间较长)

sudo make -j8

4.2可能错误

  • 第一种

在这里插入图片描述进入交叉编译工具文件下修改features.h

sudo gedit /opt/pkg/gcc_linaro/gcc-arm-8.2-2018.11-x86_64-aarch64-linux-gnu/aarch64-linux-gnu/libc/usr/include/features.h
#define_FILE_OFFSET_BITS 64
//添加内容

在这里插入图片描述

  • 第二种
    在这里插入图片描述进入/home/yunyu/opencv-4.5.5/3rdparty/libpng/pngpriv.h

将这一段代码

# if (defined(ARM_NEON) || defined(__ARM_NEON)) && */

改成

# if defined(PNG_ARM_NEON) && (defined(ARM_NEON) || defined(__ARM_NEON)) && \

4.3编译成功


5.在build目录执行make install

sudo make install 

6.进入install查看是否有编译好的文件就算完成交叉编译

二、对opencv进行交叉编译(cmake)

1.打开安装好的opencv目录,创建文件夹arm_build和arm_install(用来放交叉编译好的opencv文件)

cd /home/yunyu/opencv-4.5.5
mkdir arm_build arm_install

2.下载交叉编译工具aarch64

  • 下载需要的版本到默认文件夹下一般就在/usr/bin下

3.用cmake配置

cmake \
-D CMAKE_C_COMPILER=/usr/bin/aarch64-linux-gnu-gcc \
-D CMAKE_CXX_COMPILER=/usr/bin/aarch64-linux-gnu-g++ \
-D CMAKE_SYSTEM_NAME=Linux \
-D CMAKE_SYSTEM_PROCESSOR=aarch64  \
-D CMAKE_INSTALL_PREFIX= /home/yunyu/opencv-4.7.0/arm_install \
-D ENABLE_NEON=ON \
-D WITH_CUDA=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_PERF_TESTS=OFF \
..

4.开始编译

4.1进入build目录,进行编译(时间较长)

sudo make -j4

4.2编译成功


5.在build目录执行make install

sudo make install 

6.进入arm_install查看是否有编译好的文件就算完成交叉编译

三、移植程序到树莓派上

1.进入工程文件夹下创建新的工程文件

cd /home/yunyu/文档/cpp
mkdir ke
cd ke
mkdir build src && touch CMakeLists.txt

2.将交叉编译好的opencv的inculde,和lib放入build文件夹中


3.进入src创建cpp文件

cd src
gedit kk.cpp
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
//这里包含了所需要的头文件,包括iostream、opencv.hpp和highgui.hpp。
using namespace std;
using namespace cv;
//这里定义了两个命名空间,std和cv,以便后面的代码可以直接使用这些命名空间中定义的函数和变量,而不需要每次都写命名空间前缀。

int main(int argc,char** argv)
//这是程序的主函数。它的参数argc和argv用于从命令行读取参数,argc表示命令行参数的数量,argv是一个指向字符串数组的指针,其中每个字符串都是一个命令行参数。
{
    char *video_url;
    video_url = argv[1];
    //这里定义一个指向char类型的指针video_url,用于存储从命令行读取的视频文件的路径。第二行代码将argv[1]中的内容赋值给video_url。
    VideoCapture cap(video_url);

    if(!cap.isOpened())
    {
        std::cout << "Error: could not open video file" << std::endl;
        return -1;
    }
//这里定义一个VideoCapture对象cap,用于读取视频文件。如果无法打开视频文件,就输出错误信息并退出程序。
    while(true)
    {
        Mat frame;
        cap >> frame;

        if(frame.empty())
        {
            break;
        }

        imshow("Video", frame);

        if(waitKey(25) == 'q')
        {
            break;
        }
    }
//这是一个无限循环,用于读取视频帧并显示它们。在每次迭代中,它会创建一个Mat对象frame,用于存储从视频文件中读取的一帧图像。然后,它使用cap >> frame语句将视频帧读入frame中。

//如果frame为空,则说明已经读取完所有的视频帧,程序将跳出循环。否则,它将使用imshow函数将帧显示在名为“Video”的窗口中。

//waitKey(25)函数会等待25毫秒并读取键盘输入。如果按下了‘q’键,程序将跳出循环。
    cap.release();
    destroyAllWindows();
    printf("%s", video_url);
    return 0;
}
//这里释放VideoCapture对象的资源,并关闭所有显示的窗口。最后输出从命令行读取的视频文件的路径,并返回0以表示程序正常结束。


4.编写CMakeLists.txt文件

# 指定 CMake 的最低版本
cmake_minimum_required(VERSION 3.0)

# 指定项目名称
project(Newcross)

# 设置交叉编译器路径
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)
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(BUILD_EXAMPLES ON)
set(BUILD_DOCS OFF )
set(BUILD_TESTS OFF)
set(BUILD_PERF_TESTS OFF)
LINK_DIRECTORIES(/usr/local/lib/ /usr/lib)

# 指定交叉编译工具链文件
set(CMAKE_TOOLCHAIN_FILE /home/yunyu/opencv-4.7.0/platforms/linux/aarch64-gnu.toolchain.cmake)   


set(CMAKE_BUILD_RPATH "/usr/local/lib;/home/yunyu/文档/cpp/newcross/build/lib;../newcross/build/lib")
# 设置OpenCV库路径
set(OpenCV_DIR /home/yunyu/文档/cpp/newcross/build/lib/cmake/opencv4/ )

# 寻找OpenCV库
find_package(OpenCV REQUIRED)

# 添加可执行文件
add_executable(Newcross /home/yunyu/文档/cpp/newcross/src/five.cpp)

# 链接OpenCV库
target_link_libraries(Newcross ${OpenCV_LIBS}  )


5.进入build进行编译

cd build 
cmake ..
make

6.完成编译得到可执行文件KE

在这里插入图片描述

7.将ke文件压缩为tar压缩包

在这里插入图片描述

8.通过u盘拷贝到树莓派上

四、进行程序的运行

1.将压缩包解压

tar -xvf ke.tar.xz

2.进入工程文件的build,运行可执行文件

cd build
./KE

报错一:
在这里插入图片描述解决方法:

## 下面的操作在树莓派上进行
```bash
sudo find / -name "libopencv_highgui.*"
sudo find / -name "libopencv_videoio.*"
sudo find / -name "libopencv_core.*"
# 看有没有找到相关的文件类似 /usr/lib/aarch64-linux-gnu/libopencv_highgui.so
# /usr/lib/aarch64-linux-gnu/libopencv_videoio.so
# /usr/lib/aarch64-linux-gnu/libopencv_core.so
# 如果不一样就把你搜出来的路径替换/usr/lib/aarch64-linux-gnu/xxxxx
cd /usr/lib
sudo ln -s /usr/lib/aarch64-linux-gnu/libopencv_highgui.so libopencv_highgui.so.405
sudo ln -s /usr/lib/aarch64-linux-gnu/libopencv_videoio.so libopencv_videoio.so.405
sudo ln -s /usr/lib/aarch64-linux-gnu/libopencv_core.so libopencv_core.so.405
这样以后应该就可以显示了

但是后面还是出现报错二:
在这里插入图片描述解决方案:
这边显示的是找不到视频路径,修改代码把路径换成绝对路径
然后在ubuntu重新编译再拷贝到树莓派上

./KE /home/yunyu/Documents/ke/0001.mp4

还要注意主机和目标系统版本不统一的问题

3.运行成功

./KE /home/yunyu/Documents/ke/0001.mp4

在这里插入图片描述

更多推荐