5.14. Gaussiaans gladstrijken en randen¶
Twee taken domineren waarvoor buurtvensters in de klassieke machine vision worden gebruikt: het netjes gladstrijken van pixel-tot-pixelvariatie, en het vinden van de randen waar de afbeelding scherp verandert. Het Gaussiaanse filter is het standaardgereedschap voor het eerste, de op de Laplaciaan gebaseerde detectoren het standaardgereedschap voor het tweede – en de twee combineren goed, omdat elke randdetector beter werkt op een licht gladgestreken invoer.
5.14.1. Het Gaussiaanse filter¶
gaussian() is de centrumgewogen neef van mean(). Beide berekenen een gemiddelde over de buurt van elke pixel, maar de gewichten van de Gaussiaan zijn niet uniform: pixels dichter bij het centrum van de buurt tellen zwaarder mee, pixels aan de rand van de buurt tellen lichter mee, waarbij de gewichten de bekende klokcurve volgen die het filter zijn naam geeft.
De klokvormige weging is wat een Gaussiaans filter gladder maakt dan een box-gemiddelde. Middelende filtering kan zichtbare artefacten produceren aan de randen van objecten – een harde afsnijding in de weging introduceert kleine ringpatronen bij scherpe overgangen. De soepel afnemende gewichten van de Gaussiaan vermijden dat ringen en produceren een resultaat dat er meer uitziet zoals “vervaagd” eruit zou moeten zien. De prijs is meer rekenwerk per pixel dan het middelende filter, maar niet dramatisch veel – de kosten per pixel zijn nog steeds veel lager dan bij het bilaterale filter.
img.gaussian(1) # 3x3 Gaussian -- a clean light blur
img.gaussian(2) # 5x5 Gaussian -- stronger smoothing
Gaussiaans gladstrijken is de standaard eerste fase van vrijwel elke randdetectiepijplijn. De onderstaande randdetectoren versterken allemaal hoogfrequente inhoud, inclusief de sensorruis die het algoritme eigenlijk niet wil detecteren. Een lichte Gaussiaan eerst uitvoeren onderdrukt die ruis zonder echte randen veel te verzachten, zodat de randdetector echte randen vindt in plaats van spikkels.
5.14.2. Unsharp masking¶
Een Gaussiaans vervaagde kopie van een afbeelding is het ruwe materiaal dat de unsharp mask-techniek gebruikt voor klassieke verscherping. Door unsharp=True op het filter in te stellen schakelt het over van “produceer de vervaagde afbeelding” naar “trek de vervaagde afbeelding van het origineel af en tel het verschil weer bij het origineel op” – het effect is dat hoogfrequente randen worden versterkt ten opzichte van gladde interieurs.
img.gaussian(1, unsharp=True)
De optionele parameters mul en add schalen de sterkte van het unsharp-resultaat; de standaardwaarden (mul=1.0, add=0.0) leveren een gematigde verscherping op die sensorruis niet overdrijft.
5.14.3. Het Laplaciaanse filter¶
laplacian() voert een discrete benadering uit van de tweede ruimtelijke afgeleide van de afbeelding. De uitvoer is groot waar pixelwaarden snel veranderen, bijna nul waar ze constant zijn of lineair veranderen. De natuurlijke lezing van het resultaat is een randrespons: pixels waar de afbeelding snel verandert lichten op, pixels in gladde interieurs blijven donker.
img.laplacian(1) # 3x3 Laplacian -- edge response
Dezelfde parameters als bij gaussian zijn beschikbaar. sharpen=True produceert een verscherpte afbeelding (de Laplaciaan wordt weer bij het origineel opgeteld in plaats van op zichzelf teruggegeven). mul en add schalen de respons.
Een praktisch gebruik naast randdetectie is scherptemeting. De Laplaciaanse respons gemiddeld over een gebied geeft een ruwe maat voor hoeveel hoogfrequente inhoud het gebied bevat; bij een goed scherpgestelde frame is dat gemiddelde hoog, bij een wazige frame daalt het. Het vergelijken van de Laplaciaanse respons over frames is de goedkope manier om “is de lens scherpgesteld?” te vragen zonder een duurdere contrastmetriek nodig te hebben.
5.14.4. De find_edges-methode¶
find_edges() voert een complete randdetectiepijplijn uit in plaats van slechts een randresponsfilter. Het werkt op grijswaardenafbeeldingen, en het resultaat is een binaire afbeelding waarvan de niet-nul pixels de posities markeren waar de invoer de soort helderheidsverandering heeft die als rand zou moeten tellen.
De methode neemt een edge_type-parameter die kiest tussen twee algoritmen:
EDGE_SIMPLE voert een hoogdoorlaatfilter uit, past een drempelwaarde toe en geeft het resultaat terug. Snel, maar de uitvoer bevat elke helderheidsverandering boven de drempelwaarde, inclusief ruis en textuur waar de applicatie waarschijnlijk niet om geeft. Redelijk voor schone afbeeldingen en voor gevallen waarin de ruis door een latere morfologische doorloop wordt opgeruimd.
EDGE_CANNY voert de Canny-randdetector uit – het klassieke meertraps algoritme. Het berekent de helderheidsgradiënt, onderdrukt elke niet-maximale respons langs de gradiëntrichting (zodat elke rand één pixel breed is), en past een hysteresedrempelwaarde toe (zodat een rand die op één plek sterk is ook wordt getraceerd waar deze tussendoor vervaagt). Het resultaat is een schone, dunne, samenhangende verzameling randpixels van de soort die elk klassiek randgebaseerd algoritme wil.
De threshold-parameter is een tuple met twee elementen (low, high). Voor EDGE_CANNY is de high-waarde de afkapwaarde waarboven een pixel zeker een rand is, en de low-waarde de afkapwaarde waarboven een pixel alleen een rand is als deze verbonden is met een zekere rand. Voor EDGE_SIMPLE doet alleen de high-waarde ertoe; het is de enkele afkapwaarde waarboven een pixel als rand telt. De standaardwaarde (100, 200) is een startpunt dat het waard is om af te stemmen op de specifieke scène.
img.gaussian(1) # pre-smooth
img.find_edges(image.EDGE_CANNY, threshold=(50, 100))
De Canny-detector is de betere keuze voor vrijwel elke applicatie waar randen ertoe doen. De snellere EDGE_SIMPLE is het onthouden waard voor de gevallen waarin de kosten van Canny een probleem zijn en de ruisonderdrukking van de hysterese eigenlijk niet nodig is.
5.14.5. Adaptieve drempelwaarden op de Gaussiaan¶
Net als de statistische filters accepteert gaussian() het sleutelwoordpaar threshold=True / offset=N voor adaptieve drempelwaarden. Het gedrag is hetzelfde als bij mean(): de Gaussiaanse statistiek op elke positie wordt de lokale afkapwaarde, en de bronpixel wordt vergeleken met de statistiek plus de offset om een binair resultaat te produceren.
De Gaussiaanse variant is meestal de schoonste keuze voor adaptieve drempelwaarden wanneer de invoer redelijk ruisvrij is. Het gewogen gemiddelde geeft een gladdere afkapwaarde dan het middelende filter produceert, met minder artefacten bij scherpe verlichtingsovergangen.