Wykrywanie krawędzi OpenCV w Pythonie z cv2.Canny() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Wykrywanie krawędzi OpenCV w Pythonie za pomocą cv2.Canny()

Wprowadzenie

Wykrywanie krawędzi to coś, co robimy naturalnie, ale nie jest tak łatwe, jeśli chodzi o definiowanie reguł dla komputerów. Chociaż opracowano różne metody, metoda panowania została opracowana przez Johna F. Canny'ego w 1986 roku i jest trafnie nazwana metodą Canny'ego.

Jest szybki, dość solidny i działa prawie najlepiej, jak może działać dla rodzaju techniki, którą jest. Pod koniec przewodnika dowiesz się, jak wykonywać wykrywanie krawędzi w czasie rzeczywistym w filmach i tworzyć coś w stylu:

Pomyślne wykrywanie krawędzi

Czym jest metoda Canny'ego? Składa się z czterech różnych operacji:

  • Wygładzanie Gaussa
  • Obliczanie gradientów
  • Tłumienie niemaksymalne
  • Próg histerezy

Wygładzanie Gaussa jest używany jako pierwszy krok do „wyprasowania” obrazu wejściowego i zmiękczenia szumu, dzięki czemu końcowy wynik jest znacznie czystszy.

Gradienty obrazu były używane we wcześniejszych aplikacjach do wykrywania krawędzi. Przede wszystkim filtry Sobela i Scharra opierają się na gradientach obrazu. Filtr Sobela sprowadza się do dwóch ziaren (Gx i Gy), gdzie Gx wykrywa zmiany poziome, podczas gdy Gy wykrywa zmiany w pionie:

G

x

=

[

-
1

0

+
1

-
2

0

+
2

-
1

0

+
1

]

G

y

=

[

-
1

-
2

-
1

0

0

0

+
1

+
2

+
1

]

Kiedy przesuniesz je po obrazie, każdy z nich „podniesie” (podkreśli) linie w swojej odpowiedniej orientacji. Jądra Scharr działają w ten sam sposób, z różnymi wartościami:

G

x

=

[

+
3

0

-
3

+
10

0

-
10

+
3

0

-
3

]

G

y

=

[

+
3

+
10

+
3

0

0

0

-
3

-
10

-
3

]

Filtry te, po nałożeniu na obraz, utworzą mapy obiektów:

Wykrywanie krawędzi OpenCV w Pythonie z cv2.Canny() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Źródło obrazu: Davidwkennedy

W przypadku tych map obiektów można obliczyć wielkość gradientu i orientacja gradientu – tj. jak intensywna jest zmiana (jak prawdopodobne jest, że coś jest krawędzią) i w jakim kierunku zmierza zmiana. Ponieważ Gy oznacza zmianę pionową (gradient Y), a Gx oznacza zmianę poziomą (gradient X) – możesz obliczyć wielkość, po prostu stosując twierdzenie Pitagorasa, aby uzyskać hipotenzę trójkąta utworzonego przez „lewy” i „właściwe” kierunki:

$$
{G} ={kwadrat {{{G} _{x}}^{2}+{{G} _{y}}^{2}}}
$$

Używając wielkości i orientacji, możesz stworzyć obraz z podświetlonymi krawędziami:

Wykrywanie krawędzi OpenCV w Pythonie z cv2.Canny() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Źródło obrazu: Davidwkennedy

Aczkolwiek – widać, ile hałasu wyłapała również struktura cegieł! Gradienty obrazu są bardzo wrażliwe na szum. Właśnie dlatego filtry Sobela i Scharra zostały użyte jako komponent, ale nie jedyne podejście w metodzie Canny'ego. Tutaj również pomaga wygładzanie Gaussa.

Tłumienie niemaksymalne

Zauważalny problem z filtrem Sobela polega na tym, że krawędzie nie są tak naprawdę wyraźne. To nie tak, że ktoś wziął ołówek i narysował linię, żeby stworzyć linearność obrazu. Krawędzie obrazów zwykle nie są tak wyraźne, ponieważ światło stopniowo się rozprasza. Możemy jednak znaleźć wspólną linię na krawędziach i stłumić pozostałe piksele wokół niej, dając zamiast tego czystą, cienką linię oddzielającą. Jest to znane jako tłumienie niemaksymalne! Niemaksymalne piksele (mniejsze niż ten, z którym je porównujemy w małym polu lokalnym, takim jak jądro 3×3) są tłumione. Koncepcja ma zastosowanie do większej liczby zadań niż to, ale na razie powiążmy ją z tym kontekstem.

Próg histerezy

Wiele nie-krawędzi może i prawdopodobnie zostanie ocenionych jako krawędzie, ze względu na warunki oświetleniowe, materiały na obrazie itp. Z różnych powodów występują te błędne obliczenia – trudno jest dokonać automatycznej oceny tego, czym na pewno jest i czym jest krawędź. 't. Możesz progowe gradienty i uwzględniać tylko te silniejsze, zakładając, że „prawdziwe” krawędzie są bardziej intensywne niż „fałszywe” krawędzie.

Próg działa w podobny sposób jak zwykle – jeśli gradient jest poniżej dolnego progu, usuń go (wyzeruj), a jeśli jest powyżej danego górnego progu, zachowaj go. Wszystko pomiędzy dolną i górną granicą znajduje się w „szarej strefie”. Jeśli jakakolwiek krawędź pomiędzy progami jest połączona z a ostateczna krawędź (powyżej progu) – są też uważane za krawędzie. Jeśli nie są połączone, prawdopodobnie są wyrobami źle obliczonej krawędzi.

To jest progowanie histerezy! W efekcie pomaga oczyścić ostateczny wynik i usunąć fałszywe krawędzie, w zależności od tego, co zaklasyfikujesz jako fałszywe krawędzie. Aby znaleźć dobre wartości progowe, zazwyczaj będziesz eksperymentować z różnymi dolnymi i górnymi granicami progów lub zastosujesz zautomatyzowaną metodę, taką jak metoda Otsu lub metoda Triangle.

Załadujmy obraz w skali szarości (Canny, tak jak Sobel/Scharr wymaga, aby obrazy były w skali szarości):

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('finger.jpg', cv2.IMREAD_GRAYSCALE)
img_blur = cv2.GaussianBlur(img, (3,3), 0)

plt.imshow(img_blur, cmap='gray')

Wykrywanie krawędzi OpenCV w Pythonie z cv2.Canny() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Zbliżenie palca będzie dobrym poligonem do testowania krawędzi – nie jest łatwo odróżnić odcisk palca od obrazu, ale możemy go przybliżyć.

Wykrywanie krawędzi na obrazach za pomocą cv2.Canny()

Algorytm Canny'ego można zastosować za pomocą OpenCV Canny() metoda:

cv2.Canny(input_img, lower_bound, upper_bound)

Zapoznaj się z naszym praktycznym, praktycznym przewodnikiem dotyczącym nauki Git, zawierającym najlepsze praktyki, standardy przyjęte w branży i dołączoną ściągawkę. Zatrzymaj polecenia Google Git, a właściwie uczyć się to!

Znalezienie właściwej równowagi między dolną i górną granicą może być trudne. Jeśli oba są niskie – będziesz miał niewiele krawędzi. Jeśli dolna granica jest niska, a górna jest wysoka – będziesz miał hałas. Jeśli oba są wysoko i blisko siebie – będziesz miał niewiele krawędzi. Właściwe miejsce ma wystarczająco dużo odstępu między granicami i ma je we właściwej skali. Eksperyment!

Obraz wejściowy zostanie rozmazany metodą Canny, ale często przyniesie to korzyść zanim to również wchodzi. Metoda stosuje rozmycie gaussowskie 5×5 do danych wejściowych przed przejściem przez resztę operacji, ale nawet przy tym rozmyciu część szumu może nadal przenikać, więc zamazaliśmy obraz przed wprowadzeniem go do algorytmu:


edge = cv2.Canny(img_blur, 20, 30)

fig, ax = plt.subplots(1, 2, figsize=(18, 6), dpi=150)
ax[0].imshow(img, cmap='gray')
ax[1].imshow(edge, cmap='gray')

To skutkuje:

Wykrywanie krawędzi OpenCV w Pythonie z cv2.Canny() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Wartości 20 i 30 tutaj nie są arbitralne – przetestowałem metodę na różnych parametrach i wybrałem zestaw, który wydawał się dawać przyzwoity wynik. Czy możemy spróbować to zautomatyzować?

Automatyczne progowanie dla cv2.Canny()?

Czy potrafisz znaleźć optymalny zestaw wartości progowych? Tak, ale to nie zawsze działa. Możesz wykonać własne obliczenia dla jakiejś dobrej wartości, a następnie dostosować zakres za pomocą sigma wokół tego progu:

lower_bound = (1-sigma)*threshold
upper_bound = (1+sigma)*threshold

Kiedy sigma, powiedzmy, 0.33 – granice będą 0.66*threshold i 1.33*threshold, pozwalając na około 1/3 zasięgu wokół niego. Chociaż znalezienie threshold jest trudniejsze. OpenCV udostępnia nam metodę Otsu (świetnie sprawdza się w przypadku obrazów bimodalnych) oraz metodę Triangle. Wypróbujmy oba z nich, a jako trzecią opcję przyjmijmy prostą medianę wartości pikseli:

otsu_thresh, _ = cv2.threshold(img_blur, 0, 255, cv2.THRESH_OTSU)
triangle_thresh, _ = cv2.threshold(img_blur, 0, 255, cv2.THRESH_TRIANGLE)
manual_thresh = np.median(img_blur)

def get_range(threshold, sigma=0.33):
    return (1-sigma) * threshold, (1+sigma) * threshold

otsu_thresh = get_range(otsu_thresh)
triangle_thresh = get_range(triangle_thresh)
manual_thresh = get_range(manual_thresh)

print(f"Otsu's Threshold: {otsu_thresh} nTriangle Threshold: {triangle_thresh} nManual Threshold: {manual_thresh}")

To skutkuje:

Otsu's Threshold: (70.35, 139.65) 
Triangle Threshold: (17.419999999999998, 34.58) 
Manual Threshold: (105.18999999999998, 208.81)

Są zupełnie inne! Z wartości, które widzieliśmy wcześniej, możemy przewidzieć, że metoda Trójkąta będzie działać najlepiej tutaj. Próg ręczny nie jest zbyt dobrze poinformowany, ponieważ pobiera tylko medianę wartości piksela i kończy się na wysokim progu bazowym, który jest dalej mnożony do szerokiego zakresu dla tego obrazu. Metoda Otsu cierpi z tego powodu mniej, ale mimo to cierpi.

Jeśli uruchomimy Canny() metoda z tymi zakresami progowymi:

edge_otsu = cv2.Canny(img_blur, *otsu_thresh)
edge_triangle = cv2.Canny(img_blur, *triangle_thresh)
edge_manual = cv2.Canny(img_blur, *manual_thresh)

fig, ax = plt.subplots(1, 3, figsize=(18, 6), dpi=150)
ax[0].imshow(edge_otsu, cmap='gray')
ax[1].imshow(edge_triangle, cmap='gray')
ax[2].imshow(edge_manual, cmap='gray')

Uwaga: Funkcja oczekuje wielu argumentów, a nasze progi to pojedyncza krotka. Możemy destruktura krotka na wiele argumentów, poprzedzając ją *. Działa to również na listach i zestawach i jest świetnym sposobem na dostarczenie wielu argumentów po ich uzyskaniu za pomocą środków programowych.

To skutkuje:

Wykrywanie krawędzi OpenCV w Pythonie z cv2.Canny() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Metoda Trójkąta działała tutaj całkiem dobrze! Nie gwarantuje to, że będzie dobrze działać również w innych przypadkach.

Wykrywanie krawędzi w czasie rzeczywistym w filmach za pomocą cv2.Canny()

Na koniec zastosujmy wykrywanie krawędzi Canny do wideo w czasie rzeczywistym! Wyświetlimy przetwarzane wideo (każdą klatkę po zakończeniu) za pomocą cv2.imshow() który wyświetla okno z ramką, którą chcielibyśmy wyświetlić. Jednak zapiszemy również wideo w pliku MP4, który można później sprawdzić i udostępnić.

Aby załadować wideo za pomocą OpenCV, używamy VideoCapture() metoda. Jeśli przejdziemy dalej 0 – będzie nagrywać z bieżącej kamery internetowej, więc możesz uruchomić kod również na swojej kamerze internetowej! Jeśli podasz nazwę pliku, plik zostanie załadowany:

def edge_detection_video(filename):
    cap = cv2.VideoCapture(filename)
    
    fourcc = cv2.VideoWriter_fourcc(*'MP4V')
    out = cv2.VideoWriter('output.mp4', fourcc, 30.0, (int(cap.get(3)), int(cap.get(4))), isColor=False)
    
    while cap.isOpened():
        (ret, frame) = cap.read()
        if ret == True:
            frame = cv2.GaussianBlur(frame, (3, 3), 0)
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            edge = cv2.Canny(frame, 50, 100)
            out.write(edge)
            cv2.imshow('Edge detection', edge)
        else:
            break

        if cv2.waitKey(10) & 0xFF == ord('q'):
            break

    cap.release()
    out.release()
    cv2.destroyAllWindows()

edge_detection_video('secret_video.mp4')

Połączenia VideoWriter akceptuje kilka parametrów – nazwę pliku wyjściowego, FourCC (cztery kody kodeków, oznaczające kodek używany do kodowania wideo), liczbę klatek na sekundę i rozdzielczość jako krotkę. Aby nie zgadywać ani nie zmieniać rozmiaru wideo — użyliśmy szerokości i wysokości oryginalnego wideo, uzyskanej za pomocą VideoCapture instancja zawierająca dane o samym filmie, takie jak szerokość, wysokość, całkowita liczba klatek itp.

Podczas otwierania przechwytywania próbujemy odczytać następną klatkę za pomocą cap.read(), który zwraca kod wyniku i następną ramkę. Kod wyniku to True or False, oznaczający obecność następnej ramki lub jej brak. Dopiero gdy pojawi się ramka, spróbujemy ją dalej przetworzyć, w przeciwnym razie przerwiemy pętlę. Dla każdej prawidłowej klatki analizujemy ją przez rozmycie gaussowskie, konwertujemy do skali szarości, uruchamiamy cv2.Canny() na nim i napisz go, używając VideoWriter na dysk i wyświetlaj za pomocą cv2.imshow() do podglądu na żywo.

Wreszcie, zwalniamy przechwytywanie i zapis wideo, ponieważ oba pracują z plikami na dysku i niszczą wszystkie istniejące okna.

Po uruchomieniu metody z secret_video.mp4 input – zobaczysz wyskakujące okienko, a po jego zakończeniu plik w twoim katalogu roboczym:

Wykrywanie krawędzi OpenCV w Pythonie z cv2.Canny() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Wnioski

W tym przewodniku przyjrzeliśmy się, jak działa wykrywanie krawędzi Canny i jego części składowe – wygładzanie gaussowskie, filtry Sobela i gradienty obrazu, tłumienie niemaksymalne i próg histerezy. Na koniec zbadaliśmy metody automatycznego wyszukiwania zakresu progów dla wykrywania krawędzi Canny za pomocą cv2.Canny(), i zastosował tę technikę na wideo, zapewniając wykrywanie krawędzi w czasie rzeczywistym i zapisując wyniki w pliku wideo.

Idąc dalej – praktyczne uczenie głębokie dla wizji komputerowej

Twoja dociekliwość sprawia, że ​​chcesz iść dalej? Zalecamy sprawdzenie naszego Kurs: „Praktyczne uczenie głębokie dla widzenia komputerowego z Pythonem”.

Wykrywanie krawędzi OpenCV w Pythonie z cv2.Canny() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Kolejny kurs na temat wizji komputerowej?

Nie będziemy robić klasyfikacji cyfr MNIST ani mody MNIST. Swoją rolę pełnili dawno temu. Zbyt wiele zasobów edukacyjnych koncentruje się na podstawowych zestawach danych i podstawowych architekturach, zanim zaawansowane architektury czarnoskrzynkowe poniosą ciężar wydajności.

Chcemy się skupić demistyfikacja, praktyczność, zrozumienie, intuicja i realne projekty. Chcieć się nauczyć w jaki sposób możesz zrobić różnicę? Zabierzemy Cię na przejażdżkę od sposobu, w jaki nasze mózgi przetwarzają obrazy, przez pisanie klasyfikatora głębokiego uczenia się na poziomie badań naukowych w zakresie raka piersi, do sieci głębokiego uczenia się, które „halucynują”, ucząc Cię zasad i teorii poprzez praktyczną pracę, wyposażając Cię w know-how i narzędzia, aby stać się ekspertem w stosowaniu uczenia głębokiego do rozwiązywania wizji komputerowych.

Co jest w środku?

  • Pierwsze zasady widzenia i jak nauczyć komputery „widzieć”
  • Różne zadania i zastosowania wizji komputerowej
  • Narzędzia handlu, które ułatwią Ci pracę
  • Znajdowanie, tworzenie i wykorzystywanie zbiorów danych do wizji komputerowej
  • Teoria i zastosowanie splotowych sieci neuronowych
  • Obsługa zmiany domeny, współwystępowania i innych błędów w zbiorach danych
  • Transfer uczenia się i wykorzystanie czasu szkolenia innych i zasobów obliczeniowych dla Twojej korzyści
  • Budowanie i szkolenie najnowocześniejszego klasyfikatora raka piersi
  • Jak zastosować zdrową dawkę sceptycyzmu do głównych idei i zrozumieć konsekwencje powszechnie stosowanych technik?
  • Wizualizacja „przestrzeni koncepcyjnej” ConvNet za pomocą t-SNE i PCA
  • Studia przypadków, w jaki sposób firmy wykorzystują techniki widzenia komputerowego do osiągania lepszych wyników
  • Właściwa ocena modelu, wizualizacja przestrzeni utajonej i identyfikacja uwagi modelu
  • Wykonywanie badań domenowych, przetwarzanie własnych zbiorów danych i tworzenie testów modelowych
  • Najnowocześniejsze architektury, progresja pomysłów, co czyni je wyjątkowymi i jak je wdrażać
  • KerasCV – biblioteka WIP do tworzenia najnowocześniejszych rurociągów i modeli
  • Jak analizować i czytać artykuły i samodzielnie je wdrażać
  • Wybór modeli w zależności od aplikacji
  • Tworzenie kompleksowego procesu uczenia maszynowego
  • Krajobraz i intuicja w wykrywaniu obiektów za pomocą szybszych sieci R-CNN, sieci RetinaNet, dysków SSD i YOLO
  • Segmentacja instancyjna i semantyczna
  • Rozpoznawanie obiektów w czasie rzeczywistym za pomocą YOLOv5
  • Szkolenie wykrywaczy obiektów YOLOv5
  • Praca z transformatorami przy użyciu KerasNLP (biblioteka przemysłowa WIP)
  • Integracja Transformers z ConvNets w celu generowania podpisów obrazów
  • DeepDream
  • Optymalizacja modelu Deep Learning dla wizji komputerowej

Znak czasu:

Więcej z Nadużycie stosu