Beeldverwerking OpenCV

Beeldverwerking Opencv



We gaan de beeldverwerkingsmethoden in dit artikel bestuderen. We zullen enkele fundamentele maar kritieke onderwerpen in computervisie en machine learning onderzoeken. Deze fundamentele beeldverwerkingstechnieken kunnen complexe problemen, zoals datasets, oplossen. Als gevolg hiervan zijn er zes fundamentele stappen in beeldverwerking, die hieronder worden opgesomd:
  1. Beeldvertaling
  2. Beeldrotatie
  3. Afbeelding Rekenen
  4. Afbeelding omdraaien
  5. Afbeelding bijsnijden
  6. Formaat van afbeelding wijzigen

Nu zullen we alle bovengenoemde onderwerpen over beeldverwerking in detail uitleggen.

1. Beeldvertaling

Beeldvertaling is een beeldverwerkingsmethode die ons helpt het beeld langs de x- en y-as te verplaatsen. We kunnen de afbeelding omhoog, omlaag, naar rechts, naar links of een willekeurige combinatie verplaatsen.







We kunnen de vertaalmatrix definiëren met het symbool M, en we kunnen het in wiskundige vorm weergeven, zoals hieronder weergegeven:





We kunnen het concept van het vertaalbeeld begrijpen via dit programma.





Python-code: We behouden de naam van het volgende programma als vertalen.py .

# importeer vereiste pakketten

importeren onnozel zoals bijv.

importeren argparse

importeren nutteloos

importeren cv2

# we implementeren de argument-parser

ap_obj = argparse. ArgumentParser ( )

ap_obj. add_argument ( '-k' , '--afbeelding' , vereist = WAAR ,

helpen = 'locatie van het afbeeldingsbestand' )

argumenten = van wie ( ap_obj. ontleed_args ( ) )

# laad de afbeelding en toon deze op het scherm

afbeelding = cv2. imlezen ( argumenten [ 'afbeelding' ] )

cv2. imshow ( 'Originele afbeelding' , afbeelding )

# De vertaling van de afbeelding is een NumPy-matrix die hieronder wordt weergegeven:

# [[1, 0, shiftX], [0, 1, shiftY]]

# We gaan de bovenstaande NumPy-matrix gebruiken om de afbeeldingen langs de

# x-as en y-as richtingen. Hiervoor moeten we gewoon de pixelwaarden doorgeven.

# In dit programma verplaatsen we de afbeelding 30 pixels naar rechts

# en 70 pixels naar beneden.

vertaling_mat = bijv. vlotter32 ( [ [ 1 , 0 , 30 ] , [ 0 , 1 , 70 ] ] )

afbeelding_vertaling = cv2. warpAffine ( afbeelding , vertaling_mat ,

( afbeelding. vorm geven aan [ 1 ] , afbeelding. vorm geven aan [ 0 ] ) )

cv2. imshow ( 'Beeldvertaling naar beneden en naar rechts' , afbeelding_vertaling )

# nu gaan we de bovenstaande NumPy-matrix gebruiken om de afbeeldingen langs de

# x-as (links) en y-as (omhoog) richtingen.

# Hier gaan we de afbeeldingen 50 pixels naar links verplaatsen

# en 90 pixels naar boven.

vertaling_mat = bijv. vlotter32 ( [ [ 1 , 0 , - vijftig ] , [ 0 , 1 , - 90 ] ] )

afbeelding_vertaling = cv2. warpAffine ( afbeelding , vertaling_mat ,

( afbeelding. vorm geven aan [ 1 ] , afbeelding. vorm geven aan [ 0 ] ) )

cv2. imshow ( 'Beeldvertaling naar boven en naar links' , afbeelding_vertaling )

cv2. wachtSleutel ( 0 )

Regels 1 tot 5: We importeren alle vereiste pakketten voor dit programma, zoals OpenCV, argparser en NumPy. Houd er rekening mee dat er nog een bibliotheek is die imutils is. Dit is geen pakket van OpenCV. Dit is slechts een bibliotheek die gemakkelijk dezelfde beeldverwerking laat zien.



De imutils van de bibliotheek worden niet automatisch opgenomen wanneer we OpenCV installeren. Dus om de imutils te installeren, moeten we de volgende methode gebruiken:

pip installeer imutils

Regels 8 tot 15: We hebben onze agrparser gemaakt en onze afbeelding geladen.

Regels 24 tot 25: In dit programmagedeelte vindt de vertaling plaats. De vertaalmatrix vertelt ons hoeveel pixels de afbeelding omhoog of omlaag of naar links of rechts wordt verplaatst. Omdat OpenCV vereist dat de matrixwaarde zich in een drijvende-komma-array bevindt, neemt de vertaalmatrix waarden in drijvende-komma-arrays aan.

De eerste rij van de vertaalmatrix ziet er als volgt uit:

Deze rij van de matrix is ​​voor de x-as. De waarde van t x zal beslissen of het beeld naar links of naar rechts wordt verschoven. Als we een negatieve waarde doorgeven, betekent dit dat de afbeelding naar de linkerkant wordt verschoven, en als de waarde positief is, betekent dit dat de afbeelding naar de rechterkant wordt verschoven.

We zullen nu de tweede rij van de matrix als volgt definiëren:

Deze rij van de matrix is ​​voor de y-as. De waarde van t Y zal beslissen of het beeld omhoog of omlaag wordt verschoven. Als we een negatieve waarde doorgeven, betekent dit dat het beeld naar boven wordt verschoven, en als de waarde positief is, betekent dit dat het beeld naar beneden wordt verschoven.

In het vorige programma op regel 24 definiëren we de t x = 30 en de t Y = 70. We verplaatsen de afbeelding dus 30 pixels naar de rechterkant en 70 pixels naar beneden.

Maar het belangrijkste beeldvertalingsproces vindt plaats op regel 25, waar we de vertaalmatrix definiëren cv2.warpAffine . In deze functie geven we drie parameters door: de eerste parameter is de afbeelding, de tweede parameter is de vertaalmatrix en de derde parameter is de afbeeldingsdimensie.

Lijn 27: Regel 27 geeft het resultaat weer in de uitvoer.

Nu gaan we een andere vertaalmatrix voor de linker- en bovenzijde implementeren. Hiervoor moeten we de waarden negatief definiëren.

Lijn 33 tot 34: In het vorige programma op regel 33 definiëren we de t x = -50 en de t Y = -90. We verplaatsen de afbeelding dus 50 pixels naar de linkerkant en 90 pixels naar boven. Maar het belangrijkste beeldvertalingsproces vindt plaats op regel 34, waar we de vertaalmatrix definiëren cv2.warpAffine .

Lijn 36 : De regel 36 geeft het resultaat weer zoals weergegeven in de uitvoer.

Om de vorige code uit te voeren, moeten we het pad van de afbeelding opgeven zoals hieronder weergegeven.

Uitgang: python translate.py –afbeelding eekhoorn.jpg

Nu zullen we hetzelfde programma voor het vertalen van afbeeldingen implementeren met behulp van de nutteloos bibliotheek. Deze bibliotheek is heel gemakkelijk te gebruiken voor beeldverwerking. In deze bibliotheek hoeven we niet na te denken over de cv2.warpAffine want deze bibliotheek zal hiervoor zorgen. Dus laten we dit programma voor het vertalen van afbeeldingen implementeren met behulp van de imutils-bibliotheek.

Python-code: We behouden de naam van het volgende programma als translate_imutils.py .

# importeer de benodigde pakketten

importeren onnozel zoals bijv.

importeren argparse

importeren nutteloos

importeren cv2

# Deze functie implementeert de beeldvertaling en

# retourneert de vertaalde afbeelding naar de aanroepende functie.

def vertalen ( afbeelding , x , Y ) :

vertaling_matrix = bijv. vlotter32 ( [ [ 1 , 0 , x ] , [ 0 , 1 , Y ] ] )

afbeelding_vertaling = cv2. warpAffine ( afbeelding , vertaling_matrix ,

( afbeelding. vorm geven aan [ 1 ] , afbeelding. vorm geven aan [ 0 ] ) )

opbrengst afbeelding_vertaling

# construeer de argument-parser en ontleed de argumenten

app = argparse. ArgumentParser ( )

app. add_argument ( '-i' , '--afbeelding' , vereist = WAAR , helpen = 'Pad naar het beeld' )

argumenten = van wie ( app. ontleed_args ( ) )

# laad de afbeelding en geef deze weer op het scherm

afbeelding = cv2. imlezen ( argumenten [ 'afbeelding' ] )

cv2. imshow ( 'Originele afbeelding' , afbeelding )

afbeelding_vertaling = nutteloos. vertalen ( afbeelding , 10 , 70 )

cv2. imshow ( 'Beeldvertaling naar rechts en naar beneden' ,

afbeelding_vertaling )

cv2. wachtSleutel ( 0 )

Regels 9 tot 13: In dit gedeelte van het programma vindt de vertaling plaats. De vertaalmatrix informeert ons met hoeveel pixels de afbeelding omhoog of omlaag of naar links of rechts wordt verplaatst.

Deze regels zijn al uitgelegd, maar nu gaan we een functie genaamd translate () bouwen en er drie verschillende parameters in sturen. De afbeelding zelf dient als eerste parameter. De x- en y-waarden van de vertaalmatrix komen overeen met de tweede en derde parameter.

Opmerking : Het is niet nodig om deze vertaalfunctie in het programma te definiëren omdat deze al is opgenomen in het imutils-bibliotheekpakket. Ik heb het binnen het programma gebruikt voor een duidelijke uitleg. We kunnen deze functie direct aanroepen met de imutils, zoals weergegeven in regel 24.

Lijn 24: Het vorige programma laat zien dat we op regel 24 de tx = 10 en de ty = 70 definiëren. We verplaatsen de afbeelding dus 10 pixels naar de rechterkant en 70 pixels naar beneden.

In dit programma geven we niets om cv2.warpAffine-functies omdat ze al in het imutils-bibliotheekpakket zitten.

Om de vorige code uit te voeren, moeten we het pad van de afbeelding opgeven, zoals hieronder weergegeven:

Uitgang:

python imutils. py --afbeelding eekhoorn. jpg

2. Beeldrotatie

In de vorige les (of een combinatie daarvan) hebben we besproken hoe u een afbeelding omhoog, omlaag, naar links en naar rechts kunt vertalen (d.w.z. verschuiven). Vervolgens bespreken we rotatie in verband met beeldverwerking.

Een afbeelding wordt over een hoek, theta, gedraaid in een proces dat rotatie wordt genoemd. De hoek waarmee we de afbeelding roteren, wordt weergegeven door theta. Daarnaast zal ik later de gemaksfunctie voor roteren bieden om het roteren van afbeeldingen eenvoudiger te maken.

Vergelijkbaar met translatie, en misschien niet verrassend, rotatie over een hoek, wordt theta bepaald door een matrix M te bouwen in het volgende formaat:

Deze matrix kan een vector theta graden (tegen de klok in) roteren rond het gegeven oorsprong (x, y)-cartesiaans vlak. Gewoonlijk zou in dit scenario de oorsprong het midden van de afbeelding zijn, maar in werkelijkheid kunnen we elk willekeurig (x, y) punt aanwijzen als ons rotatiecentrum.

De geroteerde afbeelding R wordt vervolgens gemaakt op basis van de originele afbeelding I met behulp van eenvoudige matrixvermenigvuldiging: R = IM

OpenCV, aan de andere kant, biedt bovendien de mogelijkheid om (1) een afbeelding te schalen (d.w.z. formaat wijzigen) en (2) een willekeurig rotatiecentrum te bieden om de rotatie rond uit te voeren.

Onze gewijzigde rotatiematrix M wordt hieronder weergegeven:

Laten we beginnen met het openen en genereren van een nieuw bestand met de naam draaien.py :

# de vereiste pakketten importeren

importeren onnozel zoals bijv.

importeren argparse

importeren nutteloos

importeren cv2

# het argumentparser-object en het parseerargument maken

abj = argparse. ArgumentParser ( )

abj. add_argument ( '-k' , '--afbeelding' , vereist = WAAR , helpen = 'afbeelding pad' )

argumenten = van wie ( abj. ontleed_args ( ) )

afbeelding = cv2. imlezen ( argumenten [ 'afbeelding' ] )

cv2. imshow ( 'Originele afbeelding' , afbeelding )

# Bereken het midden van de afbeelding met behulp van de afmetingen van de afbeelding.

( hoogte , breedte ) = afbeelding. vorm geven aan [ : 2 ]

( centrumX , centrumY ) = ( breedte / 2 , hoogte / 2 )

# Nu, met behulp van cv2, zullen we de afbeelding 55 graden draaien naar

# bepaal de rotatiematrix met behulp van getRotationMatrix2D()

rotatieMatrix = cv2. getRotationMatrix2D ( ( centrumX , centrumY ) , 55 , 1.0 )

geroteerde afbeelding = cv2. warpAffine ( afbeelding , rotatieMatrix , ( breedte , hoogte ) )

cv2. imshow ( 'Het beeld is 55 graden gedraaid' , geroteerde afbeelding )

cv2. wachtSleutel ( 0 )

# De afbeelding wordt nu -85 graden gedraaid.

rotatieMatrix = cv2. getRotationMatrix2D ( ( centrumX , centrumY ) , - 85 , 1.0 )

geroteerde afbeelding = cv2. warpAffine ( afbeelding , rotatieMatrix , ( breedte , hoogte ) )

cv2. imshow ( 'Het beeld is -85 graden gedraaid' , geroteerde afbeelding )

cv2. wachtSleutel ( 0 )

Regels 1 tot 5: We importeren alle vereiste pakketten voor dit programma, zoals OpenCV, argparser en NumPy. Houd er rekening mee dat er nog een bibliotheek is die imutils is. Dit is geen pakket van OpenCV. Dit is slechts een bibliotheek die zal worden gebruikt om dezelfde beeldverwerking eenvoudig weer te geven.

De imutils van de bibliotheek worden niet automatisch opgenomen wanneer we OpenCV installeren. OpenCV installeert de imutils. We moeten de volgende methode gebruiken:

pip installeer imutils

Regels 8 tot 14: We hebben onze agrparser gemaakt en onze afbeelding geladen. In deze argparser gebruiken we slechts één beeldargument, dat ons het pad van de afbeelding zal vertellen dat we in dit programma zullen gebruiken om de rotatie te demonstreren.

Bij het roteren van een afbeelding moeten we het draaipunt van de rotatie definiëren. Meestal wil je een afbeelding rond het midden roteren, maar met OpenCV kun je in plaats daarvan elk willekeurig punt kiezen. Laten we de afbeelding gewoon rond het midden draaien.

Lijnen 17 tot 18 neem respectievelijk de breedte en hoogte van de afbeelding en deel vervolgens elke dimensie door twee om het midden van de afbeelding vast te stellen.

We construeren een matrix om een ​​afbeelding te roteren op dezelfde manier waarop we een matrix hebben gedefinieerd om een ​​afbeelding te vertalen. We bellen gewoon de cv2.getRotationMatrix2D functie op lijn 22 in plaats van de matrix handmatig te maken met behulp van NumPy (wat een beetje omslachtig kan zijn).

De cv2.getRotationMatrix2D functie vereist drie parameters. De eerste invoer is de gewenste rotatiehoek (in dit geval het midden van de afbeelding). Theta wordt dan gebruikt om aan te geven hoeveel (tegen de klok in) we de afbeelding zullen draaien. Hier draaien we de afbeelding 45 graden. De laatste optie heeft betrekking op de grootte van de afbeelding.

Ongeacht het feit dat we het schalen van een afbeelding nog niet hebben besproken, kunt u hier een getal met drijvende komma opgeven met 1,0 om aan te geven dat de afbeelding in de oorspronkelijke verhoudingen moet worden gebruikt. Als u echter een waarde van 2,0 typt, wordt de afbeelding twee keer zo groot. Een getal van 0,5 verkleint de grootte van de afbeelding op die manier.

Lijn 22 tot 23: Na ontvangst van onze rotatiematrix M van de cv2.getRotationMatrix2D functie roteren we onze afbeelding met behulp van de cv2.warpAffine techniek op regel 23. De eerste invoer van de functie is de afbeelding die we willen roteren. De breedte en hoogte van ons uitvoerbeeld worden dan gedefinieerd, samen met onze rotatiematrix M. Op regel 23 wordt het beeld dan 55 graden gedraaid.

U kunt zien dat onze afbeelding is gedraaid.

Lijnen 28 tot 30 vormen de tweede rotatie. Regels 22-23 van de code zijn identiek, behalve dat we deze keer -85 graden roteren in plaats van 55.

We hebben tot nu toe gewoon een afbeelding rond het midden gedraaid. Wat als we de afbeelding rond een willekeurig punt willen draaien?

Laten we beginnen met het openen en genereren van een nieuw bestand met de naam roteren.py:

# de vereiste pakketten importeren

importeren onnozel zoals bijv.

importeren argparse

importeren nutteloos

importeren cv2

# het argumentparser-object en het parseerargument maken

ap_obj = argparse. ArgumentParser ( )

ap_obj. add_argument ( '-k' , '--afbeelding' , vereist = WAAR , helpen = 'afbeelding pad' )

argument = van wie ( ap_obj. ontleed_args ( ) )

# laad de afbeelding en geef deze weer op het scherm

afbeelding = cv2. imlezen ( argument [ 'afbeelding' ] )

cv2. imshow ( 'Originele afbeelding' , afbeelding )

# Bereken het midden van de afbeelding met behulp van de afmetingen van de afbeelding.

( hoogte , breedte ) = afbeelding. vorm geven aan [ : 2 ]

( centrumX , centrumY ) = ( breedte / 2 , hoogte / 2 )

# Nu, met behulp van cv2, zullen we de afbeelding 55 graden draaien naar

# bepaal de rotatiematrix met behulp van getRotationMatrix2D()

rotatieMatrix = cv2. getRotationMatrix2D ( ( centrumX , centrumY ) , 55 , 1.0 )

geroteerde afbeelding = cv2. warpAffine ( afbeelding , rotatieMatrix , ( breedte , hoogte ) )

cv2. imshow ( 'Het beeld is 55 graden gedraaid' , geroteerde afbeelding )

cv2. wachtSleutel ( 0 )

# De afbeelding wordt nu -85 graden gedraaid.

rotatieMatrix = cv2. getRotationMatrix2D ( ( centrumX , centrumY ) , - 85 , 1.0 )

geroteerde afbeelding = cv2. warpAffine ( afbeelding , rotatieMatrix , ( breedte , hoogte ) )

cv2. imshow ( 'Het beeld is -85 graden gedraaid' , geroteerde afbeelding )

cv2. wachtSleutel ( 0 )

# beeldrotatie vanaf een willekeurig punt, niet vanuit het midden

rotatieMatrix = cv2. getRotationMatrix2D ( ( centrumX - 40 , centrumY - 40 ) , 55 , 1.0 )

geroteerde afbeelding = cv2. warpAffine ( afbeelding , rotatieMatrix , ( breedte , hoogte ) )

cv2. imshow ( 'Beeldrotatie vanaf willekeurige punten' , geroteerde afbeelding )

cv2. wachtSleutel ( 0 )

Lijn 34 tot 35: Nu zou deze code redelijk normaal moeten lijken voor het roteren van een object. Om de afbeelding rond een punt 40 pixels naar links en 40 pixels boven het midden te draaien, instrueren we de cv2.getRotationMatrix2D functie om aandacht te besteden aan de eerste parameter.

De afbeelding die wordt geproduceerd wanneer we deze rotatie toepassen, wordt hieronder weergegeven:

We kunnen duidelijk zien dat het middelpunt van de rotatie nu de (x, y)-coördinaat is, dat is 40 pixels naar links en 40 pixels boven het berekende midden van de afbeelding.

3. Rekenen met afbeeldingen

In feite is beeldrekenen niets meer dan matrixoptelling met een paar aanvullende beperkingen voor gegevenstypen die we later zullen behandelen.

Laten we even de tijd nemen om enkele mooie grondbeginselen van lineaire algebra door te nemen.

Overweeg om de volgende twee matrices te combineren:

Welk resultaat zou de matrixoptelling opleveren? Het simpele antwoord is de som van de matrixingangen, element voor element:

Eenvoudig genoeg, toch?

We begrijpen allemaal de fundamentele bewerkingen van optellen en aftrekken op dit moment. We moeten echter rekening houden met de beperkingen die worden opgelegd door onze kleurruimte en gegevenstype tijdens het werken met afbeeldingen.

Pixels in RGB-afbeeldingen vallen bijvoorbeeld tussen [0, 255]. Wat gebeurt er als we proberen 10 toe te voegen aan een pixel met een intensiteit van 250 terwijl we ernaar kijken?

We zouden uitkomen op een waarde van 260 als we standaard rekenkundige principes zouden toepassen. 260 is geen geldige waarde, aangezien RGB-afbeeldingen worden weergegeven als 8-bits niet-ondertekende gehele getallen.

Dus wat zou er moeten gebeuren? Moeten we een controle uitvoeren om er zeker van te zijn dat geen enkele pixel buiten het bereik van [0, 255] valt, waarbij we elke pixel knippen om een ​​waarde tussen 0 en 255 te krijgen?

Of 'wikkelen' we ons en voeren we een modulusbewerking uit? In overeenstemming met de modulusregels zou het optellen van 10 tot 255 resulteren in een waarde van 9.

Hoe moeten optellingen en aftrekkingen van afbeeldingen buiten het bereik van [0, 255] worden afgehandeld?

De waarheid is dat er geen goede of foute techniek is; het hangt allemaal af van hoe u met uw pixels werkt en wat u hoopt te bereiken.

Maar vergeet niet dat er verschillen zijn tussen optellen in OpenCV en optellen in NumPy. Modulus rekenkunde en 'wrap around' worden gedaan door NumPy. OpenCV zal daarentegen clipping uitvoeren en ervoor zorgen dat pixelwaarden nooit het bereik [0, 255] verlaten.

Laten we beginnen met het maken van een nieuw bestand met de naam rekenen.py en openen:

# python arithmetic.py --image eekhoorn.jpg

# de vereiste pakketten importeren

importeren onnozel zoals bijv.

importeren argparse

importeren nutteloos

importeren cv2

# het argumentparser-object en het parseerargument maken

apObj = argparse. ArgumentParser ( )

apObj. add_argument ( '-k' , '--afbeelding' , vereist = WAAR , helpen = 'afbeelding pad' )

argumenten = van wie ( apObj. ontleed_args ( ) )

afbeelding = cv2. imlezen ( argumenten [ 'afbeelding' ] )

cv2. imshow ( 'Originele afbeelding' , afbeelding )

'''

De waarden van onze pixels liggen in het bereik [0, 255]

omdat afbeeldingen NumPy-arrays zijn, die worden opgeslagen als niet-ondertekende 8-bits gehele getallen.

Bij gebruik van functies zoals cv2.add en cv2.subtract worden waarden afgekapt

binnen dit bereik, zelfs als ze worden opgeteld bij of afgetrokken van buiten de

[0, 255] bereik. Hier is een illustratie:

'''


afdrukken ( 'maximaal 255: {}' . formaat ( str ( cv2. toevoegen ( bijv. uint8 ( [ 201 ] ) ,

bijv. uint8 ( [ 100 ] ) ) ) ) )

afdrukken ( 'minimaal 0: {}' . formaat ( str ( cv2. aftrekken ( bijv. uint8 ( [ 60 ] ) ,

bijv. uint8 ( [ 100 ] ) ) ) ) )

'''

Bij het uitvoeren van rekenkundige bewerkingen met deze arrays met behulp van NumPy,

de waarde zal rondlopen in plaats van te worden afgekapt aan de

[0, 255]bereik. Bij het gebruik van afbeeldingen is het essentieel om dit te bewaren

in gedachten.

'''


afdrukken ( 'omwikkelen: {}' . formaat ( str ( bijv. uint8 ( [ 201 ] ) + bijv. uint8 ( [ 100 ] ) ) ) )

afdrukken ( 'omwikkelen: {}' . formaat ( str ( bijv. uint8 ( [ 60 ] ) - b.v. uint8 ( [ 100 ] ) ) ) )

'''

Laten we de helderheid van elke pixel in onze afbeelding vermenigvuldigen met 101.

Om dit te doen, genereren we een NumPy-array van dezelfde grootte als onze matrix,

gevuld met enen, en vermenigvuldig dit met 101 om een ​​gevulde array te verkrijgen

met 101s. Ten slotte voegen we de twee afbeeldingen samen.

U zult merken dat het beeld nu 'helderder' is.

'''


Matrix = bijv. degenen ( afbeelding. vorm geven aan , dtype = 'uint8' ) * 101

afbeelding_toegevoegd = cv2. toevoegen ( afbeelding , Matrix )

cv2. imshow ( 'Toegevoegd afbeeldingsresultaat' , afbeelding_toegevoegd )

#Op een vergelijkbare manier kunnen we ons beeld donkerder maken door te nemen

# 60 weg van alle pixels.

Matrix = bijv. degenen ( afbeelding. vorm geven aan , dtype = 'uint8' ) * 60

afbeelding_afgetrokken = cv2. aftrekken ( afbeelding , Matrix )

cv2. imshow ( 'Afgetrokken beeldresultaat' , afbeelding_afgetrokken )

cv2. wachtSleutel ( 0 )

Lijnen 1 tot en met 16 zal worden gebruikt om ons normale proces uit te voeren, wat inhoudt het importeren van onze pakketten, het configureren van onze argumentparser en het laden van onze afbeelding.

Weet je nog hoe ik eerder het onderscheid tussen OpenCV en NumPy-toevoeging besprak? Nu we het grondig hebben behandeld, laten we een specifiek geval bekijken om er zeker van te zijn dat we het begrijpen.

Twee 8-bits niet-ondertekende integer NumPy-arrays zijn gedefinieerd op lijn 26 . Een waarde van 201 is het enige element in de eerste array. Hoewel er maar één lid in de tweede array zit, heeft het een waarde van 100. De waarden worden vervolgens toegevoegd met behulp van OpenCV's cv2.add-functie.

Wat verwacht je dat het resultaat zal zijn?

In overeenstemming met conventionele rekenkundige principes zou het antwoord 301 moeten zijn. Maar vergeet niet dat we te maken hebben met 8-bits gehele getallen zonder teken, die alleen in het bereik [0, 255] kunnen liggen. Omdat we de methode cv2.add gebruiken, handelt OpenCV clipping af en zorgt ervoor dat de optelling alleen een maximaal resultaat van 255 oplevert.

De eerste regel van de onderstaande lijst toont het resultaat van het uitvoeren van deze code:

rekenkundig. py

maximaal van 255 : [ [ 255 ] ]

De som leverde inderdaad een aantal van 255 op.

Daarna, lijn 26 gebruikt cv2.subtract om een ​​aftrekking uit te voeren. Nogmaals, we definiëren twee 8-bits niet-ondertekende integers NumPy-arrays met elk een enkel element. De waarde van de eerste array is 60, terwijl de waarde van de tweede array 100 is.

Onze rekenkunde schrijft voor dat de aftrekking zou moeten resulteren in een waarde van -40, maar OpenCV regelt de clipping opnieuw voor ons. We ontdekken dat de waarde is teruggebracht tot 0. Ons onderstaande resultaat toont dit aan:

rekenkundig. py

minimaal van 0 : [ [ 0 ] ]

Gebruik cv2 om 100 af te trekken van 60 aftrekken, waardoor de waarde 0 ontstaat.

Maar wat gebeurt er als we NumPy gebruiken in plaats van OpenCV om de berekeningen uit te voeren?

Lijnen 38 en 39 aanpakken van dit probleem.

Eerst worden twee 8-bits niet-ondertekende integer NumPy-arrays met elk een enkel element gedefinieerd. De waarde van de eerste array is 201, terwijl de waarde van de tweede array 100 is. Onze toevoeging zou worden ingekort en een waarde van 255 zou worden geretourneerd als we de functie cv2.add zouden gebruiken.

NumPy, aan de andere kant, 'wikkelt zich om' en doet modulo-rekenkunde in plaats van knippen. NumPy loopt terug naar nul zodra een waarde van 255 is bereikt en hervat het tellen tot er 100 stappen zijn bereikt. Dit wordt bevestigd door de eerste uitvoerregel, die hieronder wordt weergegeven:

rekenkundig. py
omwikkelen: [ Vier vijf ]

Vervolgens worden nog twee NumPy-arrays gedefinieerd, een met een waarde van 50 en de andere met 100. Deze aftrekking zou worden bijgesneden door de cv2.subtract-methode om een ​​resultaat van 0 te retourneren. Maar we zijn ons ervan bewust dat NumPy in plaats van knippen modulo rekenen. In plaats daarvan lopen de modulo-procedures rond en beginnen ze terug te tellen vanaf 255 zodra 0 is bereikt tijdens het aftrekken. We kunnen dit zien aan de hand van de volgende uitvoer:

rekenkundig. py

omwikkelen: [ 207 ]

Eens te meer demonstreert onze terminaloutput het onderscheid tussen knippen en omwikkelen:

Het is cruciaal om het gewenste resultaat in gedachten te houden bij het uitvoeren van rekenkundige bewerkingen met gehele getallen. Wilt u dat waarden buiten het bereik [0, 255] worden afgekapt? Gebruik daarna de ingebouwde rekenkundige technieken voor afbeeldingen van OpenCV.

Wilt u waarden omwikkelen als ze buiten het bereik van [0, 255] en modulus rekenkundige bewerkingen vallen? De NumPy-arrays worden vervolgens gewoon opgeteld en afgetrokken zoals gewoonlijk.

Lijn 48 definieert een eendimensionale NumPy-array met dezelfde afmetingen als onze afbeelding. Nogmaals, we zorgen ervoor dat ons gegevenstype 8-bits niet-ondertekende gehele getallen is. We vermenigvuldigen gewoon onze matrix van eencijferige waarden met 101 om deze te vullen met waarden van 101 in plaats van 1. Ten slotte gebruiken we de cv2.add-functie om onze matrix van 100-en toe te voegen aan de originele afbeelding. Dit verhoogt de intensiteit van elke pixel met 101 en zorgt er tegelijkertijd voor dat alle waarden die de 255 proberen te overschrijden, worden afgekapt tot het bereik [0, 255].

Kijk hoe de afbeelding merkbaar helderder is en meer 'vervaagd' lijkt dan het origineel. Dit komt omdat we pixels naar helderdere kleuren sturen door hun pixelintensiteit met 101 te verhogen.

Om 60 af te trekken van elke pixelintensiteit van de afbeelding, maken we eerst een tweede NumPy-array op regel 54 die is gevuld met de jaren 60.

De resultaten van deze aftrekking worden weergegeven in de volgende afbeelding:

De items om ons heen lijken aanzienlijk donkerder dan voorheen. Dit komt omdat door 60 af te trekken van elke pixel, we de pixels in de RGB-kleurruimte naar de donkere gebieden verplaatsen.

4. Afbeelding omdraaien

Net als bij rotatie, is het spiegelen van een afbeelding over de x- of y-as een andere optie die wordt aangeboden door OpenCV. Zelfs als flipping-bewerkingen niet zo vaak worden gebruikt, is het ongelooflijk nuttig om ze te kennen om verschillende redenen die u misschien niet meteen ziet.

We ontwikkelen een machine learning-classificator voor een klein startend bedrijf dat gezichten in afbeeldingen probeert te identificeren. Om ons systeem te laten 'leren' wat een gezicht is, hebben we een soort dataset met voorbeeldgezichten nodig. Helaas heeft het bedrijf ons slechts een kleine dataset van 40 gezichten gegeven en kunnen we niet meer informatie verzamelen.

Wat doen we dan?

Aangezien een gezicht een gezicht blijft, of het nu gespiegeld is of niet, kunnen we elk beeld van een gezicht horizontaal spiegelen en de gespiegelde versies gebruiken als extra trainingsgegevens.

Dit voorbeeld lijkt misschien stom en kunstmatig, maar dat is het niet. Flipping is een bewuste strategie die wordt gebruikt door sterke deep-learning algoritmen om meer gegevens te produceren tijdens de trainingsfase.

Uit het voorgaande blijkt duidelijk dat de beeldverwerkingsmethoden die u in deze module leert, dienen als basis voor grotere computervisiesystemen.

Doelstellingen:

De ... gebruiken cv2.flip functie, leert u in deze sessie hoe u een afbeelding zowel horizontaal als verticaal kunt spiegelen.

Omdraaien is de volgende beeldmanipulatie die we zullen bestuderen. De x- en y-assen van een afbeelding kunnen worden omgedraaid of zelfs beide. Voordat we in de codering duiken, kun je het beste eerst kijken naar de resultaten van een afbeelding omdraaien. Zie een afbeelding die horizontaal is gespiegeld in de volgende afbeelding:


Let op hoe onze originele afbeelding aan de linkerkant is en hoe de afbeelding aan de rechterkant horizontaal is gespiegeld.

Laten we beginnen met het maken van een nieuw bestand met de naam flipping.py .

Je hebt een voorbeeld gezien van het omdraaien van afbeeldingen, dus laten we de code eens bekijken:

# python flipping.py --image quirrel.jpg

# de vereiste pakketten importeren

importeren argparse

importeren cv2

# het object van argumentparser maken en het argument parseren

apObj = argparse. ArgumentParser ( )

apObj. add_argument ( '-i' , '--afbeelding' , vereist = WAAR , helpen = 'afbeelding pad' )

argument = van wie ( apObj. ontleed_args ( ) )

afbeelding = cv2. imlezen ( argument [ 'afbeelding' ] )

cv2. imshow ( 'Origineel' , afbeelding )

# Draai de afbeelding horizontaal om

afbeelding omgedraaid = cv2. omdraaien ( afbeelding , 1 )

cv2. imshow ( 'Afbeelding horizontaal gespiegeld' , afbeelding omgedraaid )

# Draai de afbeelding verticaal om

afbeelding omgedraaid = cv2. omdraaien ( afbeelding , 0 )

cv2. imshow ( 'Verticaal gespiegelde afbeelding' , afbeelding omgedraaid )

# afbeelding omdraaien langs beide assen

afbeelding omgedraaid = cv2. omdraaien ( afbeelding , - 1 )

cv2. imshow ( 'Horizontaal en verticaal omgedraaid' , afbeelding omgedraaid )

cv2. wachtSleutel ( 0 )

De stappen die we nemen om onze pakketten te importeren, onze invoer te ontleden en onze afbeelding van schijf te laden, worden afgehandeld in l ines 1 t/m 12 .

Door de functie cv2.flip aan te roepen Lijn 15 , is het eenvoudig om een ​​afbeelding horizontaal te spiegelen. De afbeelding die we willen omdraaien en een specifieke code of vlag die specificeert hoe de afbeelding moet worden omgedraaid, zijn de twee argumenten die nodig zijn voor de cv2.flip-methode.

Een flip-codewaarde van 1 betekent dat we de afbeelding rond de y-as draaien om deze horizontaal te spiegelen ( Lijn 15 ). Als we een flip-code van 0 specificeren, willen we de afbeelding rond de x-as roteren ( Lijn 19 ). Een negatieve flipcode ( Lijn 23 ) roteert de afbeelding om beide assen.

Een van de gemakkelijkste voorbeelden in dit onderwerp is het omdraaien van een afbeelding, wat eenvoudig is.

Vervolgens bespreken we het bijsnijden van afbeeldingen en gebruiken we NumPy-array-segmenten om specifieke afbeeldingsdelen te extraheren.

5. Afbeelding bijsnijden

Bijsnijden, zoals de naam al aangeeft, is het proces van het kiezen en verwijderen van het interessegebied (of kortweg ROI), het gebied van de afbeelding dat ons interesseert.

Het gezicht zou uit een afbeelding moeten worden bijgesneden voor een toepassing voor gezichtsdetectie. Bovendien, als we een Python-script zouden maken om honden in afbeeldingen te vinden, zouden we de hond misschien uit de afbeelding willen bijsnijden wanneer we hem vinden.

Doelen: Ons belangrijkste doel is om vertrouwd te raken met en vertrouwd te raken met het gebruik van NumPy-array-slicing om gebieden uit een afbeelding bij te snijden.

Bijsnijden : Wanneer we een afbeelding bijsnijden, is ons doel om de uiterlijke elementen die ons niet interesseren te verwijderen. Het proces van het kiezen van onze ROI wordt vaak aangeduid als het kiezen van onze interesseregio.

Maak een nieuw bestand met de naam crop.py , open het en voeg de volgende code toe:

# python crop.py

# de vereiste pakketten importeren

importeren cv2

# afbeelding laden en weergeven op het scherm

afbeelding = cv2. imlezen ( 'eekhoorn.jpg' )

afdrukken ( afbeelding. vorm geven aan )

cv2. imshow ( 'Origineel' , afbeelding )

# NumPy-array-segmenten worden gebruikt om snel een afbeelding bij te snijden

# we gaan het eekhoorngezicht uit de afbeelding bijsnijden

eekhoorngezicht = afbeelding [ 35 : 90 , 35 : 100 ]

cv2. imshow ( 'eekhoorn gezicht' , eekhoorngezicht )

cv2. wachtSleutel ( 0 )

# En nu gaan we hier het hele lichaam bijsnijden

# van de eekhoorn

eekhoornlichaam = afbeelding [ 35 : 148 , 23 : 143 ]

cv2. imshow ( 'Eekhoornlichaam' , eekhoornlichaam )

cv2. wachtSleutel ( 0 )

We laten het bijsnijden in Python en OpenCV zien met behulp van een afbeelding die we vanaf schijf laden Lijnen 5 en 6 .

Oorspronkelijke afbeelding die we gaan bijsnijden

Door alleen basistechnieken voor het bijsnijden te gebruiken, proberen we het eekhoorngezicht en het eekhoornlichaam te scheiden van de omgeving.

We zullen onze voorkennis van de afbeelding gebruiken en handmatig de NumPy-array-segmenten leveren van waar het lichaam en het gezicht bestaan. Onder normale omstandigheden zouden we over het algemeen machine learning en computer vision-algoritmen gebruiken om het gezicht en lichaam in de afbeelding te herkennen. Maar laten we het voorlopig simpel houden en geen detectiemodellen gebruiken.

We kunnen het gezicht in de afbeelding identificeren met slechts één regel code. Lijn 13 , Om een ​​rechthoekig gedeelte van de afbeelding te extraheren, beginnend bij (35, 35), bieden we NumPy-arraysegmenten (90, 100). Het lijkt misschien verwarrend dat we het gewas voeden met de indexen in de hoogte-eerste en breedte-tweede volgorde die we doen, maar houd er rekening mee dat OpenCV afbeeldingen opslaat als NumPy-arrays. Als gevolg hiervan moeten we de waarden voor de y-as vóór de x-as opgeven.

NumPy vereist de volgende vier indexen om onze bijsnijding uit te voeren:

Begin j: De y-coördinaat aan het begin. Voor dit voorbeeld beginnen we bij y=35.

Einde y: De y-coördinaat aan het einde. Onze oogst stopt wanneer y = 90.

Begin x: De begin x-coördinaat van de slice. De uitsnede wordt gestart bij x=35.

Einde x: De eindcoördinaat van de x-as van het segment. Bij x=100 is onze plak klaar.

Op dezelfde manier snijden we de gebieden (23, 35) en (143, 148) van de originele afbeelding bij om het volledige lichaam uit de afbeelding op Lijn 19 .

Je kunt zien dat de afbeelding is bijgesneden om alleen het lichaam en het gezicht te laten zien.

6. Formaat van afbeelding wijzigen

Het proces van het vergroten of verkleinen van de breedte en hoogte van een afbeelding staat bekend als schalen of eenvoudigweg vergroten of verkleinen. Bij het wijzigen van het formaat van een afbeelding moet rekening worden gehouden met de beeldverhouding, de verhouding tussen de breedte en de hoogte van een afbeelding. Als u de beeldverhouding verwaarloost, kan dit ertoe leiden dat afbeeldingen die zijn geschaald, gecomprimeerd en vervormd lijken:

Onze eerste afbeelding is aan de linkerkant. Aan de rechterkant ziet u twee afbeeldingen die zijn geschaald zonder de beeldverhouding te behouden, waardoor de verhouding tussen de breedte en de hoogte van de afbeelding wordt vervormd. Wanneer u het formaat van uw afbeeldingen wijzigt, moet u over het algemeen rekening houden met de beeldverhouding.

De interpolatietechniek die door ons algoritme voor het wijzigen van de grootte wordt gebruikt, moet ook rekening houden met het doel van de interpolatiefunctie om deze buurten van pixels te gebruiken om de grootte van de afbeelding te vergroten of te verkleinen.

Over het algemeen is het verkleinen van de afbeelding veel effectiever. Dit komt omdat het verwijderen van pixels uit een afbeelding het enige is dat de interpolatiefunctie hoeft te doen. Aan de andere kant zou de interpolatiemethode 'de gaten moeten opvullen' tussen pixels die voorheen niet bestonden als de afbeeldingsgrootte zou worden vergroot.

We hebben onze originele afbeelding aan de linkerkant. De afbeelding is verkleind tot de helft van de oorspronkelijke grootte in het midden, maar afgezien daarvan is de 'kwaliteit' van de afbeelding niet verloren gegaan. Desalniettemin is de grootte van de afbeelding aan de rechterkant aanzienlijk verbeterd. Het lijkt nu 'opgeblazen' en 'korrelig'.

Zoals ik eerder al zei, wil je meestal de grootte van een afbeelding verkleinen in plaats van vergroten. Door de afbeeldingsgrootte te verkleinen, analyseren we minder pixels en hebben we te maken met minder 'ruis', waardoor algoritmen voor beeldverwerking sneller en nauwkeuriger worden.

Translatie en rotatie zijn de twee beeldtransformaties die tot nu toe aan bod zijn gekomen. We zullen nu onderzoeken hoe u het formaat van een afbeelding kunt wijzigen.

Het is niet verwonderlijk dat we het formaat van onze afbeeldingen zullen wijzigen met behulp van de cv2.resize-methode. Zoals ik eerder heb aangegeven, moeten we rekening houden met de beeldverhouding van de afbeelding bij het gebruik van deze methode. Maar voordat we te diep ingaan op de details, wil ik u een illustratie geven:

# python resize.py --image eekhoorn.jpg

# de vereiste pakketten importeren

importeren argparse

importeren cv2

# het object van argumentparser maken en het argument parseren

apObj = argparse. ArgumentParser ( )

apObj. add_argument ( '-k' , '--afbeelding' , vereist = WAAR , helpen = 'afbeelding pad' )

argumenten = van wie ( apObj. ontleed_args ( ) )

# laad de afbeelding en geef deze weer op het scherm

afbeelding = cv2. imlezen ( argumenten [ 'afbeelding' ] )

cv2. imshow ( 'Origineel' , afbeelding )

# Om te voorkomen dat het beeld er scheef uitziet, beeldverhouding

# moet worden beschouwd of vervormd; daarom zoeken we uit wat

# de verhouding van de nieuwe afbeelding tot de huidige afbeelding.

# Laten we de breedte van onze nieuwe afbeelding 160 pixels maken.

aspect = 160,0 / afbeelding. vorm geven aan [ 1 ]

dimensie = ( 160 , int ( afbeelding. vorm geven aan [ 0 ] *aspect ) )

# deze regel toont de daadwerkelijke bewerkingen voor het wijzigen van de grootte

verkleinde afbeelding = cv2. formaat wijzigen ( afbeelding , dimensie , interpolatie = cv2. INTER_GEBIED )

cv2. imshow ( 'Afbeeldingsbreedte aangepast' , verkleinde afbeelding )

# Wat als we de hoogte van de afbeelding willen veranderen? - de ... gebruiken

# hetzelfde principe, we kunnen de beeldverhouding berekenen op basis

# op hoogte in plaats van breedte. Laten we de schaal maken

# hoogte afbeelding 70 pixels.

aspect = 70,0 / afbeelding. vorm geven aan [ 0 ]

dimensie = ( int ( afbeelding. vorm geven aan [ 1 ] *aspect ) , 70 )

# voer de formaatwijziging uit

verkleinde afbeelding = cv2. formaat wijzigen ( afbeelding , dimensie , interpolatie = cv2. INTER_GEBIED )

cv2. imshow ( 'Verkleinde afbeeldingshoogte' , verkleinde afbeelding )

cv2. wachtSleutel ( 0 )

Regels 1-14 , Na het importeren van onze pakketten en het configureren van onze argument-parser, zullen we onze afbeelding laden en weergeven.

Regels 20 en 21: De relevante codering begint in deze regels . Bij het wijzigen van de grootte moet rekening worden gehouden met de beeldverhouding van de afbeelding. De verhouding tussen de breedte en hoogte van de afbeelding staat bekend als de beeldverhouding.

Hoogte breedte is de beeldverhouding.

Als we geen rekening houden met de beeldverhouding, zullen de resultaten van onze formaatwijziging vervormd raken.

Op Lijn 20 , is de berekening van de gewijzigde ratio voltooid. We geven de breedte van onze nieuwe afbeelding als 160 pixels in deze coderegel. We definiëren eenvoudigweg onze ratio (aspectratio) als de nieuwe breedte (160 pixels) gedeeld door de oude breedte, waartoe we toegang hebben met afbeelding, om de verhouding van de nieuwe hoogte tot de oude hoogte te berekenen. vorm[1].

De nieuwe afmetingen van de afbeelding op Lijn 21 kan worden berekend nu we onze ratio kennen. Nogmaals, de nieuwe afbeelding heeft een breedte van 160 pixels. Na het vermenigvuldigen van de oude hoogte met onze ratio en het resultaat om te zetten in een geheel getal, wordt de hoogte berekend. We kunnen de oorspronkelijke beeldverhouding van de afbeelding behouden door deze bewerking uit te voeren.

Lijn 24 is waar de afbeelding echt wordt aangepast. De afbeelding waarvan we het formaat willen wijzigen, is het eerste argument en de tweede zijn de afmetingen die we voor de nieuwe afbeelding hebben berekend. Onze interpolatiemethode, het algoritme voor het wijzigen van de grootte van de daadwerkelijke afbeelding, is de laatste parameter.

Eindelijk, op Lijn 25 , geven we onze geschaalde afbeelding weer.

We herdefiniëren onze ratio (aspectratio) op Lijn 31 . De hoogte van onze nieuwe afbeelding wordt 70 pixels. We delen 70 door de oorspronkelijke hoogte om de nieuwe verhouding hoogte/oorspronkelijke hoogte te krijgen.

Vervolgens stellen we de afmetingen van de nieuwe afbeelding vast. De nieuwe afbeelding krijgt een hoogte van 70 pixels, dat is al bekend. We kunnen de oorspronkelijke beeldverhouding van de afbeelding opnieuw behouden door de oude breedte te vermenigvuldigen met de verhouding om de nieuwe breedte te produceren.

De afbeelding wordt dan daadwerkelijk verkleind Lijn 35 , en het wordt weergegeven Lijn 36.

Hier kunnen we zien dat we de breedte en hoogte van onze originele afbeelding hebben verkleind met behoud van de beeldverhouding. Ons beeld zou vervormd lijken als de beeldverhouding niet behouden zou blijven.

Conclusie

In deze blog hebben we de verschillende basisconcepten voor beeldverwerking bestudeerd. We hebben beeldvertaling gezien met behulp van het OpenCV-pakket. We hebben de methoden gezien om het beeld omhoog, omlaag, naar rechts en naar links te verplaatsen. Deze methoden zijn erg handig wanneer we een dataset van vergelijkbare afbeeldingen maken om als trainingsdataset te geven, zodat de machine verschillende afbeeldingen ziet, zelfs als ze hetzelfde zijn. Dit artikel heeft je ook geleerd hoe je een afbeelding rond elk punt in de cartesische ruimte kunt roteren met behulp van een rotatiematrix. Toen ontdekte je hoe OpenCV afbeeldingen roteert met behulp van deze matrix en zag je een paar illustraties van draaiende afbeeldingen.

De twee fundamentele (maar significante) beeldrekenkundige bewerkingen van optellen en aftrekken werden in deze sectie onderzocht. Zoals u kunt zien, is het optellen en aftrekken van fundamentele matrices het enige wat beeldrekenkundige bewerkingen met zich meebrengen.

Daarnaast hebben we OpenCV en NumPy gebruikt om de eigenaardigheden van beeldrekenen te onderzoeken. Deze beperkingen moeten in gedachten worden gehouden, anders loopt u het risico onverwachte resultaten te krijgen bij het uitvoeren van rekenkundige bewerkingen op uw afbeeldingen.

Het is belangrijk om te onthouden dat hoewel NumPy een modulusbewerking uitvoert en 'omwikkelt', OpenCV optellen en aftrekken waarden buiten het bereik [0, 255] snijdt om binnen het bereik te passen. Wanneer u uw eigen computervisie-applicaties ontwikkelt, kunt u dit onthouden om te voorkomen dat u op lastige bugs gaat jagen.

Het omdraaien van afbeeldingen is ongetwijfeld een van de eenvoudigere ideeën die we in deze cursus zullen onderzoeken. Flipping wordt vaak gebruikt bij machine learning om meer voorbeelden van trainingsgegevens te genereren, wat resulteert in krachtigere en betrouwbaardere beeldclassificaties.

We hebben ook geleerd hoe we OpenCV kunnen gebruiken om het formaat van een afbeelding te wijzigen. Het is cruciaal om rekening te houden met zowel de interpolatiemethode die u gebruikt als de beeldverhouding van uw originele afbeelding bij het wijzigen van de grootte, zodat het resultaat niet vervormd lijkt.

Ten slotte is het cruciaal om te onthouden dat als de beeldkwaliteit een probleem is, het altijd het beste is om over te schakelen van een grotere naar een kleinere afbeelding. In de meeste gevallen leidt het vergroten van een afbeelding tot artefacten en verslechtert de kwaliteit ervan.