OpenCV实例(四)手写数字识别

news2024/12/29 2:10:49

OpenCV实例(四)手写数字识别

  • 1.基本原理
  • 2.实现步骤
    • 2.1数据准备
    • 2.2计算匹配值
    • 2.3获取最佳匹配值及对应模板
    • 2.4获取最佳匹配模板对应的数字
    • 2.5输出识别结果
  • 3.代码实例

作者:Xiou

1.基本原理

使用模板匹配的方式实现手写数字识别,其基本实现原理如图所示。

在这里插入图片描述

使用模板匹配的方式实现手写数字识别,主要包含流程如下。
Step 1:数据准备。读取待识别图像和模板库。
Step 2:计算匹配值。计算待识别图像与所有模板的匹配值。需要注意的是,匹配值的计算有多种不同的方法。有时,匹配值越大表示二者越匹配;有时,匹配值越小表示二者越匹配。通常,也将该匹配值称为距离值。
Step 3:获取最佳匹配值及对应模板。获取所有匹配值中的最佳匹配值(该匹配值可能是所有匹配值中的最大值,也可能是所有匹配值中的最小值),并找到对应的模板。
Step 4:获取最佳匹配模板对应的数字。将最佳匹配模板对应的数字作为识别结果。
Step 5:输出识别结果。综上所述,使用模板匹配的方式实现手写数字识别的流程图所示。

在这里插入图片描述

2.实现步骤

2.1数据准备

数据准备工作主要是读取待识别图像和模板库,核心程序如下:

在这里插入图片描述
上述程序中,images存储了所有模板图像的路径。程序在遍历时,按照从数字0到数字9的顺序依次遍历。因此,遍历完成后,images内依次存储了数字0到数字9的所有模板。

每个数字共有10个模板,images的索引与模板图的路径名之间的关系如表所示。

在这里插入图片描述
在这里插入图片描述
images中依次存储的是数字0~9的共计100个模板图像的路径名,其中索引对应各模板图像的编号。例如,images[mn]表示,数字m的第n个模板图像的路径名。

2.2计算匹配值

在OpenCV内,模板匹配是使用函数cv2.matchTemplate()实现的,该函数的语法格式为:

匹配值=cv2.matchTemplate(原始图像,模板图像,cv2.TM_CCOEF)

在参数cv2.TM_CCOEFF的控制下,原始图像和模板图像越匹配返回的匹配值越大;原始图像和模板图像越不匹配,返回的匹配值越小。

构造一个函数,用来计算匹配值,程序如下:

在这里插入图片描述
该函数中,参数template是文件名,参数image是待检测图像。

2.3获取最佳匹配值及对应模板

本章通过将函数cv2.matchTemplate()的参数设置为cv2.TM_CCOEFF来计算匹配值,因此最大的匹配值就是最佳匹配值。
构造一个列表matchValue用来存储待识别图像与images中每个模板的匹配值,其中依次存储的是待识别图像与数字0~9的100个模板图像的匹配值。

列表matchValue中的索引对应各模板图像的编号。例如,matchValue[mn]表示待识别图像与数字m的第n个模板图像的匹配。列表matchValue中的最大值的索引即最佳匹配模板的索引。

具体程序如下:
在这里插入图片描述

2.4获取最佳匹配模板对应的数字

找到最佳匹配模板对应的数字,将该数字作为识别结果。
模板索引整除10得到的值正好是该模板图像对应的数字值。例如,matchValue[34]对应着数字3的第4个模板图像的匹配值。简单来说,索引为34的模板,对应着数字3。

索引34整除10,int(34/10)=3,3正好是模板对应的数字。确定了模板图像索引、识别值之间的关系,就可以通过计算索引来达到数字识别的目的了。

2.5输出识别结果

将识别的数字输出,程序如下:

print('识别结果:数字',number)

3.代码实例

使用模板实现手写数字识别。

测试图片:

在这里插入图片描述

# -*- coding: utf-8 -*-
import glob
import cv2
#==============准备数据========================
#读取待识别图像
o=cv2.imread("image/test2/3.bmp",0)
# images用于存储模板
images = []
# 遍历指定目录下所有子目录及模板图像
for i in range(10):    
    images.extend(glob.glob('image/'+str(i)+'/*.*'))    
#=============计算匹配值函数=====================
def getMatchValue(template,image):
    #读取模板图像
    templateImage=cv2.imread(template)
    #模板图像色彩空间转换,BGR-->灰度
    templateImage = cv2.cvtColor(templateImage, cv2.COLOR_BGR2GRAY)
    #模板图像阈值处理, 灰度-->二值
    ret, templateImage = cv2.threshold(templateImage, 0, 255, cv2.THRESH_OTSU)
    # 获取待识别图像的尺寸
    height, width = image.shape
    # 将模板图像调整为与待识别图像尺寸一致
    templateImage = cv2.resize(templateImage, (width, height))
    #计算模板图像、待识别图像的模板匹配值
    result = cv2.matchTemplate(image, templateImage, cv2.TM_CCOEFF)
    # 将计算结果返回
    return result[0][0]
#===============计算最佳匹配值及模板序号======================
# matchValue用于存储所有匹配值
matchValue = []
# 从images中逐个提取模板,并将其与待识别图像o计算匹配值
for xi in images:
    d = getMatchValue(xi,o)
    matchValue.append(d)
# print(distance)   #测试语句:看看各个距离值
# 获取最佳匹配值
bestValue=max(matchValue)
# 获取最佳匹配值对应模板编号
i = matchValue.index(bestValue)
# print(i)         #测试语句:看看匹配的模板编号
#===============计算识别结果======================
#计算识别结果
number=int(i/10)
#===============显示识别结果======================
print("识别结果:数字",number)

输出结果:
在这里插入图片描述

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

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

相关文章

2023/4/20总结

项目 网上关于listview的资料太少了,在网上的那些资料里面,了解到以下这些。 如果希望listview后期能更改或者更新,那么需要使用到 ObservableList 它可以观察到,listview的改动。 需要特别注意一点的是:写俩者的…

如何发布自己的 npm 包?

一. 准备工作 1. 注册 npm 账号 还没有 npm 账号?去官网注册: https://www.npmjs.com/ 需要记住用户名、密码、邮箱 2. 查看本地 npm 镜像,如果不是默认的,需要改回来 npm config get registry重置镜像路径 npm config set r…

vulstack ATTCK(三)靶场

0x00环境搭建 两种形式 1.添加vmare2网卡,修改vmare2网卡的地址为192.168.93.0网段,注意不要在连接到主机适配器上打勾,这样会使本机也可以访问此电脑,5台机器都换成vmare2即可,第一台出网的centos在添加另一张nat网卡…

Docker容器---数据卷 数据容器

Docker容器---数据卷 数据容器 一、数据卷概述1、数据卷2、数据卷原理3、数据卷作用 二、数据卷容器1、数据卷容器作用2、创建数据卷容器 三、容器互联1、创建并运行源容器取名web12、创建并运行接收容器取名web2 一、数据卷概述 管理 Docker 容器中数据主要有两种方式&#x…

社科院与杜兰大学中外合作办学金融管理硕士项目——比起过往,前路更值得期待

当结束一天工作陷入沉思时,你有没有特别遗憾的事情呢,人生有太多的不确定性,比起过往,未知的人生更值得我们期待。与其懊恼没完成的遗憾,不如珍惜当下,努力创造未来。人生没有太晚的开始,在职读…

frp内网穿透——以连接到校园内网的服务器为例

有时候想摸鱼不去实验室,在宿舍就直接连接到实验室的GPU服务器。奈何服务器在校园网内部,外网无法直接直接访问。此时需要手动搭一个跳板机,来连接到内网的GPU服务器,这一过程怎么做到呢?我们可以使用frp内网穿透工具&…

Seata:连接数据与应用

作者:季敏(清铭)Seata 开源社区创始人,分布式事务团队负责人。 本文主要介绍分布式事务从内部到商业化和开源的演进历程,Seata 社区当前进展和未来规划。 Seata 是一款开源的分布式事务解决方案,旨在为现…

Java基础(十八):java比较器、系统相关类、数学相关类

Java基础系列文章 Java基础(一):语言概述 Java基础(二):原码、反码、补码及进制之间的运算 Java基础(三):数据类型与进制 Java基础(四):逻辑运算符和位运算符 Java基础(五):流程控制语句 Java基础(六)&#xff1…

JavaScript黑科技:隐秘执行

JavaScript黑科技&#xff1a;隐秘执行 如果能使网页中的JavaScript代码隐密的加载、隐密的执行&#xff0c;那对于保护JavaScript代码来说是很有利的。 本文将探索、演示一种隐秘执行JavaScript代码的技术。 源码如下&#xff1a; <html> <script>window.onlo…

Prometheus+node_exporter+Grafana+夜莺 监控部署

一、安装Prometheus 1.1 部署并配置Prometheus #主机基础配置 [rootnode4~]# systemctl stop firewalld && systemctl disable firewalld [rootnode4~]# sed -i s/enforcing/disabled/g /etc/selinux/config && setenforce 0#上传prometheus安装包并解压 [r…

8、ThingsBoard使用docker compose集群部署的问题以及如何解决问题

1、问题回顾 接着上一节继续讲解,上一节我们把整个服务全部都运行起来了,但是访问页面报错,最后查看的问题是前端的容易里面报错: 然后执行脚本删除所有的容器 2、问题分析 当遇到这个问题的时候,我当时真的不知道如何去解决,然后我又尝试使用官方的镜像来部署,发现官…

P75分层解耦-IOCDI详解

一、分层解耦-三层架构 Dao层&#xff1a;数据访问 1、接口 package com.itheima.service;import com.itheima.pojo.Emp;import java.util.List;/*** Description:* date: 2023/4/19 21:47** since JDK 11*/ public interface EmpService { // 获取员工列表数据public List&l…

RabbitMQ·入门·壹

文章目录 1 MQ思想1.1 相关概念&#xff1a;同步、异步通讯1.1.1 同步通讯1.1.2 异步通讯 1.2 MQ思想概述1.2.1 1 MQ思想 1.1 相关概念&#xff1a;同步、异步通讯 通讯方式举例优势劣势同步通讯就像打电话&#xff0c;需要实时响应。打电话可以立即得到响应。不能跟多人同时…

垃圾回收相关算法

标记阶段的算法 垃圾标记阶段&#xff1a;对象存货判断 在堆里存放着几乎所有的Java对象实例&#xff0c;在GC执行垃圾回收之前&#xff0c;首先需要区分出内存中哪些是存活对象&#xff0c;哪些是己经死亡的对象。只有被标记为己经死亡的对象&#xff0c;GC才会在执行垃圾回…

AutoGPT 环境搭建教程

文章目录 前言一、注册OpenAI和Pinecone的账号&#xff0c;并获取key二、下载Git和Python3&#xff08;自己网上搜&#xff0c;无脑安装&#xff09;![在这里插入图片描述](https://img-blog.csdnimg.cn/95bafd5ebe9d468cbceeacbfc0cb939b.png)三、进入GitHub&#xff0c;安装A…

Flowable从入门到源码分析

什么是工作流&#xff1f; 工作流&#xff0c;是把业务之间的各个步骤以及规则进行抽象和概括性的描述。使用特定的语言为业务流程建模&#xff0c;让其运行在计算机上&#xff0c;并让计算机进行计算和推动。 工作流解决的痛点在于&#xff0c;解除业务宏观流程和微观逻辑的…

【Linux】基础IO,详解系统文件IO

目录 C语言文件操作简单回顾 C语言相关文件接口汇总 默认打开的三个流 系统文件I/O open open的第一个参数 open的第二个参数 open的第三个参数 open的返回值 close write read 文件描述符 什么是文件描述符 文件描述符分配规则 重定向 重定向的本质 输出重定…

ETCD(一)简介

1. ETCD是什么 etcd 是一个分布式键值对存储&#xff0c;设计用来可靠而快速的保存关键数据并提供访问。和数据库一样都是用来存数据的&#xff0c;但是etcd有自己的特点&#xff0c;因此有自己的使用场景。 2. etcd 特点 完全复制&#xff0c;集群中的每个节点均拥有全量数…

跌倒检测和识别2:YOLOv5实现跌倒检测(含跌倒检测数据集和训练代码)

跌倒检测和识别2&#xff1a;YOLOv5实现跌倒检测(含跌倒检测数据集和训练代码) 目录 跌倒检测和识别2&#xff1a;YOLOv5实现跌倒检测(含跌倒检测数据集和训练代码) 1. 前言 2. 跌倒检测数据集说明 &#xff08;1&#xff09;跌倒检测数据集 &#xff08;2&#xff09;自定…

《离散数学导学》精炼——第10章(序列)

Learning never exhausts the mind. 文章目录 引言正文元包序列的定义序列与函数的关系空序列长度连接头尾运算符限制运算符逆置运算符单射序列 引言 笔者一直觉得在计算机这一学科的学习中&#xff0c;离散数学是极为重要的知识基础。离散化的思想体现在计算机学科的方方面面…