Python,OpenCV使用KNN来构建手写数字及字母识别OCR
生活随笔
收集整理的這篇文章主要介紹了
Python,OpenCV使用KNN来构建手写数字及字母识别OCR
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Python,OpenCV使用KNN來構建手寫數字及字母識別OCR
- 1. 原理
- 1.1 手寫數字識別
- 1.2 字母識別
- 2. 源碼
- 2.1 手寫數字OCR
- 2.2 字母OCR
- 參考
這篇博客將介紹如何借助OpenCV提供的手寫數字及字母數據集,來構建訓練KNN模型,以進行手寫數字及字母的識別。
并分別達到手寫數字 91% 的精確度,字母93%的精確度。
提升模型精確度的方法有1)增加訓練數據集以及 2)增加錯誤的數據集;
OCR 即 Optical Character Recognition 光學字符識別,表示在圖像上進行文本等的識別;
1. 原理
1.1 手寫數字識別
OpenCV提供了手寫數字數據集:digits.png 共包括5000個手寫數字(0~10),每個數字500個。
- 加載數據集 digits.png(得到5000個數據集,10個標簽(0~9)
- 拆分為訓練數據集、測試數據集(各2500個,10個標簽)
- 用訓練數據集+標簽 訓練KNN模型
- 用測試數據集+標簽 進行KNN模型準確度的驗證;
- 存儲訓練數據集+標簽,通過使用 np.savez(‘images/knn_data.npz’, train=train, train_labels=train_labels)進行保存。
1.2 字母識別
OpenCV提供了字母數據集:letter-recognition.data ,共包括 20000行,20000個字母數據集,每行第一列是字母標簽,接下來的16個數字是從 UCI 機器學習存儲庫中獲得的字母對應的特征;
- 加載數據集 (20000個)
- 拆分為訓練數據集、測試數據集(前10000個作為訓練數據,后10000個作為測試數據)
- 用訓練數據集+標簽 訓練KNN模型
- 用測試數據集+標簽 進行KNN模型準確度的驗證;
2. 源碼
2.1 手寫數字OCR
# 構建手寫數字OCR的應用程序
#
# 需要一些 train_data 和 test_data。 OpenCV 附帶一個圖像digits.png,其中有 5000 個手寫數字(每個數字 500 個)。每個數字都是一個 20x20 的圖像。、
# 第一步是將這個圖像分成 5000 個不同的數字。對于每個數字,我們將其展平為 400 像素的一行。那就是我們的特征集,即所有像素的強度值。這是我們可以創建的最簡單的功能集。
# 第二部使用每個數字的前 250 個樣本作為 train_data,剩下的250 個樣本作為 test_data
# 然后訓練數據;import numpy as np
import cv2
from matplotlib import pyplot as pltimg = cv2.imread('images/digits.png') # 原始圖像包括5000個不同的數字
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 分割圖像為5000個單元,每個20x20像素
cells = [np.hsplit(row, 100) for row in np.vsplit(gray, 50)]# 轉為Numpy數組,shape將為 (50,100,20,20)
x = np.array(cells)# 準備訓練集和測試集
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)# 為訓練數據和測試數據創建標簽
k = np.arange(10)
train_labels = np.repeat(k, 250)[:, np.newaxis]
test_labels = train_labels.copy()# 初始化KNN,訓練模型,然后對測試集使用k=1進行測試
knn = cv2.ml.KNearest_create()
print('knn: ', knn)
knn.train(train, cv2.ml.ROW_SAMPLE, train_labels)
ret, result, neighbours, dist = knn.findNearest(test, k=5)print("result: ", result, result.shape)
print("neighbours: ", neighbours)
print("distance: ", dist)# 檢查分類的準確性
# 將預測分類的結果與其所屬的測試標簽進行比較,判斷成功還是失敗
matches = result == test_labels
correct = np.count_nonzero(matches)
accuracy = correct * 100.0 / result.size# 識別手寫數字得到了91.76% 的準確率。提高準確性的一種選擇是添加更多用于訓練的數據,尤其是錯誤的數據。
# 可以把訓練的數據/模型保存下來,這樣下次就能直接從文件中加載數據/模型,然后進行分類,可借助Numpy函數(如 np.savetxt、np.savez、np.load 等)來保存模型
print("OCR digits accuracy: ", accuracy)# 保存訓練數據
# 需要大約 4MB 的內存。由于使用強度值(uint8 數據)作為特征,因此最好先將數據轉換為 np.uint8,然后再保存,這樣只需要1MB。然后在加載時再轉換回float32。
np.savez('images/knn_data.npz', train=train, train_labels=train_labels)# 加載
with np.load('images/knn_data.npz') as data:print(data.files)train = data['train']train_labels = data['train_labels']print(train.shape, train_labels.shape)# 需要大約 4MB 的內存。由于使用強度值(uint8 數據)作為特征,因此最好先將數據轉換為 np.uint8,然后再保存。這樣只需要1MB。然后在加載時再轉換回np.float32。
np.savez('images/knn_data_npuint8.npz', train=train.astype(np.uint8), train_labels=train_labels.astype(np.uint8))# 加載uint8的訓練數據
with np.load('images/knn_data_npuint8.npz') as data:print(data.files)train = data['train'].astype(np.float32)train_labels = data['train_labels'].astype(np.float32)print(train.shape, train_labels.shape)
2.2 字母OCR
# 構建英文字母OCR的應用程序# 對英文字母進行OCR,但數據和特征集與手寫數字略有變化。OpenCV 沒有提供英文字母的圖像,而是提供了一個數據文件 letter-recognition.data。
# 共20000 行,每一行中第一列是一個字母表,這是標簽。接下來的 16 個數字是其不同的功能。這些功能是從 UCI 機器學習存儲庫中獲得的。您可以在此頁面中找到這些功能的詳細信息。
# 有20000個樣本可用,因此取前10000個數據作為訓練樣本,剩下的10000個作為測試樣本。OpenCV無法直接處理字母,因此先將字母更改為 ascii 字符,然后進行處理。import cv2
import numpy as np
import matplotlib.pyplot as plt# 加載數據,并轉換字母為ASCII碼
data = np.loadtxt('images/letter-recognition.data', dtype='float32', delimiter=',',converters={0: lambda ch: ord(ch) - ord('A')})# 拆分數據為倆份,訓練數據,測試數據各10000
train, test = np.vsplit(data, 2)# 拆分訓練數據集為特征及分類
responses, trainData = np.hsplit(train, [1])
labels, testData = np.hsplit(test, [1])# 初始化KNN,訓練模型,度量其準確性
knn = cv2.ml.KNearest_create()
knn.train(trainData, cv2.ml.ROW_SAMPLE, responses)
ret, result, neighbours, dist = knn.findNearest(testData, k=5)print("result: ", result, result.shape)
print("neighbours: ", neighbours)
print("distance: ", dist)correct = np.count_nonzero(result == labels)
accuracy = correct * 100.0 / 10000# 得到了93.06%的準確度,如果要提高準確性,可以在每個級別中迭代添加錯誤數據。
print('OCR alphabet accuracy: ', accuracy)
參考
- https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_knn/py_knn_opencv/py_knn_opencv.html#knn-opencv
總結
以上是生活随笔為你收集整理的Python,OpenCV使用KNN来构建手写数字及字母识别OCR的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python,OpenCV中的K近邻(k
- 下一篇: python采用Basemap绘制完美中