交叉编译OpenCV 4.5.4(包含交叉编译环境配置)

为duo交叉编译平头哥为C906优化过的opencv

一、OpenCV源码获取

平头哥源码下载地址: 平头哥芯片开放社区-平头哥 (t-head.cn)
选择最新的OpenCV-V1.0.3.r0-20230426.tar.gz文件下载,需要注册账号。

论坛貌似不能上传附件,可能需要大家去下载下。

二、riscv-v交叉编译工具链获取

来源于算能平台编译好的,包括针对C906L的elf编译工具链及gnu、musl两个版本的工具链。

我选择带musl的工具链

Ubuntu下执行该命令即可从算能官方下载到交叉编译工具链
wget https://sophon-file.sophon.cn/sophon-prod-s3/drive/23/03/07/16/host-tools.tar.gz

三、riscv-v交叉编译工具链安装
下载完成后使用以下命令解压工具链

tar xvf host-tools.tar.gz即可解压,为了后面方便,创建一个环境导入脚本,后面soucre一下该脚本即可使用交叉编译工具链。

使用以下命令:
cd host-tools —进入交叉编译工具链目录
touch riscv-crosstool-env-init —创建脚本
vi riscv-crosstool-env-init —修改脚本

粘贴以下内容,

HOST_TOOL_PATH=/home/xxx/milk-v/CV180x/host-tools

export PATH="$HOST_TOOL_PATH/gcc/riscv64-linux-x86_64/bin:$HOST_TOOL_PATH/gcc/riscv64-linux-musl-x86_64/bin:$HOST_TOOL_PATH/gcc/riscv64-elf-x86_64/bin:$PATH"

echo -e "\033[33;1mriscv交叉编译工具链环境配置完成!\033[0m"

请将HOST_TOOL_PATH后的路径更改为自己工具链路径,可以通过在该文件打开shell输入pwd方式获得。

ESC :q方式保存该文件

后续每次使用只需要source该文件,即可使用交叉编译工具链
image

输入riscv64,然后TAB,即可查看当前的gcc工具链安装完成。1区域的工具链是实时系统编译固件工具链,2、3区域为Linux应用编译的工具链。

四、OpenCV的交叉编译
将平头哥社区下到的OpenCV源码解压
tar xvf OpenCV-V1.0.3.r0-20230426.tar.gz

在OpenCV/platforms/linux/文件下,复制一份riscv64-gcc.toolchain.cmake重命令为riscv64-musl-gcc.toolchain.cmake,然后编译器打开修改为下图

该版本cmake里会检查build不能在源码文件里,不然会cmake命令会报错,所以我们在与源码同级目录下创建一个build目录,使编译产生的文件在此。
mkdir OpenCV_build

进入该目录
cd OpenCV_build

执行编译
cmake /home/yxm/milk-v/CV180x/OpenCV -DCMAKE_TOOLCHAIN_FILE="/home/yxm/milk-v/CV180x/OpenCV/platforms/linux/riscv64-musl-gcc.toolchain.cmake" -DWITH_OPENCL=OFF -DBUILD_opencv_calib3d=ON -DBUILD_ZLIB=ON -DBUILD_PNG=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_WITH_INSTALL_RPATH=1 -DCMAKE_INSTALL_PREFIX=./c906_install -DBUILD_CSI_CV=ON -DWITH_OPENMP=OFF -DWITH_PTHREADS_PF=OFF -DCORE=C906FDV -D BUILD_SHARED_LIBS=ON -D BUILD_opencv_features2d=ON -D BUILD_opencv_apps=OFF -D BUILD_TESTS=OFF -D BUILD_opencv_highgui=OFF -D BUILD_PERF_TESTS=OFF

/home/xxx/milk-v/CV180x/OpenCV —为解压的OpenCV源码文件路径
-DCMAKE_TOOLCHAIN_FILE="/home/yxm/milk-v/CV180x/OpenCV/platforms/linux/riscv64-musl-gcc.toolchain.cmake" —前面的路径替换为本机实际的路径
-DCMAKE_INSTALL_PREFIX=./c906_install —后续make install的路径,可以自己修改
-DCORE=C906FDV —可以看到平头哥为C906优化的主要在此。

然后可以看到cmake自动生成编译相关配置文件

如果如此打印,没有报错信息,即可开始编译。

make -j4 —j后面取决于你的机器

等待编译完成,我这老的笔记本虚拟机大概几分钟,完成编译。

安装
make install


安装完成大概如上图。

cd .. 进入上一级目录即可看到编译安装的文件了
在build下的的目录会被创建一个c906_install/文件
image


至此,OpenCV交叉编译完成。

四、测试

Ubuntu构建测试程序,我们尝试将一张图片灰度会
创建一个main.cpp

#include <ctime>
#include <iostream>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc/types_c.h>
using namespace cv;

int main(int argc, char **argv) {
    Mat image;
    image = imread("./demo.jpg");
    if(!image.data)
    {
        printf("no image data (./demo.jpg)\n");
        return -1;
    }
    else
    {
        printf("read image succes!");
    }

    Mat dst;
    cvtColor(image, dst, CV_BGR2GRAY);
    imwrite("image.jpg", dst);
    printf("change succes!\n");
    return 0;
}

创建一个CMakeLists.txt文件采用cmake构建工程

cmake_minimum_required(VERSION 3.16.5)

project(opencv_test_demo)

set(CMAKE_CROSSCOMPILING TRUE)

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR riscv64)


set(CMAKE_CXX_STANDARD 11)

#没有配置环境,就下面配置绝对路径
#set(TOOLCHAIN_DIR "/home/yxm/milk-v/CV180x/host-tools/gcc/riscv64-linux-x86_64/bin")
#set(CMAKE_C_COMPILER "${TOOLCHAIN_DIR}/riscv64-unknown-linux-musl-gcc")
#set(CMAKE_CXX_COMPILER "${TOOLCHAIN_DIR}/riscv64-unknown-linux-musl-g++")

#配置了环境,直接运行
set(CMAKE_C_COMPILER "riscv64-unknown-linux-musl-gcc")
set(CMAKE_CXX_COMPILER "riscv64-unknown-linux-musl-g++")

#set(CMAKE_C_COMPILER_FORCED TRUE)
#set(CMAKE_CXX_COMPILER_FORCED TRUE)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=rv64imafdcvxthead -mcmodel=medany -mabi=lp64d")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=rv64imafdcvxthead -mcmodel=medany -mabi=lp64d")

#本机实际交叉编译出来的opencv库的路径
set(OPENCV_PATH /home/yxm/milk-v/CV180x/OpenCV_build/c906_install)


include_directories(${OPENCV_PATH}/include/opencv4)
link_directories(${OPENCV_PATH}/lib)
set(OPENCV_LIBS ${OPENCV_LIBS} opencv_core opencv_imgcodecs opencv_imgproc)

add_executable(${PROJECT_NAME} main.cpp)

target_link_libraries(${PROJECT_NAME} ${OPENCV_LIBS})

调用交叉编译工具链编译

mkdir build
cd build    
cmake .. -DCMAKE_C_COMPILER=riscv64-unknown-linux-musl-gcc -DCMAKE_CXX_COMPILER=riscv64-unknown-linux-musl-g++
make

opencv_test_demo 编译出来的目标文件。

将上一步编译生成的opencv c906_install/lib下的so文件全部拷贝进duo文件系统/usr/lib下
测试程序opencv_test_demo导入目标板,运行即可实现对demo.jpg图片的灰度化。

五、安装包及开发环境
提供一个懒人包,直接可以上面使用
image
由于论坛无法上传文件,上传到了官方的企信群。

六、运行demo出错处理

image

在编译环境查看是差什么环境

查看板子环境

发现名字有细微差异,不知道是什么原因,可能是编译时候选的环境有关???

那么我们创建一个这个运行依赖。

ln -s /usr/lib64v0p7_xthead/lp64d/libc.so /lib/ld-musl-riscv64v_xthead.so.1

再次运行demo

4 Likes

感谢 大佬 可以否投喂一个编译好的固件 :grinning:


关于Linux的交叉编译选哪一个,看系统内核编译用的那个,使用cat /proc/version可以获得

请把你的收件地址及论坛身份证明信息(可以是登陆后的截图)发送至邮箱:hoka@milkv.io

我会送你一个小礼品。可能会是未发售的SBC。

编译好的库和头文件及安装到duo板的安装包github获取链接

太棒了,保姆级教程。在遇到not found问题时,看到帖子的方法,解决后真是豁然开朗。感谢大佬

你好,我按照你的步骤后出现了这个情况,这是什么原因导致的呢,排查了下路径是没有问题,感谢大佬的回复

你这个报错是编译测试程序,cmake没有找到库,没看到你本地文件详情我也不太清楚。这个demo是个很简单的示例,排查起来很快,如果你熟悉makefile也可以自己写个makefile。

我支持使用命令行去编译也是报了一样的问题,不知道怎么回事,

riscv64-unknown-linux-musl-g++ main.cpp -o main -I /home/cz/cyy/duo/duo-buildroot-sdk/project/OpenCV/OpenCV_build/milkv_duo_install/include/opencv4/ -L /home/cz/cyy/duo/duo-buildroot-sdk/project/OpenCV/OpenCV_build/milkv_duo_install/lib/ -lopencv_core

你好可以了,应该是之前编译的opencv库有问题,库是 version 1 (GNU/Linux) 格式的,重新编译了一遍cv库就可以了version 1 (SYSV) 。

您好,我按您的教程逐步进行到在板子上运行测试时报错,请问可以帮忙看一下嘛?

我替换我编译出的so文件为您共享在github上的so文件后,重新传入duo开发板后测试没有报错。虽然我不清楚我之前的错误是什么(如果有人知道,请告诉我原因,谢谢),但现在它总算可以用了,感谢您的分享!

可能是编译时候cmake的参数不一致,你重点看下那部分把,交叉编译无非就是设置好工具链后,然后编译的配置、修改。