Możesz chcieć zdigitalizować dokument, aby zaoszczędzić miejsce fizyczne lub utworzyć kopię zapasową. Tak czy inaczej, napisanie programu, który może konwertować zdjęcia z twoich plików papierowych do formatu standardowego, jest zadaniem, w którym Python się wyróżnia.
Korzystając z kombinacji odpowiednich bibliotek, możesz zbudować małą aplikację do digitalizacji dokumentów. Twój program pobierze obraz fizycznego dokumentu jako dane wejściowe, zastosuje do niego kilka technik przetwarzania obrazu i wyśle zeskanowaną wersję danych wejściowych.
Przygotowanie środowiska
Aby śledzić ten artykuł, powinieneś znać podstawy Pythona. Trzeba mieć też pojęcie o jak pracować z biblioteką NumPy Pythona.
Otwórz dowolne środowisko IDE języka Python i utwórz dwa pliki języka Python. Nazwij jeden main.py, a drugi transform.py. Następnie uruchom następujące polecenie na terminalu, aby zainstalować wymagane biblioteki.
pip install OpenCV-Python imutils scikit-image NumPy
Użyjesz OpenCV-Python, aby pobrać obraz i wykonać pewne przetwarzanie obrazu. Imutils do zmiany rozmiaru obrazów wejściowych i wyjściowych. scikit-image, aby zastosować próg na obrazie. NumPy pomoże Ci pracować z tablicami.
Poczekaj, aż instalacja się zakończy, a IDE zaktualizuje szkielety projektu. Po zakończeniu aktualizacji szkieletów możesz rozpocząć kodowanie. Pełny kod źródłowy jest dostępny w formacie Repozytorium GitHub.
Importowanie zainstalowanych bibliotek
Otwórz plik main.py i zaimportuj biblioteki zainstalowane w środowisku. Umożliwi to dzwonienie i korzystanie z ich funkcji w razie potrzeby.
import cv2
import imutils
z skimage.filters import próg_lokalny
z przekształcać import transformacja_perspektywy
Zignoruj błąd zgłoszony podczas przekształcenia perspektywy. Zniknie po zakończeniu pracy nad plikiem transform.py.
Pobieranie i zmiana rozmiaru danych wejściowych
Zrób wyraźne zdjęcie dokumentu, który chcesz zeskanować. Upewnij się, że cztery rogi dokumentu i jego zawartość są widoczne. Skopiuj obraz do tego samego folderu, w którym przechowujesz pliki programu.
Przekaż ścieżkę obrazu wejściowego do OpenCV. Wykonaj kopię oryginalnego obrazu, ponieważ będzie ona potrzebna podczas transformacji perspektywy. Podziel wysokość oryginalnego obrazu przez wysokość, do której chcesz go zmienić. Pozwoli to zachować proporcje. Na koniec wyślij obraz o zmienionym rozmiarze.
# Przekazywanie ścieżki obrazu
oryginalny_img = cv2.odczytany(„próbka.jpg”)
kopia = oryginał_img. kopia ()# Zmieniona wysokość w setkach
ratio = oryginalny_img.kształt[0] / 500.0
img_resize = imutils.resize (oryginalny_img, wysokość=500)# Wyświetlanie danych wyjściowych
cv2.imshow(„Obraz o zmienionym rozmiarze”, img_resize)
# Oczekiwanie na naciśnięcie dowolnego klawisza przez użytkownika
cv2.waitKey(0)
Dane wyjściowe powyższego kodu są następujące:
Zmieniłeś teraz wysokość oryginalnego obrazu na 500 pikseli.
Konwersja obrazu o zmienionym rozmiarze do skali szarości
Konwertuj obraz RGB o zmienionym rozmiarze na skalę szarości. Większość bibliotek do przetwarzania obrazów działa tylko z obrazami w skali szarości, ponieważ są one łatwiejsze w obróbce.
szary_obraz = cv2.cvtColor (img_resize, cv2.COLOR_BGR2GRAY)
cv2.imshow(„Wyszarzony obraz”, szary_obraz)
cv2.waitKey(0)
Zwróć uwagę na różnicę między oryginalnym obrazem a wyszarzonym.
Kolorowy stół zmienił się w czarno-biały.
Stosowanie detektora krawędzi
Zastosuj filtr rozmycia gaussowskiego na szarym obrazie, aby usunąć szum. Następnie wywołaj funkcję canny OpenCV, aby wykryć krawędzie obecne na obrazie.
rozmyty_obraz = cv2.GaussianBlur (szary_obraz, (5, 5), 0)
edged_img = cv2.Canny (zamazany_obraz, 75, 200)
cv2.imshow(„Krawędzie obrazu”, edged_img)
cv2.waitKey(0)
Krawędzie są widoczne na wydruku.
Krawędzie, z którymi będziesz pracować, są krawędziami dokumentu.
Znalezienie największego konturu
Wykryj kontury obecne na obrazie z krawędziami. Posortuj je w kolejności malejącej, zachowując tylko pięć największych konturów. Przybliż największy kontur z czterema bokami, przeglądając posortowane kontury.
cnts, _ = cv2.findContours (edged_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = posortowane (cnts, key=cv2.contourArea, reverse=PRAWDA)[:5]Do C W cnts:
peri = cv2.arcLength (c, PRAWDA)
w przybliżeniu = cv2.w przybliżeniuPolyDP(c, 0.02 * około, PRAWDA)
Jeśli długość (w przybliżeniu) == 4:
dokument = ok
przerwa
Kontur z czterema bokami prawdopodobnie zawiera dokument.
Okrążanie czterech rogów konturu dokumentu
Zakreśl rogi wykrytego konturu dokumentu. Pomoże to ustalić, czy program był w stanie wykryć dokument na obrazie.
p = []
Do D W dokument:
punkt_krotki = krotka (d[0])
cv2.circle (img_resize, tuple_point, 3, (0, 0, 255), 4)
p.append (tuple_point)
cv2.imshow(„Zakreślone punkty narożne”, img_resize)
cv2.waitKey(0)
Zaimplementuj krążenie na obrazie RGB o zmienionym rozmiarze.
Po wykryciu dokumentu musisz teraz wyodrębnić dokument z obrazu.
Korzystanie z perspektywy wypaczenia w celu uzyskania pożądanego obrazu
Perspektywa wypaczenia to technika widzenia komputerowego służąca do przekształcania obrazu w celu skorygowania zniekształceń. Przekształca obraz w inną płaszczyznę, umożliwiając oglądanie obrazu pod innym kątem.
wypaczony_obraz = przekształcenie_perspektywy (kopia, doc.reshape(4, 2) * współczynnik)
wypaczony_obraz = cv2.cvtColor (wypaczony_obraz, cv2.COLOR_BGR2GRAY)
cv2.imshow(„Wypaczony obraz”, imutils.resize (wypaczony_obraz, wysokość=650))
cv2.waitKey(0)
Aby uzyskać wypaczony obraz, musisz stworzyć prosty moduł który wykona transformację perspektywy.
Moduł transformacji
Moduł uporządkuje punkty narożników dokumentu. Przekształci również obraz dokumentu w inną płaszczyznę i zmieni kąt kamery na ujęcie z góry.
Otwórz utworzony wcześniej plik transform.py. Importuj biblioteki OpenCV i NumPy.
import liczba Jak np
import cv2
Ten moduł będzie zawierał dwie funkcje. Utwórz funkcję, która uporządkuje współrzędne punktów narożnych dokumentu. Pierwsza współrzędna będzie współrzędną górnego lewego rogu, druga będzie współrzędną górnego prawego rogu, trzecia będzie w prawym dolnym rogu, a czwarta współrzędna będzie w lewym dolnym rogu narożnik.
pokpunkty_zamówienia(punkty):
# inicjalizacja listy współrzędnych do zamówienia
prostokąt = np.zera((4, 2), dtyp = „pływak32”)s = pkt.suma (oś = 1)
# lewy górny punkt będzie miał najmniejszą sumę
sprostować0] = pts[np.argmin (s)]# prawy dolny punkt będzie miał największą sumę
sprostować2] = pts[np.argmax (s)]obliczanie różnicy między punktami, tj
prawy górny punkt będzie miał najmniejszą różnicę,
podczas gdy dolny lewy będzie miał największą różnicę
diff = np.diff (pts, oś = 1)
sprostować1] = pts[np.argmin(różnica)]
sprostować3] = pts[np.argmax (różnica)]
# zwraca uporządkowane współrzędne
powrót prost
Utwórz drugą funkcję, która obliczy współrzędne narożników nowego obrazu i uzyska ujęcie z góry. Następnie obliczy macierz transformacji perspektywy i zwróci wypaczony obraz.
poktransformacja_perspektywy(zdjęcie, pkt):
# rozpakuj zamówione współrzędne pojedynczo
rect = order_points (pts)
(tl, tr, br, bl) = prostokątobliczyć szerokość nowego obrazu, który będzie
maksymalna odległość między dolnym prawym I na dole po lewej
współrzędne x Lub prawy górny róg I współrzędne x w lewym górnym rogu
szerokośćA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
szerokośćB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
maxWidth = max (int (szerokość A), int (szerokość B))obliczyć wysokość nowego obrazu, który będzie
maksymalna odległość między górnym lewym I współrzędne Y w lewym dolnym rogu
wysokośćA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
wysokośćB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHeight = max (int (wysokość A), int (wysokość B))skonstruuj zestaw punktów docelowych, aby uzyskać ujęcie z góry
dst = np.tablica([
[0, 0],
[maks.Szerokość- 1, 0],
[maks.Szerokość- 1, maksymalna wysokość - 1],
[0, maksymalna wysokość - 1]], dtyp = „pływak32”)# obliczyć macierz transformacji perspektywy
transform_matrix = cv2.getPerspectiveTransform (prostokąt, czas letni)# Zastosuj macierz transformacji
warped = cv2.warpPerspective (obraz, macierz_transformacji, (maks. szerokość, maks. wysokość))
# zwróć wypaczony obraz
powrót wichrowaty
Utworzyłeś teraz moduł transformacji. Błąd w imporcie przekształcenia_perspektywy teraz zniknie.
Zwróć uwagę, że wyświetlany obraz ma ujęcie z góry.
Stosowanie progu adaptacyjnego i zapisywanie zeskanowanych danych wyjściowych
W pliku main.py zastosuj próg Gaussa do wypaczonego obrazu. Dzięki temu wypaczony obraz będzie wyglądał jak zeskanowany. Zapisz zeskanowany obraz wyjściowy w folderze zawierającym pliki programu.
T = próg_lokalny (wypaczony_obraz, 11, przesunięcie=10, metoda=„gaussowski”)
wypaczony = (wypaczony_obraz > T).astype("uint8") * 255
cv2.imwrite('./'+'skanowanie'+'.png',wichrowaty)
Zapisanie skanu w formacie PNG pozwala zachować jakość dokumentu.
Wyświetlanie danych wyjściowych
Wydrukuj obraz zeskanowanego dokumentu:
cv2.imshow(„Ostateczny zeskanowany obraz”, imutils.resize (zniekształcony, wysokość=650))
cv2.waitKey(0)
cv2.destroyAllWindows()
Poniższy obraz przedstawia dane wyjściowe programu, ujęcie z góry zeskanowanego dokumentu.
Jak postępować w dziedzinie widzenia komputerowego
Tworzenie skanera dokumentów obejmuje niektóre podstawowe obszary wizji komputerowej, która jest szeroką i złożoną dziedziną. Aby rozwijać się w dziedzinie widzenia komputerowego, należy pracować nad ciekawymi, ale wymagającymi projektami.
Powinieneś także przeczytać więcej o tym, jak możesz wykorzystać widzenie komputerowe przy użyciu obecnych technologii. Dzięki temu będziesz na bieżąco informowany i podsunie Ci nowe pomysły na projekty, nad którymi możesz pracować.