Python распознавания цифр OpenCV

#python #opencv #ocr

Вопрос:

Я пытаюсь создать простой проект, который получает числа из изображения. У меня нет проблем с поиском контуров чисел, но когда дело доходит до фактического распознавания чисел, возникает много проблем. Есть ли что-то неправильное в том, как он пытается распознать числа, или есть другой способ получить более точные числа?

 import cv
import numpy as np
import imutils
from imutils import contours

DIGITS_LOOKUP = {
    (1, 1, 1, 0, 1, 1, 1): 0,
    (0, 0, 1, 0, 0, 1, 0): 1,
    (1, 0, 1, 1, 1, 1, 0): 2,
    (1, 0, 1, 1, 0, 1, 1): 3,
    (0, 1, 1, 1, 0, 1, 0): 4,
    (1, 1, 0, 1, 0, 1, 1): 5,
    (1, 1, 0, 1, 1, 1, 1): 6,
    (1, 0, 1, 0, 0, 1, 0): 7,
    (1, 1, 1, 1, 1, 1, 1): 8,
    (1, 1, 1, 1, 0, 1, 1): 9,
}


image = cv2.imread('image.jpg')
image = imutils.resize(image, height=500)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY, 255, -80)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 5))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)


kernel = np.ones((5,5),np.uint8)
dilation = cv2.dilate(thresh,kernel,iterations = int(7))
erosion = cv2.erode(dilation,kernel,iterations = int(2.5))

cnts = cv2.findContours(erosion.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
digitCnts = []
image_w_bbox = image.copy()
for c in cnts:
    (x, y, w, h) = cv2.boundingRect(c)
    if w >= 10 and (h >= 130 and h <= 500):
        digitCnts.append(c)
        image_w_bbox = cv2.rectangle(image_w_bbox,(x, y),(x w, y h),(0, 255, 0),2)
print(len(digitCnts))

digitCnts = contours.sort_contours(digitCnts,   method="left-to-right")[0]

digits = []

for c in digitCnts:
    (x, y, w, h) = cv2.boundingRect(c)
    roi = erosion[y:y   h, x:x   w]
    (roiH, roiW) = roi.shape
    (dW, dH) = (int(roiW * 0.25), int(roiH * 0.15))
    dHC = int(roiH * 0.05)

    segments = [
        ((0, 0), (w, dH)),  # top
        ((0, 0), (dW, h // 2)), # top-left
        ((w - dW, 0), (w, h // 2)), # top-right
        ((0, (h // 2) - dHC) , (w, (h // 2)   dHC)), # center
        ((0, h // 2), (dW, h)), # bottom-left
        ((w - dW, h // 2), (w, h)), # bottom-right
        ((0, h - dH), (w, h))   # bottom
    ]
    on = [0] * len(segments)

    for (i, ((xA, yA), (xB, yB))) in enumerate(segments):
        segROI = roi[yA:yB, xA:xB]
        total = cv2.countNonZero(segROI)
        area = (xB - xA) * (yB - yA)
        if total / float(area) > 0.5:
            on[i]= 1
    try:
        digit = DIGITS_LOOKUP[tuple(on)]
        digits.append(digit)
    except KeyError:
        print("number not recognized")

print("Here are the digits from left to right...")
print(digits)

cv2.imshow('frame', image_w_bbox)
cv2.waitKey(0)
cv2.destroyAllWindows()
 

»’

Комментарии:

1. Я не вижу в этом коде ничего похожего на распознавание текста. Обычно люди используют что-то вроде питессеракта или глубокого обучения.