为Nanopi m1交叉编译opencv

为Nanopi m1交叉编译opencv

一、下载交叉编译器

根据之前的博客进行

二、下载opencv和必要库

sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
git clone https://github.com/opencv/opencv.git
cd opencv

三、进行编译

  1. 创建cmake文件
nano toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

# 指定交叉编译器位置
set(CMAKE_C_COMPILER /opt/nanopi-toolchain/bin/arm-cortexa9-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER /opt/nanopi-toolchain/bin/arm-cortexa9-linux-gnueabihf-g++)

# 指定系统根目录(sysroot),这是必需的以便编译器找到正确的库和头文件
set(CMAKE_FIND_ROOT_PATH /opt/nanopi-toolchain/arm-cortexa9-linux-gnueabihf/sys-root)
  1. 创建build文件
mkdir build
cd build
  1. 创建cmake指令
    这里将opencv的编译install输出放到了output文件夹中
cmake -D CMAKE_BUILD_TYPE=Release \
      -D CMAKE_INSTALL_PREFIX=../output \
      -D BUILD_SHARED_LIBS=ON \
      -D WITH_JPEG=ON \
      -D CMAKE_TOOLCHAIN_FILE=../toolchain.cmake \
      -D BUILD_EXAMPLES=OFF \
      -D WITH_IPP=OFF \
      -D WITH_TBB=OFF \
      -D BUILD_TESTS=OFF \
      -D BUILD_PERF_TESTS=OFF \
      -D ENABLE_NEON=ON \
      -D ENABLE_VFPV3=ON \
      -D CMAKE_C_FLAGS="-std=gnu99" \
      -D CMAKE_CXX_FLAGS="-std=c++14" \
      -D BUILfD_opencv_python2=OFF \
      -D BUILD_opencv_python3=OFF \
      -D BUILD_opencv_java=OFF \
      -D WITH_OPENCL=OFF \
      -D WITH_CUDA=OFF \
      -D WITH_GTK=OFF \
      -D WITH_VTK=OFF \
      -D BUILD_opencv_gapi=OFF ..  # 禁用G-API模块
  1. make编译
make -j12
  1. 错误后的处理
    如果编译错误,可通过以下指令删除build中的文件
# cd build
rm -rf *
  1. 编译安装
    由于修改了-D CMAKE_INSTALL_PREFIX=../output,因此编译安装的文件输出到了output文件夹中
sudo make install

四、进行scp传输到M1

  1. 进入output文件夹,使用scp发送这两个文件夹中的内容到m1
cd ../output
scp -r lib/* pi@192.168.10.197:/usr/local/lib/
scp -r include/* pi@192.168.10.197:/usr/local/include/
  1. 问题处理:如果显示没有权限,则可以通过一个temp文件夹进行转存

五、进行测试

  1. 在nano pi m1中写一个test_opencv.cpp文件
#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 替换下面的路径为一个实际的图片文件路径
    cv::Mat img = cv::imread("/home/pi/head.png", cv::IMREAD_COLOR);
    if (img.empty()) {
        std::cerr << "Could not open or find the image." << std::endl;
        return -1;
    }

    // 如果在具有图形界面的系统上运行,使用以下代码显示图片
    cv::imwrite("/home/pi/output.jpg", img);
    return 0;
}
  1. 进行编译
g++ test_opencv.cpp -o test_opencv `pkg-config --cflags --libs opencv4`
  1. 测试
./test_opencv # 可以看到生成一个output.jpg文件

六、交叉编译含opencv代码

  1. 主机弄一个标准的cpp工程。包含src、include、build文件夹
  2. CMakeList.txt文件内容如下:
cmake_minimum_required(VERSION 3.10)
project(t_cv)

# 设置C++标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 添加include目录
include_directories(include)

# 指定交叉编译工具链
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

# 设置交叉编译器路径
set(CMAKE_C_COMPILER /opt/nanopi-toolchain/bin/arm-linux-gcc)
set(CMAKE_CXX_COMPILER /opt/nanopi-toolchain/bin/arm-linux-g++)

# 查找OpenCV包
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

# 添加源代码文件
file(GLOB SOURCES "src/*.cpp")
add_executable(t_cv ${SOURCES})

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

# 设置输出文件夹为 'output',没有用
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output)
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/output)
  1. main.cpp文件内容如下,一个是拍照片的,一个是保存png的:
#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 打开默认相机
    cv::VideoCapture cap(1); // 0是默认相机的设备ID。如果不起作用,尝试更换ID。
    if (!cap.isOpened()) {
        std::cerr << "Error: Couldn't open the camera.\n";
        return -1;
    }

    cv::Mat frame;
    std::cout << "Starting camera...\n";

    // 从相机捕获一帧
    cap >> frame; // 或者使用 cap.read(frame);
    if (frame.empty()) {
        std::cerr << "Error: Couldn't capture an image.\n";
        return -1;
    }

    // 保存图像
    if (!cv::imwrite("/home/pi/captured_image.png", frame)) {
        std::cerr << "Error: Couldn't save the image.\n";
        return -1;
    }

    std::cout << "Image saved as /home/pi/captured_image.png\n";

    // 释放相机
    cap.release();

    return 0;
}

// #include <opencv2/opencv.hpp>
// #include <iostream>
// using namespace std;
// int main() {
//     // 替换下面的路径为一个实际的图片文件路径
//     cv::Mat img = cv::imread("/home/pi/head.png", cv::IMREAD_COLOR);
//     if (img.empty()) {
//         std::cerr << "Could not open or find the image." << std::endl;
//         return -1;
//     }
//     cout<<"starting"<<endl;

//     // 如果在具有图形界面的系统上运行,使用以下代码显示图片
//     bool isWritten = cv::imwrite("/home/pi/output.jpg", img);
//     if (!isWritten) {
//         std::cerr << "Failed to write the image." << std::endl;
//         return -1;
//     } else {
//         cout << "Image written successfully." << endl;
//     }

//     cout<<"ok"<<endl;
//     return 0;
// }
  1. 问题:拍照片和输出png图片都没有问题,但是生成jpg文件失败。
    首先尝试在m1中安装如下库
sudo apt-get update
sudo apt-get install libjpeg62

前面的解决思路:上述通过在cmake中添加了如下对jpeg的支持,应该就解决了,上面已经添加了

-D BUILD_SHARED_LIBS=ON \
-D WITH_JPEG=ON \
  1. 问题:交叉编译的主机,显示#include <opencv2/opencv.hpp>错误找不到源。修改方式就是添加对应的源即可
    解决:在如下出问题的地方,电机快速修改,提示修改配置,然后添加对应的路径即可
    在这里插入图片描述
    图形化修改界面的内容如下
    在这里插入图片描述
    手动修改界面的内容如下
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值