OpenCV Python 2 数字识别(K近邻)

我使用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%

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值