OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

OpenCV Thresholding i Python med cv2.threshold()

Introduktion

Thresholding er en enkel og effektiv teknik til at udføre grundlæggende segmentering i et billede og at binarisere det (gøre det til et binært billede), hvor pixels er enten 0 or 1 (eller 255 hvis du bruger heltal til at repræsentere dem).

Typisk kan du bruge tærskelværdi til at udføre simpel baggrund-forgrundssegmentering i et billede, og det koger ned til varianter af en simpel teknik for hver pixel:

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

Denne væsentlige proces er kendt som Binær tærskelværdi. Nu – der er forskellige måder, du kan finjustere denne generelle idé, herunder at invertere operationerne (ved at skifte > underskrive med a < tegn), indstiller pixel_value til threshold i stedet for en maksimal værdi/0 (kendt som trunkering), bibehold pixel_value sig selv, hvis det er over threshold eller hvis det er under threshold.

Alle disse er bekvemt blevet implementeret i OpenCV som:

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

… henholdsvis. Det er relativt "naive" metoder, fordi de er ret simple, ikke tager højde for kontekst i billeder, har viden om, hvilke former der er almindelige osv. For disse egenskaber – ville vi skulle bruge meget mere beregningsmæssigt dyrere og stærkere teknikker.

Nu, selv med de "naive" metoder - nogle heuristik kan sættes på plads for at finde gode tærskler, og disse inkluderer Otsu-metoden og Trekantmetoden:

  • cv2.THRESH_OTSU
  • cv2.THRESH_TRIANGLE

Bemærk: OpenCV-tærskelværdi er en rudimentær teknik og er følsom over for lysændringer og gradienter, farveheterogenitet osv. Det er bedst at anvende på relativt rene billeder, efter at have sløret dem for at reducere støj, uden stor farvevariation i de objekter, du vil segmentere.

En anden måde at overvinde nogle af problemerne med grundlæggende tærskelværdi med en enkelt tærskelværdi er at bruge adaptiv tærskelværdi som anvender en tærskelværdi på hver lille region i et billede i stedet for globalt.

Simpel tærskelværdi med OpenCV

Tærskelværdi i OpenCV's Python API sker via cv2.threshold() metode – som accepterer et billede (NumPy-array, repræsenteret med heltal), tærskelværdien, maksimumværdien og tærskelmetoden (hvordan threshold , maximum_value er brugt):

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)

Returkoden er kun den anvendte tærskel:

print(f"Threshold: {ret}") 

Her, da tærsklen er 220 og vi har brugt THRESH_BINARY metode – hver pixelværdi ovenfor 220 vil blive øget til 255, mens hver pixelværdi nedenfor 220 vil blive sænket til 0, hvilket skaber et sort-hvidt billede med en "maske", der dækker objekterne i forgrunden.

Hvorfor 220? Ved at vide, hvordan billedet ser ud, kan du foretage nogle omtrentlige gæt om, hvilken tærskel du kan vælge. I praksis vil du sjældent ønsker at indstille en manuel tærskel, og vi dækker automatisk tærskelvalg på et øjeblik.

Lad os plotte resultatet! OpenCV-vinduer kan være lidt kræsne, så vi plotter det originale billede, det slørede billede og resultaterne ved hjælp af Matplotlib:

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

Tærskelmetoder

Som tidligere nævnt er der forskellige måder, du kan bruge tærskelværdien og maksimumværdien i en funktion. Vi har taget et kig på den binære tærskel indledningsvis. Lad os oprette en liste over metoder og anvende dem én efter én, og plotte resultaterne:

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 , THRESH_BINARY_INV er omvendt af hinanden og binariserer et billede imellem 0 , 255, ved at tildele dem til henholdsvis baggrunden og forgrunden og omvendt.

THRESH_TRUNC binariserer billedet imellem threshold , 255.

THRESH_TOZERO , THRESH_TOZERO_INV binarisere mellem 0 og den aktuelle pixelværdi (src(x, y)). Lad os tage et kig på de resulterende billeder:

OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Tjek vores praktiske, praktiske guide til at lære Git, med bedste praksis, brancheaccepterede standarder og inkluderet snydeark. Stop med at google Git-kommandoer og faktisk lærer det!

OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Disse metoder er intuitive nok - men hvordan kan vi automatisere en god tærskelværdi, og hvad betyder en "god tærskelværdi" overhovedet? De fleste af resultaterne indtil videre havde ikke-ideelle masker med mærker og pletter i dem. Dette sker på grund af forskellen i de reflekterende overflader på mønterne - de er ikke ensfarvede på grund af forskellen i, hvordan kamme reflekterer lys.

Vi kan til en vis grad bekæmpe dette ved at finde en bedre global tærskel.

Automatisk/optimeret tærskelværdi med OpenCV

OpenCV anvender to effektive globale tærskelsøgningsmetoder – Otsus metode og Triangle-metoden.

Otsus metode antager, at den arbejder på bi-modal billeder. Bi-modale billeder er billeder, hvis farvehistogrammer kun indeholder to toppe (dvs. kun har to forskellige pixelværdier). I betragtning af at toppene hver især tilhører en klasse som en "baggrund" og "forgrund" - er den ideelle tærskel lige i midten af ​​dem.

OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
Image credit: https://scipy-lectures.org/

Du kan gøre nogle billeder mere bi-modale med gaussisk sløring, men ikke alle.

En alternativ, ofte bedre ydende algoritme, er trekantalgoritmen, som beregner afstanden mellem maksimum og minimum af grå-niveau histogrammet og tegner en linje. Det punkt, hvor den linje er maksimalt langt væk fra resten af ​​histogrammet, vælges som tærsklen:

OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Begge disse forudsætter et gråtonet billede, så vi bliver nødt til at konvertere inputbilledet til gråt via 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)

Lad os køre billedet igennem med begge metoder og visualisere resultaterne:

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)

OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Lodret søgning. Ai.
OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Her overgår trekantmetoden Otsus metode, fordi billedet ikke er bi-modalt:

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)

OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Det er dog tydeligt, hvordan trekantmetoden var i stand til at arbejde med billedet og producere et mere tilfredsstillende resultat.

Begrænsninger af OpenCV Thresholding

Thresholding med OpenCV er enkel, nem og effektiv. Alligevel er det ret begrænset. Så snart du introducerer farverige elementer, uensartede baggrunde og skiftende lysforhold – bliver global tærskelværdi som koncept for stift.

Billeder er normalt for komplekse til, at en enkelt tærskel er nok, og dette kan delvist løses igennem adaptiv tærskelværdi, hvor der anvendes mange lokale tærskler i stedet for en enkelt global. Selvom adaptiv tærskelværdi også er begrænset, er den meget mere fleksibel end global tærskelværdi.

Konklusion

I de senere år er binær segmentering (som hvad vi gjorde her) og multi-label segmentering (hvor du kan få kodet et vilkårligt antal klasser) med succes blevet modelleret med deep learning netværk, som er meget mere kraftfulde og fleksible. Derudover kan de indkode global og lokal kontekst i de billeder, de segmenterer. Ulempen er – du har brug for data til at træne dem, samt tid og ekspertise.

Til simpel tærskeling undervejs kan du bruge OpenCV. For nøjagtig segmentering på produktionsniveau skal du bruge neurale netværk.

Gå videre – Praktisk dyb læring til computersyn

Din nysgerrige natur giver dig lyst til at gå længere? Vi anbefaler at tjekke vores Kursus: "Praktisk dyb læring til computersyn med Python".

OpenCV Thresholding i Python med cv2.threshold() PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Endnu et kursus i computersyn?

Vi laver ikke klassificering af MNIST-cifre eller MNIST-mode. De tjente deres del for længe siden. For mange læringsressourcer fokuserer på grundlæggende datasæt og grundlæggende arkitekturer, før de lader avancerede black-box-arkitekturer bære byrden af ​​ydeevne.

Vi ønsker at fokusere på afmystificering, praktisk, forståelse, intuition , rigtige projekter. Vil gerne lære hvordan kan du gøre en forskel? Vi tager dig med på en tur fra den måde, vores hjerner behandler billeder på, til at skrive en deep learning-klassificerer for brystkræft i forskningsklasse til deep learning-netværk, der "hallucinerer", lærer dig principperne og teorien gennem praktisk arbejde, og udstyrer dig med knowhow og værktøjer til at blive ekspert i at anvende dyb læring til at løse computervision.

Hvad er der indenfor?

  • De første principper for vision og hvordan computere kan læres at "se"
  • Forskellige opgaver og anvendelser af computersyn
  • Branchens værktøjer, der vil gøre dit arbejde lettere
  • Finde, skabe og bruge datasæt til computervision
  • Teorien og anvendelsen af ​​​​konvolutionelle neurale netværk
  • Håndtering af domæneskift, samtidige forekomster og andre skævheder i datasæt
  • Overfør Læring og udnyttelse af andres træningstid og beregningsressourcer til din fordel
  • Opbygning og træning af en avanceret brystkræftklassificering
  • Hvordan man anvender en sund dosis skepsis til mainstream ideer og forstår implikationerne af vidt anvendte teknikker
  • Visualisering af et ConvNets "konceptrum" ved hjælp af t-SNE og PCA
  • Casestudier af, hvordan virksomheder bruger computervisionsteknikker til at opnå bedre resultater
  • Korrekt modelevaluering, latent rumvisualisering og identifikation af modellens opmærksomhed
  • Udførelse af domæneforskning, bearbejdning af dine egne datasæt og etablering af modeltest
  • Banebrydende arkitekturer, udviklingen af ​​ideer, hvad der gør dem unikke, og hvordan man implementerer dem
  • KerasCV – et WIP-bibliotek til at skabe state of the art pipelines og modeller
  • Hvordan man analyserer og læser papirer og implementerer dem selv
  • Valg af modeller afhængigt af din applikation
  • Oprettelse af en end-to-end machine learning pipeline
  • Landskab og intuition på objektdetektion med hurtigere R-CNN'er, RetinaNets, SSD'er og YOLO
  • Forekomst og semantisk segmentering
  • Objektgenkendelse i realtid med YOLOv5
  • Træning af YOLOv5 objektdetektorer
  • Arbejde med transformere ved hjælp af KerasNLP (industristærkt WIP-bibliotek)
  • Integrering af transformere med ConvNets for at generere billedtekster
  • Deepdream
  • Deep Learning model optimering til computer vision

Tidsstempel:

Mere fra Stablemisbrug