Computer Vision Tutorial 2: Basisprincipes van Beeldvorming

Deze tutorial is de basis van computerzicht die wordt geleverd als “Les 2” van de serie; er zullen meer lessen volgen die gaan over het bouwen van uw eigen deep learning-gebaseerde computerzichtprojecten. U kunt de volledige syllabus en inhoudsopgave hiervinden.

De belangrijkste leerpunten uit dit artikel:

  • Het laden van een afbeelding van de schijf.
  • Het verkrijgen van de ‘hoogte’, ‘breedte’ en ‘diepte’ van de afbeelding.
  • Het vinden van de R, G en B-componenten van de afbeelding.
  • Tekenen met behulp van OpenCV.

Het laden van een afbeelding van de schijf

Voordat we enige operaties of manipulaties uitvoeren op een afbeelding, is het belangrijk dat we een afbeelding van ons keuze op de schijf laden. We zullen deze activiteit uitvoeren met behulp van OpenCV. Er zijn twee manieren waarop we deze laadoperatie kunnen uitvoeren. Een manier is om de afbeelding te laden door simpelweg het afbeeldingspad en het afbeeldingsbestand door te geven aan de “imread” functie van OpenCV. De andere manier is om de afbeelding door te geven aan een command line argument met behulp van de python module argparse.

Fig 2.1 Loading an Image from Disk by hard coding the image path and name in code.

Python

 

#Het laden van een afbeelding van de schijf

import cv2
image = cv2.imread(“C:/Sample_program/example.jpg”)
cv2.imshow(‘Image’, image)
cv2.waitKey(0)

Laten we een bestandsnaam Loading_image_from_disk.py maken in Notepad++. Eerst importeren we onze OpenCV-bibliotheek, die onze beeldverwerkingsfuncties bevat. We importeren de bibliotheek met de eerste regel code als cv2. De tweede regel code is waar we ons beeld lezen met de cv2.imread-functie in OpenCV, en we geven het pad van het beeld als parameter door; het pad moet ook de bestandsnaam bevatten met de afbeeldingsformaatextensie .jpg, .jpeg, .png of .tiff.

syntax// image=cv2.imread(“pad/naar/uw/afbeelding.jpg”) //

Zorgvuldigheid moet worden betracht bij het specificeren van de bestandsextensienaam. We krijgen waarschijnlijk de onderstaande fout als we de verkeerde extensienaam opgeven.

Python

 

ERROR :

c:\Sample_program>python Loading_image_from_disk.py
Traceback (most recent call last):
File “Loading_image_from_disk.py”, line 4, in <module>
cv2.imshow(‘Image’, image)
cv2.error: OpenCV(4.3.0) C:\projects\opencv-python\opencv\modules\highgui\src\window.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in function ‘cv::imshow’

De derde regel code is waar we ons geladen beeld daadwerkelijk weergeven. De eerste parameter is een string, of de “naam” van onze venster. De tweede parameter is het object waarnaar het beeld is geladen.

Tenslotte pauzeert een oproep naar cv2.waitKey de uitvoering van het script totdat we een toets op ons toetsenbord indrukken. Een parameter van “0” geeft aan dat elke toetsaanslag de uitvoering ongedaan zal maken. Voel je vrij om je programma uit te voeren zonder de laatste regel code in je programma te hebben om het verschil te zien.

Fig 2.2 Loading an Image using Argparse module.

Python

 

#Laden van afbeelding van schijf met behulp van Argparse

import cv2
import argparse

apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())

image = cv2.imread(args[“image”])
cv2.imshow(‘Image’, image)
cv2.waitKey(0)

Het kennen van het lezen van een afbeelding of bestand met behulp van een command line argument (argparse) is een absoluut noodzakelijke vaardigheid.

De eerste twee regels code zijn om noodzakelijke bibliotheken te importeren; hier importeren we OpenCV en Argparse. We zullen dit gedurende de cursus blijven herhalen.

De volgende drie regels code verwerken het parseren van de command line argumenten. Het enige argument dat we nodig hebben is — image: het pad naar ons beeld op de schijf. Tot slot parseren we de argumenten en slaan ze op in een dictionary genaamd args.

Laten we even pauzeren en snel bespreken wat precies de — image switch is. De — image “switch” (“switch” is een synoniem voor “command line argument” en de termen kunnen inwisselbaar worden gebruikt) is een string die we op de command line opgeven. Deze switch vertelt ons Loading_image_from_disk.py script waar het beeld dat we willen laden zich op de schijf bevindt.

De laatste drie regels code zijn eerder besproken; de cv2.imread functie neemt args[“image’] als parameter, wat niets anders is dan het beeld dat we in de commandoprompt opgeven. cv2.imshow toont het beeld, dat al is opgeslagen in een beeltobject uit de vorige regel. De laatste regel pauzeert de uitvoering van het script totdat we een toets op ons toetsenbord indrukken.

Een van de grote voordelen van het gebruik van een argparse — command line argument is dat we beelden uit verschillende maplocaties kunnen laden zonder het beeldpad in ons programma te hoeven wijzigen door dynamisch het beeldpad door te geven Ex — “C:\CV_Material\image\sample.jpg” in de commandoprompt als argument terwijl we on咱 python programma uitvoeren.

Fig 2.3 Loading Images from different folder locations using Argparse.

c:\Sample_program>python Loading_image_from_disk.py — image C:\CV_Material\session1.JPG

Hier voeren we het Loading_image_from_disk.py python-bestand uit vanaf de c:\sample_program locatie door de “-image” parameter mee te geven samen met het pad van het beeld C:\CV_Material\session1.JPG.

Het verkrijgen van de ‘Hoogte’, ‘Breedte’ en ‘Diepte’ van het Beeld

Aangezien afbeeldingen worden weergegeven als NumPy-arrays, kunnen we eenvoudig de .shape-eigenschap gebruiken om de breedte, hoogte en het aantal kanalen te onderzoeken.

Door de .shape-eigenschap op het net geladen afbeeldingobject te gebruiken, kunnen we de hoogte, breedte en diepte van de afbeelding vinden. Zoals besproken in de vorige les — 1, kan de hoogte en breedte van de afbeelding worden gecontroleerd door de afbeelding te openen in MS Paint. Raadpleeg de vorige les. We zullen het hebben over de diepte van de afbeelding in de komende lessen. Diepte wordt ook wel het kanaal van een afbeelding genoemd. Kleurenafbeeldingen hebben meestal 3 kanalen vanwege de RGB-samenstelling in de pixels en grijswaardenafbeeldingen hebben 1 kanaal. Dit hebben we besproken in de vorige Les-1.

Fig 2.4 Prints the Height, Width, and Depth of the Image.

Python

 

#Hoogte, breedte en diepte van een afbeelding verkrijgen

import cv2
import argparse

apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())

# Enige verschil met de vorige codes — shape-eigenschap toegepast op afbeeldingobject

print(f’(Height,Width,Depth) of the image is: {image.shape}’)

image = cv2.imread(args[“image”])
cv2.imshow(‘Image’, image)
cv2.waitKey(0)

Uitvoer:

(Hoogte, Breedte, Diepte) van de afbeelding is: (538, 723, 3)

Het enige verschil met de vorige codes is de printopdracht die de shape-eigenschap toepast op het geladen afbeeldingobject. f’ is de F-string @ opgemaakte string die variabelen dynamisch aanneemt en afdrukt.

f’ write anything here that you want to see in the print statement: {variables, variables, object, object.attribute,}’

Hier hebben we {object.attribute} gebruikt tussen de bloemkens voor het .shape attribuut om de hoogte, breedte en diepte van het afbeeldingsobject te berekenen.

Python

 

#Obtener Hoogte,Breedte en Diepte afzonderlijk

import cv2
import argparse

apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())

image = cv2.imread(args[“image”])

# NumPy array slicing om de hoogte, breedte en diepte afzonderlijk te verkrijgen

print(“height: %d pixels” % (image.shape[0]))
print(“width: %d pixels” % (image.shape[1]))
print(“depth: %d” % (image.shape[2]))

cv2.imshow(‘Image’, image)
cv2.waitKey(0)

Uitvoer:

breedte: 723 pixels
hoogte: 538 pixels
diepte: 3

Hier, in plaats van de (hoogte, breedte en diepte) samen als een tuple te verkrijgen. We voeren array slicing uit en verkrijgen de hoogte, breedte en diepte van de afbeelding individueel. Het 0e index van de array bevat de hoogte van de afbeelding, het 1e index bevat de breedte van de afbeelding en het 2e index bevat de diepte van de afbeelding.

Vinden van R, G en B Componenten van de Afbeelding

Fig 2.5 BGR value printed after taking the pixel co-ordinate position (y,x).

Uitvoer:

De Blauw Groen Rood componentwaarde van de afbeelding op positie (321, 308) is: (238, 242, 253)

Let op hoe de y-waarde wordt doorgegeven vóór de x-waarde — deze syntaxis kan aanvankelijk tegenintuïtief aanvoelen, maar het is consistent met hoe we waarden in een matrix benaderen: eerst specificeren we het rijnummer, dan het kolomnummer. Vanaf daar krijgen we een tuple die de Blauw, Groen en Rood componenten van de afbeelding vertegenwoordigt.

We kunnen ook de kleur van een pixel op een bepaalde positie wijzigen door de operatie om te keren.

Python

 

#Vinden R,B,G van de Afbeelding op (x,y) positie

import cv2
import argparse

apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())

image = cv2.imread(args[“image”])

# Ontvang de pixel coördinaatwaarde als [y,x] van de gebruiker, voor welke de RGB-waarden moeten worden berekend
[y,x] = list(int(x.strip()) for x in input().split(‘,’))

# Extraheer de (Blauw,groen,rood) waarden van de ontvangen pixel coördinaat
(b,g,r) = image[y,x]
print(f’The Blue Green Red component value of the image at position {(y,x)} is: {(b,g,r)}’)

cv2.imshow(‘Image’, image)
cv2.waitKey(0)

(b,g,r) = image[y,x] to image[y,x] = (b,g,r)

Hier koppelen we de kleur in (BGR) aan het beeldpixelcoördinaat. Laten we proberen door de kleur ROOD toe te wijzen aan het pixel op positie (321,308) en dit te valideren door de BGR-kleur van de gegeven positie af te drukken.

Python

 

#Omgekeerd verkeer om RGB-waarde toe te wijzen aan de pixel van onze keuze

import cv2
import argparse

apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())

image = cv2.imread(args[“image”])

# Ontvang de pixelcoördinaatwaarde als [y,x] van de gebruiker, waarvoor de RGB-waarden berekend moeten worden
[y,x] = list(int(x.strip()) for x in input().split(‘,’))

# Haal de (Blauw, groen, rood) waarden van de ontvangen pixelcoördinaat op
image[y,x] = (0,0,255)
(b,g,r) = image[y,x]
print(f’The Blue Green Red component value of the image at position {(y,x)} is: {(b,g,r)}’)

cv2.imshow(‘Image’, image)
cv2.waitKey(0)

Uitvoer:

De Blauw, Groen en Rood componentwaarden van het beeld op positie (321, 308) zijn (0, 0, 255)

In bovenstaande code ontvangen we de pixelcoördinaat via de opdrachtprompt door de waarde in te voeren zoals weergegeven in onderstaande Figuur 2.6 en wijzen we de pixelcoördinaat de kleur ROOD toe door (0,0,255) te geven, d.w.z. (Blauw, Groen, Rood), en valideren we dit door de ingevoerde pixelcoördinaat af te drukken.

Tekenen met OpenCV

Laten we leren hoe we verschillende vormen kunnen tekenen, zoals rechthoeken, vierkanten en cirkels, met OpenCV door cirkels te tekenen om mijn ogen te maskeren, rechthoeken om mijn lippen te maskeren en rechthoeken om de manta-ray vis naast me te maskeren.

De uitvoer zou er zo uit moeten zien:

Fig 2.6 Masked Photo of me with the mantra-ray fish.

Deze foto is gemaskeerd met vormen met behulp van MS Paint; we zullen proberen hetzelfde te doen met OpenCV door cirkels rond mijn ogen te tekenen en rechthoeken om mijn lippen en de matra-ray vis naast me te maskeren.

We gebruiken de methode cv2.rectangle om een rechthoek te tekenen en de methode cv2.circle om een cirkel te tekenen in OpenCV.

cv2.rectangle(image, (x1, y1), (x2, y2), (Blauw, Groen, Rood), Dikte)

De cv2.rectangle methode neemt een afbeelding als zijn eerste argument waarop we onze rechthoek willen tekenen. We willen op de geladen afbeelding object tekenen, dus we geven het aan de methode door. Het tweede argument is de beginstart (x1, y1) positie van onze rechthoek — hier beginnen we onze rechthoek bij punten (156 en 340). Vervolgens moeten we een eind (x2, y2) punt voor de rechthoek opgeven. We besluiten onze rechthoek te eindigen bij (360, 450). Het volgende argument is de kleur van de rechthoek die we willen tekenen; hier geven we in dit geval de zwarte kleur in BGR formaat door, d.w.z.,(0,0,0). Tot slot geeft het laatste argument dat we doorgeven de dikte van de lijn. We geven -1 om vaste vormen te tekenen, zoals weergegeven in Figuur 2.6.

Evenzo gebruiken we de cv2.circle methode om de cirkel te tekenen.

cv2.circle(image, (x, y), r, (Blauw, Groen, Rood), Dikte)

De cv2.circle methode neemt een afbeelding als zijn eerste argument waarop we onze rechthoek willen tekenen. We willen op het afbeelding object dat we hebben geladen tekenen, dus we geven het aan de methode door. Het tweede argument is het middelpunt (x, y) positie van onze cirkel — hier hebben we onze cirkel genomen bij punt (343, 243). Het volgende argument is de straal van de cirkel die we willen tekenen. Het volgende argument is de kleur van de cirkel; hier geven we in dit geval de Rood kleur in BGR formaat door, d.w.z.,(0,0,255). Tot slot geeft het laatste argument dat we doorgeven de dikte van de lijn. We geven -1 om vaste vormen te tekenen, zoals weergegeven in Figuur 2.6.

Ok ! Door al deze informatie te kennen. Laten we proberen te bereiken wat we zijn begonnen. Om de vormen in de afbeelding te tekenen, moeten we de begintijd en eindtijd (x,y) coördinaten van het maskeringsgebied identificeren om deze door te geven aan de desbetreffende methode.

Hoe?

We zullen nogmaals de hulp van MS Paint inroepen. Door de cursor over een van de coördinaten (linksboven) of (rechtsonder) van het te maskeren gebied te plaatsen, worden de coördinaten weergegeven in het gemarkeerde gedeelte van MS Paint zoals weergegeven in Figuur 2.7.

Fig 2.7 MSPaint to find the co-ordinates of the masking region.

Op dezelfde manier nemen we alle coördinaten (x1,y1) (x2,y2) voor alle maskeringsgebieden zoals weergegeven in Figuur 2.8.

Fig 2.8 (x.y) Co-ordinates of masking regions.

Python

 

#Tekenen met OpenCV om ogen, mond en objecten in de buurt te maskeren

import cv2
import argparse

apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())

image = cv2.imread(args[“image”])

cv2.rectangle(image, (415, 168), (471, 191), (0, 0, 255), -1)
cv2.circle(image, (425, 150), 15, (0, 0, 255), -1)
cv2.circle(image, (457, 154), 15, (0, 0, 255), -1)
cv2.rectangle(image, (156, 340), (360, 450), (0, 0, 0), -1)

#toon de uitvoer afbeelding
cv2.imshow(“Output drawing “, image)
cv2.waitKey(0)

Resultaat:



Fig 2.9 Desired Output.

Source:
https://dzone.com/articles/computer-vision-tutorial-2-image-basics