Elaborazione delle immagini OpenCV

Elaborazione Delle Immagini Opencv



In questo articolo studieremo i metodi di elaborazione delle immagini. Esamineremo alcuni argomenti fondamentali ma critici nella visione artificiale e nell'apprendimento automatico. Queste fondamentali tecniche di elaborazione delle immagini possono risolvere problemi complessi, come i set di dati. Di conseguenza, ci sono sei passaggi fondamentali nell'elaborazione delle immagini, che sono elencati di seguito:
  1. Traduzione di immagini
  2. Rotazione dell'immagine
  3. Aritmetica delle immagini
  4. Capovolgimento dell'immagine
  5. Ritaglio immagine
  6. Ridimensionamento delle immagini

Ora, spiegheremo in dettaglio tutti gli argomenti sopra menzionati sull'elaborazione delle immagini.

1. Traduzione di immagini

La traduzione delle immagini è un metodo di elaborazione delle immagini che ci aiuta a spostare l'immagine lungo gli assi x e y. Possiamo spostare l'immagine in alto, in basso, a destra, a sinistra o qualsiasi combinazione.







Possiamo definire la matrice di traduzione con il simbolo M, e possiamo rappresentarla in forma matematica, come mostrato di seguito:





Possiamo capire il concetto dell'immagine di traduzione attraverso questo programma.





Codice Python: Manterremo il seguente nome del programma come tradurre.py .

# importa i pacchetti richiesti

importare intorpidito come per esempio.

importare argparse

importare imutil

importare cv2

# implementiamo il parser di argomenti

ap_obj = argparse. ArgomentoParser ( )

ap_obj. add_argument ( '-K' , '--Immagine' , necessario = Vero ,

aiuto = 'posizione del file immagine' )

arg = il cui, di chi ( ap_obj. parse_args ( ) )

# carica l'immagine e mostrala sullo schermo

Immagine = cv2. imread ( arg [ 'Immagine' ] )

cv2. imshow ( 'Immagine originale' , Immagine )

# La traslazione dell'immagine è una matrice NumPy che è riportata di seguito:

# [[1, 0, maiuscX], [0, 1, maiuscY]]

# Utilizzeremo la matrice NumPy sopra per spostare le immagini lungo il file

# direzioni dell'asse x e dell'asse y. Per questo, dobbiamo semplicemente passare i valori dei pixel.

# In questo programma sposteremo l'immagine di 30 pixel verso destra

# e 70 pixel verso il basso.

traduzione_mat = per esempio. galleggiante32 ( [ [ 1 , 0 , 30 ] , [ 0 , 1 , 70 ] ] )

immagine_traduzione = cv2. warpAffine ( Immagine , traduzione_mat ,

( Immagine. forma [ 1 ] , Immagine. forma [ 0 ] ) )

cv2. imshow ( 'Traduzione delle immagini in basso ea destra' , immagine_traduzione )

# ora useremo la matrice NumPy sopra per spostare le immagini lungo il

# direzioni dell'asse x (sinistra) e dell'asse y (su).

# Qui sposteremo le immagini di 50 pixel a sinistra

# e 90 pixel verso l'alto.

traduzione_mat = per esempio. galleggiante32 ( [ [ 1 , 0 , - cinquanta ] , [ 0 , 1 , - 90 ] ] )

immagine_traduzione = cv2. warpAffine ( Immagine , traduzione_mat ,

( Immagine. forma [ 1 ] , Immagine. forma [ 0 ] ) )

cv2. imshow ( 'Traduzione delle immagini in alto e a sinistra' , immagine_traduzione )

cv2. waitKey ( 0 )

Righe da 1 a 5: Stiamo importando tutti i pacchetti richiesti per questo programma, come OpenCV, argparser e NumPy. Si prega di notare che esiste un'altra libreria che è imutils. Questo non è un pacchetto di OpenCV. Questa è solo una libreria che mostrerà facilmente la stessa elaborazione delle immagini.



La libreria imutils non verrà inclusa automaticamente quando installiamo OpenCV. Quindi per installare gli imutils, dobbiamo usare il seguente metodo:

pip installa imutils

Righe da 8 a 15: Abbiamo creato il nostro agrparser e caricato la nostra immagine.

Righe da 24 a 25: Questa sezione del programma è dove avviene la traduzione. La matrice di traduzione ci dice di quanti pixel l'immagine verrà spostata in alto o in basso oa sinistra oa destra. Poiché OpenCV richiede che il valore della matrice sia in una matrice a virgola mobile, la matrice di traduzione accetta valori in matrici a virgola mobile.

La prima riga della matrice di traduzione ha questo aspetto:

Questa riga della matrice è per l'asse x. Il valore di t X deciderà se l'immagine verrà spostata a sinistra oa destra. Se passiamo un valore negativo, significa che l'immagine verrà spostata sul lato sinistro e se il valore è positivo, significa che l'immagine verrà spostata sul lato destro.

Definiremo ora la seconda riga della matrice come segue:

Questa riga della matrice è per l'asse y. Il valore di t Y deciderà se l'immagine verrà spostata verso l'alto o verso il basso. Se passiamo un valore negativo, significa che l'immagine verrà spostata verso l'alto, e se il valore è positivo, significa che l'immagine verrà spostata verso il basso.

Nel programma precedente alla riga 24, definiamo il t X = 30 e la t Y = 70. Quindi spostiamo l'immagine di 30 pixel verso il lato destro e di 70 pixel verso il basso.

Ma il principale processo di traduzione dell'immagine avviene alla riga 25, dove definiamo la matrice di traduzione cv2.warpAffine . In questa funzione, stiamo passando tre parametri: il primo parametro è l'immagine, il secondo parametro è la matrice di traduzione e il terzo parametro è la dimensione dell'immagine.

Riga 27: La riga 27 visualizzerà il risultato nell'output.

Ora implementeremo un'altra matrice di traduzione per sinistra e rialzo. Per questo, dobbiamo definire i valori in negativo.

Riga da 33 a 34: Nel programma precedente alla riga 33, definiamo il t X = -50 e il t Y = -90. Quindi spostiamo l'immagine di 50 pixel verso il lato sinistro e di 90 pixel verso l'alto. Ma il principale processo di traduzione dell'immagine avviene alla riga 34, dove definiamo la matrice di traduzione cv2.warpAffine .

Riga 36 : La riga 36 visualizzerà il risultato come mostrato nell'output.

Per eseguire il codice precedente, dobbiamo fornire il percorso dell'immagine come indicato di seguito.

Produzione: python translate.py –image squirrel.jpg

Ora implementeremo lo stesso programma di traduzione di immagini utilizzando il file imutil biblioteca. Questa libreria è molto facile da usare per l'elaborazione delle immagini. In questa biblioteca, non dobbiamo pensare al cv2.warpAffine perché questa biblioteca si occuperà di questo. Quindi implementiamo questo programma di traduzione di immagini utilizzando la libreria imutils.

Codice Python: Manterremo il seguente nome del programma come translate_imutils.py .

# importa i pacchetti necessari

importare intorpidito come per esempio.

importare argparse

importare imutil

importare cv2

# Questa funzione implementa la traduzione dell'immagine e

# restituisce l'immagine tradotta alla funzione chiamante.

def tradurre ( Immagine , X , Y ) :

traduzione_matrice = per esempio. galleggiante32 ( [ [ 1 , 0 , X ] , [ 0 , 1 , Y ] ] )

immagine_traduzione = cv2. warpAffine ( Immagine , traduzione_matrice ,

( Immagine. forma [ 1 ] , Immagine. forma [ 0 ] ) )

Restituzione immagine_traduzione

# costruisce il parser di argomenti e analizza gli argomenti

ap = argparse. ArgomentoParser ( )

ap. add_argument ( '-io' , '--Immagine' , necessario = Vero , aiuto = 'Percorso verso l'immagine' )

arg = il cui, di chi ( ap. parse_args ( ) )

# caricare l'immagine e visualizzarla sullo schermo

Immagine = cv2. imread ( arg [ 'Immagine' ] )

cv2. imshow ( 'Immagine originale' , Immagine )

immagine_traduzione = imutil. tradurre ( Immagine , 10 , 70 )

cv2. imshow ( 'Traduzione dell'immagine a destra e in basso' ,

immagine_traduzione )

cv2. waitKey ( 0 )

Righe da 9 a 13: Questa sezione del programma è dove avviene la traduzione. La matrice di traduzione ci informa di quanti pixel l'immagine verrà spostata in alto o in basso oa sinistra oa destra.

Queste righe sono già state spiegate, ma ora creeremo una funzione chiamata translate() e invieremo tre parametri distinti. L'immagine stessa funge da primo parametro. I valori x e y della matrice di traduzione corrispondono al secondo e al terzo parametro.

Nota : Non è necessario definire questa funzione translate all'interno del programma perché è già inclusa nel pacchetto della libreria imutils. L'ho usato all'interno del programma per motivi di spiegazione semplice. Possiamo chiamare questa funzione direttamente con imutils, come mostrato nella riga 24.

Riga 24: Il programma precedente mostrerà che alla riga 24 definiamo tx = 10 e ty = 70. Quindi stiamo spostando l'immagine di 10 pixel verso il lato destro e di 70 pixel verso il basso.

In questo programma, non ci interessa alcuna funzione cv2.warpAffine perché sono già all'interno del pacchetto della libreria imutils.

Per eseguire il codice precedente, dobbiamo fornire il percorso dell'immagine, come indicato di seguito:

Produzione:

python imutils. py --image scoiattolo. jpg

2. Rotazione dell'immagine

Abbiamo spiegato come tradurre (cioè spostare) un'immagine in alto, in basso, a sinistra ea destra nella lezione precedente (o qualsiasi combinazione). Successivamente, discuteremo della rotazione in relazione all'elaborazione delle immagini.

Un'immagine viene ruotata di un angolo, theta, in un processo noto come rotazione. L'angolo di cui stiamo ruotando l'immagine sarà rappresentato da theta. Inoltre, in seguito fornirò la funzione di praticità della rotazione per semplificare la rotazione delle immagini.

Simile alla traslazione, e forse non sorprendentemente, alla rotazione di un angolo, theta è determinato costruendo una matrice M nel seguente formato:

Questa matrice può ruotare di un vettore theta gradi (in senso antiorario) attorno all'origine data (x, y)-piano cartesiano. Normalmente, in questo scenario, l'origine sarebbe il centro dell'immagine, ma in realtà potremmo designare qualsiasi punto casuale (x, y) come nostro centro di rotazione.

L'immagine ruotata R viene quindi creata dall'immagine originale I utilizzando una semplice moltiplicazione di matrici: R = IM

OpenCV, d'altra parte, offre inoltre la capacità di (1) ridimensionare (ovvero ridimensionare) un'immagine e (2) offrire un centro di rotazione arbitrario per eseguire la rotazione.

La nostra matrice di rotazione modificata M è mostrata di seguito:

Iniziamo aprendo e generando un nuovo file chiamato ruotare.py :

# importazione dei pacchetti richiesti

importare intorpidito come per esempio.

importare argparse

importare imutil

importare cv2

# creando l'oggetto argumentparser e analizzando l'argomento

apobj = argparse. ArgomentoParser ( )

apobj. add_argument ( '-K' , '--Immagine' , necessario = Vero , aiuto = 'percorso immagine' )

argomenti = il cui, di chi ( apobj. parse_args ( ) )

Immagine = cv2. imread ( argomenti [ 'Immagine' ] )

cv2. imshow ( 'Immagine originale' , Immagine )

# Calcola il centro dell'immagine usando le dimensioni dell'immagine.

( altezza , larghezza ) = Immagine. forma [ : 2 ]

( centerX , centroY ) = ( larghezza / 2 , altezza / 2 )

# Ora, usando cv2, ruoteremo l'immagine di 55 gradi a

# determina la matrice di rotazione usando getRotationMatrix2D()

rotazioneMatrice = cv2. getMatriceRotazione2D ( ( centerX , centroY ) , 55 , 1.0 )

immagine ruotata = cv2. warpAffine ( Immagine , rotazioneMatrice , ( larghezza , altezza ) )

cv2. imshow ( 'L'immagine è stata ruotata di 55 gradi' , immagine ruotata )

cv2. waitKey ( 0 )

# L'immagine verrà ora ruotata di -85 gradi.

rotazioneMatrice = cv2. getMatriceRotazione2D ( ( centerX , centroY ) , - 85 , 1.0 )

immagine ruotata = cv2. warpAffine ( Immagine , rotazioneMatrice , ( larghezza , altezza ) )

cv2. imshow ( 'L'immagine è stata ruotata di -85 gradi' , immagine ruotata )

cv2. waitKey ( 0 )

Righe da 1 a 5: Stiamo importando tutti i pacchetti richiesti per questo programma, come OpenCV, argparser e NumPy. Si prega di notare che esiste un'altra libreria che è imutils. Questo non è un pacchetto di OpenCV. Questa è solo una libreria che verrà utilizzata per mostrare facilmente la stessa elaborazione delle immagini.

La libreria imutils non verrà inclusa automaticamente quando installiamo OpenCV. OpenCV installa imutils. Dobbiamo utilizzare il seguente metodo:

pip installa imutils

Righe da 8 a 14: Abbiamo creato il nostro agrparser e caricato la nostra immagine. In questo argparser, usiamo un solo argomento image, che ci dirà il percorso dell'immagine che useremo in questo programma per dimostrare la rotazione.

Quando ruotiamo un'immagine, dobbiamo definire il punto di rotazione della rotazione. La maggior parte delle volte, vorrai ruotare un'immagine attorno al suo centro, ma OpenCV ti consente invece di scegliere qualsiasi punto casuale. Ruotiamo semplicemente l'immagine attorno al suo centro.

Linee da 17 a 18 prendi rispettivamente la larghezza e l'altezza dell'immagine, quindi dividi ciascuna dimensione per due per stabilire il centro dell'immagine.

Costruiamo una matrice per ruotare un'immagine nello stesso modo in cui abbiamo definito una matrice per tradurre un'immagine. Chiameremo semplicemente il cv2.getRotationMatrix2D funzione sulla riga 22 piuttosto che creare manualmente la matrice utilizzando NumPy (che potrebbe essere un po' macchinoso).

Il cv2.getRotationMatrix2D funzione richiede tre parametri. Il primo input è l'angolo di rotazione desiderato (in questo caso, il centro dell'immagine). Theta viene quindi utilizzato per specificare di quanti gradi (in senso antiorario) ruoteremo l'immagine. Qui ruoteremo l'immagine di 45 gradi. L'ultima opzione è correlata alla dimensione dell'immagine.

Indipendentemente dal fatto che non abbiamo ancora discusso del ridimensionamento di un'immagine, qui puoi fornire un numero in virgola mobile con 1.0 che denota che l'immagine deve essere utilizzata nelle sue proporzioni originali. Tuttavia, se digitassi un valore di 2.0, le dimensioni dell'immagine raddoppierebbero. Un numero di 0,5 riduce le dimensioni dell'immagine in questo modo.

Riga da 22 a 23: Dopo aver ricevuto la nostra matrice di rotazione M dal file cv2.getRotationMatrix2D funzione, ruotiamo la nostra immagine usando il cv2.warpAffine tecnica sulla riga 23. Il primo input della funzione è l'immagine che vogliamo ruotare. La larghezza e l'altezza della nostra immagine di output vengono quindi definite, insieme alla nostra matrice di rotazione M. Sulla riga 23, l'immagine viene quindi ruotata di 55 gradi.

Puoi notare che la nostra immagine è stata ruotata.

Linee da 28 a 30 costituiscono la seconda rotazione. Le righe 22-23 del codice sono identiche, tranne per il fatto che questa volta ruotiamo di -85 gradi anziché 55.

Abbiamo semplicemente ruotato un'immagine attorno al suo centro fino a questo punto. E se volessimo ruotare l'immagine attorno a un punto casuale?

Iniziamo aprendo e generando un nuovo file chiamato ruota.py:

# importazione dei pacchetti richiesti

importare intorpidito come per esempio.

importare argparse

importare imutil

importare cv2

# creando l'oggetto argumentparser e analizzando l'argomento

ap_obj = argparse. ArgomentoParser ( )

ap_obj. add_argument ( '-K' , '--Immagine' , necessario = Vero , aiuto = 'percorso immagine' )

discussione = il cui, di chi ( ap_obj. parse_args ( ) )

# caricare l'immagine e visualizzarla sullo schermo

Immagine = cv2. imread ( discussione [ 'Immagine' ] )

cv2. imshow ( 'Immagine originale' , Immagine )

# Calcola il centro dell'immagine usando le dimensioni dell'immagine.

( altezza , larghezza ) = Immagine. forma [ : 2 ]

( centerX , centroY ) = ( larghezza / 2 , altezza / 2 )

# Ora, usando cv2, ruoteremo l'immagine di 55 gradi a

# determina la matrice di rotazione usando getRotationMatrix2D()

rotazioneMatrice = cv2. getMatriceRotazione2D ( ( centerX , centroY ) , 55 , 1.0 )

immagine ruotata = cv2. warpAffine ( Immagine , rotazioneMatrice , ( larghezza , altezza ) )

cv2. imshow ( 'L'immagine è stata ruotata di 55 gradi' , immagine ruotata )

cv2. waitKey ( 0 )

# L'immagine verrà ora ruotata di -85 gradi.

rotazioneMatrice = cv2. getMatriceRotazione2D ( ( centerX , centroY ) , - 85 , 1.0 )

immagine ruotata = cv2. warpAffine ( Immagine , rotazioneMatrice , ( larghezza , altezza ) )

cv2. imshow ( 'L'immagine è stata ruotata di -85 gradi' , immagine ruotata )

cv2. waitKey ( 0 )

# rotazione dell'immagine da un punto arbitrario, non dal centro

rotazioneMatrice = cv2. getMatriceRotazione2D ( ( centroX - 40 , centroY - 40 ) , 55 , 1.0 )

immagine ruotata = cv2. warpAffine ( Immagine , rotazioneMatrice , ( larghezza , altezza ) )

cv2. imshow ( 'Rotazione dell'immagine da punti arbitrari' , immagine ruotata )

cv2. waitKey ( 0 )

Riga da 34 a 35: Ora, questo codice dovrebbe sembrare abbastanza comune per ruotare un oggetto. Per ruotare l'immagine attorno a un punto 40 pixel a sinistra e 40 pixel sopra il suo centro, istruiamo il cv2.getRotationMatrix2D funzione per prestare attenzione al suo primo parametro.

L'immagine prodotta quando applichiamo questa rotazione è mostrata di seguito:

Possiamo vedere chiaramente che il centro della rotazione è ora la coordinata (x, y), che è 40 pixel a sinistra e 40 pixel sopra il centro calcolato dell'immagine.

3. Aritmetica delle immagini

In effetti, l'aritmetica delle immagini è solo un'addizione di matrici con alcune restrizioni aggiuntive sui tipi di dati che tratteremo in seguito.

Prendiamoci un momento per esaminare alcuni bei fondamenti dell'algebra lineare.

Prova a combinare le due matrici successive:

Quale risultato produrrebbe l'addizione matriciale? La semplice risposta è la somma delle voci della matrice, elemento per elemento:

Abbastanza semplice, vero?

Comprendiamo tutti le operazioni fondamentali di addizione e sottrazione in questo momento. Tuttavia, dobbiamo essere consapevoli delle restrizioni imposte dal nostro spazio colore e dal tipo di dati mentre lavoriamo con le immagini.

I pixel nelle immagini RGB, ad esempio, sono compresi tra [0, 255]. Cosa succede se proviamo ad aggiungere 10 a un pixel con un'intensità di 250 mentre lo guardiamo?

Arriveremmo a un valore di 260 se applicassimo i principi aritmetici standard. 260 non è un valore valido, poiché le immagini RGB sono rappresentate come interi senza segno a 8 bit.

Quindi cosa dovrebbe accadere? Dovremmo eseguire un controllo per garantire che nessun pixel sia oltre l'intervallo di [0, 255], ritagliando ogni pixel per avere un valore compreso tra 0 e 255?

Oppure ci 'avvolgiamo' ed eseguiamo un'operazione di modulo? In conformità con le regole del modulo, l'aggiunta di 10 a 255 risulterebbe solo in un valore di 9.

Come dovrebbero essere gestite le addizioni e le sottrazioni alle immagini oltre l'intervallo di [0, 255]?

La verità è che non esiste una tecnica giusta o sbagliata; tutto dipende da come stai lavorando con i tuoi pixel e da cosa speri di ottenere.

Ma ricorda che ci sono differenze tra l'aggiunta in OpenCV e l'aggiunta in NumPy. L'aritmetica del modulo e il 'wrap around' saranno eseguiti da NumPy. Al contrario, OpenCV eseguirà il ritaglio e si assicurerà che i valori dei pixel non lascino mai l'intervallo [0, 255].

Iniziamo creando un nuovo file chiamato aritmetica.py e aprendolo:

# python arithmetic.py --image squirrel.jpg

# importazione dei pacchetti richiesti

importare intorpidito come per esempio.

importare argparse

importare imutil

importare cv2

# creando l'oggetto argumentparser e analizzando l'argomento

apOb = argparse. ArgomentoParser ( )

apOb. add_argument ( '-K' , '--Immagine' , necessario = Vero , aiuto = 'percorso immagine' )

argomenti = il cui, di chi ( apOb. parse_args ( ) )

Immagine = cv2. imread ( argomenti [ 'Immagine' ] )

cv2. imshow ( 'Immagine originale' , Immagine )

'''

I valori dei nostri pixel saranno compresi nell'intervallo [0, 255]

poiché le immagini sono array NumPy, che vengono archiviati come numeri interi a 8 bit senza segno.

Quando si utilizzano funzioni come cv2.add e cv2.subtract, i valori verranno ritagliati

a questo intervallo anche se vengono aggiunti o sottratti dall'esterno del

[0, 255] intervallo. Ecco un'illustrazione:

'''


Stampa ( 'massimo 255: {}' . formato ( str ( cv2. Inserisci ( per esempio. uint8 ( [ 201 ] ) ,

per esempio. uint8 ( [ 100 ] ) ) ) ) )

Stampa ( 'minimo di 0: {}' . formato ( str ( cv2. sottrarre ( per esempio. uint8 ( [ 60 ] ) ,

per esempio. uint8 ( [ 100 ] ) ) ) ) )

'''

Quando si eseguono operazioni aritmetiche con questi array utilizzando NumPy,

il valore andrà a capo anziché essere ritagliato su

[0, 255]intervallo. Quando si usano le immagini, è essenziale conservarle

in mente.

'''


Stampa ( 'arrotolare: {}' . formato ( str ( per esempio. uint8 ( [ 201 ] ) + ad es. uint8 ( [ 100 ] ) ) ) )

Stampa ( 'arrotolare: {}' . formato ( str ( per esempio. uint8 ( [ 60 ] ) - per esempio. uint8 ( [ 100 ] ) ) ) )

'''

Moltiplichiamo la luminosità di ogni pixel nella nostra immagine per 101.

Per fare ciò, generiamo un array NumPy delle stesse dimensioni della nostra matrice,

riempito con quelli e moltiplicalo per 101 per produrre un array riempito

con 101. Infine, uniamo le due immagini.

Noterai che l'immagine è ora 'più luminosa'.

'''


Matrice = per esempio. quelli ( Immagine. forma , dtype = 'uint8' ) * 101

image_added = cv2. Inserisci ( Immagine , Matrice )

cv2. imshow ( 'Risultato immagine aggiunta' , image_added )

#In modo simile, possiamo rendere la nostra immagine più scura scattando

# 60 di distanza da tutti i pixel.

Matrice = per esempio. quelli ( Immagine. forma , dtype = 'uint8' ) * 60

immagine_sottratta = cv2. sottrarre ( Immagine , Matrice )

cv2. imshow ( 'Risultato immagine sottratto' , immagine_sottratta )

cv2. waitKey ( 0 )

Linee da 1 a 16 verrà utilizzato per eseguire il nostro normale processo, che comporta l'importazione dei nostri pacchetti, la configurazione del nostro parser di argomenti e il caricamento della nostra immagine.

Ricordi come ho discusso in precedenza della distinzione tra aggiunta di OpenCV e NumPy? Ora che l'abbiamo trattato a fondo, diamo un'occhiata a un caso specifico per assicurarci di comprenderlo.

Su cui sono definiti due array NumPy di ​​numeri interi senza segno a 8 bit linea 26 . Un valore di 201 è l'unico elemento nel primo array. Sebbene solo un membro si trovi nel secondo array, ha un valore di 100. I valori vengono quindi aggiunti utilizzando la funzione cv2.add di OpenCV.

Quale ti aspetti che sia il risultato?

In accordo con i principi aritmetici convenzionali, la risposta dovrebbe essere 301. Ma ricorda che abbiamo a che fare con numeri interi senza segno a 8 bit, che possono essere solo nell'intervallo [0, 255]. Poiché stiamo utilizzando il metodo cv2.add, OpenCV gestisce il ritaglio e garantisce che l'addizione restituisca solo un risultato massimo di 255.

La prima riga dell'elenco seguente mostra il risultato dell'esecuzione di questo codice:

aritmetica. py

massimo di 255 : [ [ 255 ] ]

La somma ha effettivamente prodotto un numero di 255.

Seguendo quello, linea 26 utilizza cv2.subtract per eseguire una sottrazione. Ancora una volta, definiamo due array NumPy di ​​numeri interi senza segno a 8 bit con un singolo elemento in ciascuno. Il valore del primo array è 60, mentre il valore del secondo array è 100.

La nostra aritmetica impone che la sottrazione dovrebbe risultare in un valore di -40, ma OpenCV gestisce il ritaglio per noi ancora una volta. Scopriamo che il valore è stato ridotto a 0. Il nostro risultato di seguito lo dimostra:

aritmetica. py

minimo di 0 : [ [ 0 ] ]

Usando cv2, sottrai 100 da 60 sottrai, producendo il valore 0.

Ma cosa succede se utilizziamo NumPy al posto di OpenCV per eseguire i calcoli?

Linee 38 e 39 affrontare questo problema.

Innanzitutto, vengono definiti due array NumPy interi senza segno a 8 bit con un singolo elemento ciascuno. Il valore del primo array è 201, mentre il valore del secondo array è 100. La nostra addizione verrebbe tagliata e verrebbe restituito un valore di 255 se utilizzassimo la funzione cv2.add.

NumPy, d'altra parte, 'si avvolge' e fa il modulo aritmetico piuttosto che il ritaglio. NumPy torna a zero una volta raggiunto un valore di 255 e quindi riprende il conteggio fino al raggiungimento di 100 passaggi. Ciò è confermato dalla prima riga di output, mostrata di seguito:

aritmetica. py
arrotolare: [ Quattro cinque ]

Quindi, vengono definiti altri due array NumPy, uno con un valore di 50 e l'altro con 100. Questa sottrazione verrebbe tagliata dal metodo cv2.subtract per restituire un risultato di 0. Ma siamo consapevoli che invece di ritagliare, NumPy esegue modulo aritmetico. Invece, le procedure modulo si riavvolgono e iniziano a contare all'indietro da 255 una volta raggiunto 0 durante la sottrazione. Possiamo vederlo dal seguente output:

aritmetica. py

arrotolare: [ 207 ]

Ancora una volta, il nostro output del terminale dimostra la distinzione tra ritaglio e wrapping:

È fondamentale tenere a mente il risultato desiderato quando si esegue l'aritmetica dei numeri interi. Vuoi che tutti i valori al di fuori dell'intervallo [0, 255] vengano tagliati? Successivamente, utilizza le tecniche aritmetiche delle immagini integrate di OpenCV.

Vuoi che i valori vadano a capo se sono al di fuori dell'intervallo di [0, 255] e delle operazioni aritmetiche del modulo? Gli array NumPy vengono quindi semplicemente aggiunti e sottratti come al solito.

Riga 48 definisce un array NumPy unidimensionale con le stesse dimensioni della nostra immagine. Ancora una volta, ci assicuriamo che il nostro tipo di dati sia un numero intero senza segno a 8 bit. Moltiplichiamo semplicemente la nostra matrice di valori a una cifra per 101 per riempirla con valori di 101 invece di 1. Infine, usiamo la funzione cv2.add per aggiungere la nostra matrice di 100 all'immagine originale. Ciò aumenta l'intensità di ciascun pixel di 101, garantendo al contempo che tutti i valori che tentano di superare 255 vengano ritagliati nell'intervallo [0, 255].

Osserva come l'immagine è notevolmente più luminosa e appare più 'sbiadita' rispetto all'originale. Questo perché stiamo guidando i pixel verso colori più luminosi aumentando la loro intensità di pixel di 101.

Per sottrarre 60 dall'intensità di ciascun pixel dell'immagine, per prima cosa stabiliamo un secondo array NumPy sulla riga 54 che è riempito con gli anni '60.

I risultati di questa sottrazione sono rappresentati nell'immagine seguente:

Gli oggetti intorno a noi appaiono significativamente più scuri rispetto a prima. Questo perché sottraendo 60 da ciascun pixel, stiamo spostando i pixel nello spazio colore RGB nelle regioni più scure.

4. Capovolgimento dell'immagine

Simile alla rotazione, capovolgere un'immagine sul suo asse x o y è un'altra opzione offerta da OpenCV. Anche se le operazioni di capovolgimento non vengono utilizzate così frequentemente, conoscerle è incredibilmente vantaggioso per vari motivi che potresti non vedere immediatamente.

Stiamo sviluppando un classificatore di machine learning per una piccola startup che cerca di identificare i volti nelle immagini. Affinché il nostro sistema 'apprenda' cos'è un volto, avremmo bisogno di una sorta di set di dati con volti campione. Sfortunatamente, l'azienda ci ha fornito solo un piccolo set di dati di 40 volti e non siamo in grado di raccogliere ulteriori informazioni.

Cosa facciamo allora?

Dal momento che una faccia rimane una faccia che sia specchiata o meno, siamo in grado di capovolgere orizzontalmente ogni immagine di una faccia e utilizzare le versioni specchiate come dati di addestramento extra.

Questo esempio può sembrare stupido e artificiale, ma non lo è. Il flipping è una strategia deliberata utilizzata da potenti algoritmi di deep learning per produrre più dati durante la fase di addestramento.

È chiaro dal precedente che i metodi di elaborazione delle immagini appresi in questo modulo servono come base per sistemi di visione artificiale più grandi.

Obiettivi:

Usando il cv2.flip funzione, imparerai come capovolgere un'immagine sia orizzontalmente che verticalmente in questa sessione.

Il capovolgimento è la prossima manipolazione delle immagini che studieremo. Gli assi x e y di un'immagine possono essere capovolti o anche entrambi. Prima di immergerci nella codifica, è meglio esaminare i risultati di un capovolgimento dell'immagine. Guarda un'immagine che è stata capovolta orizzontalmente nell'immagine seguente:


Prendi nota di come la nostra immagine originale è a sinistra e di come l'immagine è stata specchiata orizzontalmente a destra.

Iniziamo creando un nuovo file chiamato lanciando.py .

Hai visto un esempio di capovolgimento di un'immagine, quindi esaminiamo il codice:

# python flipping.py --image quirrel.jpg

# importazione dei pacchetti richiesti

importare argparse

importare cv2

# crea l'oggetto dell'argomento parser e analizza l'argomento

apOb = argparse. ArgomentoParser ( )

apOb. add_argument ( '-io' , '--Immagine' , necessario = Vero , aiuto = 'percorso immagine' )

discussione = il cui, di chi ( apOb. parse_args ( ) )

Immagine = cv2. imread ( discussione [ 'Immagine' ] )

cv2. imshow ( 'Originale' , Immagine )

# capovolge orizzontalmente l'immagine

imageflipped = cv2. Flip ( Immagine , 1 )

cv2. imshow ( 'Immagine capovolta orizzontalmente' , imageflipped )

# capovolge verticalmente l'immagine

imageflipped = cv2. Flip ( Immagine , 0 )

cv2. imshow ( 'Immagine capovolta verticalmente' , imageflipped )

# immagine capovolta lungo entrambi gli assi

imageflipped = cv2. Flip ( Immagine , - 1 )

cv2. imshow ( 'Capovolto orizzontalmente e verticalmente' , imageflipped )

cv2. waitKey ( 0 )

I passaggi che eseguiamo per importare i nostri pacchetti, analizzare i nostri input e caricare la nostra immagine dal disco sono gestiti in l righe da 1 a 12 .

Chiamando la funzione cv2.flip on Riga 15 , è semplice capovolgere un'immagine orizzontalmente. L'immagine che cerchiamo di capovolgere e uno specifico codice o flag che specifica come capovolgere l'immagine sono i due argomenti necessari per il metodo cv2.flip.

Un valore di codice di capovolgimento pari a 1 significa che ruoteremo l'immagine attorno all'asse y per capovolgerla orizzontalmente ( Riga 15 ). Se specifichiamo un flip code pari a 0, desideriamo ruotare l'immagine attorno all'asse x ( Riga 19 ). Un codice capovolgimento negativo ( Riga 23 ) ruota l'immagine su entrambi gli assi.

Uno degli esempi più semplici in questo argomento è capovolgere un'immagine, che è fondamentale.

Successivamente, discuteremo del ritaglio delle immagini e dell'utilizzo delle sezioni dell'array NumPy per estrarre parti specifiche dell'immagine.

5. Ritaglio dell'immagine

Il ritaglio, come suggerisce il nome, è il processo di scelta e rimozione della regione di interesse (o semplicemente ROI), ovvero l'area dell'immagine che ci interessa.

Il volto dovrebbe essere ritagliato da un'immagine per un'applicazione di rilevamento del volto. Inoltre, se stessimo creando uno script Python per trovare i cani nelle immagini, potremmo voler ritagliare il cane dall'immagine quando lo individuiamo.

Obiettivi: Il nostro obiettivo principale è acquisire familiarità e disinvoltura utilizzando l'affettatura dell'array NumPy per ritagliare aree da un'immagine.

Ritaglio : Quando ritagliamo un'immagine, il nostro obiettivo è eliminare gli elementi esterni che non ci interessano. Il processo di scelta del nostro ROI viene spesso definito come la scelta della nostra regione di interesse.

Crea un nuovo file chiamato crop.py , aprilo e aggiungi il seguente codice:

# python crop.py

# importazione dei pacchetti richiesti

importare cv2

# immagine caricata e visualizzata sullo schermo

Immagine = cv2. imread ( 'scoiattolo.jpg' )

Stampa ( Immagine. forma )

cv2. imshow ( 'Originale' , Immagine )

# Le sezioni dell'array NumPy vengono utilizzate per ritagliare rapidamente un'immagine

# taglieremo la faccia dello scoiattolo dall'immagine

scoiattolo = Immagine [ 35 : 90 , 35 : 100 ]

cv2. imshow ( 'Faccia di scoiattolo' , scoiattolo )

cv2. waitKey ( 0 )

# E ora, qui taglieremo l'intero corpo

# dello scoiattolo

scoiattolo = Immagine [ 35 : 148 , 23 : 143 ]

cv2. imshow ( 'Corpo di scoiattolo' , scoiattolo )

cv2. waitKey ( 0 )

Mostreremo il ritaglio in Python e OpenCV usando un'immagine che carichiamo dal disco Linee 5 e 6 .

Immagine originale che ritaglieremo

Utilizzando solo tecniche di ritaglio di base, miriamo a separare la faccia e il corpo dello scoiattolo dall'area circostante.

Useremo la nostra precedente conoscenza dell'immagine e forniremo manualmente le fette dell'array NumPy di ​​dove esistono il corpo e il viso. In condizioni normali, generalmente utilizziamo algoritmi di machine learning e computer vision per riconoscere il volto e il corpo nell'immagine. Ma manteniamo le cose semplici per il momento ed evitiamo di utilizzare qualsiasi modello di rilevamento.

Possiamo identificare il volto nell'immagine con una sola riga di codice. Riga 13 , Per estrarre una porzione rettangolare dell'immagine, a partire da (35, 35), forniamo le sezioni dell'array NumPy (90, 100). Può sembrare confuso il fatto che alimentiamo il ritaglio con gli indici nell'ordine altezza-prima e larghezza-secondo che facciamo, ma tieni presente che OpenCV memorizza le immagini come array NumPy. Di conseguenza, dobbiamo fornire i valori per l'asse y prima dell'asse x.

NumPy richiede i seguenti quattro indici per eseguire il ritaglio:

Inizio y: La coordinata y all'inizio. Per questo caso, iniziamo da y=35.

Fine a: La coordinata y alla fine. Il nostro raccolto si fermerà quando y = 90.

Inizio x: La coordinata x iniziale della sezione. Il raccolto inizia a x=35.

Fine x: La coordinata dell'asse x finale della sezione. A x=100, la nostra fetta è finita.

Allo stesso modo, ritagliamo le regioni (23, 35) e (143, 148) dall'immagine originale per estrarre l'intero corpo dall'immagine su Riga 19 .

Puoi osservare che l'immagine è stata ritagliata per mostrare solo il corpo e il viso.

6. Ridimensionamento delle immagini

Il processo di aumento o diminuzione della larghezza e dell'altezza di un'immagine è noto come ridimensionamento o semplicemente ridimensionamento. Le proporzioni, che sono la proporzione tra la larghezza e l'altezza di un'immagine, devono essere considerate quando si ridimensiona un'immagine. Trascurare le proporzioni può comportare immagini che sono state ridimensionate che appaiono compresse e distorte:

La nostra immagine iniziale è a sinistra. Sulla destra, vedrai due immagini che sono state ridimensionate senza mantenere le proporzioni, distorcendo la proporzione tra la larghezza dell'immagine e la sua altezza. Quando ridimensioni le tue immagini, dovresti generalmente considerare le proporzioni.

La tecnica di interpolazione utilizzata dal nostro algoritmo di ridimensionamento deve anche considerare l'obiettivo della funzione di interpolazione di utilizzare questi quartieri di pixel per aumentare o diminuire le dimensioni dell'immagine.

In generale, ridurre le dimensioni dell'immagine è molto più efficace. Questo perché rimuovere i pixel da un'immagine è tutto ciò che la funzione di interpolazione deve fare. D'altra parte, il metodo di interpolazione dovrebbe 'riempire gli spazi vuoti' tra i pixel che in precedenza non esistevano se la dimensione dell'immagine dovesse essere aumentata.

Abbiamo la nostra immagine originale sulla sinistra. L'immagine è stata ridotta della metà della sua dimensione originale al centro, ma a parte questo, non c'è stata alcuna perdita di 'qualità' dell'immagine. Tuttavia, la dimensione dell'immagine è stata notevolmente migliorata sulla destra. Ora appare 'esploso' e 'pixelato'.

Come ho affermato in precedenza, in genere vorrai ridurre le dimensioni di un'immagine piuttosto che aumentarle. Riducendo le dimensioni dell'immagine, analizziamo meno pixel e abbiamo a che fare con meno 'rumore', il che rende gli algoritmi di elaborazione delle immagini più veloci e precisi.

Traslazione e rotazione sono le due trasformazioni dell'immagine affrontate finora. Ora esamineremo come ridimensionare un'immagine.

Non sorprende che ridimensioneremo le nostre immagini utilizzando il metodo cv2.resize. Come ho indicato in precedenza, dobbiamo considerare le proporzioni dell'immagine quando utilizziamo questo metodo. Ma prima di entrare troppo nello specifico, permettetemi di darvi un esempio:

# python resize.py --image squirrel.jpg

# importazione dei pacchetti richiesti

importare argparse

importare cv2

# crea l'oggetto dell'argomento parser e analizza l'argomento

apOb = argparse. ArgomentoParser ( )

apOb. add_argument ( '-K' , '--Immagine' , necessario = Vero , aiuto = 'percorso immagine' )

argomenti = il cui, di chi ( apOb. parse_args ( ) )

# caricare l'immagine e visualizzarla sullo schermo

Immagine = cv2. imread ( argomenti [ 'Immagine' ] )

cv2. imshow ( 'Originale' , Immagine )

# Per evitare che l'immagine appaia distorta, proporzioni

# deve essere considerato o deformato; quindi, capiamo cosa

# il rapporto della nuova immagine rispetto all'immagine corrente.

# Facciamo in modo che la larghezza della nostra nuova immagine sia di 160 pixel.

aspetto = 160,0 / Immagine. forma [ 1 ]

dimensione = ( 160 , int ( Immagine. forma [ 0 ] * aspetto ) )

# questa riga mostrerà le effettive operazioni di ridimensionamento

immagine ridimensionata = cv2. ridimensionare ( Immagine , dimensione , interpolazione = cv2. INTER_AREA )

cv2. imshow ( 'Larghezza immagine ridimensionata' , immagine ridimensionata )

# E se volessimo cambiare l'altezza dell'immagine? - usando il

# stesso principio, possiamo calcolare le proporzioni in base

# in altezza piuttosto che in larghezza. Facciamo la scalata

# altezza dell'immagine 70 pixel.

aspetto = 70.0 / Immagine. forma [ 0 ]

dimensione = ( int ( Immagine. forma [ 1 ] * aspetto ) , 70 )

# esegue il ridimensionamento

immagine ridimensionata = cv2. ridimensionare ( Immagine , dimensione , interpolazione = cv2. INTER_AREA )

cv2. imshow ( 'Altezza immagine ridimensionata' , immagine ridimensionata )

cv2. waitKey ( 0 )

Linee 1-14 , Dopo aver importato i nostri pacchetti e configurato il nostro parser di argomenti, caricheremo e mostreremo la nostra immagine.

Righe 20 e 21: la relativa codifica inizia in queste righe . Le proporzioni dell'immagine devono essere prese in considerazione durante il ridimensionamento. La proporzione tra la larghezza e l'altezza dell'immagine è nota come proporzioni.

Altezza larghezza è il rapporto di aspetto.

Se non prendiamo in considerazione le proporzioni, i risultati del nostro ridimensionamento risulteranno distorti.

SU Riga 20 , il calcolo del rapporto ridimensionato viene eseguito. Forniamo la larghezza della nostra nuova immagine come 160 pixel in questa riga di codice. Definiamo semplicemente il nostro rapporto (aspectratio) come la nuova larghezza (160 pixel) divisa per la vecchia larghezza, a cui accediamo usando l'immagine, per calcolare il rapporto tra la nuova altezza e la vecchia altezza. forma[1].

Le nuove dimensioni dell'immagine su Riga 21 può essere calcolato ora che conosciamo il nostro rapporto. Ancora una volta, la nuova immagine avrà una larghezza di 160 pixel. Dopo aver moltiplicato la vecchia altezza per il nostro rapporto e aver convertito il risultato in un numero intero, viene calcolata l'altezza. Possiamo mantenere le proporzioni originali dell'immagine eseguendo questa operazione.

Riga 24 è dove l'immagine viene realmente ridimensionata. L'immagine che vogliamo ridimensionare è il primo argomento, e il secondo sono le dimensioni che abbiamo calcolato per la nuova immagine. Il nostro metodo di interpolazione, che è l'algoritmo per ridimensionare l'immagine reale, è l'ultimo parametro.

Infine, su Riga 25 , mostriamo la nostra immagine in scala.

Ridefiniamo il nostro rapporto (aspectratio) su Riga 31 . L'altezza della nostra nuova immagine sarà di 70 pixel. Dividiamo 70 per l'altezza originale per ottenere il nuovo rapporto tra altezza e altezza originale.

Successivamente, stabiliamo le dimensioni della nuova immagine. La nuova immagine avrà un'altezza di 70 pixel, che è già nota. Possiamo ancora una volta mantenere le proporzioni originali dell'immagine moltiplicando la vecchia larghezza per il rapporto per produrre la nuova larghezza.

L'immagine viene quindi effettivamente ridimensionata Riga 35 , ed è visualizzato su Riga 36.

Qui possiamo vedere che abbiamo ridotto la larghezza e l'altezza della nostra immagine originale mantenendo le proporzioni. La nostra immagine sembrerebbe distorta se le proporzioni non fossero mantenute.

Conclusione

In questo blog, abbiamo studiato i diversi concetti base di elaborazione delle immagini. Abbiamo visto la traduzione delle immagini con l'aiuto del pacchetto OpenCV. Abbiamo visto i metodi per spostare l'immagine in alto, in basso, a destra ea sinistra. Questi metodi sono molto utili quando creiamo un set di dati di immagini simili da fornire come set di dati di addestramento, quindi la macchina vedrà immagini diverse anche se sono uguali. Questo articolo ti ha anche insegnato come ruotare un'immagine attorno a qualsiasi punto nello spazio cartesiano usando una matrice di rotazione. Poi hai scoperto come OpenCV ruota le immagini usando questa matrice e hai visto un paio di illustrazioni di immagini rotanti.

In questa sezione sono state esaminate le due fondamentali (ma significative) operazioni aritmetiche dell'immagine di addizione e sottrazione. Come puoi vedere, l'aggiunta e la sottrazione di matrici fondamentali è tutte le operazioni aritmetiche dell'immagine che comportano.

Inoltre, abbiamo utilizzato OpenCV e NumPy per studiare le peculiarità dell'aritmetica delle immagini. Queste restrizioni devono essere tenute presenti o rischi di ottenere risultati imprevisti durante l'esecuzione di operazioni aritmetiche sulle tue immagini.

È importante ricordare che sebbene NumPy esegua un'operazione di modulo e 'riavvolga', l'addizione e la sottrazione di OpenCV tagliano i valori oltre l'intervallo [0, 255] per rientrare nell'intervallo. Quando sviluppi le tue applicazioni di visione artificiale, ricordare questo ti aiuterà a evitare di dare la caccia a bug complicati.

Il capovolgimento delle immagini è senza dubbio una delle idee più semplici che esploreremo in questo corso. Il capovolgimento è spesso impiegato nell'apprendimento automatico per generare più campioni di dati di addestramento, risultando in classificatori di immagini più potenti e affidabili.

Abbiamo anche imparato come utilizzare OpenCV per ridimensionare un'immagine. È fondamentale considerare sia il metodo di interpolazione che stai utilizzando sia le proporzioni dell'immagine originale quando ne ridimensioni una in modo che il risultato non appaia distorto.

Infine, è fondamentale ricordare che se la qualità dell'immagine è un problema, è sempre meglio passare da un'immagine più grande a una più piccola. Nella maggior parte dei casi, l'ingrandimento di un'immagine crea artefatti e ne degrada la qualità.