Czytelnicy tacy jak ty pomagają wspierać MUO. Kiedy dokonujesz zakupu za pomocą linków na naszej stronie, możemy otrzymać prowizję partnerską. Czytaj więcej.

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.

instagram viewer
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ąt

obliczyć 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ć.