OpenCV使用KNN完成OCR手写体识别

 更新时间:2023年05月10日 08:45:27   作者:uncle_ll  
这篇文章主要为大家介绍了OpenCV使用KNN完成OCR手写体识别示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

目标

在本章中,将学习

  • 使用kNN来构建基本的OCR应用程
  • 使用OpenCV自带的数字和字母数据集

手写数字的OCR

目标是构建一个可以读取手写数字的应用程序。为此,需要一些 train_datatest_data 。OpenCV git项目中有一个图片 digits.png (opencv/samples/data/ 中),其中包含 5000 个手写数字(每个数字500个),每个数字都是尺寸大小为 20x20 的图像。

因此,第一步是将上面这张图像分割成 5000 (500*10)个不同的数字。对于每个数字,将其展平为 400 像素的一行,这就是训练集,即所有像素的强度值。这个是可以创建的最简单的特征集合。将每个数字的前 250个样本用作训练集train_data ,然后将 250 个样本用作 测试集test_data

import cv2
import numpy as np
img = cv2.imread('digits.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Now we split the image to 5000 cells, each 20x20 size
cells = [np.hsplit(row, 100) for row in np.vsplit(gray, 50)]
# Make it into a numpy array: its size will be (50, 100, 20, 20)
x = np.array(cells)
# Now we prepare the training data and test data
train = x[:,:50].reshape(-1,400).astype(np.float32) # Size = (2500,400)
test = x[:,50:100].reshape(-1,400).astype(np.float32) # Size = (2500,400)
# Create labels for train and test data
k = np.arange(10)
train_labels = np.repeat(k, 250)[:, np.newaxis]
test_labels = train_labels.copy()
# Initiate kNN, train it on the training data, then test it with the test data with k=1
knn = cv2.ml.KNearest_create()
knn.train(train, cv2.ml.ROW_SAMPLE, train_labels)
ret, result, neighbours, dist = knn.findNearest(test, k=5)
# Now we check the accuracy of classification
# For that, compare the result with test_labels and check which are wrong
matches = result==test_labels
correct = np.count_nonzero(matches)
accuracy = correct * 100.0/result.size
print( accuracy )  # 91.76

可以看到,上述构建了一个基础的数字手写体OCR应用程序已准备就绪。在这个特定的例子中的准确度是91.76%。

提高准确度方法:

  • 一种提高准确性的选择是添加更多数据进行训练,尤其是错误的数据。

  • 另外一种是更换更优的算法

本文中,每次启动应用程序时都找不到该训练数据,不如将其保存,以便下次直接从文件中读取此数据并开始分类。可以借助一些Numpy函数(例如np.savetxtnp.saveznp.load等)来完成此操作。

# Save the data
np.savez('knn_dight_data.npz', train=train, train_labels=train_labels)
# Now load the data
whit np.load('knn_data.npz') as data:
    print(data.files)
    train = data['train']
    train_labels = data['train_labels']

在windows系统下,大约需要大约 3.82 MB 的内存。由于仅使用强度值(uint8数据)作为特征,如果需要考虑内存的问题时候,可以先将数据转换为 np.uint8 ,然后再将其保存。在这种情况下,仅占用 0.98MB 。然后在加载时,可以转换回 float32

train_uint8 = train.astype(np.uint8)
train_labels_uint8 = train_labels.astype(np.uint8)
np.savez('knn_dight_data_int8.npz', train=train_uint8, train_labels=train_labels_uint8)

也可以用来预测单个数字

# 取测试集中的一个元素
single_data = testData[0].reshape(-1, 400)
single_label = labels[0]
ret, result, neighbours, dist = knn.findNearest(data, k=5)
print(result)  # [[0]]
print(label)   # [[0.]]
print(result==label)  # True

英文字母的OCR

接下来,对英语字母执行相同的操作,但是数据和特征集会稍有变化。OpenCV使用文件letter-recognition.data( /data/samples/data/letter-recognition.data)代替图像 。如果打开它,将看到20000行,乍一看可能看起来像垃圾数字。

实际上,在每一行中,第一列是字母,这是标签接下来的16个数字是它的不同特征,这些特征是从UCI机器学习存储库获得的。可以在此页面中找到这些功能的详细信息。

现有20000个样本,将前10000个数据作为训练样本,剩余的10000个作为测试样本。字母应该更改为ASCII字符,因为不能直接使用字母。

import numpy as np
import cv2
#  Load the data and convert the letters to numbers
data = np.loadtxt('letter-recognition.data', dtype='float32', delimiter=',', converters={0: lambda ch: ord(ch)-ord('A')})
# Split the dataset in two, with 10000 samples each for training and test sets
train, test = np.vsplit(data, 2)
# Split trainData and testData into features and responses
responses, trainData = np.hsplit(train, [1])
labels, testData = np.hsplit(test, [1])
# Initiate the kNN, classify, measure accuracy
knn = cv2.ml.KNearest_create()
knn.train(trainData, cv2.ml.ROW_SAMPLE, responses)
ret, result, neighbours, dist = knn.findNearest(testData, k=5)
correct = np.count_nonzero(result==labels)
accuracy = correct * 100 / result.size
print(accuracy)  # 93.06

它给我的准确性为 93.06% 。同样,如果要提高准确性,则可以迭代地在每个类别中添加错误数据。

附加资源

以上就是OpenCV使用KNN完成OCR手写体识别的详细内容,更多关于OpenCV KNN识别OCR手写体的资料请关注脚本之家其它相关文章!

相关文章

  • keras实现theano和tensorflow训练的模型相互转换

    keras实现theano和tensorflow训练的模型相互转换

    这篇文章主要介绍了keras实现theano和tensorflow训练的模型相互转换,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-06-06
  • openCV提取图像中的矩形区域

    openCV提取图像中的矩形区域

    这篇文章主要为大家详细介绍了openCV提取图像中的矩形区域,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • 如何将你的应用迁移到Python3的三个步骤

    如何将你的应用迁移到Python3的三个步骤

    这篇文章主要介绍了如何将你的应用迁移到Python3的三个步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • 如何使用OpenCV进行视频读取与处理的完整指南

    如何使用OpenCV进行视频读取与处理的完整指南

    OpenCV是一个开源的计算机视觉和机器学习软件库,广泛应用于图像和视频的处理,本篇文章将详细解析如何使用OpenCV读取和处理视频,并结合实际的代码示例来展示操作的全过程,同时探讨一些性能优化的策略
    2024-08-08
  • Python中json.dumps()函数使用和示例

    Python中json.dumps()函数使用和示例

    这篇文章主要介绍了Python中json.dumps()函数使用和示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Flask添加路由的三种方法

    Flask添加路由的三种方法

    Flask 是一个流行的 Python Web 框架,它提供了多种方法来添加路由,本文详细的介绍了Flask添加路由的三种方法,感兴趣的可以了解一下
    2023-11-11
  • 使用Rasterio读取栅格数据的实例讲解

    使用Rasterio读取栅格数据的实例讲解

    今天小编就为大家分享一篇使用Rasterio读取栅格数据的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • 解决yum对python依赖版本问题

    解决yum对python依赖版本问题

    这篇文章主要介绍了解决yum对python依赖版本问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Python常见异常分类与处理方法

    Python常见异常分类与处理方法

    之前在学习python的时候有整理过python异常处理的文章,不够简单也不够完整,所以决定再整理一篇,算做补充。
    2017-06-06
  • python代码打包超详细教程

    python代码打包超详细教程

    在Python开发的过程中我们经常会需要将自己的代码打包成一个可执行文件,方便将代码分享给其他人使用,下面这篇文章主要给大家介绍了关于python代码打包的相关资料,需要的朋友可以参考下
    2023-06-06

最新评论