我使用OpenCV中的KNearest来实现简单的文字识别OCR。下面是我实现的步骤,学习学习
以下是我的训练数据图:
(训练数据量较少。所有的字母都是相同的字体和大小)。
我用OpenCV编写了一个小代码处理数据:
a)加载图像。
(B)选择数字(是通过轮廓查找并对字母的面积和高度施加约束来避免错误检测)。
(C)给字母绘制边框,并自己按数字键与图中一致
(D)一旦按下相应的数字键,它将该框调整为10x10,并在一个数组中保存100个像素值(此处为示例),并在另一个数组中保存相应的手动输入数字
然后将两个数组保存在单独的txt文件中。
在手动数字分类结束时,训练数据(TRAIN.png)中的所有数字都由我们手工标记,图像如下所示:
下面是用于上述处理的代码:
import sys
import numpy as np
import cv2
im = cv2.imread('pitrain.png')
im3 = im.copy()
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),0)
thresh = cv2.adaptiveThreshold(blur,255,1,1,11,2)
################# Now finding Contours ###################
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
samples = np.empty((0,100))
responses = []
keys = [i for i in range(48,58)]
for cnt in contours:
if cv2.contourArea(cnt)>50:
[x,y,w,h] = cv2.boundingRect(cnt)
if h>28:
cv2.rectangle(im,(x,y),(x+w,y+h),(0,0,255),2)
roi = thresh[y:y+h,x:x+w]
roismall = cv2.resize(roi,(10,10))
cv2.imshow('norm',im)
key = cv2.waitKey(0)
if key == 27: # (escape to quit)
sys.exit()
elif key in keys:
responses.append(int(chr(key)))
sample = roismall.reshape((1,100))
samples = np.append(samples,sample,0)
responses = np.array(responses,np.float32)
responses = responses.reshape((responses.size,1))
print "training complete"
np.savetxt('generalsamples.data',samples)
np.savetxt('generalresponses.data',responses)
现在进入训练和测试部分。
在测试部分,我使用了下面的图像,它的字母类型是一样的
关于训练
(A)加载我们前面已经保存的txt文件
(B)创建分类器实例(在这里,它是KNeest)
(C)然后使用KNearest.TRANS函数对数据进行训练。
关于测试
(A)我们加载用于测试的图像
(B)像以前一样处理图像,并使用轮廓法提取每一个数字。
c)为其绘制边框,然后调整大小为10x10,并像前面所做的那样将其像素值存储在数组中。
(D)然后我们使用 KNearest.find_nearest()函数的查找最近项,以找到与我们提供的项最接近的项。
我将最后两个步骤(训练和测试)放在下面的代码中:
import cv2
import numpy as np
####### training part ###############
samples = np.loadtxt('generalsamples.data',np.float32)
responses = np.loadtxt('generalresponses.data',np.float32)
responses = responses.reshape((responses.size,1))
model = cv2.KNearest()
model.train(samples,responses)
############################# testing part #########################
im = cv2.imread('pi.png')
out = np.zeros(im.shape,np.uint8)
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,1,1,11,2)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
if cv2.contourArea(cnt)>50:
[x,y,w,h] = cv2.boundingRect(cnt)
if h>28:
cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)
roi = thresh[y:y+h,x:x+w]
roismall = cv2.resize(roi,(10,10))
roismall = roismall.reshape((1,100))
roismall = np.float32(roismall)
retval, results, neigh_resp, dists = model.find_nearest(roismall, k = 1)
string = str(int((results[0][0])))
cv2.putText(out,string,(x,y+h),0,1,(0,255,0))
cv2.imshow('im',im)
cv2.imshow('out',out)
cv2.waitKey(0)
得到结果:
这里,精度为100%