3 grudnia 2024
W dzisiejszych czasach zdjęcia składają się z dziesiątek milionów pikseli, zawierających niezliczoną ilość danych. Może to nas skłonić do zastanowienia się- w jaki sposób uzyskać dostęp do tych informacji? W tym wpisie zaprezentuję krok po kroku, jak odczytać dane tekstowe ze zdjęcia, wykorzystam w tym celu biblioteki wymienione w tytule artykułu: OpenCV oraz Tesseract OCR.
Na sam początek przygotujmy środowisko programistyczne, musimy zainstalować:
pip install matplotlib
pip install pytesseract
pip install opencv-python
pip install matplotlib
sudo apt-get install -y tesseract-ocr
Użytkownicy innych systemów operacyjnych mogą wykorzystać opis znajdujący się na githubie tesseract.
Najważniejszym zadaniem jest oddzielenie napisu od tła. Jeśli odpowiednio przefiltrujemy dany obrazek lub zdjęcie, w taki sposób, że tło zostanie zamienione na białe piksele to tesseract nie będzie mieć problemu z odczytaniem tekstu. Zacznijmy od wczytania zdjęcia i wykonaniu na nim kilku operacji.
import cv2
import matplotlib as plt
img = cv2.imread('example.jpg') # wczytanie obrazka
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # konwersja na czarno białe
thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)[1] # wszystkie wartości powyżej 127 zamieniane na 255(biały)
plt.imshow(out, 'gray')
plt.show() # wyświetlanie obrazka
Przykładowe zdjęcie napisu z chusteczek do czyszczenia okularów, które znalazłem na szafce, przed i po zastosowaniu powyższych operacji.
Teraz wystarczy podać nasz wynikowy obraz do przetworzenia przez tesseract.
from pytesseract import image_to_string
output = image_to_string(thresh, lang='eng', config='--psm 7')
print('Output: ', output)
Wyjście w tym przypadku to: "Output: GLASSES WIPES", zatem wszystko się zgadza. Co do wartości config='-- psm 7', są one różne w zależności od tego co dokładnie chcemy osiągnąć, a prezentują się w następujący sposób:
Page segmentation modes:
0 Orientation and script detection (OSD) only.
1 Automatic page segmentation with OSD.
2 Automatic page segmentation, but no OSD, or OCR.
3 Fully automatic page segmentation, but no OSD. (Default)
4 Assume a single column of text of variable sizes.
5 Assume a single uniform block of vertically aligned text.
6 Assume a single uniform block of text.
7 Treat the image as a single text line.
8 Treat the image as a single word.
9 Treat the image as a single word in a circle.
10 Treat the image as a single character.
11 Sparse text. Find as much text as possible in no particular order.
12 Sparse text with OSD.
13 Raw line. Treat the image as a single text line,
bypassing hacks that are Tesseract-specific.
Spróbujmy z tekstem znajdujących się w wielu liniach(config='-- psm 6')
i tym razem wynik okazał się być prawidłowy:
Output: Ala ma kota,
kot ma Ale,
ale Ala,
nie ma psa.
Jak widać odczytanie tekstu ze zdjęć lub obrazów nie jest trudne. Oczywiście można robić więcej z zdjęciem, np rozszerzać wartości pikseli na cały zakres skali([0:255]), czy usuwać elementy, które według nas są zanieczyszczeniami tła, lub nawet wypełniać nasz obszar, gdy pojawiają się jakieś braki. Warto zaznaczyć, że nasz "domowy OCR" potrafi poradzić sobie nawet z pismem odręcznym, oczywiście jeśli jest ono choć trochę czytelne.
Zdjęcie tytułowe: pexels.com