基于opencv的数字识别系统

2023-11-05

一、目的

想要实现的功能:帮助我们在泵中扫描燃油,并在应用程序中输入燃油信息。

所需技术:①python程序对于拍摄的汽油泵的图像,尝试从中读取数字。——opencv实现。②先使用python对其进行原型设计,然后将代码转换成C++以在ios应用程序上运行。

        但是我不会部署在移动端,对第二个不做研究。

目标:需要考虑两个问题:

  1. 可以从图像中分离出数字吗?——用opencv图像阈值法来查找数字,进行裁剪轮廓
  2. 可以确定图像代表哪个数字吗?——KNN进行分类训练。

二、图像中分离出数字

思路:利用简单的图像阈值法来查找数字。

图像阈值法:将图像转换为灰度,然后说灰度值小于某个常数的任何像素,则该像素为一个值,否则为另一个。最后,得到的二进制图像只有两种颜色,在大多数情况下只是黑白图像。一幅图通常包含目标物体还有各种背景和噪声,想要得到目标物体,就要设置一个阈值,用阈值将图像的像素分割成两部分。

        但是阈值的值如何确定呢?——五、自动化可以解决阈值的选择

        这个概念在OCR应用中非常有效,但是主要问题是决定对该阈值使用什么。我们可以选择一些常量,也可以使用OpenCV选择其他一些选项。我们可以使用自适应阈值而不是使用常数,这将使用图像的较小部分并确定要使用的不同阈值。这在具有不同照明情况的应用中特别有用,特别是在扫描气泵中。

设置好阈值后,使用opencv中的findcontours方法查找图像中连接了白色像素部分的区域。绘制轮廓后,便可以裁剪出这些区域并确定它们是否可能是数字以及是什么数字。

2.1 图像处理流程

这是我在测试图像处理中使用的原始图像。它有一些眩光点,但是图像相当干净。让我们逐步完成获取此源图像的过程,并尝试将其分解为单个数字。

在代码中主要对应于playground.py函数,这个相当于完整的代码,会输出最后的预测结果,其中图像分割部分主要调用的是frameProcessor.py文件中的函数。

原始图片

 2.1.1 图像准备

在开始图像处理流程之前,我们决定先调整一些图像属性,然后再继续。这有点试验和错误,但注意到,当我们调整图像的曝光度时,可以获得更好的结果。下面是使用Python调整后的图像,相当于曝光(阿尔法)的图像cv::Mat::convertTo这是刚刚在图像点乘法操作cv2.multiply(some_img, np.array([some_alpha]),

调整曝光

2.1.2 灰阶

将图像转换为灰度。

转换为灰度

2.1.3 模糊

模糊图像以减少噪点。我们尝试了许多不同的模糊选项,但仅用轻微的模糊就找到了最佳结果。

稍微模糊

2.1.4 阈值化

图像转换为黑白图像

在下图中,使用cv2.adaptiveThreshold带有cv2.ADAPTIVE_THRES_GAUSSIAN_C选项的方法。此方法采用两个参数,块大小和要调整的常数。确定这两者需要一些试验和错误,更多有关优化部分的内容。

阈值为黑/白

2.1.5 填补空白

由于大多数燃油泵都使用某种7段LCD显示屏,因此数字中存在一些细微的间隙,无法使用轮廓绘制方法,因此我们需要使这些段看起来相连。在这种情况下,我们将转到erode(黑多白少)图像来弥补这些差距。由于大家可能希望使用,所以这似乎向后看,dilate但是这些方法通常适用于图像的白色部分。在我们的案例中,我们正在“侵蚀erode”白色背景以使数字看起来更大。

侵蚀出来的数字

2.1.6 反转图像

在尝试在图像中查找轮廓之前,我们需要反转颜色,因为该findContours方法将找到白色的连接部分,而当前的数字是黑色。

颜色反转

2.1.7 在图像上找到轮廓

下图显示了我们的原始图像,该图像在上图的每个轮廓上都有包围框。大家可以看到它找到了数字,但也找到了一堆不是数字的东西,因此我们需要将它们过滤掉。

红色框显示所有找到的轮廓

轮廓过滤

  1. 现在我们有了许多轮廓,我们需要找出我们关心的轮廓。浏览了一堆气泵的显示和场景后,使用一套适用于轮廓的快速规则。
  2. 收集所有我们将分类为潜在小数的正方形轮廓。
  3. 扔掉任何不是正方形或高矩形的东西。
  4. 使轮廓与某些长宽比匹配。LCD显示屏中的十个数字中有九个数字的长宽比类似于下面的蓝色框高光之一。该规则的例外是数字“ 1”,其长宽比略有不同。通过使用一些样本轮廓,我将0–9!1方面确定为0.6,将1方面确定为0.3。它将使用这些比率和+/-缓冲区来确定轮廓是否是我们想要的东西,并收集这些轮廓。
  5. 对潜在数字应用一组附加规则,在这里我们将确定轮廓边界是否偏离所有其他潜在数字的平均高度或垂直位置。由于数字的大小应相同,并且在相同的Y上对齐,因此我们可以丢弃它认为是数字的任何轮廓,但不能像其他轮廓那样将其对齐和调整大小。

蓝色矩形显示我们的数字/十进制,红色被忽略

 2.1.8 查找小数点

在图像中查找小数点是要解决的另一个问题。由于它很小,有时会连接到它旁边的手指,因此使用我们在手指上使用的方法来确定它似乎有问题。当我们过滤轮廓时,我们收集了可能是十进制的正方形轮廓。从上一步获得经过验证的数字轮廓之后,我们将找到数字的最左x位置和最右x位置,以确定我们期望的小数位数。然后,我们将遍历那些潜在的小数,确定它是否在该空间以及该空间的下半部分,并将其分类为小数。找到小数点后,我们可以将其插入到我们上面预测的数字字符串中。

只在黄色部分中查找小数

 2.1.9 将识别的数字裁剪

cropped = eroded[y:y + h, x: x + w]

直接选用img[h, w, c]进行切割。

三、 对切割的数字进行预测

3.1 数字训练

在机器学习的世界中,解决OCR问题是一个分类问题。我们建立了一组训练有素的数据,例如图像处理中的数字,将它们分类为某种东西,然后使用该数据来匹配任何新图像。一旦基本的图像隔离功能开始工作,我就创建了一个脚本,generate_distorted_images.py,该脚本可以遍历图像文件夹,运行数字隔离代码,然后将裁剪的数字保存到新文件夹中供我查看。运行完之后,我会有一个未经训练的数字文件夹,然后可以用来训练系统。(其实感觉是对裁剪好的数字图像进行腐蚀或者膨胀操作,然后增加数字图像的,类似于数据增强的操作一样

由于OpenCV已经包含了k近邻(k-NN)实现,因此无需引入任何其他库。为了进行训练,我们浏览了数字图像的文件夹,然后将其放入标有0–9的新文件夹中,因此每个文件夹中都有一个数字的不同版本的集合。我们没有大量的这些图像,但是有足够的证据来证明这是可行的。由于这些数字是相当标准的,我认为我不需要大量训练有素的图像就可以相当准确。

k-NN工作原理的基础是,我们将以黑白方式加载每个图像,将该图像存储在每个像素处于打开或关闭状态的数组中,然后将这些打开/关闭像素与特定的数字相关联。然后,当我们要预测一个新图像时,它将找出哪个训练图像与这些像素最匹配,然后向我们返回最接近的值。frameProcessor.py

# 调用cv2.ml.KNearest_create()创建一个KNN分类器,
# 然后调用train方法进行训练,
# 调用findNearest方法进行测试,
# findNearest的返回值result表示根据knn算法得到的测试图像对应的标签,neighbours表示测试图像的k个最近邻,dist表示相应最近邻的距离

整理好数字后,将创建一个新的脚本,该脚本将遍历这些文件夹,获取每个图像并将该图像与数字关联。到目前为止,在大多数代码中,一般的图像处理概念在Python和C ++中都应用相同,但是在这里会有细微的差别。train_model.py文件写分类结果

 在大多数此类应用程序的Python示例中,分类被写入两个文件,一个包含分类,另一个包含该分类的图像内容。通常使用NumPy和标准文本文件完成此操作。但是,由于我想在iOS应用程序上重用该系统,因此我需要想出一种可以拥有跨平台分类文件的方式。当时,我什么都找不到,因此最终编写了一个快速实用程序,该实用程序将从Python中获取分类数据并将其序列化为JSON文件,我可以在OpenCV的FileStorage系统的C ++端使用它。这不漂亮,但是我写了一个简单的MatPython中的序列化方法,它将为OpenCV创建合适的结构以在iOS端读取。现在,当我训练数字时,我将获得NumPy文件供我的Python测试使用,然后获取一个JSON文档,我可以将其拖到我的iOS应用程序中。您可以在此处看到该代码。

3.2 预测

有两个等高线轮廓,一个带潜在位数,一个带潜在小数位,我们可以使用这些轮廓边界裁剪图像,并将其输入经过训练的系统中以预测其值。有关此过程的更多信息,请参见“3.1 数字训练”部分。

 四、优化

playground.py

一旦确定了数字隔离和预测的两个目标,就需要对算法进行优化,以预测泵的新图像上的数字。

在优化的初始阶段,创建了一个简单的Playground应用程序,其中使用了OpenCV提供的一些简单的UI组件。使用这些组件,可以创建一些简单的轨迹栏,以左右滑动并更改不同的值并重新处理图像。围绕该cv2.imshow方法创建了一个小包装程序,该方法可以平铺显示的窗口,因为我讨厌总是重新放置它们,

尝试不同的变量

我们可以加载不同的图像,并在图像处理中尝试变量的不同变化,并确定最佳的组合。

 五、自动化

test_processing.py中的bulk_run方法

在每个图像上测试不同的变量是上手的好方法,但是我们想要一种更好的方法来验证是否更改了一个图像的变量是否会对其他任何图像产生影响。为此,我们想出了针对这些图像进行一些自动化测试的系统。

我拍摄了每个测试图像,并将它们放在文件夹中。然后,我用图像中期望的数字来命名每个文件,并用小数点“ A”表示。应用程序可以加载该目录中的每个图像并预测数字,然后将其与文件名中的数字进行比较以确定是否匹配。这使我们可以针对所有不同的图像快速尝试更改。

自动测试输出

更进一步,我创建了此脚本的不同版本,该脚本将尝试对这组图像进行模糊,阈值等变量的几乎每种组合,并找出最优化的变量集将具有最佳的性能。准确性。该脚本在计算机上花费了相当长的时间才能运行,大约需要7个小时,但是最后提出了一组不同的变量,这些变量在我们手动测试时找不到。

 六、结论

这是否是任何人实际上都会使用的功能尚待确定,但这在实现某些机器学习概念和使用OpenCV方面是一个有趣的练习。到目前为止,在我们的测试中,应用程序最大的问题是泵显示屏上的眩光。根据泵上的照明和手机的角度,可能会导致某些扫描失效。

代码链接: https://download.csdn.net/download/weixin_45823221/87364739

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

基于opencv的数字识别系统 的相关文章

  • 为什么 Python 在导入脚本时只保存脚本的字节码?

    既然执行Python字节码会比运行原始源代码更快 因为Python不需要重新编译 为什么Python在导入脚本时只保存编译后的字节码呢 为每个执行的脚本保存 pyc 文件不是更好吗 无论如何 Python 解释器的启动时间都需要时间 即使您
  • 为什么需要在 Python 方法中显式使用“self”参数? [复制]

    这个问题在这里已经有答案了 当在 Python 中的类上定义方法时 它看起来像这样 class MyClass object def init self x y self x x self y y 但在其他一些语言中 例如 C 您可以使用
  • str.translate 与 str.replace - 何时使用哪一个?

    何时以及为什么使用前者而不是后者 反之亦然 目前尚不完全清楚为什么有些人使用前者以及为什么有些人使用后者 它们有不同的目的 translate只能用任意字符串替换单个字符 但一次调用可以执行多次替换 它的参数是一个特殊的表 它将单个字符映射
  • 在 Visual Studio C++ 2008 中包含 dll

    有没有办法将 dll 包含在项目中 这样我就不必在编译后将这些 dll 与可执行文件放在同一文件夹中 这样我就可以用它们编译我的项目 这是否有可能 如果是 有人可以指导我 我的项目是一个 opencv 项目 有很多 dll 我必须包含在文件
  • Flask 中“缺少 CSRF 令牌”,但它在模板中呈现

    问题 当我尝试登录 使用 Flask login 时 我得到Bad Request The CSRF session token is missing但令牌正在呈现 在模板中 secret key 已设置 并且我在本地运行localhost
  • Matplotlib 图例,跨列添加项目而不是向下添加项目

    对于下面的简单绘图 有没有办法让 matplotlib 填充图例 以便它从左到右填充行 而不是第一列然后第二列 gt gt gt from pylab import gt gt gt x arange 2 pi 2 pi 0 1 gt gt
  • django 模板 - 如何动态访问变量?

    假设我有一个具有以下上下文的 django 模板 data1 this is data1 data2 this is data2 data name data2 现在我知道了data name 假设它是 data2 是否可以用它来访问变量d
  • 带有 mkdocs 的本地 mathjax

    我想在无法访问互联网的计算机上使用 MathJax 和 Mkdocs 因此我不能只调用 Mathjax CDN Config mkdocs yml site name My Docs extra javascript javascripts
  • 使用pathlib获取主目录

    翻看新的pathlib在 Python 3 4 中 我注意到没有任何简单的方法来获取用户的主目录 我能想到的获取用户主目录的唯一方法是使用旧的os path像这样的库 import pathlib from os import path p
  • Django 多对多关系(类别)

    我的目标是向我的 Post 模型添加类别 我希望以后能够按不同类别 有时是多个类别 查询所有帖子 模型 py class Category models Model categories 1 red 2 blue 3 black title
  • 查找与另一列 Pandas 中的唯一值关联的列中的值的交集

    如果我有一个像这样的数据框 非常小的例子 col1 col2 0 a 1 1 a 2 2 b 1 3 b 2 4 b 4 5 c 1 6 c 2 7 c 3 我想要所有的交集col2当价值观与其独特性相关时col1值 因此在这种情况下 交集
  • Py2exe - Pmw WindowsError:[错误 3]

    我正在尝试使用 Py2exe 构建独立的可执行文件 我已经导入了 Pmw 类 当我运行独立可执行文件时 出现以下错误 Traceback most recent call last File py line 9 in
  • 是否可以在Python中将日+月(不是年)与当前日+月进行比较?

    我正在获取 5 月 10 日 格式的数据 我试图弄清楚它是今年还是明年 该日期仅一年 因此 5 月 10 日表示 2015 年 5 月 10 日 而 5 月 20 日表示 2014 年 5 月 20 日 为此 我想将字符串转换为日期格式并进
  • 如何按 pandas 中的值对系列进行分组?

    我现在有一只熊猫Series与数据类型Timestamp 我想按日期对其进行分组 并且每组中有许多行具有不同的时间 看似显而易见的方法类似于 grouped s groupby lambda x x date 然而 熊猫的groupby按索
  • 如何在matplotlib中调整x轴

    I have a graph like this x轴上的数据表示小时 所以我希望x轴设置为0 24 48 72 而不是现在的值 很难看到 0 100 之间的数据 fig1 plt figure ax fig1 add subplot 11
  • 从迭代器外部将 StopIteration 发送到 for 循环

    有几种方法可以打破一些嵌套循环 他们是 1 使用中断 继续 for x in xrange 10 for y in xrange 10 print x y if x y gt 50 break else continue only exec
  • 如何创建用于霍夫曼编码和解码的树?

    对于我的作业 我将对霍夫曼树进行编码和解码 我在创建树时遇到问题 并且陷入困境 不要介意打印语句 它们只是让我测试并查看函数运行时的输出是什么 对于第一个 for 循环 我从主块中用于测试的文本文件中获取了所有值和索引 在第二个 for 循
  • 如何使用 enumerate 来倒数?

    letters a b c 假设这是我的清单 在哪里for i letter in enumerate letters 将会 0 a 1 b 2 c 我怎样才能让它向后枚举 如 2 a 1 b 0 c 这是一个很好的解决方案并且工作完美 i
  • python中有没有一种方法可以将存储在列表中的正则表达式模式列表应用到单个字符串?

    我有一个正则表达式模式列表 存储在列表类型中 我想将其应用于字符串 有谁知道一个好方法 将列表中的每个正则表达式模式应用于字符串 和 如果匹配 则调用与列表中该模式关联的不同函数 如果可能的话我想用 python 来做这件事 提前致谢 im
  • 为什么Android的ImageReader类这么慢?

    我尝试了适用于 Android 3 4 1 的全新 OpenCVJavaCamera2View但它太慢了 仅显示相机视图约 15 fps 当我尝试较旧的JavaCameraView相反 它给了我很好的结果 30fps 这是我相机的极限 我想

随机推荐

  • PYthon 转换HTML到Text纯文本

    今天项目需要将HTML转换为纯文本 去网上搜了一下 发现Python果然是神通广大 无所不能 方法是五花八门 拿今天亲自试的两个方法举例 以方便后人 方法一 1 安装nltk 可以去pipy装 注 需要依赖以下包 numpy PyYAML
  • AT24C02的使用说明和完整代码-51单片机

    AT24C02的使用说明和完整代码 51单片机 简述 at24c02为存储器芯片 可以使用单片机将数据存入其中 同时也可以任意读取 at24c02的原理及使用方法在其说明资料中已有充分的讲述 本篇仅对其使用的关键步骤进行罗列 以及说明一下具
  • MySQL主从复制的实现

    MySQL主从复制的理解图 MySQL Replication原理 主从复制 也称 AB 复制 允许将来自一个MySQL数据库服务器 主服务器 的数据复制到一个或多个MySQL数据库服务器 从服务器 复制是异步的 从站不需要永久连接以接收来
  • React中文文档之Lifting State Up

    Lifting State Up 提升状态 经常的 几个组件需要映射相同的数据改变 我们推荐提升共享的state状态到它们最近的公共祖先元素 让我们看看这是如何实现的 在这个章节 我们将创建一个温度计算器 计算在一个给定的温度 水是否会沸腾
  • 20200331 --【Python】-- selenium 登录练习

    学习 python 的第59天 模拟腾讯课堂 自动化 登录案例 简单 coding utf 8 Time 2020 3 31 10 52 Author admin Site File 腾讯课堂登录 py Software PyCharm i
  • Allegro显示飞线和隐藏飞线

    隐藏飞线 显示飞线
  • C++ 标准库中数据类型转换

    头文件引用
  • 延迟队列的方案设计

    延迟队列的实现方案 一 应用场景 什么是延时队列 顾名思义 首先它要具有队列的特性 再给它附加一个延迟消费队列消息的功能 也就是说可以指定队列中的消息在哪个时间点被消费 延时队列在项目中的应用场景是比较多的 尤其像电商类平台 1 订单成功后
  • 基于js利用经纬度进行两地的距离计算

    根据地球上两点之间的经纬度计算两点之间的直线距离 经纬度到距离的计算在通信工程中应用比较广泛 所以cosbeta通过搜索找到了一个js的计算脚本 其实是google map的计算脚本 应该算是比较准确了 做成了这个经纬度算距离的工具 今天有
  • 全到哭,阿里新产2023版Java架构核心宝典,涵盖Java进阶所有主流技术

    导言 什么是架构师 对于程序员来说 聊架构是一个永不过时的话题 实际上 每一家公司都有自己对架构师不同的定位 因为不同的公司 所处的阶段 业务模式以及应用场景都不一样 因此对架构师的要求不一样 所以定位也就不同 但是 无论如何 架构师除了优
  • STM32------TFTLCD原理

    目录 TFTLCD简介 一 知识点 1 TFTLCD驱动原理 ALINETEK TFTLCD模块介绍 2 2 8寸TFLCD模块特点 3 TFTLCD模块原理图 4 TFTLCD接口说明 5 并口驱动简介 6 ILI9341驱动时序 7 驱
  • 过滤器使用与bean注入

    1 web xml中各元素启动顺序 在项目启动时 监听器listener最先初始化 然后是过滤器filter 最后是servlet Spring监听器在启动时会读取spring配置文件 进行spring容器的初始化 springMVC的di
  • springBoot上传文件时MultipartFile报null 空 问题解决方法

    1 问题描述 之前用spring MVC 转成spring boot之后发现上传不能用 网上参考说是spring boot已经有CommonsMultipartResolver了 但是我的上传后台接收的还是null 2 第一种解决方法 加入
  • Jenkins中使用火线进行Android静态代码扫描

    背景 火线 是360Qtest测试团队在公司内部经过半年实践后向外推出的一款针对Android代码的静态扫描工具 本文主要介绍如何在Jenkins下植入火线扫描并实时查看结果的配置 环境配置 Jenkins 推荐使用最新的版本 本文使用的是
  • Java基础系列8:Java的序列化与反序列化(修)

    一 简介 对象序列化就是把一个对象变成二进制的数据流的一种方法 通过对象序列化可以方便地实现对象的传输和存储 把对象转换为字节序列的过程称为对象的序列化 把字节序列恢复为对象的过程称为对象的反序列化 对象的序列化主要有两种用途 1 把对象的
  • matlab gui 如何输入矩阵,在matlab中如何输入矩阵方?

    这需要GUI设置 举个例子 By lyqmath DLUT School of Mathematical Sciences BLOG http blog csdn net lyqmathfunction main clc clear all
  • 【华为OD机试真题 JAVA】按身高和体重排队

    JS版 华为OD机试真题 JS 按身高和体重排队 标题 按身高和体重排队 时间限制 1秒 内存限制 262144K 语言限制 不限 某学校举行运动会 学生们按编号 1 2 3 n 进行标识 现需要按照身高由低到高排列 对身高相同的人 按体重
  • python3GUI--模仿一些b站网页端组件By:PyQt5(详细介绍、附下载地址)

    文章目录 一 前言 二 展示 1 banner 1 静图 2 动图 2 一般视频组件 1 静图 2 动图 3 排行榜 1 静图 2 动图 三 设计心得 顺序由简到难 1 排行榜 2 一般视频组件 3 banner 四 总结 五 下载地址 一
  • 介绍一下lpc1114

    我是LPC1114 它是一款由NXP半导体制造的低功耗32位ARM Cortex M0微控制器 具有多种外设 可满足高性能应用的需求 它拥有一个32位ARM Cortex M0内核 可以运行频率高达50MHz 提供最大64KB的Flash存
  • 基于opencv的数字识别系统

    一 目的 想要实现的功能 帮助我们在泵中扫描燃油 并在应用程序中输入燃油信息 所需技术 python程序对于拍摄的汽油泵的图像 尝试从中读取数字 opencv实现 先使用python对其进行原型设计 然后将代码转换成C 以在ios应用程序上