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:
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
.
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)
Je vous suggère fortement de vous référer aux exemples suivants, qui sont une référence utile pour l'OCR.