为Nanopi m1交叉编译opencv

news2024/11/16 9:47:52

为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>错误找不到源。修改方式就是添加对应的源即可
    解决:在如下出问题的地方,电机快速修改,提示修改配置,然后添加对应的路径即可
    在这里插入图片描述
    图形化修改界面的内容如下
    在这里插入图片描述
    手动修改界面的内容如下
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1809578.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

纯理论容器实现的原理

近期在复习容器的原理&#xff0c;希望这篇文章可以帮助到大家。 一、什么是容器&#xff1f; 容器本质上就是主机上的一个进程。这个进程拥有自己的用户空间并且和主机共享内核空间。 容器内的进程可以通过系统调用与内核进行交互&#xff0c;使用内核提供的各种功能和资源。…

达梦数据库搭建守护集群

前言 DM 数据守护&#xff08;Data Watch&#xff09;是一种集成化的高可用、高性能数据库解决方案&#xff0c;是数据库异地容灾的首选方案。通过部署 DM 数据守护&#xff0c;可以在硬件故障&#xff08;如磁盘损坏&#xff09;、自然灾害&#xff08;地震、火灾&#xff09…

速度位置规划实现精确定位的问题

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

NettyのBufferChannelSelector用法

这一篇介绍Buffer&Channel&Selector的常见API使用案例 1、Buffer 1.1、从Buffe中读取/写入 以ByteBuffer为例。Buffer需要和Channel结合使用&#xff08;在上一篇中提到&#xff0c;通道是数据传输的载体&#xff0c;缓冲区是数据的临时存储区&#xff09;。 那么如何…

44【Aseprite 作图】樱花丸子——拆解

1 枝干 2 花朵&#xff1a;其实只要形状差不多都行&#xff0c;有三个颜色&#xff0c;中间花蕊颜色深一点&#xff0c;中间花蕊外的颜色偏白&#xff1b;不透明度也可以改一下&#xff0c;就变成不同颜色 3 丸子 最外层的颜色最深&#xff0c;中间稍浅&#xff0c;加一些高光…

解决福昕风腾PDF套装无法打印在线电子签章的方法

使用福昕风腾PDF套装打印在线电子签章文件时发现&#xff0c;在线盖的电子印章和签名却打印不出来&#xff0c;后现发现&#xff0c;按图中选项选择“文档”&#xff0c;即可完整打印文件内容及电子签章。留印。

【2023】LitCTF

LitCTF2023&#xff08;复现&#xff09; Web&#xff1a; 1、我Flag呢&#xff1f; ​ ctrlu 读取源码&#xff0c;在最后发现了flag&#xff1a; <!--flag is here flagNSSCTF{3d5218b9-4e24-4d61-9c15-68f8789e8c48} -->2、PHP是世界上最好的语言&#xff01;&…

Spring AOP 基于注解实现用户权限校验

主要注解 interface&#xff1a;继承了 Annotation 接口的自定义注解&#xff0c;定义注释类型。 Target&#xff1a;表示这个注解可以应用的地方&#xff0c;此处做权限校验是用在方法上的&#xff0c;所以此处的值为 Target(ElementType.METHOD) …

Qt设置进程环境变量

目的 最近遇上了设置环境变量的问题,看似是小问题,想解决好,实在是一件不容易的事。 看看当时,我遇到这些问题的无奈: 首先说,是在windows进行环境变量的设置,如果在Linux那肯定是简单了。 一般来说,首先是设置系统的环境变量,这条路,是一条复杂的路,首先得写一个…

接口测试时, 数据Mock为何如此重要?

一、为什么要mock 工作中遇到以下问题&#xff0c;我们可以使用mock解决&#xff1a; 1、无法控制第三方系统某接口的返回&#xff0c;返回的数据不满足要求 2、某依赖系统还未开发完成&#xff0c;就需要对被测系统进行测试 3、有些系统不支持重复请求&#xff0c;或有访问…

使用命令给电脑添加虚拟网卡和IP

目录 1、添加网卡 1-1、windows系统添加网卡 1-2、Linux系统中添加网卡 2、添加IP和DNS 2-1、添加IP 2-2、 设置DNS 3、删除网卡 3-1、Windows: 3-2、Linux 3-3、macOS 4、示例&#xff1a; 首先以管理员方式进入CMD命令行&#xff1b; 点击“开始”->“管理员…

力扣74. 搜索二维矩阵

给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a;每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示…

猫头虎分享已解决Bug || Uncaught TypeError: Cannot set property ‘innerHTML‘ of null**

猫头虎分享已解决Bug || Uncaught TypeError: Cannot set property ‘innerHTML’ of null** 原创作者&#xff1a; 猫头虎 作者微信号&#xff1a; Libin9iOak 作者公众号&#xff1a; 猫头虎技术团队 更新日期&#xff1a; 2024年6月6日 博主猫头虎的技术世界 &#x…

让GNSSRTK不再难【第二天-第3部分】

第11讲 定位方程构建以及最小二乘 11.1 定位方程重构 历史讲中我们已经初步构建了单点定位的先验残差&#xff1a; p i s P i s − ( X s − X 0 ) 2 ( Y s − Y 0 ) 2 ( Z s − Z 0 ) 2 c δ t r − I i s − T i s − ϵ P i s p_i^s P_i^s - \sqrt{(X^s - X_0)^2 (Y…

Java入门基础11:面向对象高级一(static、extends继承)

Java面向对象高级特性有以下几个&#xff1a;继承&#xff0c;多态&#xff0c;封装&#xff0c;抽象&#xff0c;接口&#xff0c;匿名内部类&#xff0c;静态成员&#xff0c;final关键字&#xff0c;异常处理等。 我会将它分为三章详细讲&#xff0c;本章主要讲静态和继承 …

Java——方法详细介绍

一、方法调用机制 1、方法调用机制详细介绍 下面对方法调用在内存中的情况进行分析&#xff0c;以下面的代码为例&#xff1a; public class Test {public static void main(String[] args) {Person person new Person();person.name "张三";person.age 18;int…

GUI编程02-布局管理器

流式布局 FlowLayout 东西南北中 BorderLayout 表格布局 GridLayout 流式布局 package YMP.GUI; ​ import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; ​ public class TestFlowLayout {public static void main(String[] args…

oracle 12.1 rac to rac adg(maa)搭建保姆级教程

目录 资源配置 一、主库集群操作 1.主库增加standbylog 2.主库开启force logging及归档 3.主库配置参数 4.生成参数文件并将参数文件、密码文件拷贝至备库 4.1参数文件处理 4.2密码文件处理 二、备库操作 1.备库修改参数文件 1.1创建adump目录并在参数文件修改&#…

Mysql基础 - 事务

Mysql基础 - 事务 文章目录 Mysql基础 - 事务1 事务简介2 事务操作2.1 控制事务一2.2 控制事务二 3 事务四大特性4 并发事务问题5 事务隔离级别 1 事务简介 事务是一组操作的集合&#xff0c;他是一个不可分割的工作单位&#xff0c;事务会把所有操作作为一个整体一起向系统提…

Word中插入Mathtype右编号,调整公式与编号的位置

当你已经将mathtype内置于word后&#xff0c;可以使用右编号快速插入公式 但是往往会出现公式和编号出现的位置或之间的距离不合适 比如我在双栏下插入公式&#xff0c;会发现插入的公式与编号是适用于单栏的 解决办法&#xff1a; 开始->样式->MTDisplayLquation -&g…