首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数字识别,使用opencv

数字识别,使用opencv
EN

Stack Overflow用户
提问于 2018-08-29 17:25:52
回答 2查看 4.3K关注 0票数 3

我有4张小照片。

有数字6,16,9和9。我将图片和数字与我的模板进行比较,只有30种变体0-30。照片-截图是。数字出现在不同的正方形位置(例子中,左角9位,右角9位)。

我使用两种方法:用白色计算像素的质量。

代码语言:javascript
复制
original = cv2.imread('im/16.png')
sought = [254,254,254]
result = np.count_nonzero(np.all(original==sought,axis=2)) 

这种方式总是工作,除了6和9。白色像素的质量在这种情况下是相等的。

第二种方法:获取图像上所有像素的位置,并与其他图像进行数据比较:

代码语言:javascript
复制
# tit - title of image
# same list for equal images
difference = cv2.subtract(original,image_to_compare)
b,g,r = cv2.split(difference)
cv2.countNonZero(b) == 0:
    same.append(tit)
if len(same) > 1:
    res = same
    print(res)

这个方法帮助我区分6和9,但是!在两幅有9张不同角落的图片中,它也能识别出不同之处。

我要我的代码识别每一个数字,而不是看到一个数字之间的差异,在右边或左边的图像。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-04 11:11:06

您可以找到许多关于OCR的论文和软件,因为它在许多应用程序中得到了广泛的应用。我想为您的问题提供非常简单的解决方案,使用numpy和opencv,这样就可以完成任务。

我们要做的是:

  1. 进口numpy和opencv
  2. 加载您提供的映像
  3. 抓住他们
  4. 函数,它将返回给定图像中的数字数组。
  5. 比较图1和图2中的数字
  6. 让我们的“数字银行”,让我们知道数字9的样子
  7. 将我们在图3中找到的数字与我们的“数字库”进行比较。

代码:

代码语言:javascript
复制
import cv2
import numpy as np

treshold = 70

#Treshold every image, so "0" in image means no digit and "1" is digit 
image1 = (cv2.imread("number_1.png",0) > treshold).astype(np.uint8)
image2 = (cv2.imread("number_2.png",0) > treshold).astype(np.uint8)
image3 = (cv2.imread("number_3.png",0) > treshold).astype(np.uint8)
image4 = (cv2.imread("number_4.png",0) > treshold).astype(np.uint8)

函数,它将返回给定图像中的数字数组:

代码语言:javascript
复制
def get_images_of_digits(image):
    components = cv2.connectedComponentsWithStats(image, 8, cv2.CV_16U) #Separate digits
    #Get position of every components
    #For details how this works take a look at 
    #https://stackoverflow.com/questions/35854197/how-to-use-opencvs-connected-components-with-stats-in-python
    position_of_digits = components[2] 
    number_of_digits = len(position_of_digits) - 1 #number of digits found in image
    digits = [] #Array with every digit in image
    for i in range(number_of_digits):    
        w = position_of_digits[i+1,0] #Left corner of digit
        h = position_of_digits[i+1,1] #Top corner of digit
        digit = image[h:h+height_of_digit,w:w+width_of_digit] #Cut this digit out of image

        #Count how many white pixels there are
        px_count = np.count_nonzero(digit)
        #Divide every pixel by square root of count of pixels in digit. 
        #Why? If we make convolution with the same digit it will give us sweet "1", which means these digits are identical
        digit = digit / np.sqrt(px_count)  
    digits.append(digit)

return digits #Return all digits

获取位数

代码语言:javascript
复制
d_1 = get_images_of_digits(image1)[0] #Digit "9" from first image
d_2 = get_images_of_digits(image2)[0] #Digit "9" from second image
d_3 = get_images_of_digits(image4)[0] #Digit "6" from last image

print(cv2.filter2D(d_1,-1,d_2).max()) #Digit "9" on image 1 and 2 match perfectly (result of convolution is 1).
#Filter2D does convolution (correlation to be precise, but they are the same for our purpose)

将第一个图像中的"9“号和最后一个图像中的"6”号放入数字库。然后将我们在图3中找到的每一个数字与我们的数字库进行比较。如果分数低于0.9,则不匹配。

代码语言:javascript
复制
bank_of_digits = {"9":d_1, "6":d_3} 
for digit in get_images_of_digits(image3):
    #print(digit)
    best_restult = 0.9 #If score is above 0.9, we say it is match
    #Maybe tweak this higher for separating chars "8" and "9" and "0"
    matching_digit = "?" #Default char, when there is no match
    for number in bank_of_digits:
        score = cv2.filter2D(digit,-1,bank_of_digits[number]).max() #Returns 0-1 . 1 Means perfect match       
        print("Score for number " + number +" is: "+ str(np.round(score,2)) )
        if score > best_restult: #If we find better match
            best_restult = score #Set highest score yet
            matching_digit = number #Set best match number
    print("Best match: " + matching_digit)

最后的结果将是"?“对于图3中的第一个数字,因为在我们的银行中没有数字"1“,第二个结果是"6”,分数为0.97。

TLDR:我制定了将数字和图像分开的算法,并对这些数字进行了比较。最好的匹配是打印出来的。

票数 3
EN

Stack Overflow用户

发布于 2018-08-29 18:06:09

opencv中,您可以在69上训练一个分类器,比如基于Haar特征的级联对象检测分类器( objdetect.htmltraincascade.html )。

示例代码在即https://coding-robin.de/2013/07/22/train-your-own-opencv-haar-classifier.html

我不知道这是否是一项任务,如果您是固定到opencv,如果没有,您可以使用神经网络,参考章节隧道视觉的https://medium.com/@ageitgey/machine-learning-is-fun-part-3-deep-learning-and-convolutional-neural-networks-f40359318721https://towardsdatascience.com/convnets-series-spatial-transformer-networks-cff47565ae81,但空间变压器网络是有点过于复杂的这个问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52083129

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档