Odkrivanje robov OpenCV v Pythonu s cv2.Canny() PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Zaznavanje robov OpenCV v Pythonu s cv2.Canny()

Predstavitev

Zaznavanje robov je nekaj, kar počnemo naravno, vendar ni tako enostavno, ko gre za definiranje pravil za računalnike. Medtem ko so bile ustvarjene različne metode, je metodo reigning razvil John F. Canny leta 1986 in je primerno poimenovana metoda Canny.

Je hiter, dokaj robusten in deluje skoraj najbolje, kar bi lahko deloval za to vrsto tehnike. Na koncu vodnika boste vedeli, kako izvesti zaznavanje robov v realnem času na videoposnetkih in ustvariti nekaj v skladu z:

Canny Edge Detection

Kaj je metoda Canny? Sestavljen je iz štirih različnih operacij:

  • Gaussovo glajenje
  • Računalniški gradienti
  • Ne-Max Supresija
  • Histerezni prag

Gaussovo glajenje se uporablja kot prvi korak za "glajenje" vhodne slike in zmehčanje šuma, zaradi česar je končni rezultat veliko čistejši.

Prelivi slike so bili v prejšnjih aplikacijah za zaznavanje robov. Predvsem Sobelova in Scharrova filtra temeljita na prelivih slike. Sobelov filter se skrči na dve jedri (Gx in Gy), kje Gx zazna horizontalne spremembe, medtem ko Gy zazna vertikalne spremembe:

G

x

=

[

-
1

0

+
1

-
2

0

+
2

-
1

0

+
1

]

G

y

=

[

-
1

-
2

-
1

0

0

0

+
1

+
2

+
1

]

Ko z njimi drsite po sliki, bodo vsaka »pobrala« (poudarila) vrstice v svoji usmerjenosti. Jedra Scharr delujejo na enak način, z različnimi vrednostmi:

G

x

=

[

+
3

0

-
3

+
10

0

-
10

+
3

0

-
3

]

G

y

=

[

+
3

+
10

+
3

0

0

0

-
3

-
10

-
3

]

Ti filtri, ko jih zavijete čez sliko, bodo ustvarili zemljevide funkcij:

Odkrivanje robov OpenCV v Pythonu s cv2.Canny() PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Avtor slike: Davidwkennedy

Za te zemljevide funkcij lahko izračunate velikost gradienta in gradientna usmerjenost – tj. kako intenzivna je sprememba (kako verjetno je, da je nekaj rob) in v katero smer kaže sprememba. Ker Gy označuje navpično spremembo (Y-gradient), Gx pa vodoravno spremembo (X-gradient), lahko izračunate velikost tako, da preprosto uporabite Pitagorov izrek, da dobite hipotenuzo trikotnika, ki ga tvorita "levo" in "prave" smeri:

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

Z uporabo velikosti in orientacije lahko ustvarite sliko s poudarjenimi robovi:

Odkrivanje robov OpenCV v Pythonu s cv2.Canny() PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Avtor slike: Davidwkennedy

Vendar – koliko hrupa se je ujelo tudi iz teksture zidakov, lahko vidite! Prelivi slike so zelo občutljivi na šum. Zato sta bila Sobelova in Scharrova filtra uporabljena kot komponenta, vendar ne edini pristop v Cannyjevi metodi. Gaussovo glajenje pomaga tudi tukaj.

Ne-Max Supresija

Opazna težava s Sobelovim filtrom je, da robovi niso res jasni. Ni tako, kot da bi nekdo vzel svinčnik in narisal črto, da bi ustvaril lineart slike. Robovi na slikah običajno niso tako jasni, saj se svetloba postopoma razprši. Vendar pa lahko najdemo skupno črto na robovih in potlačimo preostale slikovne pike okoli nje, tako da namesto tega dobimo čisto, tanko ločilno črto. To je znano kot ne-max supresija! Ne-max slikovne pike (manjše od tiste, s katero jih primerjamo v majhnem lokalnem polju, kot je jedro 3 × 3) so potlačene. Koncept je uporaben za več nalog, vendar ga za zdaj povežimo s tem kontekstom.

Histerezni prag

Številni nerobovi se lahko in bodo verjetno ovrednoteni kot robovi zaradi svetlobnih pogojev, materialov na sliki itd. Zaradi različnih razlogov pride do teh napačnih izračunov – težko je avtomatsko oceniti, kaj rob zagotovo je in kaj ni 't. Prelive lahko omejite in vključite samo močnejše, ob predpostavki, da so »pravi« robovi intenzivnejši od »lažnih«.

Določanje praga deluje na približno enak način kot običajno – če je gradient pod spodnjim pragom, ga odstranite (izničite), če pa je nad danim zgornjim pragom, ga obdržite. Vse, kar je med spodnjo in zgornjo mejo, je v »sivi coni«. Če je kateri koli rob med pragoma povezan z a dokončni rob (tisti nad pragom) – prav tako se štejejo za robove. Če nista povezana, sta verjetno posledica napačno izračunane prednosti.

To je histerezni prag! Pravzaprav pomaga očistiti končni rezultat in odstraniti lažne robove, odvisno od tega, kaj označite kot lažni rob. Če želite najti dobre mejne vrednosti, boste na splošno preizkusili različne spodnje in zgornje meje za pragove ali uporabili avtomatizirano metodo, kot je Otsujeva metoda ali metoda trikotnika.

Naložimo sliko in jo obarvamo v sivine (Canny, tako kot Sobel/Scharr zahtevata, da so slike v sivinah):

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')

Odkrivanje robov OpenCV v Pythonu s cv2.Canny() PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Slika prsta od blizu bo služila kot dober testni poligon za zaznavanje robov – na sliki ni lahko razbrati prstnega odtisa, lahko pa ga približno izračunamo.

Zaznavanje robov na slikah s cv2.Canny()

Cannyjev algoritem je mogoče uporabiti z uporabo OpenCV Canny() metoda:

cv2.Canny(input_img, lower_bound, upper_bound)

Oglejte si naš praktični, praktični vodnik za učenje Gita z najboljšimi praksami, standardi, sprejetimi v panogi, in priloženo goljufijo. Nehajte Googlati ukaze Git in pravzaprav naučiti it!

Iskanje pravega ravnovesja med spodnjo in zgornjo mejo je lahko težavno. Če sta oba nizka – boste imeli malo robov. Če je spodnja meja nizka in zgornja visoka – boste imeli hrup. Če sta oba visoka in blizu drug drugemu – boste imeli malo robov. Pravo mesto ima ravno dovolj vrzeli med mejami in jih ima na pravem merilu. Eksperimentirajte!

Vhodna slika bo zamegljena z metodo Canny, vendar vam bo zameglitev pogosto koristila pred gre tudi notri. Metoda uporabi Gaussovo zameglitev 5 × 5 na vhodu, preden gre skozi preostale operacije, vendar tudi s to zameglitvijo lahko še vedno prodre nekaj šuma, zato smo zameglili sliko, preden smo jo vnesli v algoritem:


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')

Rezultat tega je:

Odkrivanje robov OpenCV v Pythonu s cv2.Canny() PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Vrednosti 20 in 30 tukaj niso samovoljni – metodo sem preizkusil na različnih parametrih in izbral nabor, za katerega se je zdelo, da daje spodoben rezultat. Ali lahko poskusimo to avtomatizirati?

Samodejno določanje praga za cv2.Canny()?

Ali lahko najdete optimalen niz mejnih vrednosti? Da, vendar ne deluje vedno. Lahko naredite svoj izračun za dobro vrednost in nato prilagodite obseg z a sigma okoli tega praga:

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

Kdaj sigma, je recimo, 0.33 – meje bodo 0.66*threshold in 1.33*threshold, kar omogoča ~1/3 razpon okoli njega. Čeprav je iskanje threshold kaj je težje. OpenCV nam ponuja Otsujevo metodo (odlično deluje za bi-modalne slike) in metodo trikotnika. Preizkusimo oboje, kot tretjo možnost pa vzamemo preprosto srednjo vrednost slikovnih pik:

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}")

Rezultat tega je:

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

Te so precej drugačne! Glede na vrednosti, ki smo jih videli prej, lahko predvidevamo, da bo metoda trikotnika tukaj najbolje delovala. Ročni prag ni zelo obveščen, saj vzame samo srednjo vrednost slikovnih pik in ima na koncu visok osnovni prag, ki se za to sliko dodatno pomnoži v širok razpon. Otsujeva metoda zaradi tega manj trpi, a kljub temu trpi.

Če zaženemo Canny() metoda s temi pragovi:

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')

Opomba: Funkcija pričakuje več argumentov, naši pragovi pa so ena sama torka. Mi lahko uničenje tuple v več argumentov tako, da mu dodate predpono z *. To deluje tudi na seznamih in nizih in je odličen način za zagotavljanje več argumentov, potem ko jih pridobite s programskimi sredstvi.

Rezultat tega je:

Odkrivanje robov OpenCV v Pythonu s cv2.Canny() PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Metoda trikotnika je tukaj delovala precej dobro! To ni zagotovilo, da bo dobro delovalo tudi v drugih primerih.

Zaznavanje robov v realnem času na videoposnetkih s cv2.Canny()

Končno uporabimo zaznavanje robov Canny za video v realnem času! Prikazali bomo videoposnetek, ki se obdeluje (vsak okvir, ko je končan), z uporabo cv2.imshow() ki prikaže okno z okvirjem, ki ga želimo prikazati. Vendar bomo videoposnetek shranili tudi v datoteko MP4, ki jo bo mogoče pozneje pregledati in dati v skupno rabo.

Za nalaganje videoposnetka z uporabo OpenCV uporabljamo VideoCapture() metoda. Če vstopimo 0 – snemal bo s trenutno spletno kamero, tako da lahko kodo zaženete tudi na svoji spletni kameri! Če podate ime datoteke, bo naložila datoteko:

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')

O VideoWriter sprejme več parametrov – ime izhodne datoteke, FourCC (štiri kode kodekov, ki označujejo kodek, ki se uporablja za kodiranje videoposnetka), hitrost sličic in ločljivost kot tuple. Da ne bi ugibali ali spreminjali velikosti videoposnetka – uporabili smo širino in višino izvirnega videa, pridobljeno prek VideoCapture primerek, ki vsebuje podatke o samem videu, kot so širina, višina, skupno število sličic itd.

Ko je zajem odprt, skušamo prebrati naslednji okvir cap.read(), ki vrne kodo rezultata in naslednji okvir. Koda rezultata je True or False, ki označuje prisotnost naslednjega okvirja ali njegovo pomanjkanje. Šele ko bo okvir, ga bomo poskušali nadalje obdelati, drugače bomo prekinili zanko. Za vsak veljaven okvir ga poženemo skozi gaussovo zameglitev, pretvorimo v sivine in zaženemo cv2.Canny() nanjo in jo napišite z uporabo VideoWriter na disk in prikaz z uporabo cv2.imshow() za ogled v živo.

Končno izdamo zajem in zapisovalnik videa, saj oba delata z datotekami na disku in uničita vsa obstoječa okna.

Ko zaženete metodo z a secret_video.mp4 vnos – videli boste pojavno okno in ko bo končano, datoteko v vašem delovnem imeniku:

Odkrivanje robov OpenCV v Pythonu s cv2.Canny() PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

zaključek

V tem priročniku smo si ogledali, kako deluje zaznavanje robov Canny, in njegove sestavne dele – gaussovo glajenje, Sobelove filtre in prelive slike, ne-max supresijo in histerezni prag. Končno smo raziskali metode za samodejno iskanje obsega praga za zaznavanje robov Canny cv2.Canny(), in uporabil tehniko na videu, s čimer je zagotovil zaznavanje robov v realnem času in shranil rezultate v video datoteko.

Naprej – Praktično poglobljeno učenje za računalniški vid

Ali zaradi vaše radovedne narave želite iti dlje? Priporočamo, da si ogledate naše Tečaj: »Praktično poglobljeno učenje za računalniški vid s Pythonom«.

Odkrivanje robov OpenCV v Pythonu s cv2.Canny() PlatoBlockchain Data Intelligence. Navpično iskanje. Ai.

Še en tečaj računalniškega vida?

Ne bomo izvajali klasifikacije števk MNIST ali načina MNIST. Svojo so že zdavnaj odslužili. Preveč učnih virov se osredotoča na osnovne nabore podatkov in osnovne arhitekture, preden prepusti naprednim arhitekturam črnih skrinjic breme zmogljivosti.

Želimo se osredotočiti na demistifikacija, praktičnosti, razumevanje, intuicija in pravi projekti. Želim se naučiti kako lahko kaj spremeniš? Popeljali vas bomo od načina, na katerega naši možgani obdelujejo slike, do pisanja raziskovalnega klasifikatorja globokega učenja za raka dojke do omrežij globokega učenja, ki »halucinirajo«, vas naučijo načel in teorije s praktičnim delom ter vas opremijo z znanje in izkušnje ter orodja, da postanete strokovnjak za uporabo globokega učenja za reševanje računalniškega vida.

Kaj je notri?

  • Prva načela vida in kako lahko računalnike naučimo "videti"
  • Različne naloge in aplikacije računalniškega vida
  • Strokovna orodja, ki vam bodo olajšala delo
  • Iskanje, ustvarjanje in uporaba naborov podatkov za računalniški vid
  • Teorija in uporaba konvolucijskih nevronskih mrež
  • Obravnava premikov domene, sopojavljanja in drugih pristranskosti v nizih podatkov
  • Prenos učenja in uporaba časa za usposabljanje in računalniških virov drugih v vašo korist
  • Izdelava in usposabljanje najsodobnejšega klasifikatorja raka dojke
  • Kako uporabiti zdrav odmerek skepticizma za glavne ideje in razumeti posledice splošno sprejetih tehnik
  • Vizualizacija »konceptnega prostora« ConvNet z uporabo t-SNE in PCA
  • Študije primerov o tem, kako podjetja uporabljajo tehnike računalniškega vida za doseganje boljših rezultatov
  • Pravilno vrednotenje modela, vizualizacija latentnega prostora in prepoznavanje pozornosti modela
  • Izvajanje domenskih raziskav, obdelava lastnih naborov podatkov in vzpostavljanje testov modelov
  • Vrhunske arhitekture, razvoj idej, kaj jih dela edinstvene in kako jih uresničiti
  • KerasCV – knjižnica WIP za ustvarjanje najsodobnejših cevovodov in modelov
  • Kako razčleniti in brati prispevke ter jih implementirati sami
  • Izbira modelov glede na vašo aplikacijo
  • Ustvarjanje cevovoda strojnega učenja od konca do konca
  • Pokrajina in intuicija pri zaznavanju predmetov s hitrejšimi R-CNN, RetinaNets, SSD in YOLO
  • Instančna in pomenska segmentacija
  • Prepoznavanje predmetov v realnem času z YOLOv5
  • Usposabljanje detektorjev predmetov YOLOv5
  • Delo s transformatorji z uporabo KerasNLP (industrijska knjižnica WIP)
  • Integracija Transformers s ConvNets za ustvarjanje napisov slik
  • Deepdream
  • Optimizacija modela globokega učenja za računalniški vid

Časovni žig:

Več od Stackabuse