web-dev-qa-db-fra.com

Comment détecter les numéros d'indice dans une image à l'aide de l'OCR?

J'utilise tesseract pour l'OCR, via les liaisons pytesseract. Malheureusement, je rencontre des difficultés en essayant d'extraire du texte comprenant des nombres de style indice - le numéro d'indice est plutôt interprété comme une lettre.

Par exemple, dans l'image de base:

enter image description here

Je souhaite extraire le texte en tant que "CH3", c'est-à-dire que je ne suis pas inquiet de savoir que le nombre 3 était un indice dans l'image.

Ma tentative en utilisant tesseract est:

import cv2
import pytesseract

img = cv2.imread('test.jpeg')

# Note that I have reduced the region of interest to the known 
# text portion of the image
text = pytesseract.image_to_string(
    img[200:300, 200:320], config='-l eng --oem 1 --psm 13'
)
print(text)

Malheureusement, cela affichera incorrectement

'CHs'

Il est également possible d'obtenir 'CHa', en fonction du paramètre psm.

Je soupçonne que ce problème est lié au fait que la "ligne de base" du texte est incohérente sur toute la ligne, mais je ne suis pas certain.

Comment extraire avec précision le texte de ce type d'image?

Mise à jour - 19 mai 2020

Après avoir vu la réponse d'Achintha Ihalage, qui ne fournit aucune option de configuration à tesseract, j'ai exploré les options psm.

Étant donné que la région d'intérêt est connue (dans ce cas, j'utilise la détection EAST pour localiser la zone de délimitation du texte), l'option psm config pour tesseract, qui dans mon code d'origine traite le texte en une seule ligne, peut ne pas être nécessaire. Fonctionnement image_to_string par rapport à la région d'intérêt donnée par la boîte englobante ci-dessus donne la sortie

CH

3

qui peut, bien sûr, être facilement traité pour obtenir CH3.

9
dspencer

Je pense que cette manière peut être plus adaptée à la situation générale.

import cv2
import pytesseract
from pathlib import Path

image = cv2.imread('test.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]  # (suitable for sharper black and white pictures
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]  # is OpenCV2.4 or OpenCV3
result_list = []
for c in contours:
    x, y, w, h = cv2.boundingRect(c)
    area = cv2.contourArea(c)
    if area > 200:
        detect_area = image[y:y + h, x:x + w]
        # detect_area = cv2.GaussianBlur(detect_area, (3, 3), 0)
        predict_char = pytesseract.image_to_string(detect_area, lang='eng', config='--oem 0 --psm 10')
        result_list.append((x, predict_char))
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), thickness=2)

result = ''.join([char for _, char in sorted(result_list, key=lambda _x: _x[0])])
print(result)  # CH3


output_dir = Path('./temp')
output_dir.mkdir(parents=True, exist_ok=True)
cv2.imwrite(f"{output_dir/Path('image.png')}", image)
cv2.imwrite(f"{output_dir/Path('clean.png')}", thresh)

PLUS DE RÉFÉRENCE

Je vous suggère fortement de vous référer aux exemples suivants, qui sont une référence utile pour l'OCR.

  1. Obtenez l'emplacement de tout le texte présent dans l'image en utilisant opencv
  2. tilisation de YOLO ou d'autres techniques de reconnaissance d'image pour identifier tout le texte alphanumérique présent dans les images

enter image description here

1
Carson