Progowanie OpenCV w Pythonie z cv2.threshold() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Progowanie OpenCV w Pythonie za pomocą cv2.threshold()

Wprowadzenie

Progowanie to prosta i wydajna technika wykonywania podstawowej segmentacji obrazu i jego binaryzacji (przekształcenia go w obraz binarny), gdzie piksele są albo 0 or 1 (lub 255 jeśli używasz liczb całkowitych do ich reprezentowania).

Zazwyczaj możesz użyć progowania, aby wykonać prostą segmentację tła i pierwszego planu na obrazie, a sprowadza się to do wariantów prostej techniki dla każdego piksela:

if pixel_value > threshold:
    pixel_value = MAX
else:
    pixel_value = 0

Ten niezbędny proces jest znany jako Progowanie binarne. Teraz – są różne sposoby na poprawienie tego ogólnego pomysłu, w tym odwracanie operacji (przełączanie > podpisać z < znak), ustawienie pixel_value do threshold zamiast maksymalnej wartości/0 (tzw. obcinanie), zachowując pixel_value się, jeśli jest powyżej threshold lub jeśli jest poniżej threshold.

Wszystko to zostało wygodnie zaimplementowane w OpenCV jako:

  • cv2.THRESH_BINARY
  • cv2.THRESH_BINARY_INV
  • cv2.THRESH_TRUNC
  • cv2.THRESH_TOZERO
  • cv2.THRESH_TOZERO_INV

… odpowiednio. Są to stosunkowo „naiwne” metody, ponieważ są dość proste, nie uwzględniają kontekstu w obrazach, mają wiedzę o tym, jakie kształty są powszechne itp. W przypadku tych właściwości musielibyśmy zastosować znacznie droższe obliczeniowo i potężne techniki.

Teraz, nawet przy „naiwnych” metodach – kilka można zastosować heurystyki w celu znalezienia dobrych progów, a należą do nich metoda Otsu i metoda Trójkątów:

  • cv2.THRESH_OTSU
  • cv2.THRESH_TRIANGLE

Uwaga: Progowanie OpenCV to podstawowa technika, która jest wrażliwa na zmiany oświetlenia i gradienty, niejednorodność kolorów itp. Najlepiej stosować ją na stosunkowo czystych obrazach, po ich rozmyciu w celu zmniejszenia szumów, bez dużej zmienności kolorów w obiektach, które chcesz segmentować.

Innym sposobem przezwyciężenia niektórych problemów z podstawowym progowaniem za pomocą jednej wartości progowej jest użycie progowanie adaptacyjne która stosuje wartość progową do każdego małego regionu obrazu, a nie globalnie.

Proste progowanie z OpenCV

Progowanie w API Pythona OpenCV odbywa się za pomocą cv2.threshold() metoda – która przyjmuje obraz (tablica NumPy, reprezentowana przez liczby całkowite), próg, wartość maksymalną oraz metodę progowania (jak threshold i maximum_value są używane):

img = cv2.imread('objects.jpg')

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)


blurred = cv2.GaussianBlur(img, (7, 7), 0)

ret, img_masked = cv2.threshold(blurred, 220, 255, cv2.THRESH_BINARY)

Kod powrotu to tylko zastosowany próg:

print(f"Threshold: {ret}") 

Tutaj, ponieważ próg jest 220 i użyliśmy THRESH_BINARY metoda – każda wartość piksela powyżej 220 zostanie zwiększona do 255, podczas gdy każda wartość piksela poniżej 220 zostanie obniżony do 0, tworząc obraz czarno-biały, z „maską”, zakrywającą obiekty pierwszego planu.

Dlaczego 220? Wiedząc, jak wygląda obraz, możesz zgadywać w przybliżeniu, jaki próg możesz wybrać. W praktyce rzadko będziesz chciał ustawić próg ręczny, a automatyczny wybór progu zajmiemy się za chwilę.

Wykreślmy wynik! Okna OpenCV mogą być nieco skomplikowane, więc narysujemy oryginalny obraz, rozmazany obraz i wyniki za pomocą Matplotlib:

fig, ax = plt.subplots(1, 3, figsize=(12, 8))
ax[0].imshow(img)
ax[1].imshow(blurred)
ax[2].imshow(img_masked)

Metody progowe

Jak wspomniano wcześniej, istnieje wiele sposobów wykorzystania progu i maksymalnej wartości w funkcji. Na początku przyjrzeliśmy się progowi binarnemu. Stwórzmy listę metod i zastosujmy je jedna po drugiej, wykreślając wyniki:

methods = [cv2.THRESH_BINARY, cv2.THRESH_BINARY_INV, cv2.THRESH_TRUNC, cv2.THRESH_TOZERO, cv2.THRESH_TOZERO_INV]
names = ['Binary Threshold', 'Inverse Binary Threshold', 'Truncated Threshold', 'To-Zero Threshold', 'Inverse To-Zero Threshold']

def thresh(img_path, method, index):
    img = cv2.imread(img_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    blurred = cv2.GaussianBlur(img, (7, 7), 0)
    ret, img_masked = cv2.threshold(blurred, 220, 255, method)

    fig, ax = plt.subplots(1, 3, figsize=(12, 4))
    fig.suptitle(names[index], fontsize=18)
    ax[0].imshow(img)
    ax[1].imshow(blurred)
    ax[2].imshow(img_masked)
    plt.tight_layout()

for index, method in enumerate(methods):
    thresh('coins.jpeg', method, index)

THRESH_BINARY i THRESH_BINARY_INV są odwrotne do siebie i zbinaryzują obraz pomiędzy 0 i 255, przypisując je odpowiednio do tła i pierwszego planu i odwrotnie.

THRESH_TRUNC binaryzuje obraz pomiędzy threshold i 255.

THRESH_TOZERO i THRESH_TOZERO_INV Binaryzować pomiędzy 0 i aktualna wartość piksela (src(x, y)). Rzućmy okiem na powstałe obrazy:

Progowanie OpenCV w Pythonie z cv2.threshold() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

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!

Progowanie OpenCV w Pythonie z cv2.threshold() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.
Progowanie OpenCV w Pythonie z cv2.threshold() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.
Progowanie OpenCV w Pythonie z cv2.threshold() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.
Progowanie OpenCV w Pythonie z cv2.threshold() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Te metody są wystarczająco intuicyjne – ale jak możemy zautomatyzować dobrą wartość progową i co w ogóle oznacza „dobry próg”? Większość dotychczasowych wyników miała nieidealne maski ze znakami i plamkami. Dzieje się tak z powodu różnicy w odbijających powierzchniach monet – nie są one jednolicie zabarwione ze względu na różnicę w odbijaniu światła przez prążki.

Do pewnego stopnia możemy z tym walczyć, znajdując lepszy globalny próg.

Automatyczne/zoptymalizowane progowanie z OpenCV

OpenCV wykorzystuje dwie efektywne metody wyszukiwania progów globalnych – metodę Otsu i metodę Triangle.

Metoda Otsu zakłada, że ​​to działa bimodalny obrazy. Obrazy bimodalne to obrazy, których histogramy kolorów zawierają tylko dwa szczyty (tj. mają tylko dwie różne wartości pikseli). Biorąc pod uwagę, że każdy ze szczytów należy do klasy takiej jak „tło” i „pierwszy plan” – idealny próg znajduje się dokładnie pośrodku nich.

Progowanie OpenCV w Pythonie z cv2.threshold() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.
Kredyt obrazu: https://scipy-lectures.org/

Niektóre obrazy mogą być bardziej bimodalne z rozmyciem gaussowskim, ale nie wszystkie.

Alternatywnym, często lepszym algorytmem jest algorytm trójkąta, który oblicza odległość między maksimum i minimum histogramu poziomu szarości i rysuje linię. Punkt, w którym linia ta znajduje się maksymalnie daleko od reszty histogramu, wybierany jest jako próg:

Progowanie OpenCV w Pythonie z cv2.threshold() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Obydwa zakładają obraz w skali szarości, więc musimy przekonwertować obraz wejściowy na szary za pomocą cv2.cvtColor():

img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)

ret, mask1 = cv2.threshold(blurred, 0, 255, cv2.THRESH_OTSU)
ret, mask2 = cv2.threshold(blurred, 0, 255, cv2.THRESH_TRIANGLE)

masked = cv2.bitwise_and(img, img, mask=mask1)

Przeprowadźmy obraz obiema metodami i zwizualizujmy wyniki:

methods = [cv2.THRESH_OTSU, cv2.THRESH_TRIANGLE]
names = ['Otsu Method', 'Triangle Method']

def thresh(img_path, method, index):
    img = cv2.imread(img_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (7, 7), 0)

    ret, img_masked = cv2.threshold(blurred, 0, 255, method)
    print(f"Threshold: {ret}")

    fig, ax = plt.subplots(1, 3, figsize=(12, 5))
    fig.suptitle(names[index], fontsize=18)
    ax[0].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    ax[1].imshow(cv2.cvtColor(gray, cv2.COLOR_BGR2RGB))
    ax[2].imshow(cv2.cvtColor(img_masked, cv2.COLOR_BGR2RGB))

for index, method in enumerate(methods):
    thresh('coins.jpeg', method, index)

Progowanie OpenCV w Pythonie z cv2.threshold() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.
Progowanie OpenCV w Pythonie z cv2.threshold() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Tutaj metoda trójkąta przewyższa metodę Otsu, ponieważ obraz nie jest bimodalny:

import numpy as np

img = cv2.imread('coins.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)

histogram_gray, bin_edges_gray = np.histogram(gray, bins=256, range=(0, 255))
histogram_blurred, bin_edges_blurred = np.histogram(blurred, bins=256, range=(0, 255))

fig, ax = plt.subplots(1, 2, figsize=(12, 4))

ax[0].plot(bin_edges_gray[0:-1], histogram_gray)
ax[1].plot(bin_edges_blurred[0:-1], histogram_blurred)

Progowanie OpenCV w Pythonie z cv2.threshold() PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Jednak jest jasne, w jaki sposób metoda trójkąta była w stanie pracować z obrazem i uzyskać bardziej satysfakcjonujący wynik.

Ograniczenia progów OpenCV

Progowanie z OpenCV jest proste, łatwe i wydajne. Jednak jest to dość ograniczone. Gdy tylko wprowadzisz kolorowe elementy, niejednolite tło i zmieniające się warunki oświetleniowe – globalne progowanie jako koncepcja staje się zbyt sztywne.

Obrazy są zwykle zbyt złożone, aby wystarczyło pojedynczy próg, co można częściowo rozwiązać poprzez: progowanie adaptacyjne, gdzie stosuje się wiele lokalnych progów zamiast jednego globalnego. Choć również ograniczone, progowanie adaptacyjne jest znacznie bardziej elastyczne niż progowanie globalne.

Wnioski

W ostatnich latach segmentacja binarna (tak jak to zrobiliśmy tutaj) i segmentacja wieloetykietowa (gdzie można zakodować dowolną liczbę klas) z powodzeniem modelowano za pomocą sieci głębokiego uczenia, które są znacznie bardziej wydajne i elastyczne. Ponadto mogą kodować kontekst globalny i lokalny w obrazach, które segmentują. Minusem jest to, że do ich szkolenia potrzebne są dane, a także czas i doświadczenie.

Do prostego wyznaczania progów w locie można użyć OpenCV. Do dokładnej segmentacji na poziomie produkcyjnym warto użyć sieci neuronowych.

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”.

Progowanie OpenCV w Pythonie z cv2.threshold() 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