【智能车】从零写一份自己的完全模型智能车寻路算法(有手就行) --- 01

这篇具有很好参考价值的文章主要介绍了【智能车】从零写一份自己的完全模型智能车寻路算法(有手就行) --- 01。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

有手就行的智能车视觉寻路算法

前言

被同学拉进了智能车完全模型组做智能车的上层视觉软件算法,在交流群里吹水很多人起哄说让写一篇博客来教他们怎么写寻路。众望所托,今天就开始了这一系列的更新,保证有手就行,从最基础的开始。
其它的话:距离上次更新数据结构博客也很久了,那个博客并没有鸽,在复习二叉树的时候感觉这东西没啥好写的,和链表一样,而后面一直在看算法方面的东西,所以没有更新,后面的树状数组等等都会有更新的。

一、提出一份完整的需求

一份需求一定要层层细分:

最笼统的需求

  1. 能够识别道路线
  2. 能够识别道路标识
  3. 能够给出运动方向
  4. 特殊任务状态下的寻路
  5. 使用json控制一些变量的输入,方便后期调车
  6. 不重要:图形化界面,修改json文件并查看小车实时状态;使用socket等远程实时调试小车

这些就是最笼统的概念,接下来要细分到每一个部分上去:

识别道路线

识别道路线会遇到多种情况,包括直路,左右转弯,十字路口,环岛。

  1. 精确的识别出直线
  2. 判断出左右转弯状态
  3. 十字路口优化,单独处理十字路口
  4. 环岛入环,出环等状态的判断

识别道路标识

道路标识识别方法比较单一,只能是检测到目标然后进行图像分类确定标识种类。这就是需求了。
方案直接在这里给出:

  1. 直接使用目标检测算法,如yolo。但是效率会低,选择哪种算法请自行考虑。
  2. 传统图像算法优化目标检测,通过图像处理去到标识物的最小正接矩形范围,提取出图片,通过图像分类算法直接得到标识类别。

方便起见,直接选择方案一绝对是最好的,如果想要提升帧率,可以考虑借鉴方案二,或者自己找到其它更优解也是可以的。

给出运动方向

这里需要通过数学方法计算出小车后面需要行进的方向,具体如下

  1. 获得小车行进路线状态
  2. 数学方法处理路线,如拟合成直线等
  3. 通过斜率等判断转向度数
  4. pwm
  5. 串口传输pwm舵机打角信息

特殊任务

根据比赛规则自行调试,这里暂时不写需求

json文件

  1. 编写json文件读取协议
  2. 通过读取json文件初始化程序配置

本教程只针对基础寻路部分进行教学

二、板子的算力限制

这块板子真的是算力有限,只能说比树莓派强。在这样算力有限的情况下要是想跑yolov5或者一些图像分割算法的话那肯定是很难的,帧数很低,做人脸识别还可以,但是做这种实时高速识别的东西确实不太好。
因此,对于道路的识别我们要采用传统视觉算法。

三、从零开始

从零开始我们要先知道需要的一些基础技术,好进行学习。

1. 语言基础

推荐学习C/C++,python可针对深度学习单独学习。
推荐教程:
黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难
从0基础系统化学习C++,不可能学不会
MOOC浙大翁恺C语言
菜鸟教程python

2. OpenCV部分

用啥建议直接百度,最好谷歌,有一些问题上stackoverflow也有解,注意搜索的姿势就行(

如果是想了解一下,这里推荐看贾志刚老师的教程(网上很多,就不放链接了),但是很容易困,稍微了解下,剩下的慢慢学,用到的算法我都会写是怎么回事。

3. 开发环境搭建

对于大型项目,尤其是需要放到linux上的,我更倾向于使用Clion来编写,当然vs也是不错的,vscode可以用,就是有点费劲。
因此我选取Clion作为我开发这个寻路程序的IDE。
有了IDE,接下来就该了解一下需要配置什么环境:
首先是C++编译环境,Clion上建议使用CMake,它也会帮你生成CMakeLists.txt这个文件,同时我的CMake用的是clang++编译器,还可以选择g++等,可以自己选择编译器。
有了C++的编译环境,需要配置OpenCV库,EB板子自带一个低版本OpenCV,如果直接在上面开发可以直接看一下怎么用就行了。如果想在自己电脑上调试的话,可以百度,有很多教程,每个人遇到的问题都不一样,但是网上基本都有解了。
串口通讯库,可能会需要,也可能自己写。
额外的,为了后面读取json文件,需要选择一个json解释器的库,这个暂时不谈。
有可能自己需要一个日志系统,选择自己喜欢的日志库就行。
图形库可以暂时不做,因此不装了先。

总结下来就是下面这些:

  1. IDE
  2. C++编译器
  3. CMake帮助编译大型项目
  4. OpenCV环境
  5. 串口库(可能需要)
  6. json解释器(暂时不用管)
  7. 日志库(暂时不用管)
  8. 图形库(暂时不用管)

4. 创建项目

智能车算法,智能车寻路,算法
选择好自己想要的路行,c++标准建议选择c++14、c++17或者c++20,接下来点击创建。
智能车算法,智能车寻路,算法
这是创建后自动生成的主函数文件,我们来看一下文件树。
智能车算法,智能车寻路,算法
红色框出的部分是cmake编译生成的东西,不用管,我们来看另外两个文件。
智能车算法,智能车寻路,算法
这个是main.cpp,生成了一个hello world测试程序,我们可以点一下右上角的运行按钮测试一下能否使用:
智能车算法,智能车寻路,算法
这里可以看到程序运行正常,证明Clion成功找到CMake程序,CMake成功找到了c++编译器并进行编译,同时运行。
智能车算法,智能车寻路,算法
这两个按钮用的比较多,第一个是上面用到的那个功能,后面这个是调试按钮,也就是debug。
我们来看看剩下的CMakeLists.txt这个文件:
智能车算法,智能车寻路,算法
这就是用来编译c++项目的cmake的配置文件,具体使用方法百度找个文档就可以很快入门了。
接下来就该将OpenCV引入项目,直接在这个文件中加入下面语句:

#find OpenCV
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

和:

target_link_libraries(zhiNengChe ${OpenCV_LIBS})

智能车算法,智能车寻路,算法

然后将main.cpp改成下面这段代码,运行测试能否编译成功,如果不可以,请检查自己的opencv是否安装正确。(请将图片路径,红色圈出部分,修改为自己的图片路径,随便找一张图片测试就行)

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

int main() {
    cv::Mat frame = cv::imread("../114.png");
    cv::imshow("test", frame);
    cv::waitKey(0);
    return 0;
}

智能车算法,智能车寻路,算法

智能车算法,智能车寻路,算法

好了,到这里,所有暂时需要的环境已经配置完成,可以开始项目的内容了。

附测试用图:
智能车算法,智能车寻路,算法

四、图像预处理

1. 创建文件

智能车算法,智能车寻路,算法
右键文件夹,新建图像预处理类。
智能车算法,智能车寻路,算法
会在侧面显示出新生成的类文件。我们把他们重构到两个文件夹中,一个取名为include,另一个取名为src,方便前期管理文件,后期要更加细分。
直接将文件拖动到文件夹中,点击重构,即可自动重构CMakeLists.txt。
智能车算法,智能车寻路,算法

2. 编写类文件

文件会自动生成一些信息,学过c++应该能看懂了。
我们直接处理图像:
在这个类中我需要一份原图像数组,一份处理后的图像数组。一个处理图像函数,一个获取处理后图像的接口函数:

Pretreatment.hpp

//
// Created by JYSimilar on 2023/2/2.
//

#ifndef ZHI_NENG_CHE_PRETREATMENT_HPP
#define ZHI_NENG_CHE_PRETREATMENT_HPP

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


/*
 * @brief: 图像预处理类
 * @brief: 实例化后通过run函数传入原图,通过getBinaryImage获取二值化结果图
 *
 */
class Pretreatment {
private:
    cv::Mat m_frame;            // 原图
    cv::Mat m_binary;           // 二值化图像

private:                        // 临时参数
    cv::Mat m_element1 = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
    cv::Mat m_element2 = getStructuringElement(cv::MORPH_RECT, cv::Size(7, 7));
    std::vector<cv::Point2f> m_srcPoint;
    std::vector<cv::Point2f> m_dstPoint;
    cv::Mat m_perspectiveMat;
    int m_cols, m_rows;

private:
    /*
     * @brief: 处理图像函数
     */
    bool processImage();

public:
    // 初始化图像大小
    Pretreatment(const int cols, const int rows):
    m_cols(cols),
    m_rows(rows)
    {
        m_srcPoint.resize(4);
        m_dstPoint.resize(4);
    }
    /*
     * @brief: 处理图像函数接口
     */
    void run(const cv::Mat frame);

    /*
     * @brief: 获取二值化图像接口
     */
    cv::Mat getBinaryImage();
};


#endif //ZHI_NENG_CHE_PRETREATMENT_HPP

Pretreatment.cpp

//
// Created by JYSimilar on 2023/2/2.
//

#include "../include/Pretreatment.hpp"

/**************************** 类内程序 ****************************/



bool Pretreatment :: processImage() {
    // 可以直接做灰度二值化,很方便,也好用好调
    // 这里处理比较复杂了

    if (m_frame.empty()) return false;
    cv::Mat gray;
    std::vector<cv::Mat> bgr;
    cvtColor(m_frame, gray, cv::COLOR_BGR2GRAY);
    split(m_frame, bgr);

    cv::Mat gray_bin, color_bin;
    // 二值化等
    cv::threshold(gray, gray_bin, 140, 255, cv::THRESH_BINARY);
    cv::subtract(bgr[0], bgr[2], color_bin);
    cv::threshold(color_bin, color_bin, 60, 255, cv::THRESH_BINARY);
    m_binary = gray_bin - color_bin;
    cv::morphologyEx(m_binary, m_binary, cv::MORPH_CLOSE, m_element1);
    // 腐蚀膨胀
    cv::erode(m_binary, m_binary, m_element2);
    cv::erode(m_binary, m_binary, m_element2);
    cv::dilate(m_binary, m_binary, m_element2);

    // 后面这一部分整体提到初始化中(到透视变换矩阵位置),减少运算时间
    m_rows = m_binary.rows, m_cols = m_binary.cols;
    m_srcPoint[0] = cv::Point2f(0, m_rows / 4);
    m_srcPoint[1] = cv::Point2f(m_cols, m_rows / 4);
    m_srcPoint[2] = cv::Point2f(m_cols, m_rows);
    m_srcPoint[3] = cv::Point2f(0, m_rows);
    m_dstPoint[0] = cv::Point2f(-230, 0);
    m_dstPoint[1] = cv::Point2f(m_cols + 230, 0);
    m_dstPoint[2] = cv::Point2f(m_cols - 230, m_rows);
    m_dstPoint[3] = cv::Point2f(230, m_rows);
    // 应用透视变换,矫正成规则矩形
    cv::Mat transform = getPerspectiveTransform(m_srcPoint, m_dstPoint);

    warpPerspective(m_binary, m_perspectiveMat, transform, m_binary.size());

    return true;
}


/**************************** 接口程序 ****************************/

void Pretreatment :: run(const cv::Mat frame){
    // 复制图片,使用=会修改原图
    frame.copyTo(m_frame);
    if (!processImage()) {
        std:: cout << "Image is empty...\n";
    }
}

cv::Mat Pretreatment :: getBinaryImage(){
    return m_perspectiveMat;
}

具体操作在代码中有写注释,这里解释一下灰度二值化。
我的方法不适合新上手的新人,放在这里做参考,仅供学习。

灰度二值化

灰度二值化就是将图片先改成灰度图,然后通过设定阈值,阈值内设为某种亮度,阈值外设为某种亮度,来实现二值化,如亮度为100以内的都修改为0,高于100修改为255,这就是一种二值化操作了,在opencv中以API threshold 封装,具体使用方法百度。

3. 处理结果

测试主函数:

#include "../include/Pretreatment.hpp"

int main() {
    Pretreatment pretreatment(640, 480);
    cv::Mat frame = cv::imread("../114.png");
    pretreatment.run(frame);
    cv::Mat binary = pretreatment.getBinaryImage();
    cv::imshow("test", binary);
    cv::waitKey(0);
    return 0;
}

智能车算法,智能车寻路,算法

五、结语

目前先写这么多了,如果反响不错,会继续写下一集的扫线算法。文章来源地址https://www.toymoban.com/news/detail-757132.html

到了这里,关于【智能车】从零写一份自己的完全模型智能车寻路算法(有手就行) --- 01的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Apple主推的智能家居是什么、怎么用?一篇文章带你从零完全入门 HomeKit

    如果你对智能家居有所了解,那应该或多或少听人聊起过 HomeKit。由 Apple 开发并主推的的 HomeKit 既因为产品选择少、价格高而难以成为主流,又因其独特的优秀体验和「出身名门」而成为智能家居领域的焦点。HomeKit 究竟是什么?能做什么?怎么做到的? 想要准确描述 HomeK

    2024年02月13日
    浏览(43)
  • 构建自己的ChatGPT:从零开始构建个性化语言模型

    🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐 🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬

    2024年02月15日
    浏览(31)
  • YOLOv5入门实践(5)——从零开始,手把手教你训练自己的目标检测模型(包含pyqt5界面)

      通过前几篇文章,相信大家已经学会训练自己的数据集了。本篇是YOLOv5入门实践系列的最后一篇,也是一篇总结,我们再来一起按着 配置环境--标注数据集--划分数据集--训练模型--测试模型--推理模型 的步骤,从零开始,一起实现自己的目标检测模型吧! 前期回顾: YOLO

    2023年04月26日
    浏览(45)
  • 将别人的 Git 仓库源码复制一份到自己的新仓库上

    从原地址克隆一份到本地。 然后到 Git 创建一个新仓库。 进入项目目录,以推送的方式上传代码到自己的 Git 服务上。 删除本地代码 这种方式可以保留原版本库中的所有内容。

    2024年02月12日
    浏览(43)
  • 从零开始:如何用Python建立你的第一个人工智能模型

    在这篇文章中,我们将介绍如何 从零开始使用Python建立你的第一个人工智能模型 。无论你是刚接触编程的新手,还是有经验的开发者想进一步探索人工智能领域,这篇文章都将为你提供清晰、详细的指南。我们将一步步探索数据预处理、模型建立、训练和测试的过程,以及

    2024年02月09日
    浏览(35)
  • 在Remix中编写你的第一份智能合约

    智能合约简单来讲就是: 部署在去中心化区块链上的一个合约或者一组指令,当这个合约或者这组指令被部署以后,它就不能被改变了,并会自动执行,每个人都可以看到合约里面的条款 。 更深层次的理解就是:这些代码会被去中心化地执行,就像一群人运行了某个软件,

    2024年02月04日
    浏览(33)
  • 【ChatGPT】从零开始构建基于ChatGPT的嵌入式(Embedding) 本地(Local) 智能客服问答机器人模型

      目录 方案流程 1. Embeddings 介绍 术语:微调 vs 嵌入

    2024年02月10日
    浏览(42)
  • 从零开始学习R语言编程:完全指南

    R语言是一种流行的数据分析语言,广泛应用于学术界、商业界和社会科学研究等领域。与其它数据分析软件相比,R语言的优点包括免费开源、高效可靠、具有强大的数据分析和可视化能力等。R语言的编程基础包括了各种控制结构和函数,可以方便地实现算法和数据操作。本

    2024年02月10日
    浏览(46)
  • 民谣女神唱流行,基于AI人工智能so-vits库训练自己的音色模型(叶蓓/Python3.10)

    流行天后孙燕姿的音色固然是极好的,但是目前全网都是她的声音复刻,听多了难免会有些审美疲劳,在网络上检索了一圈,还没有发现民谣歌手的音色模型,人就是这样,得不到的永远在骚动,本次我们自己构建训练集,来打造自己的音色模型,让民谣女神来唱流行歌曲,

    2024年02月04日
    浏览(40)
  • 基于LangChain从零实现Auto-GPT完全指南

    LangChain是何方神圣? 远的不说,我们就拿当下火热的项目 Auto-GPT 来说,该项目集成了: 自动推理 、 联网搜索 、 LLM推理 。那么现在好了,你可能会好奇他是怎么做到的!那么告诉你 LangChain 这个框架可以帮你从零到一实现一个比 Auto-GPT 还要强大的产品! 难道你还不心动吗

    2024年02月06日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包