我使用OpenCV中的KNeest或SVM特性来实现简单的文字识别OCR。下面是我实现的步骤,学习学习

1)我的第一个问题是关于OpenCV示例附带的数据文件。我想知道文件里有什么。

它包含一个字母,以及该字母的16个特征。

和this SOF帮我找到了。本文对这16个特征进行了说明。使用Holland分类器进行字母识别

2)如果不了解这些特性,就很难做。所以能实现就好,我没有太关注性能

以下是我的训练数据图:

使用opencv识别图片中的文字 opencv识别图片中的数字_数组

(训练数据量较少。所有的字母都是相同的字体和大小)。

我用OpenCV编写了一个小代码处理数据:

a)加载图像。

(B)选择数字(是通过轮廓查找并对字母的面积和高度施加约束来避免错误检测)。

(C)给字母绘制边框,并自己按数字键与图中一致

(D)一旦按下相应的数字键,它将该框调整为10x10,并在一个数组中保存100个像素值(此处为示例),并在另一个数组中保存相应的手动输入数字

然后将两个数组保存在单独的txt文件中。

在手动数字分类结束时,训练数据(TRAIN.png)中的所有数字都由我们手工标记,图像如下所示:

使用opencv识别图片中的文字 opencv识别图片中的数字_数组_02

下面是用于上述处理的代码: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)

现在进入训练和测试部分。

在测试部分,我使用了下面的图像,它的字母类型是一样的

使用opencv识别图片中的文字 opencv识别图片中的数字_OpenCV_03

关于训练

(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)

得到结果:

使用opencv识别图片中的文字 opencv识别图片中的数字_python识别图片中数字_04

这里,精度为100%