Bevezetés
Az élérzékelést természetesen csináljuk, de ez nem olyan egyszerű, ha a számítógépekre vonatkozó szabályokat kell meghatározni. Míg különféle módszereket dolgoztak ki, az uralkodási módszert John F. Canny fejlesztette ki 1986-ban, és találóan Canny-módszernek nevezik.
Gyors, meglehetősen robusztus, és a legjobban működik, ami az adott típusú technikához képes. Az útmutató végére tudni fogja, hogyan kell valós idejű élérzékelést végrehajtani a videókon, és hogyan készítsen valamit a következők szerint:
Canny Edge Detection
Mi az a Canny módszer? Négy különálló műveletből áll:
- Gauss simítás
- Gradiensek számítása
- Nem maximális elnyomás
- Hiszterézis küszöbérték
Gauss simítás A bemeneti kép „kivasalására” és a zaj tompítására szolgáló első lépésként használják, így a végső kimenet sokkal tisztább.
Képátmenetek korábban élészlelési alkalmazásokban használták. A Sobel és Scharr szűrők leginkább a képátmenetekre támaszkodnak. A Sobel szűrő két magra forr (Gx és a Gy), hol Gx vízszintes változásokat észlel, míg Gy függőleges változásokat észlel:
G
x
=
[
-
1
0
+
1
-
2
0
+
2
-
1
0
+
1
]
G
y
=
[
-
1
-
2
-
1
0
0
0
+
1
+
2
+
1
]
Ha egy kép fölé csúsztatja őket, mindegyik „felveszi” (kiemeli) a vonalakat a megfelelő tájolásukban. A Scharr kernelek ugyanúgy működnek, eltérő értékekkel:
G
x
=
[
+
3
0
-
3
+
10
0
-
10
+
3
0
-
3
]
G
y
=
[
+
3
+
10
+
3
0
0
0
-
3
-
10
-
3
]
Ezek a szűrők, amint a képre vannak kapcsolva, jellemzőtérképeket készítenek:
A kép jóváírása: Davidwkennedy
Ezekhez a jellemzőtérképekhez kiszámolhatja a gradiens nagysága és a gradiens orientáció – azaz mennyire intenzív a változás (mennyire valószínű, hogy valami él), és milyen irányba mutat a változás. Mivel Gy a függőleges változást (Y-gradiens), Gx pedig a vízszintes változást (X-gradiens) jelöli, a Pitagorasz-tétel segítségével egyszerűen kiszámíthatja a nagyságot, hogy megkapja a „bal” és a „bal” által alkotott háromszög hipotenuzáját. „helyes” útmutatás:
$$
{G} ={sqrt {{{G} _{x}}^{2}+{{G} _{y}}^{2}}}
$$
A nagyság és a tájolás használatával olyan képet készíthet, amelynek élei kiemelve:
A kép jóváírása: Davidwkennedy
Azonban – láthatja, mekkora zajt is fogott a téglák szerkezete! A képátmenetek nagyon érzékenyek a zajra. Ez az oka annak, hogy Sobel és Scharr szűrőket használtak komponensként, de nem az egyetlen megközelítés Canny módszerében. A Gauss-simítás itt is segít.
Nem maximális elnyomás
A Sobel szűrővel kapcsolatos észrevehető probléma az, hogy a szélek nem igazán tiszták. Nem olyan, mintha valaki vett egy ceruzát, és vonalat húzott a kép lineáris ábrázolásához. A szélek általában nem olyan egyértelműek a képeken, mivel a fény fokozatosan diffundál. Megtalálhatjuk azonban a közös vonalat az éleken, és elnyomhatjuk körülötte a többi képpontot, így tiszta, vékony elválasztóvonalat kapunk. Ez az úgynevezett Non-Max Elnyomás! A nem maximális pixelek (azok, amelyek kisebbek, mint amivel összehasonlítjuk őket egy kis helyi mezőben, például egy 3 × 3-as kernelben) elnyomódnak. A koncepció ennél több feladatra is alkalmazható, de most kössük ehhez a kontextushoz.
Hiszterézis küszöbérték
A fényviszonyok, a képen lévő anyagok stb. miatt sok nem élt lehet és valószínűleg élként értékelnek ki. A különböző okok miatt ezek a hibás számítások előfordulnak – nehéz automatizáltan értékelni, hogy mi az él, és mi az 't. A színátmeneteket küszöbölheti, és csak az erősebbeket tartalmazza, feltételezve, hogy a „valódi” élek intenzívebbek, mint a „hamis” élek.
A küszöbérték nagyjából ugyanúgy működik, mint általában – ha a gradiens egy alsó küszöb alatt van, távolítsa el (nullázza ki), és ha egy adott felső küszöb felett van, tartsa meg. Minden, ami az alsó és a felső határ között van, a „szürke zónában” van. Ha a küszöbök közötti bármely él kapcsolódik a végleges él (a küszöb felettiek) – ezek is élnek számítanak. Ha nincsenek összekapcsolva, akkor valószínűleg egy rosszul kiszámított él arficatai.
Ez a hiszterézis küszöbértéke! Valójában segít megtisztítani a végső kimenetet és eltávolítani a hamis éleket attól függően, hogy mit minősít hamis élnek. A jó küszöbértékek megtalálásához általában kísérletezni kell a küszöbértékek alsó és felső határaival, vagy olyan automatizált módszert kell alkalmazni, mint az Otsu-módszer vagy a Háromszög-módszer.
Töltsünk be egy képet, és szürkeárnyalatosítsuk (Canny, ahogy a Sobel/Scharr is megköveteli, hogy a képeket szürkeárnyalatos legyen):
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')
Az ujj közeli képe jó tesztelési terepe lesz az élérzékeléshez – az ujjlenyomatot nem könnyű megkülönböztetni a képről, de megközelítőleg tudjuk.
Élérzékelés képeken a cv2.Canny() segítségével
A Canny algoritmusa OpenCV-vel is alkalmazható Canny()
eljárás:
cv2.Canny(input_img, lower_bound, upper_bound)
Tekintse meg gyakorlatias, gyakorlati útmutatónkat a Git tanulásához, amely tartalmazza a bevált gyakorlatokat, az iparág által elfogadott szabványokat és a mellékelt csalólapot. Hagyd abba a guglizást a Git parancsokkal, és valójában tanulni meg!
Az alsó és a felső határ közötti megfelelő egyensúly megtalálása bonyolult lehet. Ha mindkettő alacsony – kevés éle lesz. Ha az alsó határ alacsony, a felső pedig magas, akkor zaj lesz. Ha mindkettő magasan és közel van egymáshoz – kevés éled lesz. A megfelelő helyen épp elég rés van a határok között, és a megfelelő skálán vannak. Kísérlet!
A bemeneti kép elmosódik a Canny-módszerrel, de gyakran előnyös lehet az elmosódás előtt az is bemegy. A módszer 5×5-ös Gauss-elmosódást alkalmaz a bemeneten, mielőtt végigcsinálná a többi műveletet, de még ezzel az elmosódással is átszivároghat némi zaj, ezért elmostuk a képet, mielőtt betápláljuk az algoritmusba:
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')
Ennek eredményeként:
Az értékek 20
és a 30
itt nem önkényesek – teszteltem a módszert különböző paramétereken, és olyan készletet választottam, amely tisztességes eredményt hozott. Megpróbálhatjuk ezt automatizálni?
Automatizált küszöbérték a cv2.Canny() számára?
Meg tudod találni a küszöbértékek optimális halmazát? Igen, de ez nem mindig működik. Készíthet saját számítást valamilyen jó értékre, majd állítsa be a tartományt a gombbal sigma
e küszöb körül:
lower_bound = (1-sigma)*threshold
upper_bound = (1+sigma)*threshold
Amikor sigma
, mondjuk, 0.33
– a határok meg lesznek 0.66*threshold
és a 1.33*threshold
, ami körülbelül 1/3 tartományt tesz lehetővé körülötte. Azonban megtalálni a threshold
az a nehezebb. Az OpenCV biztosítja számunkra az Otsu-módszert (nagyon működik a bimodális képekhez) és a Triangle módszert. Próbáljuk ki mindkettőt, és vegyük harmadik lehetőségként a pixelértékek egyszerű mediánját:
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}")
Ennek eredményeként:
Otsu's Threshold: (70.35, 139.65)
Triangle Threshold: (17.419999999999998, 34.58)
Manual Threshold: (105.18999999999998, 208.81)
Ezek eléggé különbözőek! A korábban látott értékek alapján a háromszög módszer itt működik a legjobban. A kézi küszöbérték nem túl tájékozott, mivel csak a középső pixelértéket veszi fel, és végül magas alapküszöbértéket kap, amelyet tovább szoroznak a kép széles tartományába. Otsu módszere kevésbé szenved ettől, de mégis szenved.
Ha futtatjuk a Canny()
módszer ezekkel a küszöbtartományokkal:
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')
Jegyzet: A függvény több argumentumot vár, a küszöbértékeink pedig egyetlen sor. Tudunk destrukció a leírót több argumentummá a következővel előtagozva *
. Ez működik listákon és halmazokon is, és nagyszerű módja annak, hogy több argumentumot adjon meg, miután azokat programozott módon megszerezte.
Ennek eredményeként:
A háromszög módszer itt elég jól bevált! Ez nem garancia arra, hogy más esetekben is jól fog működni.
Valós idejű élészlelés videókon a cv2.Canny() segítségével
Végül alkalmazzuk a Canny élérzékelést egy videóra valós időben! Megjelenítjük a feldolgozás alatt álló videót (minden képkockát, ahogy elkészült) segítségével cv2.imshow()
amely egy ablakot jelenít meg a megjeleníteni kívánt kerettel. A videót azonban MP4 fájlba is mentjük, amely később megtekinthető és megosztható.
A videó OpenCV használatával történő betöltéséhez a VideoCapture()
módszer. Ha bemegyünk 0
– az aktuális webkameráról rögzít, így a kódot a webkamerán is futtathatja! Ha átad egy fájlnevet, akkor betölti a fájlt:
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')
A VideoWriter
Számos paramétert fogad el – a kimeneti fájlnevet, a FourCC-t (négy kodekkód, amelyek a videó kódolásához használt kodeket jelölik), a képkocka sebességet és a felbontást sorként. A videó kitalálása vagy átméretezése elkerülése érdekében az eredeti videó szélességét és magasságát használtuk, amelyet a VideoCapture
példány, amely magáról a videóról tartalmaz adatokat, mint például a szélesség, magasság, a képkockák teljes száma stb.
Amíg a rögzítés meg van nyitva, megpróbáljuk beolvasni a következő képkockát cap.read()
, amely egy eredménykódot és a következő keretet adja vissza. Az eredmény kódja True
or False
, amely a következő képkocka jelenlétét vagy annak hiányát jelzi. Csak ha van keret, akkor megpróbáljuk tovább feldolgozni, különben megszakítjuk a hurkot. Minden érvényes képkockánál átfuttatjuk egy Gauss-elmosódáson, átváltjuk szürkeárnyalatossá, futtatjuk cv2.Canny()
rá, és írja be a segítségével VideoWriter
a lemezre, és a segítségével jelenítse meg cv2.imshow()
élő nézethez.
Végül felszabadítjuk a rögzítést és a videóírót, mivel mindkettő a lemezen lévő fájlokkal dolgozik, és megsemmisíti az összes meglévő ablakot.
Amikor a módszert a secret_video.mp4
bevitel – megjelenik egy felugró ablak, és amint kész, egy fájl a munkakönyvtárban:
Következtetés
Ebben az útmutatóban megnéztük, hogyan működik a Canny élérzékelés, és annak alkotóelemei – Gauss-simítás, Sobel-szűrők és képátmenetek, nem-maximális elnyomás és hiszterézis küszöbérték. Végül megvizsgáltuk a Canny élészlelés automatizált küszöbtartomány-keresési módszereit cv2.Canny()
, és a technikát videón alkalmazta, valós idejű élérzékelést biztosítva, és az eredményeket videofájlba mentve.
Továbblépve – Gyakorlati mélytanulás a számítógépes látáshoz
Érdeklődő természete arra készteti, hogy tovább menjen? Javasoljuk, hogy tekintse meg nálunk Tanfolyam: „Practical Deep Learning for Computer Vision with Python”.
Újabb számítógépes látás tanfolyam?
Nem végezzük az MNIST számjegyek osztályozását vagy az MNIST divatot. Régen kiszolgálták a részüket. Túl sok tanulási erőforrás összpontosít az alapvető adatkészletekre és alapvető architektúrákra, mielőtt a fejlett feketedoboz-architektúrákra hagyná a teljesítmény terhét.
Mi arra szeretnénk koncentrálni demisztifikáció, gyakorlatiasság, megértés, intuíció és a valódi projektek. Tanulni akar hogyan tudsz változtatni? Elvezetjük Önt az agyunk képfeldolgozási módjától a mellrák kutatási szintű mélytanulási osztályozójának megírásáig a mély tanulási hálózatokig, amelyek „hallucinálnak”, gyakorlati munkán keresztül megtanítjuk az alapelveket és az elméletet, felkészítve a know-how és eszközök ahhoz, hogy szakértővé váljon a mélytanulás alkalmazásában a számítógépes látás megoldásában.
Mi van benne?
- A látás első alapelvei és hogyan lehet a számítógépeket „látni” tanítani
- A számítógépes látás különböző feladatai és alkalmazásai
- A szakma eszközei, amelyek megkönnyítik a munkáját
- Adatkészletek keresése, létrehozása és felhasználása számítógépes látáshoz
- A konvolúciós neurális hálózatok elmélete és alkalmazása
- Tartományeltolódás, együttes előfordulás és egyéb torzítások kezelése az adatkészletekben
- Transzfer Tanulás és mások képzési idejének és számítási erőforrásainak felhasználása az Ön javára
- Korszerű emlőrák osztályozó felépítése és betanítása
- Hogyan alkalmazzunk egy egészséges adag szkepticizmust a mainstream ötletekhez, és hogyan értsük meg a széles körben elfogadott technikák következményeit
- A ConvNet „koncepcióterének” megjelenítése t-SNE és PCA segítségével
- Esettanulmányok arról, hogy a vállalatok hogyan használják a számítógépes látástechnikákat a jobb eredmények elérése érdekében
- Megfelelő modellértékelés, látens tér vizualizáció és a modell figyelmének azonosítása
- Domainkutatás végzése, saját adatkészletek feldolgozása és modelltesztek létrehozása
- Élvonalbeli architektúrák, az ötletek fejlődése, mi teszi őket egyedivé és hogyan valósítsuk meg őket
- KerasCV – WIP-könyvtár a legkorszerűbb csővezetékek és modellek létrehozásához
- Hogyan elemezze és olvassa el a dolgozatokat, és saját maga hajtsa végre azokat
- Modellek kiválasztása az alkalmazástól függően
- Végpontok közötti gépi tanulási folyamat létrehozása
- Tájkép és intuíció a tárgyfelismeréshez a gyorsabb R-CNN-ekkel, RetinaNetekkel, SSD-kkel és YOLO-val
- Példány és szemantikai szegmentáció
- Valós idejű objektumfelismerés a YOLOv5 segítségével
- YOLOv5 objektumdetektorok képzése
- Transzformátorokkal való munkavégzés KerasNLP-vel (ipari erősségű WIP-könyvtár)
- Transformers integrálása ConvNetekkel a képek feliratainak létrehozásához
- Deepdream
- Deep Learning modell optimalizálása számítógépes látáshoz