Rozpoznawanie ekranu #3: OpenCV

Wyzwaniem jest automatyzacja testów UI (Interfejsu użytkownika). Biblioteka pytesseract może być pomocna w ich wykonaniu do czytania tekstów.

Rozpoznawanie ekran

Rozpoznawanie ekranu


Bazując na poprzedniej odsłonie serii Rozpoznawanie ekranu, pojawiły się problemy niedokładnego odczytania tekstu przez Tesseract, jednakże nie bardzo mu to ułatwialiśmy. Prowadząc testy i zakładając, że odczyt obrazu ekranu nie będzie radykalnie różnił się za każdym kolejnym wykonywaniem testów (stabilne stanowisko testowe), raz przyjęte obrabianie tekstu powinno być powtarzalne.

Instalacja

OpenCV w odróżnieniu od Tesseract’a wymaga jedynie instalacji Python’owej biblioteki, gdyż cała obsługa OpenCV jest instalowana wraz z nią. Instalacje przeprowadzamy za pomocą aplikacji pip:

pip install opencv-python

Obrabianie tekstu

Imitacją zdjęcia ekranu będzie kubek z poprzedniej części serii. Tym razem będzie obrabiany z poziomu Python’a:

Jak już wiemy z poprzedniej części, wielkość ma znaczenie – należy ją dostosować do możliwości Tesseracta. Zacznijmy jednak od zaimportowana biblioteki za pomocą import cv2 i następnie możemy wczytać plik za pomocą komendy imread znajdującej się w tej bibliotece i płynnie przejść do sprawdzenia wielkości rysunku przy pomocy metody shape wywoływanej z właśnie utworzonego obiektu obrazka. W poniższym kodzie prezentuję opisane wcześniej kroki:

import pytesseract
import cv2
 
img_cv = cv2.imread('./read_photo_part_2.jpg')
print(f"image size: {img_cv.shape}")

Wynikiem wykonania tego kodu będzie kolejno wysokość obrazka, jego długość oraz sumę składników używanych do reprezentacji każdego z plikseli, czyli w naszym przypadku plik jest RGB, każdy piksel jest miksem trzech kolorów:

image size: (2953, 2451, 3)

Obraz okazał się ogromy. Do zmniejszenia możemy użyć komendy resize, podając obowiązkowe argumenty: jaki obiekt rysunku ma zostać pomniejszony i do jakiej wielkości. Parametr wielkości podajemy w formie krotki, wpisując kolejno wartość wysokości i szerokości obrazu docelowego:

import pytesseract
import cv2
 
img_cv = cv2.imread('./read_photo_part_2.jpg')
img_cv = cv2.resize(img_cv, (700, 800))
 
print(f"image size: {img_cv.shape}")

Następnym krokiem w obróbce zdjęcia będzie obrócenie napisu horyzontalnie. Bez tego kroku Tesseract nie odczyta tekstu poprawnie. Można to wykonać za pomocą metody rotate. Jako jej argumenty podajemy, jaki obiekt obrazu ma zostać obrócony. W moim przypadku pracuję ciągle na obiekcie przypisanym do zmiennej img_cv. A także sposób obracania obrazu. W bibliotece cv2 możemy znaleźć stałe przygotowane do tego typu czynności. Ja obrócę obrazek o 90 stopni w zgodnie z ruchem wskazówek cv2.cv2.ROTATE_90_CLOCKWISE:

import pytesseract
import cv2
 
img_cv = cv2.imread('./read_photo_part_2.jpg')
img_cv = cv2.resize(img_cv, (700, 800))
img_cv = cv2.rotate(img_cv, cv2.cv2.ROTATE_90_CLOCKWISE)
 
print(f"image size: {img_cv.shape}")

Można się zastanawiać, skąd wiem, że operacje, które wykonuję, są na pewno poprawne. Aby upewnić się, że wszystko idzie zgodnie z planem, wyświetl aktualnie obrobiony obraz, za pomocą imshow. Podaj za argumenty dowolną nazwę okna w jakim wyświetli się plik (w przykładzie użyłem nazwy image) i obiekt obrazu który stworzyliśmy wcześniej. Niestety może to powodować błąd wykonywanego skryptu. Aby temu zapobiec, zaraz po niej wykonaj metodę cv2.waitKey(0) i cv2.destroyAllWindows():

import pytesseract
import cv2
 
img_cv = cv2.imread('./read_photo_part_2.jpg')
img_cv = cv2.resize(img_cv, (700, 800))
img_cv = cv2.rotate(img_cv, cv2.cv2.ROTATE_90_CLOCKWISE)
 
print(f"image size: {img_cv.shape}")
 
cv2.imshow('image', img_cv)
cv2.waitKey(0)
cv2.destroyAllWindows()

Czas na kolejny krok, który bardzo ułatwia odczyt tekstu z obrazu aplikacji Tesseract. Obraz w tylko w skali szarości. Do wyszarzenia używam metody cvtColor, podając obiekt obrazu i sposób obróbki koloru. Do przerobienia obrazu na szary służy stała cv2.cv2.COLOR_BGR2GRAY. Ostatecznym krokiem jest sprawdzenie, czy tekst zostanie poprawnie odczytany przy pomocy pytesseract’a:

import pytesseract
import cv2
 
img_cv = cv2.imread('./read_photo_part_2.jpg')
img_cv = cv2.resize(img_cv, (700, 800))
img_cv = cv2.rotate(img_cv, cv2.cv2.ROTATE_90_CLOCKWISE)
 
img_cv = cv2.cvtColor(img_cv, cv2.COLOR_BGR2GRAY)
print(f"Text: {pytesseract.image_to_string(img_cv)}")

Wynik print’a mogę uznać za sukces:

Text: Qabrio.pl

Pisząc ten artykuł, natknąłem się znaczący problem, którym jest instalacja OpenCV, na mikrokomputerach Raspberry Pi. Nie wystarcza tam prosta komenda pip install opencv-python. Jako że nie tylko ja mogłem mieć takie problemy, w kolejnym artykule opiszę, w jaki sposób można je rozwiązać. Poprawnie przeprowadzić instalację tak przydatnej biblioteki.

close

Newsletter