- 1. Segmentatie en contouren
- 2. Hiërarchie- en ophaalmodus
- 3. De contouren benaderen en hun convexe romp vinden
- 4. Convexe romp
- 5. Passende contouren door vormen
- 6. Vormen identificeren (cirkel, rechthoek, driehoek, vierkant, ster)
- 7. Lijndetectie
- 8. Blob-detectie
- 9. De blobs filteren - Cirkels en ellipsen tellen
In de vorige tutorials hebben we OpenCV gebruikt voor basisbeeldverwerking en enkele geavanceerde beeldbewerkingsbewerkingen uitgevoerd. Zoals we weten, is OpenCV een Open Source Commuter Vision-bibliotheek die C ++, Python en Java-interfaces heeft en Windows, Linux, Mac OS, iOS en Android ondersteunt. Het kan dus eenvoudig worden geïnstalleerd in Raspberry Pi met Python- en Linux-omgeving. En Raspberry Pi met OpenCV en aangesloten camera kan worden gebruikt om veel real-time beeldverwerkingstoepassingen te maken, zoals gezichtsdetectie, gezichtsvergrendeling, objecttracering, kentekenplaatdetectie, huisbeveiligingssysteem enz. In deze tutorial zullen we leren dat hoe te doen beeldsegmentatie met OpenCV. De bewerkingen die we gaan uitvoeren, staan hieronder vermeld:
- Segmentatie en contouren
- Hiërarchie- en ophaalmodus
- Contouren benaderen en hun bolle romp vinden
- Conex Hull
- Bijpassende contour
- Vormen identificeren (cirkel, rechthoek, driehoek, vierkant, ster)
- Lijndetectie
- Blob-detectie
- De blobs filteren - cirkels en ellipsen tellen
1. Segmentatie en contouren
Beeldsegmentatie is een proces waarbij we afbeeldingen in verschillende regio's verdelen. Terwijl de contouren de doorlopende lijnen of curven zijn die de volledige grens van een object in een afbeelding begrenzen of bedekken. En hier zullen we de beeldsegmentatietechniek, contouren genaamd, gebruiken om de delen van een afbeelding te extraheren.
Ook contouren zijn erg belangrijk in
- Object detectie
- Vormanalyse
En ze hebben een zeer breed toepassingsgebied, van beeldanalyse uit de echte wereld tot medische beeldanalyse zoals in MRI's
Laten we weten hoe we contouren in opencv kunnen implementeren door contouren van vierkanten te extraheren.
import cv2 import numpy als np
Laten we een eenvoudige afbeelding laden met 3 zwarte vierkanten
image = cv2.imread ('squares.jpg') cv2.imshow ('input afbeelding', afbeelding) cv2.waitKey (0)
Grijstinten
grey = cv2.cvtColor (afbeelding, cv2.COLOR_BGR2GRAY)
Zoek slimme randen
edged = cv2.Canny (grijs, 30,200) cv2.imshow ('slimme randen', edged) cv2.waitKey (0)
Contouren zoeken
#gebruik een kopie van je afbeelding, bijv. - edged.copy (), aangezien het vinden van contouren de afbeelding verandert #we moeten _ voor de contouren toevoegen als een leeg argument vanwege de upgrade van de OpenCV-versie _, contouren, hiërarchie = cv2.findContours (edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) cv2.imshow ('slimme randen na contouren', edged) cv2.waitKey (0)
Het contourbestand afdrukken om te weten waaruit de contouren bestaan
print (contouren) print ('Aantallen contouren gevonden =' + str (len (contouren)))
Teken alle contouren
#gebruik -1 als de 3e parameter om alle contouren te tekenen cv2.drawContours (afbeelding, contouren, -1, (0,255,0), 3) cv2.imshow ('contouren', afbeelding) cv2.waitKey (0) cv2. destroyAllWindows ()
Console-uitgang -],],], …,],],]], dtype = int32), matrix (],],
], …,
],],]], dtype = int32), array (],],], …,],],]], dtype = int32)]
Aantallen gevonden contouren = 3. We hebben dus in totaal drie contouren gevonden.
Nu hadden we in de bovenstaande code ook het contourbestand afgedrukt met , dit bestand vertelt hoe deze contouren eruit zien, zoals afgedrukt in de uitvoer van de console.
In de bovenstaande console-uitvoer hebben we een matrix die eruitziet als coördinaten van x, y-punten. OpenCV slaat contouren op in lijsten met lijsten. We kunnen de bovenstaande console-uitvoer eenvoudig als volgt weergeven:
CONTOUR 1 CONTOUR 2 CONTOUR 3
], array (], array (],],],],],],],
…,…,…,],],],],],],]], dtype = int32),]], dtype = int32),]], dtype = int32)]
Nu we de lengtefunctie op een contourbestand gebruiken, krijgen we de lengte gelijk aan 3, dit betekent dat er drie lijsten met lijsten in dat bestand waren, dwz drie contouren.
Stel je nu voor dat CONTOUR 1 het eerste element in die array is en die lijst bevat een lijst met alle coördinaten en deze coördinaten zijn de punten langs de contouren die we net zagen, als de groene rechthoekige vakken.
Er zijn verschillende methoden om deze coördinaten op te slaan en deze worden benaderingsmethoden genoemd, in principe zijn er twee soorten benaderingsmethoden
- cv2.CHAIN_APPROX_NONE
- cv2.CHAIN_APPROX_SIMPLE
cv2.CHAIN_APPROX_NONE slaat al het grenspunt op, maar we hebben niet noodzakelijk alle grenspunten nodig, als het punt een rechte lijn vormt, hebben we alleen het startpunt en eindpunt op die lijn nodig.
cv2.CHAIN_APPROX_SIMPLE geeft in plaats daarvan alleen de start- en eindpunten van de begrenzende contouren, het resultaat is een veel efficiëntere opslag van contourinformatie.
_, contouren, hiërarchie = cv2.findContours (edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
In de bovenstaande code is cv2.RETR_EXTERNAL de ophaalmodus terwijl de cv2.CHAIN_APPROX_NONE is
de benaderingsmethode.
Dus we hebben geleerd over contouren en benaderingsmethode, laten we nu de hiërarchie en ophaalmodus onderzoeken.
2. Hiërarchie- en ophaalmodus
De ophaalmodus definieert de hiërarchie in contouren zoals subcontouren, of externe contouren of alle contouren.
Nu zijn er vier ophaalmodi gesorteerd op de hiërarchietypes.
cv2.RETR_LIST - haalt alle contouren op.
cv2.RETR_EXTERNAL - haalt alleen externe of buitencontouren op.
cv2.RETR_CCOMP - haalt alles op in een hiërarchie met 2 niveaus.
cv2.RETR_TREE - haalt alles op in een volledige hiërarchie.
Hiërarchie wordt opgeslagen in de volgende indeling
Laten we nu het verschil illustreren tussen de eerste twee ophaalmodi, cv2.RETR_LIST en cv2.RETR_EXTERNAL.
import cv2 import numpy als np
Laten we een eenvoudige afbeelding laden met 3 zwarte vierkanten
image = cv2.imread ('vierkante donut.jpg') cv2.imshow ('invoerafbeelding', afbeelding) cv2.waitKey (0)
Grijstinten
grey = cv2.cvtColor (afbeelding, cv2.COLOR_BGR2GRAY)
Vind Canny Edges
edged = cv2.Canny (grijs, 30,200) cv2.imshow ('slimme randen', edged) cv2.waitKey (0)
Contouren zoeken
#gebruik een kopie van je afbeelding, bijv. - edged.copy (), aangezien het vinden van contouren de afbeelding verandert #we moeten _ toevoegen, vóór de contouren als een leeg argument vanwege de upgrade van de open cv-versie _, contouren, hiërarchie = cv2.findContours (edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) cv2.imshow ('slimme randen na contouren', edged) cv2.waitKey (0)
Het contourbestand afdrukken om te weten waaruit de contouren bestaan.
print (contouren) print ('Aantallen contouren gevonden =' + str (len (contouren)))
Teken alle contouren
#gebruik -1 als de 3e parameter om alle contouren te tekenen cv2.drawContours (afbeelding, contouren, -1, (0,255,0), 3) cv2.imshow ('contouren', afbeelding) cv2.waitKey (0) cv2. destroyAllWindows
import cv2 import numpy als np
Laten we een eenvoudige afbeelding laden met 3 zwarte vierkanten
image = cv2.imread ('vierkante donut.jpg') cv2.imshow ('invoerafbeelding', afbeelding) cv2.waitKey (0)
Grijstinten
grey = cv2.cvtColor (afbeelding, cv2.COLOR_BGR2GRAY)
Zoek slimme randen
edged = cv2.Canny (grijs, 30,200) cv2.imshow ('slimme randen', edged) cv2.waitKey (0)
Contouren zoeken
#gebruik een kopie van je afbeelding, bijv. - edged.copy (), aangezien het vinden van contouren de afbeelding verandert #we moeten _ voor de contouren toevoegen als een leeg argument vanwege de upgrade van de open cv-versie _, contouren, hiërarchie = cv2.findContours (edged, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) cv2.imshow ('slimme randen na contouren', edged) cv2.waitKey (0)
Het contourbestand afdrukken om te weten waaruit de contouren bestaan.
print (contouren) print ('Aantallen contouren gevonden =' + str (len (contouren)))
Teken alle contouren
#gebruik -1 als de 3e parameter om alle contouren te tekenen cv2.drawContours (afbeelding, contouren, -1, (0,255,0), 3) cv2.imshow ('contouren', afbeelding) cv2.waitKey (0) cv2. destroyAllWindows ()
Dus door de demonstratie van bovenstaande codes konden we duidelijk het verschil zien tussen de cv2.RETR_LIST en cv2.RETR_EXTERNNAL , in cv2.RETR_EXTERNNAL wordt alleen rekening gehouden met de buitenste contouren terwijl de binnenste contouren worden genegeerd.
In cv2.RETR_LIST wordt ook rekening gehouden met binnencontouren.
3. De contouren benaderen en hun convexe romp vinden
Bij benaderende contouren wordt een contourvorm benaderd over een andere contourvorm, die misschien niet veel lijkt op de eerste contourvorm.
Voor benadering gebruiken we de approxPolyDP- functie van openCV die hieronder wordt uitgelegd
cv2.approxPolyDP (contour, benaderingsnauwkeurigheid, gesloten)
Parameters:
- Contour - is de individuele contour die we willen benaderen.
- Benaderingsnauwkeurigheid - belangrijke parameter bij het bepalen van de nauwkeurigheid van de benadering, kleine waarde geeft nauwkeurige benadering, grote waarden geven meer algemene informatie. Een goede vuistregel is minder dan 5% van de contouromtrek.
- Gesloten - een Booleaanse waarde die aangeeft of de geschatte contour open of gesloten kan zijn.
Laten we proberen een eenvoudige afbeelding van een huis te benaderen
importeer numpy als np importeer cv2
Laad de afbeelding en bewaar een kopie
image = cv2.imread ('house.jpg') orig_image = image.copy () cv2.imshow ('originele afbeelding', orig_image) cv2.waitKey (0)
Grijstinten en binariseer de afbeelding
grey = cv2.cvtColor (afbeelding, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold (grijs, 127.255, cv2.THRESH_BINARY_INV)
Vind contouren
_, contouren, hiërarchie = cv2.findContours (thresh.copy (), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
Herhaal elke contour en bereken hun begrenzende rechthoek
voor c in contouren: x, y, w, h = cv2.boundingRect (c) cv2.rechthoek (orig_image, (x, y), (x + w, y + h), (0,0,255), 2) cv2.imshow ('Bounding rect', orig_image) cv2.waitKey (0)
Herhaal elke contour en bereken de ongeveer contour
voor c in contouren:
#bereken nauwkeurigheid als een percentage van de omtreknauwkeurigheid van de contour = 0,03 * cv2.arcLength (c, True) approx = cv2.approxPolyDP (c, accuratesse, True) cv2.drawContours (afbeelding,, 0, (0,255,0), 2) cv2.imshow ('Ca. polyDP', afbeelding) cv2.waitKey (0) cv2.destroyAllWindows ()
4. Convexe romp
Convexe romp is in feite de buitenranden, weergegeven door lijnen over een bepaalde figuur te trekken.
Het zou de kleinste polygoon kunnen zijn die om het object zelf past.
import cv2 import numpy als np afbeelding = cv2.imread ('star.jpg') grey = cv2.cvtColor (afbeelding, cv2.COLOR_BGR2GRAY) cv2.imshow ('originele afbeelding', afbeelding) cv2.waitKey (0)
Drempel de afbeelding
ret, thresh = cv2.threshold (grijs, 176,255,0)
Vind contouren
_, contouren, hiërarchie = cv2.findContours (thresh.copy (), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
Sorteer de contouren op gebied en verwijder vervolgens de grootste framecontour
n = len (contouren) -1 contouren = gesorteerd (contouren, sleutel = cv2.contourArea, omgekeerd = False)
Itereer door de contouren en teken een bolle romp
voor c in contouren:
hull = cv2.convexHull (c) cv2.drawContours (afbeelding,, 0, (0,255,0), 2) cv2.imshow ('bolle romp', afbeelding) cv2.waitKey (0) cv2.destroyAllWindows ()
5. Passende contouren door vormen
cv2.matchShapes (contoursjabloon, contourmethode, methodeparameter)
Output - match waarde (lagere waarde betekent een nauwere match)
contoursjabloon - Dit is onze referentiecontour die we in een nieuwe afbeelding proberen te vinden.
contour - De individuele contour die we controleren.
Methode - Type contouraanpassing (1,2,3).
method parameter - laat staan als 0.0 (niet gebruikt in python opencv)
import cv2 import numpy als np
Laad de vormsjabloon of referentieafbeelding
template = cv2.imread ('star.jpg', 0) cv2.imshow ('template', sjabloon) cv2.waitKey (0)
Laad de doelafbeelding met de vormen die we proberen te matchen
target = cv2.imread ('shapestomatch.jpg') grijs = cv2.cvtColor (target, cv2.COLOR_BGR2GRAY)
Drempel eerst beide afbeeldingen op voordat u cv2.findContours gebruikt
ret, thresh1 = cv2.threshold (sjabloon, 127,255,0) ret, thresh2 = cv2.threshold (grijs, 127,255,0)
Vind contouren in sjabloon
_, contouren, hierarhy = cv2.findContours (thresh1, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) # we moeten de contouren sorteren op gebied zodat we de grootste contour kunnen verwijderen die is
Afbeelding overzicht
sorted_contours = gesorteerde (contouren, key = cv2.contourArea, reverse = True) #We pak het op een na grootste contour die onze template contour zal zijn tempelate_contour = contouren #extract de contouren van het tweede doel van _, contouren, hiërarchie = cv2.findContours (thresh2, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) voor c in contouren: #itereer door elke contour in de doelafbeelding en gebruik cv2.matchShape om de contourvorm te vergelijken match = cv2.matchShapes (tempelate_contour, c, 1,0.0) print ("match") # als de matchwaarde kleiner is dan 0,15 if match <0,16: dichtstbijzijnde_contour = c else: dichtstbijzijnde_contour = cv2.drawContours (target,, - 1, (0,255,0), 3) cv2.imshow ('output',doelwit) cv2.waitKey (0) cv2.destroyAllWindows ()
Console-uitgang -
0.16818605122199104
0.19946910256158912
0.18949760627309664
0.11101058276281539
Er zijn drie verschillende methoden met verschillende wiskundige functies, we kunnen met elke methode experimenteren door simpelweg cv2.matchShapes (tempelate_contour, c, 1, 0.0) methodewaarden te vervangen die variëren van 1,2 en 3, voor elke waarde krijg je een andere match waarden in console-uitvoer.
6. Vormen identificeren (cirkel, rechthoek, driehoek, vierkant, ster)
OpenCV kan ook worden gebruikt voor het automatisch detecteren van verschillende soorten vormen uit de afbeelding. Door onderstaande code te gebruiken, kunnen we cirkel, rechthoek, driehoek, vierkant en sterren uit de afbeelding detecteren.
import cv2 import numpy als np
Laad en vervolgens grijsschaalafbeeldingen
image = cv2.imread ('shapes.jpg') grey = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) cv2.imshow ('vormen identificeren', afbeelding) cv2.waitKey (0) ret, thresh = cv2.threshold (grijs, 127,255,1)
Extraheer contouren
_, contouren, hiërarchie = cv2.findContours (thresh.copy (), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
Voor cnt in contouren:
Krijg geschatte polygonen bij benadering = cv2.approxPolyDP (cnt, 0.01 * cv2.arcLength (cnt, True), True) als len (ongeveer) == 3: shape_name = "Triangle" cv2.drawContours (afbeelding,, 0, (0,255, 0), - 1)
zoek contourcentrum om tekst in het midden te plaatsen
M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M) cv2.putText (afbeelding, vorm_naam, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0, 0), 1) elif len (ongeveer) == 4: x, y, w, h = cv2.boundingRect (cnt) M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M)
Controleer of die vierzijdige veelhoek vierkant of rechthoekig is
# cv2.boundingRect retourneert de linker breedte en hoogte in pixels, beginnend vanaf de linkerbovenhoek, voor vierkant zou het ongeveer hetzelfde zijn als abs (wh) <= 3: shape_name = "square" #find contour center om tekst op te plaatsen center cv2.drawContours (afbeelding,, 0, (0,125,255), - 1) cv2.putText (afbeelding, vorm_naam, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0), 1) anders: shape_name = "Reactangle" #find contour center om tekst in het midden te plaatsen cv2.drawContours (image,, 0, (0,0,255), - 1) M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M) cv2.putText (afbeelding, vorm_naam, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0), 1) elif len (ongeveer) == 10: vorm_naam = 'ster' cv2.drawContours (afbeelding,, 0, (255,255,0), - 1) M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M) cv2.putText (afbeelding, vorm_naam, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0), 1) elif len (ongeveer)> = 15: shape_name = 'cirkel' cv2.drawContours (afbeelding,, 0, (0,255,255), -1) M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M) cv2.putText (afbeelding, vorm_naam, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0), 1) cv2.imshow ('vormen identificeren', afbeelding) cv2.waitKey (0) cv2.destroyAllWindows ()
7. Lijndetectie
Lijndetectie is een zeer belangrijk concept in OpenCV, en heeft een veelbelovend gebruik in de echte wereld. Autonome auto's gebruiken algoritmen voor lijndetectie voor het detecteren van rijstroken en wegen.
Bij lijndetectie behandelen we twee algoritmen,
- Hough Line-algoritme
- Probalistisch Hough Line-algoritme.
Je herinnert je misschien de weergave van de lijn uit de wiskunde op de middelbare school met de vergelijking, y = mx + c.
In OpenCV wordt de lijn echter op een andere manier weergegeven
De bovenstaande vergelijking ρ = xcosӨ + ysincosӨ is de OpenCV-weergave van de lijn, waarbij ρ de loodrechte afstand van de lijn vanaf de oorsprong is en Ө de hoek is die wordt gevormd door de normaal van deze lijn naar de oorsprong (gemeten in radialen, waarbij 1pi radialen / 180 = 1 graad).
De OpenCV-functie voor het detecteren van een lijn wordt gegeven als
cv2.HoughLines (gebinariseerde afbeelding, ρ nauwkeurigheid, Ө nauwkeurigheid, drempelwaarde), waarbij de drempel de minimumstem is om als een lijn te worden beschouwd.
Laten we nu lijnen detecteren voor een kaderafbeelding met behulp van de Hough-lijnfunctie van opencv.
import cv2 import numpy als np image = cv2.imread ('box.jpg')
Grijstinten en ingewikkelde randen geëxtraheerd
grey = cv2.cvtColor (afbeelding, cv2.COLOR_BGR2GRAY) randen = cv2.Canny (grijs, 100,170, apertureSize = 3)
Voer Hough-lijnen uit met een nauwkeurigheid van 1 pixel
#theta nauwkeurigheid van (np.pi / 180) wat 1 graad is # lijndrempel is ingesteld op 240 (aantal punten op lijn) lijnen = cv2.HoughLines (randen, 1, np.pi / 180, 240) #we itereren door elke regel en converteer naar het formaat #vereist door cv2.lines (dwz eindpunten vereist) voor i in bereik (0, len (regels)): voor rho, theta in regels: a = np.cos (theta) b = np.sin (theta) x0 = a * rho y0 = b * rho x1 = int (x0 + 1000 * (- b)) y1 = int (y0 + 1000 * (a)) x2 = int (x0-1000 * (-b)) y2 = int (y0-1000 * (a)) cv2.line (afbeelding, (x1, y1), (x2, y2), (0,255,0), 2) cv2.imshow ('hough lines', afbeelding) cv2.waitKey (0) cv2.destroyAllWindows ()
Laten we nu de detectie boven de lijn herhalen met een ander algoritme van de probabilistische Hough-lijn.
Het idee achter de probabilistische Hough-lijn is om een willekeurige subset van punten te nemen die voldoende zijn voor lijndetectie.
De OpenCV-functie voor de probabilistische Hough-lijn wordt weergegeven als cv2.HoughLinesP (gebinariseerde afbeelding, ρ nauwkeurigheid, Ө nauwkeurigheid, drempelwaarde, minimale lijnlengte, maximale lijnafstand)
Laten we nu boxlijnen detecteren met behulp van probabilistische Hough-lijnen.
import cv2 import numpy als np
Grijstinten en scherpe randen Geëxtraheerd
image = cv2.imread ('box.jpg') grey = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) randen = cv2.Canny (grijs, 50,150, apertureSize = 3) # we gebruiken opnieuw dezelfde rho- en theta-nauwkeurigheden # echter, specificeren we een minimum aantal stemmen (punten langs de lijn) van 100 # en een minimale regellengte van 5 pixels en een maximum tussenruimte tussen de regels van 10 pixels regels = cv2.HoughLinesP (randen, 1, np.pi / 180,100,100,10) voor i in bereik (0, len (regels)): voor x1, y1, x2, y2 in regels: cv2.line (afbeelding, (x1, y1), (x2, y2), (0,255,0), 3) cv2. imshow ('probalistic hough lines', afbeelding) cv2.waitKey (0) cv2.destroyAllWindows
8. Blob-detectie
Blobs kunnen worden omschreven als een groep verbonden pixels die allemaal een gemeenschappelijke eigenschap hebben. De methode om OpenCV blob-detector te gebruiken, wordt beschreven in dit stroomschema.
Voor het tekenen van de belangrijkste punten gebruiken we cv2.drawKeypoints waaraan de volgende argumenten moeten voldoen .
cv2.drawKeypoints (invoerbeeld, sleutelpunten, blank_output_array, kleur, vlaggen)
waar in de vlaggen zouden kunnen zijn
cv2.DRAW_MATCHES_FLAGS_DEFAULT
cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG
cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
en blanco is hier vrijwel niets anders dan een een voor een matrix van nullen
Laten we nu de blob-detectie uitvoeren op een afbeelding van zonnebloemen, waarbij de blobs de centrale delen van de bloem zouden zijn, aangezien ze veel voorkomen bij alle bloemen.
import cv2 import numpy als np image = cv2.imread ('Sunflowers.jpg', cv2.IMREAD_GRAYSCALE)
Stel de detector in met standaardparameters
detector = cv2.SimpleBlobDetector_create ()
Detecteer blobs
keypoints = detector.detect (afbeelding)
Teken gedetecteerde blobs als rode cirkels
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS zorg ervoor dat de #grootte van de cirkel overeenkomt met de grootte van de blanco blanco = np.zeros ((1,1)) blobs = cv2.drawKeypoints (afbeelding, sleutelpunten, blanco, (0,255,255), cv2.DRAW_MATCHES_FA
Toon sleutelpunten
cv2.imshow ('blobs', blobs) cv2.waitKey (0) cv2.destroyAllWindows ()
Ook al werkt de code prima, maar sommige klodders worden gemist vanwege ongelijke afmetingen van de bloemen, aangezien de bloemen aan de voorkant groot zijn in vergelijking met de bloemen aan het einde.
9. De blobs filteren - Cirkels en ellipsen tellen
We kunnen parameters gebruiken om de blobs te filteren op basis van hun vorm, grootte en kleur. Voor het gebruik van parameters met blob-detector gebruiken we de OpenCV-functie
cv2.SimpleBlobDetector_Params ()
We zullen zien dat de blobs worden gefilterd door voornamelijk deze vier parameters die hieronder worden vermeld:
Oppervlakte
params.filterByArea = Waar / niet waar params.minArea = pixels params.maxArea = pixels
Circulariteit
params.filterByCircularity = Waar / niet waar params.minCircularity = 1 is perfect, 0 is het tegenovergestelde
Convexiteit - Gebied van blob / gebied van bolle romp
params.filterByConvexity = Waar / niet waar params.minConvexity = Gebied
Traagheid
params.filterByInertia = Waar / niet waar params.minInertiaRatio = 0.01
Laten we nu proberen blobs te filteren op bovengenoemde parameters
import cv2 import numpy als np afbeelding = cv2.imread ('blobs.jpg') cv2.imshow ('originele afbeelding', afbeelding) cv2.waitKey (0)
Initialiseer de detector met de standaardparameters
detector = cv2.SimpleBlobDetector_create ()
Detecteer blobs
keypoints = detector.detect (afbeelding)
Teken blobs op onze afbeelding als rode cirkels
blank = np.zeros ((1,1)) blobs = cv2.drawKeypoints (image, keypoints, blank, (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) number_of_blobs = len (keypoints) text = "totaal aantal blobs" + str (len (keypoints)) cv2.putText (blobs, tekst, (20,550), cv2.FONT_HERSHEY_SIMPLEX, 1, (100,0,255), 2)
Geef een afbeelding weer met blob-sleutelpunten
cv2.imshow ('blob met standaardparameters', blobs) cv2.waitKey (0)
Stel onze filterparameters in
#initialize parameterinstelling met cv2.SimpleBlobDetector params = cv2.SimpleBlobDetector_Params ()
Stel parameters voor gebiedsfiltering in
params.filterByArea = Echte params.minArea = 100
Stel cirkelvormige filterparameters in
params.filterByCircularity = Echte params.minCircularity = 0.9
Stel de parameter voor het filteren van convexiteit in
params.filterByConvexity = Valse params.minConvexity = 0.2
Traagheidsfilterparameter instellen
params.filterByInertia = Echte params.minInertiaRatio = 0.01
Maak een detector met parameter
detector = cv2.SimpleBlobDetector_create (params)
Detecteer blobs
keypoints = detector.detect (afbeelding)
Teken blobs op de afbeeldingen als rode cirkels
blank = np.zeros ((1,1)) blobs = cv2.drawKeypoints (image, keypoints, blank, (0,255,0), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) number_of_blobs = len (keypoints) text = "totaal aantal ronde blobs" + str (len (keypoints)) cv2.putText (blobs, tekst, (20,550), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,100,255), 2)
Blobs weergeven
cv2.imshow ('filtering circulaire blobs', blobs) cv2.waitKey (0) cv2.destroyAllWindows ()
Dit is dus hoe beeldsegmentatie kan worden gedaan in Python-OpenCV. Om een goed begrip te krijgen van computervisie en OpenCV, ga je door eerdere artikelen (Aan de slag met Python OpenCV en beeldmanipulaties in Python OpenCV, dan kun je iets cools maken met Computer Vision.