Yolo opencv刻度尺识别 刻度读数识别 水尺识别 水位识别源码

刻度识别项目

    • 简介
    • 实现效果
    • 实现流程
    • 实现原理
      • 刻度尺的标定
        • 指针位置标定
        • 读数位置标定
        • 刻度线标定
      • 数字检测
      • 数字分割
      • 数字识别
    • web部署
    • 附录


简介

好久不见了,我看了一下我最近的博客到现在已经3个月时间没更新了。这是因为我最近都在忙毕业设计,所以一直没有时间更新。我这三个月的收获还是丰富的,最近会慢慢通过博客和大家分享。现在马上水上一篇吧。如果大家有看过我的EAST文本检测器应用这一篇博客的话,可能会好奇我最后的gif demo是怎么完成的。那个其实是我大三的一个srp项目。现在我就介绍一下它。


实现效果

需求不用啰嗦,直接看看效果即可,其实我也是做得比较简单,还有很多可以改进的地方。

1. demo1

在这里插入图片描述

2. demo2

在这里插入图片描述


实现流程

我完成上述的基本功能主要包含以下即可步骤。

  • 刻度尺的标定
  • 数字位置的检测和分割
  • 数字识别
  • 结果可视化
  • 部署到web

其中,✔的是必须的,而其余的是个性化的可选项。


实现原理


刻度尺的标定

刻度尺的标定是非常重要的一环。考虑到刻度尺位置是相对固定的,因此通过简单的人工标定过程就可以知道指针、刻度和数字的相对位置。当然也可以用如今非常厉害的基于深度学习的目标检测技术,大家可以自行发挥。

下面是标定的示意图:
在这里插入图片描述
从demo中可以看到整个读数系统可以象形地作成上图。需要关注的是:1)指针的位置;2)刻度尺读数的位置,我们不妨假定我们可以框出数字,那么框框的中心坐标就是读数的位置;3)读数到指针所指位置的距离;首先数字的起始位置都是有一条粗黑实线,然后得到的实线到指针的像素距离需要转换成实际的刻度距离。


指针位置标定

指针位置标定非常简单,因为其一般呈现等腰三角形,我们把它的边缘绘制出来,然后求其角平分线,就得到指针的指向。

在这里插入图片描述
我的标定程序需要从上往下按顺序指定三个红点,指定后自动连接绿线(指针边缘),然后自动生成其角平分线(蓝线),整个程序是交互式的,执行过程有提示信息,最终标定文件会自动保存,下次使用时加载标定文件即可。


读数位置标定

假定我们得到离指针位置最近的数字的中心像素坐标,但我们还需要知道这个像素坐标离它低下那条粗黑实线有多远。在这里,我假定这个中心坐标的y坐标y c y_c yc​和粗实线所在的y坐标y b y_b yb​存在二次函数的关系,这其实并不严格,只是感觉。所以有:
y b = a y c 2 + b y c + c y_b = ay_c^2 + by_c + c yb​=ayc2​+byc​+c
这样,我们对多张图片的多个位置标定出( y c , y b ) (y_c, y_b) (yc​,yb​),我们就可以拟合出系数。

在这里插入图片描述
程序需要人工框出所有数字,会自动返回红色中心点;然后人工点出黑色实线(蓝点),程序采集足够多组样本之后就可以拟合,生成拟合曲线:

在这里插入图片描述
这个拟合关系还是不错的。


刻度线标定

我们现在可以推出起始的粗实线的坐标,我们还需要知道:1)指针指向和刻度尺的交点(结束坐标);2)像素距离到刻度尺距离的转换。首先,我们先标定刻度,如下所示:
在这里插入图片描述
按从下到上或相反的顺序点出刻度,而且尽量使点排成大致的直线,这是因为在采集多张图以后,程序会把这个直线拟合出来。拟合出的刻度直线,和最开始标定出来的指针的角平分线求交点,得到的y轴方向坐标就是结束坐标。

有开始坐标和结束坐标,就还剩下距离转换的问题了。在这里我也是在此假设,任一y轴坐标y 0 y_0 y0​,它的上一个刻度和下一个刻度的像素增量δ y ↑ , δ y ↓ \delta y_{\uparrow}, \delta y_{\downarrow} δy↑​,δy↓​也存在二次函数的关系,即:
δ y ↑ = a ↑ y 0 2 + b ↑ y 0 + c ↑ δ y ↓ = a ↓ y 0 2 + b ↓ y 0 + c ↓ \delta y_{\uparrow} = a_{\uparrow}y_0^2 + b_{\uparrow}y_0 + c_{\uparrow} \\ \delta y_{\downarrow} = a_{\downarrow}y_0^2 + b_{\downarrow}y_0 + c_{\downarrow} \\ δy↑​=a↑​y02​+b↑​y0​+c↑​δy↓​=a↓​y02​+b↓​y0​+c↓​
和上面一样,采集足够的样本之后拟合,拟合效果如下:
在这里插入图片描述
可见效果还是可以的。拟合之后,假定我们起始坐标和结束坐标为y s , y e y_s,y_e ys​,ye​。那么我们可以求出y s y_s ys​下一个刻度的像素坐标:
y s , 1 = y s + δ y s = a ↓ y s 2 + ( b ↓ + 1 ) y s + c ↓ y_{s,1} = y_s + \delta y_s = a_{\downarrow}y_s^2 + (b_{\downarrow}+1)y_s + c_{\downarrow} ys,1​=ys​+δys​=a↓​ys2​+(b↓​+1)ys​+c↓​
不断重复上述过程,我们可以求出毫米级读数y s , k ≤ y e ≤ y s , k + 1 y_{s,k} \le y_e \le y_{s,k+1} ys,k​≤ye​≤ys,k+1​。如果需要取两位小数,那么在这个区间等比例取就可以了。


数字检测

数字检测使用我之前的博客提到的EAST模型,里面详细介绍了如何配置和使用,模型输入原图片,返回数字的中心坐标。


数字分割

本人数字分割使用的同样是比较传统的方法。首先,将图像转化为灰度图,然后使用OTSU方法对图片进行二值化。最后,对二值化的图片使用MSER算法,这个算法可以有效地抠出连通域。这样的话我们就得到单个分割的数字了。

mser = cv2.MSER_create(_min_area=min_area, _max_area=max_area)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)		# 转为灰度图
_, img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)	# 二值化
_, boxes = self.mser.detectRegions(img)		# MSER分割


数字识别

容易发现,我们需要识别的数字都是印刷体的。所以,数据集只需要印刷体数字0~9即可,你可能会觉得找数据集是件麻烦事,但印刷体数据集是可以用opencv生成的。这一部分我参考了开源项目digitx,它非常详细地给出了生成数据集和数据增强的方案,并且训练了一个简单的CNN实现了高效的数字识别。


web部署

本人使用flask实现,但使用本地电脑作为服务器部署后只能供局域网访问,如果需要让国内的朋友都能访问的话,可以申请一个公网的服务器,比如阿里云等,然后把代码放到上面运行,别人就可以访问了。


附录

完整代码见:github

如有问题,可以加下面二维码咨询

 

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

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

相关文章

Python检查特定值是否包含在列表中

python 检查特定值是否包含在列表中 # -*- coding: utf-8 -*-listA ["23", "45", "78", "92"] strB "45" strC "12"if __name__ __main__:if strB in listA:print(%s is on the list % strB)if strC not in …

【数据结构与算法】通俗易懂说链表

一:概述链表(Linked list)由一些节点组成,物理存储非连续的线性表。其中每个节点都会存储下个节点的指针,由于实际存储空间不连续,对链表插入节点,删除节点可以达到O(1)的复杂度,但是…

Yolov5实现道路裂缝检测

Yolov5实现道路裂缝检测 GitHub参考代码链接 我修改后的代码百度网盘链接 密码:2mzl 数据集链接 密码:06dj 基于Pytorch的Yolov5道路裂缝检测程序运行说明。大家可以结合我的说明和原文说明使用,有问题欢迎询问。 文章目录 Yolov5实现…

五、QPushButton按钮和QLineEdit控件操作

在第四节基础上,下面来进行QPushButton按钮和QLineEdit控件操作。 1.在主界面添加三个QLineEdit编辑框(其控件对象依次为lineEditNum1、lineEditNum2、lineEditSum)存放整数和一个按钮(其控件对象btnCalculate及5个QLable,进行2个数和的计算。 2.为按钮添加信号槽函数 单…

JVM史上最佳入门指南

提到Java虚拟机(JVM),可能大部分人的第一印象是“难”,但当让我们真正走入“JVM世界”的时候,会发现其实问题并不像我们想象中的那么复杂。唯一真正令我们恐惧的,其实是恐惧本身。而作为整个JVM系列的首篇&…

Docker Registry 删除镜像并清理

目录 修改Docker Registry配置使用Registry V2 RestfulAPI 删除镜像Docker Registry GC回收空间使用UI管理Docker Registry 修改Docker Registry配置 配置开启删除功能:config.yml version: 0.1 log:fields:service: registry storage:delete:enabled: truecache:blobdescri…

1-3.Win10系统利用Pycharm社区版安装Django搭建一个简单Python Web项目的步骤之三

在1-1.Win10系统利用Pycharm社区版安装Django搭建一个简单Python Web项目的步骤之一 基础上进行如下操作: 所有路由不能全部都在myDjango下的urls.py路由文件中,一个app创建一个路由分发文件urls.py, 在myDjango下的urls.py路由文件中只对每…

阿里《Java手册》做一个有技术情怀的人

导读最近重温了阿里的《码出高效Java开发手册》,感觉最后一页“聊聊成长”这一小块的内容写的很棒,特意把它复制出来,送给每一个技术人,愿你做一个有技术情怀的人。正文成长并没有直线式的捷径,“不走弯路就是捷径”这…

安卓应用在各大应用市场上架方法整理

安卓应用在各大应用市场上架方法整理 正在上传…重新上传取消​ ASO优化师-酱紫 酱紫ASO、ASA推广运营研究 ​关注她 1 人赞同了该文章 想要把APP上架到应用市场都要先注册开发者账号才可以。这里的方法包括注册帐号和后期上架及一些需要注意的问题。注意:首次…

Linux Shell编程之脚本执行方式

1.新建bash脚本文件 打开命令终端 touch hello.sh vim hello.sh2.编辑bash文件 #!/bin/bash # this is a test programerecho "hello word"3.脚本执行 赋予执行权限,直接运行 chmod 755 hello.sh ./hello.sh输出结果:

经典面试题|讲一讲JVM的组成

JVM(Java 虚拟机)算是面试必问的问题的了,而但凡问 JVM 一定会问的第一个问题就是:讲一讲 JVM 的组成?那本文就注重讲一下 JVM 的组成。 首先来说 JVM 的组成分为,整体组成部分和运行时数据区组成部分&…

ST-GCN训练自建数据集

参考了许多博文,慢慢地也就把st-gcn跑出来了,参考的文章一会附在文章里面,实测有用。 1.安装st-gcn 复现STGCN CPU版 (ubuntu16.04pytorch0.4.0openposecaffe)_Significance的博客-程序员秘密​​​​​​复现旧版STG…

[翻译] Haneke(处理图片缓存问题)

Haneke https://github.com/hpique/Haneke A lightweight zero-config image cache for iOS. 轻量级0配置图片缓存。 Haneke resizes images and caches the result on memory and disk. Everything is done in background, allowing for fast, responsive scrolling. Asking H…

面试题:为什么Java中的字符串对象是不可变的

阅读本文大概需要 4分钟。所谓不可变对象,是指一个对象在创建后,它的内部状态不会被改变的对象。这意味着当我们将一个不可变对象的引用赋值给某个变量后,我们就不能改变该对象的内部状态。 James Gosling也说过——Java开发者应该尽量使用不…

复现STGCN CPU版 (ubuntu16.04+pytorch0.4.0+openpose+caffe)

前提:ubuntu下将python3.5.2设为默认(百度) 一.下载stgcn (gitbub上fork后导入到gitee快些): st-gcn: Spatial Temporal Graph Convolutional Networks (ST-GCN) for Skeleton-Based Action Recognition in PyTorch…

Linux Shell编程之输入输出重定向

一、.输出重定向: 1.以覆盖方式把正确输入和错误输入都保存在同一个文件中 命令 &> 文件 2.以追加方式把正确输入和错误输入都保存在同一个文件中 命令 &>> 文件 3.以追加方式把正确输入保存在文件1中,把错误输入保存在文件2中 命令 …

不止JDK7的HashMap,JDK8的ConcurrentHashMap也会造成CPU 100%

大家可能都听过JDK7中的HashMap在多线程环境下可能造成CPU 100%的现象,这个由于在扩容的时候put时产生了死链,由此会在get时造成了CPU 100%。这个问题在JDK8中的HashMap获得了解决。其实JDK7中的HashMap在多线程环境下不止只有CPU 100%这一共怪异现象&am…

关于发布DIPS的MVC项目的IIS 7.0环境配置的方法

本人技术笨拙,今天在发布DIPS的MVC4.0项目,并部署到IIS上,遇到各种问题。在查询相关资料后,最终得以解决,所以想把这个过程记录下来。 注:DIPS为一种非关系型数据库 首先,需要安装和注册DIPS。注…

Veket PuppyLinux系统装在U盘中

在碎片化或移动式办公的需求前,怎样才能做到只借助别人的硬件,而使用的是自己的操作系统以及保存数据呢?此时你可能会想到将某个Linux的桌面版本推送并存放在U盘中,便于按需进行启动与使用。 Veket是基于Puppy的一个Linux简体中文…

Java调优:Mybaitis的缓存优化

作者:肥朝,来自肥朝(ID:feichao_java)我们先来看代码这段代码中, Mybatis一共发了两条SQL,这就好像说, Mybatis中没有缓存,然后我们打开Mybatis的文档一看,顿时震惊这难道是骗人的,说好的默认开启缓存呢…..其实不是的…