Randdetectie is een essentiële beeldanalysetechniek wanneer iemand geïnteresseerd is in het herkennen van objecten op basis van hun contouren, en wordt ook beschouwd als een essentiële stap in het herstellen van informatie uit afbeeldingen.
Belangrijke kenmerken zoals lijnen en curven kunnen bijvoorbeeld worden geëxtraheerd met behulp van randdetectie, die dan normaal gesproken wordt gebruikt door computervisies op hoger niveau of algoritmes voor beeldverwerking. Een goed algoritme voor randdetectie zou de locaties van de hoofdranden in een afbeelding markeren, terwijl tegelijkertijd eventuele valse randen die door ruis worden veroorzaakt worden genegeerd.
Maar wat zijn randen eigenlijk? Randen zijn afbeeldingsfuncties die kunnen worden gebruikt bij het schatten en analyseren van de structuur van objecten in een afbeelding. Ze vertegenwoordigen significante lokale veranderingen die plaatsvonden in de beeldintensiteit (d.w.z. pixelwaarde). Randen komen normaal gesproken voor op de grens tussen twee verschillende gebieden in de afbeelding.
In deze tutorial ga ik het Canny edge-detectoralgoritme beschrijven en hoe we het in Python kunnen implementeren.
Het Canny edge-detectoralgoritme is vernoemd naar de uitvinder, John F. Canny, die het algoritme in 1986 uitvond. De Canny edge-detector neemt normaal gesproken een beeld in grijstinten als invoer en produceert een beeld dat de locatie van intensiteitsdiscontinuïteiten als uitvoer (dat wil zeggen randen) toont.
Ik wil hier niet wiskundig gaan werken, maar ik zal beschrijven wat er achter de schermen gebeurt in het Canny edge detector-algoritme vanuit een hoogstaand gezichtspunt.
Het eerste dat de Canny-randdetector doet, is dat het de convolutie van Gauss gebruikt om het invoerbeeld te verzachten en ruis te verwijderen. Een eerste afgeleide operator wordt vervolgens toegepast op het afgevlakte beeld om die gebieden van het beeld met hoge eerste ruimtelijke derivaten te markeren.
Het algoritme vindt dan zowel de gradiëntgrootheid als richting door het x-derivaat en het y-derivaat te berekenen, vooral omdat het kennen van de richting van de gradiënt ons in feite in staat stelt de richting van de randen te bepalen.
Het algoritme voert dan uit wat wordt genoemd niet-maximale onderdrukking, waar het langs de top van de richels die van de randen opstijgen volgt, en zet die pixels die niet op de noktop staan op nul, waardoor uiteindelijk een dunne lijn in het resultaat ontstaat.
Met andere woorden, we controleren of het in de vorige stap berekende verloop wordt beschouwd als het maximum van de naburige punten die liggen in zowel de positieve als de negatieve richting van het verloop. Als het verloop het maximum was, wordt dit beschouwd als onderdeel van de rand en omgekeerd.
Het volgproces hierboven wordt bestuurd door twee drempels, t1
en T2
, zoals dat L1> L2
, verwezen naar Als hysteresis drempelwaarde.Het volgen begint op een punt op de rand dat hoger is dan t1
, en gaat dan verder in beide richtingen uit dat punt totdat de hoogte van de rand minder wordt dan T2
.
Dus, in principe, wat hier gebeurt, is dat we alle randpunten selecteren die zich boven de bovenste drempel bevinden t1
, en onderzoek vervolgens of er buren zijn van deze punten die onder de bovengrens worden beschouwd t1
en boven de lagere drempel T2
. In dit geval zouden dergelijke buren deel uitmaken van de rand.
Dus, de breedte van de Gausse kernel gebruikt voor het effenen van het invoerbeeld, en de t1 (boven en T2 (lagere) drempelwaarden die door de tracker worden gebruikt, zijn de parameters die het effect van de gevaarlijke randdetector bepalen.
In dit gedeelte beschrijf ik twee manieren waarop we de Canny edge-detector kunnen implementeren. Een manier gebruikt de scikit-image
bibliotheek, en de andere gebruikt de OpenCV
bibliotheek.
scikit-image
Als je het niet hebt scikit-image
al geïnstalleerd op uw computer, ga je gang en installeer het door de instructies op de installerende scikit-afbeeldingpagina te volgen.
Zoals ik een gebruik Ubuntu
Ik moest gewoon de volgende opdracht uitvoeren in mijn Terminal om de bibliotheek aan de gang te krijgen:
sudo apt-get install python-skimage
De scikit-image
bibliotheek heeft een canny ()
functie die we kunnen gebruiken om de Canny edge detector op onze afbeelding toe te passen. Merk op dat de functie deel uitmaakt van de voorzien zijn van
module.
Voordat we verdergaan, laten we een afbeelding van een speeltje gebruiken om mee te experimenteren. Je kunt echter elke afbeelding gebruiken. Ik ga de onderstaande boot.png-afbeelding gebruiken (klik op de koppeling om de afbeelding te downloaden):
Zonder verder oponthoud, laten we zien hoe we de randen in de bovenstaande afbeelding (dat wil zeggen boot) kunnen detecteren met behulp van de Canny edge-detector. Vergeet niet dat onze afbeelding grijswaarden moet zijn. Omdat onze afbeelding al in grijstinten is, hoeven we op dit moment niets te doen, zoals het converteren van de afbeelding van kleur naar grijswaarden. Het script voor de Canny edge detector ziet er als volgt uit:
van skimage import io uit skimage import functie im = io.imread ('boat.png') edges = feature.canny (im) io.imshow (randen) io.show ()
Dus, zoals je kunt zien, lezen we eerst ons beeld, boat.png
. Daarna passen we de canny ()
functie op de afbeelding (ik heb geen aangepaste parameters doorgegeven, behalve onze afbeelding, en liet deze staan op de standaardwaarden van de functie). Ten slotte geven we ons resultaat weer dat de gedetecteerde randen laat zien. Het resultaat van het bovenstaande script ziet er als volgt uit:
Je kunt met de parameters spelen om verschillende resultaten te krijgen over hoe randen worden gedetecteerd. Maar het resultaat ziet er goed uit met die gedetecteerde randen, nietwaar?!
OpenCV
In deze sectie gaan we kijken hoe we kunnen gebruiken OpenCV
om de Canny edge detector toe te passen op onze boot image. Als u nog geen OpenCV hebt geïnstalleerd, ga dan gang en installeer het. U kunt de volgende artikelen bekijken over hoe u kunt installeren OpenCV
op uw machine. Ik heb verschillende artikelen voor verschillende besturingssystemen opgenomen:
Zoals met de scikit-image
bibliotheek, OpenCV
heeft ook een functie genaamd canny ()
om het Canny edge detector-algoritme op de afbeelding toe te passen. Het volgende script laat zien hoe we kunnen gebruiken OpenCV
om de randen in onze afbeelding te vinden:
import cv2 import matplotlib.pyplot als plt im = cv2.imread ('boat.png') edges = cv2.Canny (im, 25,255, L2gradient = False) plt.imshow (edges, cmap = 'gray') plt.show ( )
Merk op dat ik het volgende heb doorgegeven als argumenten voor de Canny ()
functie:
im
: afbeeldingnaamlagere drempel
: 25bovenste drempel
: 255L2gradient = False
: dit betekent dat de L1-norm wordt gebruikt. Indien ingesteld op waar
, de L2-norm zal worden gebruikt.De matplotlib
bibliotheek is vervolgens gebruikt om de resultaten te plotten. Raadpleeg mijn zelfstudie voor meer informatie over deze bibliotheek: Introductie van de Matplotlib-bibliotheek van Python.
Het resultaat van het bovenstaande script is als volgt:
In deze tutorial hebben we geleerd over de Canny edge detector en gezien hoe de scikit-image
en OpenCV
bibliotheken stellen ons in staat om deze detector eenvoudig te implementeren met een paar regels code.