Python实现识别手写数字 简易图片存储管理系统

写在前面

上一篇文章Python实现识别手写数字—图像的处理中我们讲了图片的处理,将图片经过剪裁,拉伸等操作以后将每一个图片变成了1x10000大小的向量。但是如果只是这样的话,我们每一次运行的时候都需要将他们计算一遍,当图片特别多的时候会消耗大量的时间。

所以我们需要将这些向量存入一个文件当中,每次先看看图库中有没有新增的图片,如果有新增的图片,那么就将新增的图片变成1x10000向量再存入文件之中,然后从文件中读取全部图片向量即可。当图库中没有新增图片的时候,那么就直接调用文件中的图片向量进行计算就好。这样子算是节省了大量的时间。

所以本文就是从零开始建立一个这样的图片存储管理系统。

实现逻辑

第一次读入图片

我们的图库中拥有一大堆图片,每一张图片上面都是一个手写的数字,图片的名称为[数字内容]_[序号]。比如说一个图片的名称为2_3,代表这一张图片里面的数字是2,并且是“数字是2的第3张图片”。

存在一个csv文件作为我们的建议的图片数据库,名称为Data.csv。

首先我们读取图库中所有图片的名称,保存在fileNames中。然后读取Data.csv中所有数据。

提取出Data.csv的最后一列(一共10002列,第10001列说明该数字是什么数字,第10002列是图片的名称),也就是数据库中存储的所有图片的名称,存储在item中。

将新加入图库的图片名称保存在newFileNames中。如果Data.csv为空,那么就直接令newFileNames = fileNames。也就是说如果数据库中什么也没有,那么图库中所有图片都是新加入的。

如果Data.csv不为空,那么就将item里面的内容与fileNames的内容比较,如果出现了fileNames里面有的名称item中没有,那么就将这些名称放进newFileNames中。如果item里有的名称fileNames中没有,那就不管。

也就是说,我令我们的数据库只进不出。

现在我们得到了新加入图库的图片的名称newFileNames。

将newFileNames中的名称的图片带入上一文中函数GetTrainPicture进行处理,得到了一个nx10001的矩阵,每一行代表一个新加入的图片,前10000列是图片向量,第10001列是该图片的数字,保存在pic中。

将这些图片压入到数据库的后面。

读取之前数据库原有的图片向量,并与pic合并,得到目前拥有的所有的训练图片向量pic。

以上就是本章写的所有内容,下面放出代码来详细解释一下。

代码解析

主文件

import os
import numpy as np
import OperatePicture as OP
import OperateDataBase as OD
import csv

##Essential vavriable 基础变量
#Standard size 标准大小
N = 100
#Gray threshold 灰度阈值
color = 100/255

#读取原CSV文件
reader = list(csv.reader(open('DataBase.csv', encoding = 'utf-8')))
#清除读取后的第一个空行
del reader[0]
#读取num目录下的所有文件名
fileNames = os.listdir(r"./num/")
#对比fileNames与reader,得到新增的图片newFileNames
newFileNames = OD.NewFiles(fileNames, reader)
print('New pictures are: 'newFileNames)
#得到newFilesNames对应的矩阵
pic = OP.GetTrainPicture(newFileNames)
#将新增图片矩阵存入CSV中
OD.SaveToCSV(pic, newFileNames)
#将原数据库矩阵与新数据库矩阵合并
pic = OD.Combination(reader, pic)

我将两节内容分别封装在两个py文件里面,上一篇文章中的图片的切割与处理等所有内容我放在文件OperatePicture里面了,这一节的数据库处理放在了文件OperateDatabase里面。

因为整个代码的逻辑我在上面已经捋过一遍了,所以我不再解释其中的内容,接下来针对每个函数开始讲解。

OperateDatabase代码

从上面的主文件中,我们首先用到了函数NewFiles,主要是对比fileNames和reader这两个文件中图片的名称有什么不同,返回值是新增的图片的名称的列表。下面是代码

def NewFiles(fileNames, reader):
 '''判断是否有不同于数据库中的新文件加入'''
 #如果数据库中没有数据,则返回filenames
 if len(reader) == 0:
  return fileNames
 else:
  #从数据库中提取所有名称
  files = [item[10001] for item in reader]
  #需要加入的图片名称
  newFileNames = []
  for item in fileNames:
   #判断当前名称是否存在数据库中
   #如果不存在,则加入newFileNames
   if item not in files:
    newFileNames.append(item)
  return newFileNames

首先判断reader是否有内容,如果没有内容,说明是第一次执行,那么会直接把fileNames返回。否则才会进入下面进行比较。

返回了newFileNames之后,就会把这个列表中的所有名称的图片通过GetTrainPicture函数得到一个1x10001大小的矩阵,具体过程请看我上一篇文章讲的内容。

之后为了把新的数据存入CSV文件中,我们利用函数SaveToCSV将pic存入文件中,具体代码如下。

def SaveToCSV(pic, fileNames):
 '''将pic与对应的dileNames存入CSV文件'''
 writer = csv.writer(open('Database.csv', 'a', newline = ''), dialect = 'excel')
 #将fileNames变为列表
 f = [item for item in fileNames]
 #每一行依次写入文件中
 for i in range(len(pic)):
  #将改行图片向量转为list
  item = pic[i].tolist()
  #将这个图片向量对应的名称f放入列表最后一个
  item.append(f[i])
  writer.writerow(item)

当函数运行过后,会把pic矩阵对应的内容直接给续写入CSV文件中,相当于数据库操纵的写入,并不会覆盖之前原有的数据。

之后我们需要将数据库原有的一大堆数据reader和新加进来的数据pic合并到pic里面,所以利用Combination函数将两个矩阵合并,代码如下

def Combination(reader, pic):
 '''将两个矩阵reader与pic合并'''
 #两个矩阵的总行数
 l = len(reader) + len(pic)
 #初始化新的矩阵
 newPic = np.zeros(l*10001).reshape(l, 10001)
 #将reader最后的那个字符串名称去掉
 for item in reader:
  item.pop()
 #将reader转化为numpy的矩阵形式
 reader = np.array(reader)
 #新矩阵前半部分放reader,后半部分放pic
 if len(reader) != 0:
  newPic[0:len(reader), :] = reader
 newPic[len(reader):len(pic), :] = pic
 return newPic

因为reader最后一行还包括了一个图片的名称,所以先利用pop将其去掉,之后转化为矩阵形式,然后再直接放入矩阵中。这个矩阵操作可能没有见过,下面我详细解释一下。

假如我现在有一个2x3的矩阵和一个2x2的矩阵

m = [[1 2 3]
  [4 5 6]]
n = [[7 8]
  [9 1]]

我可以进行如下操作

#操作一
m[:, 0:2] = n
print(m)
#操作二
m[:, 1:3] = n
print(m)

#以下为输出结果
#操作一
[[7 8 3]
 [9 1 6]]
#操作二
[[7 7 8]
 [9 9 1]]

可以看出操作一直接把m的第一二列给替换成n,操作二把m的第二三列替换成了n。具体过程可以百度查一下numpy的矩阵的操作,也可以自己总结规律,不细讲了。

以上就是这一篇的全部代码。

小结

这一篇我相当于用CSV文件制作了一个非常简陋的数据库,能够执行的操作只有识别已有内容NewFiles与添加内容SaveToCSV,并没有插入、删改等操作。主要是我觉得这两个函数目前已经够用,因此只写了这两个操作,所以再需求已经被满足的情况下就不再拓展了。

所有的源代码已经上传到了我的GitHub上,可以前去下载,谢谢阅读。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Python实现识别手写数字 Python图片读入与处理
  • Python实现识别手写数字大纲
  • python实现识别手写数字 python图像识别算法
  • python实现图像识别功能
  • 学习Python3 Dlib19.7进行人脸面部识别
  • Python3结合Dlib实现人脸识别和剪切
  • 用Python进行简单图像识别(验证码)
  • Python3一行代码实现图片文字识别的示例
  • Python用sndhdr模块识别音频格式详解
  • Python用imghdr模块识别图片格式实例解析
(0)

相关推荐

  • Python3一行代码实现图片文字识别的示例

    自学Python3第5天,今天突发奇想,想用Python识别图片里的文字.没想到Python实现图片文字识别这么简单,只需要一行代码就能搞定 from PIL import Image import pytesseract #上面都是导包,只需要下面这一行就能实现图片文字识别 text=pytesseract.image_to_string(Image.open('denggao.jpeg'),lang='chi_sim') print(text) 我们以识别诗词为例 下面是我们要识别的图片 先

  • Python3结合Dlib实现人脸识别和剪切

    0.引言 利用python开发,借助Dlib库进行人脸识别,然后将检测到的人脸剪切下来,依次排序显示在新的图像上: 实现的效果如下图所示,将图1原图中的6张人脸检测出来,然后剪切下来,在图像窗口中依次输出显示人脸: 实现比较简单,代码量也比较少,适合入门或者兴趣学习. 图1 原图和处理后得到的图像窗口 1.开发环境 python: 3.6.3 dlib: 19.7 OpenCv, numpy import dlib # 人脸识别的库dlib import numpy as np # 数据处理的库

  • Python实现识别手写数字 Python图片读入与处理

    写在前面 在上一篇文章Python徒手实现手写数字识别-大纲中,我们已经讲过了我们想要写的全部思路,所以我们不再说全部的思路. 我这一次将图片的读入与处理的代码写了一下,和大纲写的过程一样,这一段代码分为以下几个部分: 读入图片: 将图片读取为灰度值矩阵: 图片背景去噪: 切割图片,得到手写数字的最小矩阵: 拉伸/压缩图片,得到标准大小为100x100大小矩阵: 将图片拉为1x10000大小向量,存入训练矩阵中. 所以下面将会对这几个函数进行详解. 代码分析 基础内容 首先我们现在最前面定义基础

  • Python用imghdr模块识别图片格式实例解析

    imghdr模块 功能描述:imghdr模块用于识别图片的格式.它通过检测文件的前几个字节,从而判断图片的格式. 唯一一个API imghdr.what(file, h=None) 第一个参数file可以是用rb模式打开的file对象或者表示路径的字符串和PathLike对象.h参数是一段字节串.函数返回表示图片格式的字符串. >>> import imghdr >>> imghdr.what('test.jpg') 'jpeg' 具体的返回值和描述如下: 返回值 描述

  • python实现图像识别功能

    本文实例为大家分享了python实现图像识别的具体代码,供大家参考,具体内容如下 #! /usr/bin/env python from PIL import Image import pytesseract url='img/denggao.jpeg' image=Image.open(url) #image=image.convert('RGB') # RGB image=image.convert('L') # 灰度 image.load() text=pytesseract.image_

  • Python实现识别手写数字大纲

    写在前面 其实我之前写过一个简单的识别手写数字的程序,但是因为逻辑比较简单,而且要求比较严苛,是在50x50大小像素的白底图上手写黑色数字,并且给的训练材料也不够多,导致准确率只能五五开.所以这一次准备写一个加强升级版的,借此来提升我对Python处理文件与图片的能力. 这次准备加强难度: 被识别图片可以是任意大小: 不一定是白底图,只要数字颜色是黑色,周围环境是浅色就行: 加强识别手写数字的逻辑,提升准确率. 因为我还没开始正式写,并且最近专业课程学习也比较紧迫,所以可能更新的比较慢.不过放心

  • python实现识别手写数字 python图像识别算法

    写在前面 这一段的内容可以说是最难的一部分之一了,因为是识别图像,所以涉及到的算法会相比之前的来说比较困难,所以我尽量会讲得清楚一点. 而且因为在编写的过程中,把前面的一些逻辑也修改了一些,将其变得更完善了,所以一切以本篇的为准.当然,如果想要直接看代码,代码全部放在我的GitHub中,所以这篇文章主要负责讲解,如需代码请自行前往GitHub. 本次大纲 上一次写到了数据库的建立,我们能够实时的将更新的训练图片存入CSV文件中.所以这次继续往下走,该轮到识别图片的内容了. 首先我们需要从文件夹中

  • 学习Python3 Dlib19.7进行人脸面部识别

    0.引言 自己在下载dlib官网给的example代码时,一开始不知道怎么使用,在一番摸索之后弄明白怎么使用了: 现分享下 face_detector.py 和 face_landmark_detection.py 这两个py的使用方法: 1.简介 python: 3.6.3 dlib: 19.7 利用dlib的特征提取器,进行人脸 矩形框 的特征提取: dets = dlib.get_frontal_face_detector(img) 利用dlib的68点特征预测器,进行人脸 68点 特征提

  • Python用sndhdr模块识别音频格式详解

    本文主要介绍了Python编程中,用sndhdr模块识别音频格式的相关内容,具体如下. sndhdr模块 功能描述:sndhdr模块提供检测音频类型的接口. 唯一一个API sndhdr模块提供了sndhdr.what(filename)和sndhdr.whathdr(filename)两个函数.但实际上它们的功能是一样的.(不知道多写一个的意义何在,what函数在内部调用了whathdr函数并把数据完完整整地返回) 在之前的版本,whathdr函数返回元组类型的数据,在Python3.5版本之

  • 用Python进行简单图像识别(验证码)

    这是一个最简单的图像识别,将图片加载后直接利用Python的一个识别引擎进行识别 将图片中的数字通过 pytesseract.image_to_string(image)识别后将结果存入到本地的txt文件中 #-*-encoding:utf-8-*- import pytesseract from PIL import Image class GetImageDate(object): def m(self): image = Image.open(u"C:\\a.png") text

随机推荐