当前位置: 首页 > news >正文

闪烁与常亮的符号状态判断机制(状态机算法)

背景说明

        在视觉项目中,经常要判断目标的状态,例如:符号的不同频率闪烁、常亮等。然而常规的视觉算法例如YOLO,仅仅只能获取当前帧是否存在该符号,而无法对于符号状态进行判断,然而重新写一个基于时序的卷积神经网络又未免太过了,而且效果也往往低于预期。

        所以笔者通过借鉴操作系统的状态转换策略,想了一个符号状态的状态机转换算法。

算法难点说明

对于该算法的主要难点如下

 对于以YOLO为例的视觉检测算法传递的只有当前帧的符号类别列表,而且是非常快速的传递,状态判断算法很难直接融入到主程序当中,只能进行模块解耦。

对于视觉检测算法,必然会存在检测错误的情况(误检、漏检,错检),此时就会产生“噪声”,我们的状态判断算法必须要有足够的抗噪能力,然而对于如何进行抗噪又是一大难题。

状态机算法说明

 误识别情况说明:

  • 目标符号被短暂地识别为其他符号
  • 其他符号被短暂地识别为目标符号

图的说明
对于所有的符号,定义模型识别到该符号记为positive,没有识别到该符号记为negative。(这里单纯指的是识别的结果)

符号共有4种状态:状态0、状态1、状态2、状态3。

3种表现形式:暗、常亮、闪烁。

所有的符号初始化为状态0、暗。

对于状态0的符号:

  • 连续识别到该符号3次以上(即positive三次以上),切换为状态1,并记为常亮。
  • 没有识别到该符号,保持状态不变

对于状态1的符号:

  • 连续没有识别到该符号3次以上(即negative三次以上),切换为状态2。
  • 连续识别到该符号,保持状态不变

对于状态2的符号:

  • 连续识别到该符号3次以上(即positive三次以上),切换为状态3,并记为闪烁。
  • 连续没有识别到该符号3次以上(即negative四次以上),切换为状态0,并记为暗。
  • 停留在状态2时长超过2s将会进行状态的坍缩,会坍缩到上一个状态,有可能是状态2,也有可能是状态3

对于状态3的符号:

  • 连续没有识别到该符号3次以上(即negative三次以上),切换为状态2。

  • 连续识别到该符号5次以上(即positive五次以上),切换为状态1,并记为常亮

闪烁频率判断算法

对于闪烁频率的判断,由于检测的频率和性能的问题,实际上比较复杂,算法中采用的是100ms收集一次识别结果的方式。

例如:

对于400ms闪烁的情况:

  • 理想情况:0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 ……
  • 实际情况:0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 1 ……

对于200ms闪烁的情况:

  • 理想情况:0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 ……
  • 实际情况:0 0 0 1 0 0 1 1 1 0 0 1 1 0 1 1 1 0 1 1 ……

下图是对于闪烁频率判断的具体操作方式

代码示例

下列为状态机与频率计算算法

class Label:#初始化def __init__(self):self.frequency = 0        #记录闪烁频率self.isLight = False      #常亮标志self.isFlashing = False   #闪烁标志self.id = 0               #符号IDself.status = 0           #临时状态self.posCount = 0         #检测到1计数self.negCount = 0         #检测到0计数self.start_time = 0       #用以判断频率self.flag_time = 0        #用以判断是否是0之后的第一个1#计数次数def count(self,flag):if(flag == 0):self.negCount = self.negCount + 1self.posCount = 0self.flag_time = 0#检测到该符号if(flag == 1):#0之后的第一个1if(self.flag_time == 0):self.flag_time = 1temp_time = time.time()self.frequency = float(temp_time - self.start_time)*1000 #单位msself.start_time = temp_timeself.posCount = self.posCount + 1self.negCount = 0#刷新状态          def refresh(self):#详情请见confluence常亮和闪烁状态切换页面if(self.status == 0):#连续positive5次---->状态1,常亮if(self.posCount >= 5):self.isLight = Trueself.isFlashing = Falseself.status = 1self.posCount = 0self.negCount = 0elif(self.status == 1):#当处于状态1时,negative3次---->状态2,常亮if(self.negCount >= 3):self.status = 2self.posCount = 0self.negCount = 0elif(self.status == 2):#当处于状态2时,negative10次---->状态0,暗if(self.negCount >= 10):self.status = 0self.isFlashing = Falseself.isLight = Falseself.posCount = 0self.negCount = 0#当处于状态2时,positive4次---->状态3,闪烁if(self.posCount >= 4):self.status = 3self.isFlashing = Trueself.isLight = Falseself.posCount = 0self.negCount = 0elif(self.status == 3):#当处于状态3时,negative4次---->状态2,闪烁if(self.negCount >= 4):self.status = 2self.posCount = 0self.negCount = 0#当处于状态3时,posCount10次---->状态1,常亮if(self.posCount >= 10):self.status = 1self.isLight = Trueself.isFlashing = Falseself.posCount = 0self.negCount = 0

http://www.lryc.cn/news/374093.html

相关文章:

  • Hyper-V如何将文件复制到虚拟机?教您3个简单的方法!
  • Vue主要使用-03
  • LoadBalance客户端负载均衡
  • Burp Suite Professional 2024.5 (macOS, Linux, Windows) - Web 应用安全、测试和扫描
  • 逢3必过报数游戏-第13届蓝桥杯省赛Python真题精选
  • 解决Qt的multimedia库在clion中依赖库补全的问题
  • 图像处理:Python使用OpenCV进行图像锐化 (非锐化掩模、拉普拉斯滤波器)
  • windows用脚本编译qt的项目
  • mybatis-plus使用拦截器实现sql完整打印
  • GPT-4并非世界模型,LeCun双手赞同!ACL力证LLM无法模拟真实世界
  • 第 6 章: Spring 中的 JDBC
  • [C++ STL] vector 详解
  • PHP简约轻型聊天室留言源码
  • 代码随想录算法训练营day23|669.修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树
  • 实时通信websocket和sse
  • (超详细)基于动态顺序表实现简单的通讯录项目
  • 修改SubVI的LabVIEW默认搜索路径
  • 基于python深度学习的CNN图像识别鲜花-含数据集+pyqt界面
  • 第九站:Java黑——安全编码的坚固防线(第②篇)
  • 如何优雅的删除正式环境中的大表
  • Vulnhub-DC-1,7
  • 使用MySQL全文索引实现高效搜索功能
  • 数据结构学习笔记-图
  • 【归并排序】| 详解归并排序核心代码之合并两个有序数组 力扣88
  • 51单片机STC89C52RC——2.3 两个独立按键模拟控制LED流水灯方向
  • Neo4j连接
  • List 列表
  • nginx ws长连接配置
  • Windows下访问wsl的数据
  • 机器学习笔记 - 用于3D数据分类、分割的Point Net简述