自动识别击打控制系统

2023-05-16

目录

摘 要

关键词

一、系统方案

 1.1 系统基本方案 

 1.2 程序算法的具体流程

二、视觉程序识别框架

2.1多线程

2.2 opencv配置文件

2.3 主函数

 三、装甲板识别算法

3.1 装甲板识别

3.2 识别函数介绍

四、目标位置解算

4.1 摄像头标定

4.2 根据小孔成像原理得到需要的转角

(在这里打公式实在是太麻烦了,我直接在我的文档里截图算了。。。)

4.3 角度测量验证

五、程序源码(代码及完整论文可私)


摘 要:

        本次视觉作业主要实现的目标是:通过一个摄像头识别前方的一个矩形装
甲板(该矩形装甲板装有灯条),判断前方是否存在装甲板,如果存在,那么具
体在哪里,当摄像头检测到该装甲板上的灯条后,先对图像进行预处理、滤波等
处理,找到符合灯条条件的轮廓,匹配装甲板,然后计算出装甲板的位置,即相
机距装甲板的角度、距离、俯仰角等信息,并将这些信息发送给下位机,进而控
制下位机上的舵机移动,使枪口中心始终正对着装甲板正中心,实现自动瞄准功
能。

关键词:机器视觉、摄像头、矩形装甲板、预处理、滤波算法


一、系统方案

 1.1 系统基本方案

        我的程序主要是基于 C++中的 Opencv 实现的,实际运行在 linux 环境下,摄像头驱
动采用的是 V4L2 驱动框架,接下来介绍一下该框架下视觉识别基本算法。
以下思维导图展示了该程序算法的整个流程:

1.2 程序算法的具体流程

        ①降低相机曝光:在装甲识别中,曝光度是决定能否成功识别到装甲板的关键因素,当我们拍摄能自主发光的物体时,可以降低曝光时间可以减少环境光的影响。这时通过阈值处理得到二值图就可以进一步处理。

下面是我对比的一下摄像头正常曝光和低曝光的巨大差别:

 为了让便于分离灯条与其他光线,一般将曝光设置得很低,如下图为相机获取到的实际画面:

        ②预处理:通过相机,我们能够源源不断地获取到当前的画面,也就是一帧帧的图像。该算法处理的对象,就是这每一张图像。因为我们要从图像中找到装甲板上的灯条,因此需要先对图像进行预处理,即排除掉画面中的其他多余的光线。

        下面是我程序中使用的处理方法:

        下图为经过预处理之后的效果(二值化图像),可见除了灯条外的地方几乎都被排除掉了:

        ③找到符合灯条条件的轮廓:通过预处理得到的图片是二值图,即我们把可能是灯条的位置处理变成白色,其他地方都是黑的。此时可以通过Opencv的函数对轮廓用矩形框起来,然后通过几何关系判断其是否符合灯条的条件(角度,长宽比等条件)

下图为框选出来的符合灯条条件的灯条:

        ④匹配装甲板如果上一步得到的灯条个数大于1,就进行装甲板的匹配,主要是通过两个灯条的几何信息进行匹配(高度差,宽度差,角度差,形成的装甲板的角度,长宽比等信息最终得到若干个装甲板

        下图为用黄色矩形框选出来的装甲板:

        ⑤选择最后的装甲板如果上一步得到的装甲板个数大于0则进行装甲板的选择

        ⑥PNP结算装甲板信息:我们找到了装甲板的位置,还需要告诉舵机应当如何移动才能让枪管指向装甲板的中心。这里的如何移动,其实就是角度的偏移,左右偏多少度(yaw角),上下偏多少度(pitch角),相机距离装甲板的距离是多少得到这些信息之后,发送给下位机,舵机就知道怎么动了。

最后展示一下最终算法效果图:


二、视觉程序识别框架

2.1多线程

        由于我们相机每秒钟可以获取到很多张图片,实际处理中最好是几毫秒处理一张图,否则就会因为延时而无法跟上装甲板的移动。 而程序中采用多线程就是一个实现加速的好方法,因为相机获取图片和我们处理图片是两个相对独立的过程,因此可以利用多线程进行加速。

        使用 opencv 的时候写程序通常的流程就是读入图片/视频/摄像头,对每张图片进行处理,处理后进行输出(显示图片/显示识别结果等等)。这种模式基本上是一条线走下来的,前一个步骤没有完成就无法进行下一步的操作。

        而使用多线程后就可以把每个步骤拆分开,用单独的线程来完成对应的操作。

        由于使用了多线程就可以进行流水线作业,这样在图像处理线程处理本张图片的时候图像读取线程可以读入下一张图片。

 多结构结构框图如下:

2.2 opencv配置文件

        我是在linux平台上使用qtcreate搭建的opencv程序,在程序中的.pro文件就是该项目的配置文件。

         然后是头文件和源文件,这些是添加相应文件后 qtcreator 自动生成的,也可以手动添加或者手动注释。

2.3 主函数

        主函数的主要功能是:作为一个入口,创建 ImgProdCons 类,执行初始化成员函数,创建多线程。

主函数如下:

 其中produceThread()函数负责获取图像保存到缓存队列中,consumeThread()函数负责对图图片的处理和指令的发送,而 senseThread()函数用于接收数据。


 三、装甲板识别算法

3.1 装甲板识别

装甲板识别步骤:

1、找出图片中所有的灯条

2、根据长宽比、面积大小和凸度来筛选灯条

3、对找出的灯条进行匹配找到合适的配对

4、配对灯条作为候选装甲板

        在识别主程序中首先定义要用到的一些变量,定义时间变量t1记录当前时间用于之后的算法耗费时间的度量,之后获取待识别图片,图片可以通过produce线程获得也可以通过视频获得,之后将图片载入到armorDetector中进行识别,识别到后的返回值在

ArmorDetector.h中有定义:

enum ArmorFlag
{
	ARMOR_NO = 0,		     
	ARMOR_LOST = 1,		 
	ARMOR_GLOBAL = 2,	     
	ARMOR_LOCAL = 3		
};

         若识别到则获取关于装甲板矩形四个顶点的图像坐标来解算装甲板相对摄像头的空间坐标,之后将数据发给下位机就可以了(发送给下位机的是拍下这张图片时以摄像头或装甲板为原点的相对坐标值转化成的角度值,依靠这个可以随动跟踪)。

3.2 识别函数介绍

        识别函数int ArmorDetector::detect()函数是算法的核心,类中的其他函数都是为它服务的。

        该算法的第一步是存储灯条对应上面的第一步和第二步。

        对于图像中红色物体来说,其rgb分量中r的值最大,g和b在理想情况下应该是0,同理蓝色物体的b分量应该最大。

        如果识别红色物体可以直接用r通道-b通道。由于在低曝光下只有灯条是有颜色的,两通道相减后,其他区域的部分会因为r和b的值差不多而被减去,而蓝色灯条部分由于r通道比b通道的值小,相减后就归0了,也就是剩下的灰度图只留下了红色灯条。

颜色识别处理程序如下:

// 功能:把一个3通道图像转换成3个单通道图像

split(_roiImg,channels);//分离色彩通道

if(_enemy_color==RED)
    _grayImg=channels.at(2)-channels.at(0);//Get red-blue image;
Else
_grayImg=channels.at(0)-channels.at(2);//Get blue-red image;

膨胀处理:得到灰度图后需要阈值化处理得到二值图,之后可以进行膨胀处理让图像中的轮廓更明显。

Mat binBrightImg;
//阈值化
threshold(_grayImg, binBrightImg,_param.brightness_threshold
              , 255, cv::THRESH_BINARY);
Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3));
//膨胀
dilate(binBrightImg, binBrightImg, element);

 找轮廓:这步是整个算法中最耗时的部分,如果预处理做的好,可以极大地减少找轮廓中花费的时间。

 

 找到轮廓后开始遍历轮廓提取灯条:

对灯条进行匹配筛选:

 对找到的装甲板进行筛选:判断是不是装甲板我用的是模板匹配的方法,模板匹配特别适合待识别图片不会变化的场景,选择合适的模板可以得到很高的准确率。

装甲板筛选后可能会有多个装甲板,这时候需要选定一个进行跟踪。


四、目标位置解算

4.1 摄像头标定

        因为我们需要从图像中得到关于物理世界的信息,所以需要标定摄像头来得到摄像头内参。

标定板:

         直接而在MATLAB的Command Window里面输入cameraCalibrator即可调用标定应用。

Matlab中标定如下:

  点击show Undistorted即可看到无畸变的图像:

 最后选择导出参数,即可把参数进行保存。

4.2 根据小孔成像原理得到需要的转角

(在这里打公式实在是太麻烦了,我直接在我的文档里截图算了。。。)

4.3 角度测量验证

        如何知道我们测出的角度是正确的呢?可以通过一把三角尺来进行测量。

        将三角尺的30度尖对准摄像头,不断调整位置,使尖对准cx的像素值位置,之后不断调整摄像头,使三角尺的两条边在图像中平行于y轴,此时就可以选取三角尺边上的像素点来测量角度了,如下图:

 

拍摄出的图像如图:

 这个时候选择左边那条边测得的角度就是30度,选择右边的那条边测得的角度就是0度。

五、程序源码(代码及完整论文可主页联系)

这里也可下载

机器视觉预处理、滤波算法+自动瞄准算法+自定义协议与下位机进行通信-智能家居文档类资源-CSDN文库

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自动识别击打控制系统 的相关文章

随机推荐

  • ubuntu克隆ue4源码

    ubuntu克隆ue4源码 1 进入ue官网 xff0c 登陆自己账号 xff0c 进入个人账户界面 xff0c 点击连接 xff0c 账户 xff0c 关联github Epic Games 2 之后按照操作进行 xff0c 关联自己的g
  • Windows环境跑通清华开源通用时间序列分析模型TimesNet

    1 需要按照给定配置准备python3 8环境与相关依赖包 xff0c 全程在windows环境下进行 2 github thuml Time Series Library A Library for Advanced Deep Time
  • 嵌入式工程师职业生涯该怎样规划

    嵌入式工程师分布在各行各业 xff0c 包括消费电子 工业电子 汽车电子和军用电子等 从功能上面看 xff0c 嵌入式本身包括了51 mcu soc soc 43 baseband等很多形式 从开发的结构上看 xff0c 有些同学专注于底层
  • 使用ros实现c++与python通信

    创建工作空间 选择在桌面创建 cd mkdir p my workspace src 编译工作空间 cd my workspace catkin make source一下新生成的setup bash文件 xff1a source deve
  • C++输出系统时间

    编译软件 xff1a dev5 4 0 程序功能 xff1a 输出系统时间 xff0c 输出格式 2018 08 10 15 14 40 方法 xff1a 使用time t获取系统时间 xff0c 再使用strftime 函数对日期和时间进
  • 该博客已搬家至 博客园

    由于CSDN不支持metaweblog xff0c 该博客今日起停止更新 所有内容移至博客园 我的博客园博客地址 xff1a 戳我 https www cnblogs com wittxie CSDN写文章真的难受 xff0c 具体原因你们
  • Kernel Based Progressive Distillation for Adder Neural Networks:基于核的渐进式蒸馏的加法神经网络

    2020 NeurIPS AdderNet基于核的渐进式的蒸馏加法神经网络 一 简介二 问题解决2 1问题提出2 2初步解决方案2 3具体分析2 4问题解决 用核方法来解决这个问题2 5渐进式学习 三 实验结果分析3 1基于MNIST数据集
  • 人脸识别 灰度化

    人脸识别 灰度化 欢迎使用Markdown编辑器 你好 xff01 这是你第一次使用 Markdown编辑器 所展示的欢迎页 如果你想学习如何使用Markdown编辑器 可以仔细阅读这篇文章 xff0c 了解一下Markdown的基本语法知
  • 基于STM32F103的红外遥控小车

    本人小白一个 xff0c 利用空闲时间 xff0c 做了一些小东西 xff0c 跟大家分享一下自己的代码 如有不对的地方 xff0c 还请各位前辈指正 话不多说 xff0c 先上干货 include 34 remote h 34 inclu
  • 关于realsense d435i的安装步骤及问题总结

    一 realsense的安装过程 参考链接 xff1a 1 Ubuntu18 04 安装D435i ROS 2 Ubuntu下Realsense SDK的安装 3 Realsense D435i 在ubuntu上安装SDK与ROS Wrap
  • ROS编译catkin_make的时候报错找不到xxx.h头文件

    报错内容 xff1a home firefly eai ws src square square goal service src service server cpp 3 53 fatal error square goal servic
  • Ubuntu下安装GParted并分区,进行虚拟机内存扩展

    首先对于虚拟机下的Ubuntu系统安装Gparted 直接使用sudo apt get install gparted 关机先进行内存分配后 xff0c 再进行下面操作 网上还有其他适合的教程 xff0c 我的16 04这样安装是没问题的
  • PIP版本过低,更新无用,Command “python setup.py egg_info“ failed with error code 1 in报错

    Ubuntu下pip install 时候python2 7总是报错 Complete output from command python setup py egg info Traceback most recent call last
  • 小觅双目相机进行ROS标定

    安装image pipeline包 使用ROS官方提供的 camera calibration 包对双目相机进行标定 详情可见官网camera calibration Tutorials StereoCalibration ROS Wiki
  • ubuntu18.04安装ORB_SLAM3以及遇到的问题

    目录 1 安装c 43 43 11 2 安装Pangolin a xff09 安装依赖 b xff09 编译pangolin 切换到pangolin下载包里面 3 安装opencv 4 eigen3安装 5 boost安装 6 编译ORB
  • 【论文写作】Word中公式快捷输入方式

    环境 Win10 64位 用到软件 Mirsoft Word MathType Mathpix snipping tool Quicker 说明 xff1a 点击链接可以直达官网 一 前言 针对Word中公式输入效率低的问题 xff0c 本
  • 练习7-10 查找指定字符 (15分)

    本题要求编写程序 xff0c 从给定字符串中查找某指定的字符 输入格式 xff1a 输入的第一行是一个待查找的字符 第二行是一个以回车结束的非空字符串 xff08 不超过80个字符 xff09 输出格式 xff1a 如果找到 xff0c 在
  • 用cropper.js裁剪图片并上传到服务器,解析base64转存图片到本地

    今天要写上传图片功能 xff0c 研究了一下cropper 将图片上传服务器并保存到本地 html lt html gt lt head gt lt title gt 基于cropper js的图片裁剪 lt title gt lt met
  • 通讯协议详解

    1 xff0c 概念 网络协议指的是计算机网络中互相通信的对等实体之间交换信息时所必须遵守的规则的集合 网络上的计算机之间是如何交换信息的呢 xff1f 就像我们说话用某种语言一样 xff0c 在网络上的各台计算机之间也有一种语言 xff0
  • 自动识别击打控制系统

    目录 摘 要 关键词 一 系统方案 1 1 系统基本方案 1 2 程序算法的具体流程 二 视觉程序识别框架 2 1多线程 2 2 opencv配置文件 2 3 主函数 三 装甲板识别算法 3 1 装甲板识别 3 2 识别函数介绍 四 目标位