# 构建手写数字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 img = cv2.imread('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) # 检查分类的准确性 # 将预测分类的结果与其所属的测试标签进行比较,判断成功还是失败 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) image = cv2.imread('9/9.jpg',0) #img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY); image.resize(20,20) ret, image = cv2.threshold(image, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV) testImage = image.reshape(-1,400).astype(np.float32) # 用所有数据作为训练数据 ret,result,neighbours,dist = knn.findNearest(testImage, 1) print(result)