Procesarea imaginii OpenCV

Procesarea Imaginii Opencv



Vom studia metodele de procesare a imaginii în acest articol. Vom examina câteva subiecte fundamentale, dar critice în viziunea computerizată și învățarea automată. Aceste tehnici fundamentale de procesare a imaginilor pot rezolva probleme complexe, cum ar fi seturile de date. Ca rezultat, există șase pași fundamentali în procesarea imaginilor, care sunt enumerați mai jos:
  1. Traducerea imaginilor
  2. Rotația imaginii
  3. Aritmetica imaginii
  4. Întoarcerea imaginii
  5. Decuparea imaginii
  6. Redimensionarea imaginii

Acum, vom explica în detaliu toate subiectele de procesare a imaginilor menționate mai sus.

1. Traducere imagini

Traducerea imaginii este o metodă de procesare a imaginii care ne ajută să deplasăm imaginea de-a lungul axelor x și y. Putem muta imaginea în sus, în jos, la dreapta, la stânga sau orice combinație.







Putem defini Matricea de traducere cu simbolul M și o putem reprezenta în formă matematică, așa cum se arată mai jos:





Putem înțelege conceptul de imagine de traducere prin intermediul acestui program.





Cod Python: Vom păstra numele următorului program ca traduce.py .

# import pachetele necesare

import numpy la fel de de exemplu.

import argparse

import imutil

import cv2

# implementăm analizatorul de argumente

ap_obj = argparse. ArgumentParser ( )

ap_obj. add_argument ( '-k' , '--imagine' , necesar = Adevărat ,

Ajutor = „locația fișierului imagine” )

argumente = a caror ( ap_obj. parse_args ( ) )

# încărcați imaginea și afișați-o pe ecran

imagine = cv2. imcitit ( argumente [ 'imagine' ] )

cv2. imshow ( „Imagine_originală” , imagine )

# Traducerea imaginii este o matrice NumPy care este dată mai jos:

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

# Vom folosi matricea NumPy de mai sus pentru a muta imaginile de-a lungul

# direcții pe axa x și pe axa y. Pentru aceasta, trebuie să trecem pur și simplu valorile pixelilor.

# În acest program, vom muta imaginea cu 30 de pixeli la dreapta

# și 70 de pixeli spre partea de jos.

traducere_mat = de exemplu. plutitor32 ( [ [ 1 , 0 , 30 ] , [ 0 , 1 , 70 ] ] )

traducere_imagine = cv2. warpAffine ( imagine , traducere_mat ,

( imagine. formă [ 1 ] , imagine. formă [ 0 ] ) )

cv2. imshow ( „Traducerea imaginii în jos și în dreapta” , traducere_imagine )

# acum, vom folosi matricea NumPy de mai sus pentru a muta imaginile de-a lungul

# direcții axa x (stânga) și axa y (sus).

# Aici, vom muta imaginile cu 50 de pixeli la stânga

# și 90 de pixeli în sus.

traducere_mat = de exemplu. plutitor32 ( [ [ 1 , 0 , - cincizeci ] , [ 0 , 1 , - 90 ] ] )

traducere_imagine = cv2. warpAffine ( imagine , traducere_mat ,

( imagine. formă [ 1 ] , imagine. formă [ 0 ] ) )

cv2. imshow ( „Traducerea imaginii în sus și în stânga” , traducere_imagine )

cv2. waitTasta ( 0 )

Rândurile de la 1 la 5: Importăm toate pachetele necesare pentru acest program, cum ar fi OpenCV, argparser și NumPy. Vă rugăm să rețineți că există o altă bibliotecă care este imutils. Acesta nu este un pachet OpenCV. Aceasta este doar o bibliotecă care va afișa cu ușurință aceeași procesare a imaginii.



Biblioteca imutils nu va fi inclusă automat când instalăm OpenCV. Deci, pentru a instala imutils, trebuie să folosim următoarea metodă:

pip install imutils

Liniile de la 8 la 15: Ne-am creat agrparserul și ne-am încărcat imaginea.

Liniile de la 24 la 25: Această secțiune de program este locul unde are loc traducerea. Matricea de translație ne spune câți pixeli va fi mutată imaginea în sus sau în jos sau la stânga sau la dreapta. Deoarece OpenCV necesită ca valoarea matricei să fie într-o matrice în virgulă mobilă, matricea de translație preia valori în matrice în virgulă mobilă.

Primul rând al matricei de traducere arată astfel:

Acest rând al matricei este pentru axa x. Valoarea lui t X va decide dacă imaginea va fi deplasată spre stânga sau spre dreapta. Dacă trecem o valoare negativă, înseamnă că imaginea va fi deplasată în partea stângă, iar dacă valoarea este pozitivă, atunci înseamnă că imaginea va fi deplasată în partea dreaptă.

Vom defini acum al doilea rând al matricei după cum urmează:

Acest rând al matricei este pentru axa y. Valoarea lui t Y va decide dacă imaginea va fi deplasată în sus sau în jos. Dacă trecem o valoare negativă, înseamnă că imaginea va fi deplasată în sus, iar dacă valoarea este pozitivă, înseamnă că imaginea va fi deplasată în jos.

În programul anterior de la linia 24, definim t X = 30 și t Y = 70. Deci mutăm imaginea cu 30 de pixeli spre partea dreaptă și cu 70 de pixeli în jos.

Dar procesul principal de traducere a imaginii are loc la linia 25, unde definim matricea de traducere cv2.warpAffine . În această funcție, trecem trei parametri: primul parametru este imaginea, al doilea parametru este matricea de translație, iar al treilea parametru este dimensiunea imaginii.

Linia 27: Linia 27 va afișa rezultatul în rezultat.

Acum, vom implementa o altă matrice de traducere pentru stânga și sus. Pentru aceasta, trebuie să definim valorile în negativ.

Linia 33 până la 34: În programul anterior de la linia 33, definim t X = -50 și t Y = -90. Deci, mutăm imaginea cu 50 de pixeli spre partea stângă și cu 90 de pixeli în sus. Dar procesul principal de traducere a imaginii are loc la linia 34, unde definim matricea de traducere cv2.warpAffine .

Linia 36 : Linia 36 va afișa rezultatul așa cum se arată în rezultat.

Pentru a rula codul anterior, trebuie să dăm calea imaginii așa cum este prezentat mai jos.

Ieșire: python translate.py –imagine veveriță.jpg

Acum, vom implementa același program de traducere a imaginilor folosind imutil bibliotecă. Această bibliotecă este foarte ușor de utilizat pentru procesarea imaginilor. În această bibliotecă, nu trebuie să ne gândim la cv2.warpAffine pentru că această bibliotecă se va ocupa de asta. Deci, să implementăm acest program de traducere a imaginilor folosind biblioteca imutils.

Cod Python: Vom păstra numele următorului program ca translate_imutils.py .

# importa pachetele necesare

import numpy la fel de de exemplu.

import argparse

import imutil

import cv2

# Această funcție implementează traducerea imaginii și

# returnează imaginea tradusă la funcția de apelare.

def Traduceți ( imagine , X , Y ) :

matrice_traducere = de exemplu. plutitor32 ( [ [ 1 , 0 , X ] , [ 0 , 1 , Y ] ] )

traducere_imagine = cv2. warpAffine ( imagine , matrice_traducere ,

( imagine. formă [ 1 ] , imagine. formă [ 0 ] ) )

întoarcere traducere_imagine

# construiți analizatorul de argumente și analizați argumentele

ap = argparse. ArgumentParser ( )

ap. add_argument ( '-i' , '--imagine' , necesar = Adevărat , Ajutor = „Cale către imagine” )

argumente = a caror ( ap. parse_args ( ) )

# încărcați imaginea și afișați-o pe ecran

imagine = cv2. imcitit ( argumente [ 'imagine' ] )

cv2. imshow ( „Imagine_originală” , imagine )

traducere_imagine = imutil. Traduceți ( imagine , 10 , 70 )

cv2. imshow ( „Traducerea imaginii în dreapta și în jos” ,

traducere_imagine )

cv2. waitTasta ( 0 )

Liniile de la 9 la 13: Această secțiune a programului este locul unde are loc traducerea. Matricea de translație ne informează prin câți pixeli va fi mutată imaginea în sus sau în jos sau la stânga sau la dreapta.

Aceste linii au fost deja explicate, dar acum vom construi o funcție numită translate () și vom trimite trei parametri distincți în ea. Imaginea în sine servește ca prim parametru. Valorile x și y ale matricei de translație corespund celui de-al doilea și al treilea parametru.

Notă : Nu este nevoie să definiți această funcție de traducere în cadrul programului deoarece este deja inclusă în pachetul de bibliotecă imutils. L-am folosit în cadrul programului de dragul unei explicații directe. Putem apela această funcție direct cu imutils, așa cum se arată în linia 24.

Linia 24: Programul anterior va arăta că la linia 24, definim tx = 10 și ty = 70. Deci mutăm imaginea cu 10 pixeli spre partea dreaptă și 70 pixeli în jos.

În acest program, nu ne pasă de nicio funcție cv2.warpAffine, deoarece acestea sunt deja în pachetul de bibliotecă imutils.

Pentru a rula codul anterior, trebuie să dăm calea imaginii, după cum este prezentat mai jos:

Ieșire:

python imutils. py --imagine veveriță. jpg

2. Rotația imaginii

Am analizat cum să traducem (adică să deplasăm) o imagine în sus, în jos, la stânga și la dreapta în lecția anterioară (sau orice combinație). În continuare, vom discuta despre rotație în legătură cu procesarea imaginilor.

O imagine este rotită cu un unghi, theta, într-un proces cunoscut sub numele de rotație. Unghiul cu care rotim imaginea va fi reprezentat prin theta. În plus, voi oferi ulterior funcția de rotire confortabilă pentru a simplifica rotația imaginilor.

Similar cu translația și, probabil, nu este surprinzător, cu rotația printr-un unghi, theta este determinată prin construirea unei matrice M în următorul format:

Această matrice poate roti un vector grade theta (în sens invers acelor de ceasornic) în jurul originii date (x, y)-planul cartezian. De obicei, în acest scenariu, originea ar fi centrul imaginii, dar în realitate, am putea desemna orice punct aleatoriu (x, y) drept centru de rotație.

Imaginea rotită R este apoi creată din imaginea originală I folosind o înmulțire matrice simplă: R = IM

OpenCV, pe de altă parte, oferă în plus capacitatea de a (1) scala (adică, redimensiona) o imagine și (2) oferă un centru de rotație arbitrar pentru a efectua rotația.

Matricea noastră de rotație M modificată este prezentată mai jos:

Să începem prin a deschide și a genera un nou fișier numit roti.py :

# importul pachetelor necesare

import numpy la fel de de exemplu.

import argparse

import imutil

import cv2

# crearea obiectului argumentparser și analizarea argumentului

apobj = argparse. ArgumentParser ( )

apobj. add_argument ( '-k' , '--imagine' , necesar = Adevărat , Ajutor = 'calea imaginii' )

argumente = a caror ( apobj. parse_args ( ) )

imagine = cv2. imcitit ( argumente [ 'imagine' ] )

cv2. imshow ( „Imagine_originală” , imagine )

# Calculați centrul imaginii folosind dimensiunile imaginii.

( înălţime , lăţime ) = imagine. formă [ : 2 ]

( centruX , centruY ) = ( latime / 2 , inaltime / 2 )

# Acum, folosind cv2, vom roti imaginea cu 55 de grade către

# determinați matricea de rotație folosind getRotationMatrix2D()

rotationMatrix = cv2. getRotationMatrix2D ( ( centruX , centruY ) , 55 , 1.0 )

rotităImagine = cv2. warpAffine ( imagine , rotationMatrix , ( lăţime , înălţime ) )

cv2. imshow ( „S-a rotit imaginea cu 55 de grade” , rotităImagine )

cv2. waitTasta ( 0 )

# Imaginea va fi rotită acum cu -85 de grade.

rotationMatrix = cv2. getRotationMatrix2D ( ( centruX , centruY ) , - 85 , 1.0 )

rotităImagine = cv2. warpAffine ( imagine , rotationMatrix , ( lăţime , înălţime ) )

cv2. imshow ( „S-a rotit imaginea cu -85 de grade” , rotităImagine )

cv2. waitTasta ( 0 )

Rândurile de la 1 la 5: Importăm toate pachetele necesare pentru acest program, cum ar fi OpenCV, argparser și NumPy. Vă rugăm să rețineți că există o altă bibliotecă care este imutils. Acesta nu este un pachet OpenCV. Aceasta este doar o bibliotecă care va fi folosită pentru a afișa cu ușurință aceeași procesare a imaginii.

Biblioteca imutils nu va fi inclusă automat când instalăm OpenCV. OpenCV instalează imutils. Trebuie să folosim următoarea metodă:

pip install imutils

Liniile de la 8 la 14: Ne-am creat agrparserul și ne-am încărcat imaginea. În acest argparser, folosim un singur argument de imagine, care ne va spune calea imaginii pe care o vom folosi în acest program pentru a demonstra rotația.

Când rotim o imagine, trebuie să definim punctul de pivotare al rotației. De cele mai multe ori, veți dori să rotiți o imagine în jurul centrului ei, dar OpenCV vă permite să alegeți orice punct aleatoriu. Să rotim pur și simplu imaginea în jurul centrului ei.

Liniile 17 până la 18 luați lățimea și, respectiv, înălțimea imaginii, apoi împărțiți fiecare dimensiune cu două pentru a stabili centrul imaginii.

Construim o matrice pentru a roti o imagine în același mod în care am definit o matrice pentru a traduce o imagine. Vom suna doar la cv2.getRotationMatrix2D funcția pe linia 22, mai degrabă decât crearea manuală a matricei folosind NumPy (ceea ce poate fi puțin greoi).

The cv2.getRotationMatrix2D funcția necesită trei parametri. Prima intrare este unghiul de rotație dorit (în acest caz, centrul imaginii). Theta este apoi folosit pentru a specifica câte grade (în sens invers acelor de ceasornic) vom roti imaginea. Aici, vom roti imaginea cu 45 de grade. Opțiunea finală este legată de dimensiunea imaginii.

Indiferent de faptul că nu am discutat încă despre scalarea unei imagini, puteți furniza aici un număr în virgulă mobilă cu 1.0 care indică faptul că imaginea trebuie utilizată în proporțiile sale originale. Cu toate acestea, dacă introduceți o valoare de 2,0, dimensiunea imaginii s-ar dubla. Un număr de 0,5 reduce dimensiunea imaginii astfel.

Linia 22 până la 23: După ce am primit matricea noastră de rotație M de la cv2.getRotationMatrix2D funcția, ne rotim imaginea folosind cv2.warpAffine tehnica pe linia 23. Prima intrare a funcției este imaginea pe care dorim să o rotim. Lățimea și înălțimea imaginii noastre de ieșire sunt apoi definite, împreună cu matricea noastră de rotație M. Pe linia 23, imaginea este apoi rotită cu 55 de grade.

Puteți observa că imaginea noastră a fost rotită.

Liniile 28 până la 30 constituie a doua rotaţie. Liniile 22–23 ale codului sunt identice, cu excepția faptului că de data aceasta ne rotim cu -85 de grade, spre deosebire de 55.

Pur și simplu am rotit o imagine în jurul centrului ei până în acest punct. Ce se întâmplă dacă am dori să rotim imaginea în jurul unui punct aleatoriu?

Să începem prin a deschide și a genera un nou fișier numit rotate.py:

# importul pachetelor necesare

import numpy la fel de de exemplu.

import argparse

import imutil

import cv2

# crearea obiectului argumentparser și analizarea argumentului

ap_obj = argparse. ArgumentParser ( )

ap_obj. add_argument ( '-k' , '--imagine' , necesar = Adevărat , Ajutor = 'calea imaginii' )

argument = a caror ( ap_obj. parse_args ( ) )

# încărcați imaginea și afișați-o pe ecran

imagine = cv2. imcitit ( argument [ 'imagine' ] )

cv2. imshow ( „Imagine_originală” , imagine )

# Calculați centrul imaginii folosind dimensiunile imaginii.

( înălţime , lăţime ) = imagine. formă [ : 2 ]

( centruX , centruY ) = ( latime / 2 , inaltime / 2 )

# Acum, folosind cv2, vom roti imaginea cu 55 de grade către

# determinați matricea de rotație folosind getRotationMatrix2D()

rotationMatrix = cv2. getRotationMatrix2D ( ( centruX , centruY ) , 55 , 1.0 )

rotităImagine = cv2. warpAffine ( imagine , rotationMatrix , ( lăţime , înălţime ) )

cv2. imshow ( „S-a rotit imaginea cu 55 de grade” , rotităImagine )

cv2. waitTasta ( 0 )

# Imaginea va fi rotită acum cu -85 de grade.

rotationMatrix = cv2. getRotationMatrix2D ( ( centruX , centruY ) , - 85 , 1.0 )

rotităImagine = cv2. warpAffine ( imagine , rotationMatrix , ( lăţime , înălţime ) )

cv2. imshow ( „S-a rotit imaginea cu -85 de grade” , rotităImagine )

cv2. waitTasta ( 0 )

# rotirea imaginii dintr-un punct arbitrar, nu din centru

rotationMatrix = cv2. getRotationMatrix2D ( ( centerX - 40 , centruY - 40 ) , 55 , 1.0 )

rotităImagine = cv2. warpAffine ( imagine , rotationMatrix , ( lăţime , înălţime ) )

cv2. imshow ( „Rotația imaginii din puncte arbitrare” , rotităImagine )

cv2. waitTasta ( 0 )

Linia 34 până la 35: Acum, acest cod ar trebui să pară destul de comun pentru rotirea unui obiect. Pentru a roti imaginea în jurul unui punct la 40 de pixeli la stânga și la 40 de pixeli deasupra centrului său, instruim cv2.getRotationMatrix2D funcție de a acorda atenție primului său parametru.

Imaginea produsă atunci când aplicăm această rotație este prezentată mai jos:

Putem vedea clar că centrul de rotație este acum coordonatele (x, y), care se află la 40 de pixeli la stânga și la 40 de pixeli deasupra centrului calculat al imaginii.

3. Aritmetica imaginii

De fapt, aritmetica imaginii este doar o adăugare de matrice cu câteva restricții suplimentare privind tipurile de date pe care le vom acoperi mai târziu.

Să luăm un moment pentru a trece peste câteva elemente fundamentale ale algebrei liniare.

Luați în considerare combinarea următoarelor două matrici:

Ce rezultat ar produce adăugarea matricei? Răspunsul simplu este suma intrărilor din matrice, element cu element:

Destul de simplu, nu?

Cu toții înțelegem operațiile fundamentale de adunare și scădere în acest moment. Cu toate acestea, trebuie să fim atenți la restricțiile impuse de spațiul nostru de culoare și tipul de date atunci când lucrăm cu imagini.

Pixelii din imaginile RGB, de exemplu, se încadrează între [0, 255]. Ce se întâmplă dacă încercăm să adăugăm 10 la un pixel cu o intensitate de 250 în timp ce ne uităm la el?

Am ajunge la o valoare de 260 dacă am aplica principiile aritmetice standard. 260 nu este o valoare validă, deoarece imaginile RGB sunt reprezentate ca numere întregi fără semn pe 8 biți.

Deci, ce ar trebui să se întâmple? Ar trebui să executăm o verificare pentru a ne asigura că niciun pixel nu este dincolo de intervalul [0, 255], tăind fiecare pixel pentru a avea o valoare între 0 și 255?

Sau „înfășurăm” și efectuăm o operație cu modul? În conformitate cu regulile modulului, adăugarea de la 10 la 255 ar duce doar la o valoare de 9.

Cum ar trebui gestionate adunările și scăderile la imagini dincolo de intervalul [0, 255]?

Adevărul este că nu există o tehnică corectă sau greșită; totul depinde de modul în care lucrezi cu pixelii tăi și de ceea ce speri să obții.

Dar amintiți-vă că există diferențe între adăugarea în OpenCV și adăugarea în NumPy. Aritmetica modulului și „înfășurarea” vor fi făcute de NumPy. În schimb, OpenCV va executa tăierea și se va asigura că valorile pixelilor nu părăsesc niciodată intervalul [0, 255].

Să începem prin a crea un nou fișier numit aritmetică.py și deschizându-l:

# python arithmetic.py --image squirrel.jpg

# importul pachetelor necesare

import numpy la fel de de exemplu.

import argparse

import imutil

import cv2

# crearea obiectului argumentparser și analizarea argumentului

apObj = argparse. ArgumentParser ( )

apObj. add_argument ( '-k' , '--imagine' , necesar = Adevărat , Ajutor = 'calea imaginii' )

argumente = a caror ( apObj. parse_args ( ) )

imagine = cv2. imcitit ( argumente [ 'imagine' ] )

cv2. imshow ( „Imagine_originală” , imagine )

'''

Valorile pixelilor noștri vor fi în intervalul [0, 255]

deoarece imaginile sunt matrice NumPy, care sunt stocate ca numere întregi nesemnate de 8 biți.

Când utilizați funcții precum cv2.add și cv2.subtract, valorile vor fi tăiate

la acest interval chiar dacă sunt adăugate sau scazute din exteriorul

intervalul [0, 255]. Iată o ilustrație:

'''


imprimare ( „maximum de 255: {}” . format ( str ( cv2. adăuga ( de exemplu. uint8 ( [ 201 ] ) ,

de exemplu. uint8 ( [ 100 ] ) ) ) ) )

imprimare ( „minimum 0: {}” . format ( str ( cv2. scădea ( de exemplu. uint8 ( [ 60 ] ) ,

de exemplu. uint8 ( [ 100 ] ) ) ) ) )

'''

Când efectuați operații aritmetice cu aceste matrice folosind NumPy,

valoarea se va înfășura mai degrabă decât să fie tăiată la

intervalul [0, 255]. Când utilizați imagini, este esențial să păstrați acest lucru

in minte.

'''


imprimare ( „înfășurare: {}” . format ( str ( de exemplu. uint8 ( [ 201 ] ) + de ex. uint8 ( [ 100 ] ) ) ) )

imprimare ( „înfășurare: {}” . format ( str ( de exemplu. uint8 ( [ 60 ] ) - de exemplu. uint8 ( [ 100 ] ) ) ) )

'''

Să înmulțim luminozitatea fiecărui pixel din imaginea noastră cu 101.

Pentru a face acest lucru, generăm o matrice NumPy de aceeași dimensiune ca matricea noastră,

umplut cu unele și înmulțiți-l cu 101 pentru a produce o matrice plină

cu 101s. În cele din urmă, îmbinăm cele două imagini.

Veți observa că imaginea este acum „mai luminoasă”.

'''


Matrice = de exemplu. cele ( imagine. formă , dtype = 'uint8' ) * 101

imagine_adăugă = cv2. adăuga ( imagine , Matrice )

cv2. imshow ( „Rezultat imagine adăugată” , imagine_adăugă )

#În mod similar, ne putem întuneca imaginea prin luare

#60 distanță de toți pixelii.

Matrice = de exemplu. cele ( imagine. formă , dtype = 'uint8' ) * 60

imagine_scăzută = cv2. scădea ( imagine , Matrice )

cv2. imshow ( „Rezultat imagine scăzută” , imagine_scăzută )

cv2. waitTasta ( 0 )

Liniile de la 1 la 16 va fi folosit pentru a efectua procesul nostru normal, care implică importarea pachetelor noastre, configurarea analizatorului de argumente și încărcarea imaginii noastre.

Vă amintiți cum am discutat anterior despre distincția dintre OpenCV și adăugarea NumPy? Acum că l-am acoperit în detaliu, să ne uităm la un caz specific pentru a ne asigura că îl înțelegem.

Sunt definite două matrice NumPy cu numere întregi nesemnate de 8 biți linia 26 . O valoare de 201 este singurul element din prima matrice. Deși doar un membru se află în a doua matrice, acesta are o valoare de 100. Valorile sunt apoi adăugate folosind funcția cv2.add de la OpenCV.

Care anticipați să fie rezultatul?

În conformitate cu principiile aritmetice convenționale, răspunsul ar trebui să fie 301. Dar amintiți-vă că avem de-a face cu numere întregi fără semn de 8 biți, care pot fi doar în intervalul [0, 255]. Deoarece utilizăm metoda cv2.add, OpenCV gestionează tăierea și se asigură că adăugarea returnează doar un rezultat maxim de 255.

Prima linie a listei de mai jos arată rezultatul rulării acestui cod:

aritmetic. py

maxim de 255 : [ [ 255 ] ]

Suma a produs într-adevăr un număr de 255.

În urma acesteia, linia 26 folosește cv2.subtract pentru a realiza o scădere. Încă o dată, definim două matrice NumPy de numere întregi nesemnate de 8 biți cu un singur element în fiecare. Valoarea primei matrice este 60, în timp ce valoarea celei de-a doua matrice este 100.

Aritmetica noastră dictează că scăderea ar trebui să aibă ca rezultat o valoare de -40, dar OpenCV se ocupă încă o dată de tăierea pentru noi. Descoperim că valoarea a fost redusă la 0. Rezultatul nostru de mai jos demonstrează acest lucru:

aritmetic. py

minim de 0 : [ [ 0 ] ]

Folosind cv2, scădeți 100 din 60 scădeți, producând valoarea 0.

Dar ce se întâmplă dacă folosim NumPy în loc de OpenCV pentru a efectua calculele?

Liniile 38 și 39 abordează această problemă.

În primul rând, sunt definite două matrice NumPy întregi nesemnate de 8 biți cu un singur element fiecare. Valoarea primei matrice este 201, în timp ce valoarea celei de-a doua matrice este 100. Adăugarea noastră ar fi tăiată și o valoare de 255 ar fi returnată dacă am folosi funcția cv2.add.

NumPy, pe de altă parte, „se înfășoară” și face modul aritmetică mai degrabă decât tăierea. NumPy se întoarce la zero odată ce este atinsă o valoare de 255 și apoi reia numărătoarea până când s-au atins 100 de pași. Acest lucru este confirmat de prima linie de ieșire, care este prezentată mai jos:

aritmetic. py
înfășura: [ Patru cinci ]

Apoi, sunt definite încă două tablouri NumPy, unul cu valoarea 50 și celălalt cu 100. Această scădere ar fi tăiată prin metoda cv2.subtract pentru a returna un rezultat de 0. Dar suntem conștienți că, în loc de tăiere, NumPy execută modulo aritmetică. În schimb, procedurile modulo se înfășoară și încep să numere înapoi de la 255 odată ce 0 este atins în timpul scăderii. Putem vedea acest lucru din următoarea ieșire:

aritmetic. py

înfășura: [ 207 ]

Încă o dată, ieșirea terminalului nostru demonstrează distincția dintre tăiere și înfășurare:

Este esențial să țineți cont de rezultatul dorit atunci când efectuați aritmetica întregi. Doriți să fie tăiate valorile din afara intervalului [0, 255]? Utilizați tehnicile de aritmetică a imaginii încorporate ale OpenCV după aceea.

Doriți ca valorile să se înglobeze dacă sunt în afara intervalului [0, 255] și a operațiilor aritmetice cu modul? Matricele NumPy sunt apoi pur și simplu adăugate și scăzute ca de obicei.

Linia 48 definește o matrice NumPy unidimensională cu aceleași dimensiuni ca imaginea noastră. Încă o dată, ne asigurăm că tipul nostru de date este de 8 biți întregi fără semn. Doar înmulțim matricea noastră de valori dintr-o cifră cu 101 pentru a o umple cu valori de 101 în loc de 1. În cele din urmă, folosim funcția cv2.add pentru a adăuga matricea noastră de 100s la imaginea originală. Acest lucru mărește intensitatea fiecărui pixel cu 101, asigurând, de asemenea, că orice valoare care încearcă să depășească 255 este tăiată în intervalul [0, 255].

Observați cum imaginea este vizibil mai luminoasă și pare mai „spălată” decât originalul. Acest lucru se datorează faptului că conducem pixelii către culori mai strălucitoare prin creșterea intensității pixelilor cu 101.

Pentru a scădea 60 din intensitatea fiecărei pixeli a imaginii, stabilim mai întâi o a doua matrice NumPy pe linia 54 care este umplută cu anii 60.

Rezultatele acestei scăderi sunt prezentate în următoarea imagine:

Elementele din jurul nostru par mult mai întunecate decât înainte. Acest lucru se datorează faptului că scăzând 60 din fiecare pixel, mutăm pixelii din spațiul de culoare RGB în regiunile mai întunecate.

4. Întoarcerea imaginii

Similar cu rotația, răsturnarea unei imagini pe axa x sau y este o altă opțiune oferită de OpenCV. Chiar dacă operațiunile de răsturnare nu sunt utilizate la fel de frecvent, cunoașterea lor este incredibil de benefică din diverse motive pe care s-ar putea să nu le vedeți imediat.

Dezvoltăm un clasificator de învățare automată pentru o mică companie startup care încearcă să identifice fețele în imagini. Pentru ca sistemul nostru să „învețe” ce este o față, am avea nevoie de un fel de set de date cu fețe eșantion. Din păcate, compania ne-a oferit doar un mic set de date de 40 de chipuri și nu putem aduna mai multe informații.

Atunci ce facem?

Deoarece o față rămâne o față, indiferent dacă este în oglindă sau nu, suntem capabili să întoarcem orizontal fiecare imagine a unei fețe și să folosim versiunile în oglindă ca date suplimentare de antrenament.

Acest exemplu poate părea stupid și artificial, dar nu este. Flipping este o strategie deliberată folosită de algoritmi puternici de învățare profundă pentru a produce mai multe date în timpul fazei de antrenament.

Din partea anterioară este clar că metodele de procesare a imaginilor pe care le învățați în acest modul servesc drept fundație pentru sisteme mai mari de viziune computerizată.

Obiective:

Folosind cv2.flip veți învăța cum să răsturnați o imagine atât pe orizontală, cât și pe verticală în această sesiune.

Întoarcerea este următoarea manipulare a imaginii pe care o vom studia. Axele x și y ale unei imagini pot fi răsturnate sau chiar ambele. Înainte de a ne aprofunda în codificare, cel mai bine este să ne uităm mai întâi la rezultatele unei întoarceri de imagine. Vedeți o imagine care a fost răsturnată orizontal în următoarea imagine:


Rețineți cum este imaginea noastră originală în stânga și cum imaginea a fost oglindită orizontal în dreapta.

Să începem prin a crea un nou fișier numit răsturnând.py .

Ați văzut un exemplu de întoarcere a imaginii, așa că haideți să examinăm codul:

# python flipping.py --image quirrel.jpg

# importul pachetelor necesare

import argparse

import cv2

# crearea obiectului parserului de argument și analiza argumentului

apObj = argparse. ArgumentParser ( )

apObj. add_argument ( '-i' , '--imagine' , necesar = Adevărat , Ajutor = 'calea imaginii' )

argument = a caror ( apObj. parse_args ( ) )

imagine = cv2. imcitit ( argument [ 'imagine' ] )

cv2. imshow ( 'Original' , imagine )

# întoarce imaginea pe orizontală

imagine răsturnată = cv2. flip ( imagine , 1 )

cv2. imshow ( „Imaginea inversată pe orizontală” , imagine răsturnată )

# răsturnează imaginea pe verticală

imagine răsturnată = cv2. flip ( imagine , 0 )

cv2. imshow ( „Imaginea inversată pe verticală” , imagine răsturnată )

# întoarcerea imaginii de-a lungul ambelor axe

imagine răsturnată = cv2. flip ( imagine , - 1 )

cv2. imshow ( „Întors orizontal și vertical” , imagine răsturnată )

cv2. waitTasta ( 0 )

Pașii pe care îi luăm pentru a ne importa pachetele, a ne analiza intrările și a încărca imaginea noastră de pe disc sunt gestionați în l inele de la 1 la 12 .

Apelând funcția cv2.flip activată Linia 15 , este simplu să răsturnați o imagine pe orizontală. Imaginea pe care căutăm să o răsturnăm și un anumit cod sau steag care specifică cum să răsturnăm imaginea sunt cele două argumente necesare pentru metoda cv2.flip.

O valoare a codului de întoarcere de 1 înseamnă că vom roti imaginea în jurul axei y pentru a o întoarce pe orizontală ( Linia 15 ). Dacă specificăm un cod flip de 0, dorim să rotim imaginea în jurul axei x ( Linia 19 ). Un cod flip negativ ( Linia 23 ) rotește imaginea pe ambele axe.

Unul dintre cele mai ușoare exemple în acest subiect este răsturnarea unei imagini, care este de bază.

În continuare, vom discuta despre tăierea imaginilor și vom folosi felii de matrice NumPy pentru a extrage anumite porțiuni de imagine.

5. Decuparea imaginii

Decuparea, după cum sugerează și numele, este procesul de alegere și eliminare a Regiunii de interes (sau pur și simplu ROI), care este zona imaginii care ne interesează.

Fața ar trebui să fie tăiată dintr-o imagine pentru o aplicație de detectare a feței. În plus, dacă am crea un script Python pentru a găsi câini în imagini, ar putea dori să decupăm câinele din imagine când îl găsim.

Obiective: Scopul nostru principal este să ne familiarizăm și să ne ușurim folosind tăierea matricei NumPy pentru a decupa zone dintr-o imagine.

Decuparea : Când decupăm o imagine, scopul nostru este să eliminăm elementele exterioare care nu ne interesează. Procesul de alegere a rentabilității investiției este adesea denumit alegerea regiunii noastre de interes.

Creați un fișier nou numit crop.py , deschideți-l și adăugați următorul cod:

# python crop.py

# importul pachetelor necesare

import cv2

# încărcarea imaginii și afișarea pe ecran

imagine = cv2. imcitit ( „veveriță.jpg” )

imprimare ( imagine. formă )

cv2. imshow ( 'Original' , imagine )

# Secțiunile de matrice NumPy sunt folosite pentru a tăia rapid o imagine

# vom decupa fața de veveriță din imagine

chip de veveriță = imagine [ 35 : 90 , 35 : 100 ]

cv2. imshow ( 'față de veveriță' , chip de veveriță )

cv2. waitTasta ( 0 )

# Și acum, aici vom tăia întregul corp

# de veveriță

corp de veveriță = imagine [ 35 : 148 , 23 : 143 ]

cv2. imshow ( „Corpul de veveriță” , corp de veveriță )

cv2. waitTasta ( 0 )

Vom afișa decuparea în Python și OpenCV folosind o imagine pe care o încărcăm de pe disc Rândurile 5 și 6 .

Imagine originală pe care o vom decupa

Folosind numai tehnici de tăiere de bază, ne propunem să separăm fața și corpul veveriței de zona înconjurătoare.

Vom folosi cunoștințele noastre anterioare despre imagine și vom furniza manual secțiunile de matrice NumPy ale locului în care există corpul și fața. În condiții normale, am folosi, în general, algoritmi de învățare automată și de viziune pe computer pentru a recunoaște fața și corpul din imagine. Dar să menținem lucrurile simple deocamdată și să evităm să folosim orice model de detectare.

Putem identifica fața din imagine cu o singură linie de cod. Linia 13 , Pentru a extrage o porțiune dreptunghiulară a imaginii, începând cu (35, 35), oferim felii de matrice NumPy (90, 100). Poate părea confuz faptul că alimentăm decuparea cu indici în ordinea înălțimii prima și lățimea a doua pe care o facem, dar rețineți că OpenCV stochează imaginile ca matrice NumPy. Ca rezultat, trebuie să furnizăm valorile pentru axa y înainte de axa x.

NumPy necesită următorii patru indici pentru a efectua tăierea noastră:

Începeți : Coordonata y la început. În acest caz, începem de la y=35.

Sfârșit y: Coordonata y la final. Recolta noastră se va opri când y = 90.

Începe x: Coordonata x începută a feliei. Cultivarea începe la x=35.

Sfârșit x: Coordonata finală a axei x a feliei. La x=100, felia noastră este terminată.

În mod similar, decupăm regiunile (23, 35) și (143, 148) din imaginea originală pentru a extrage întregul corp din imaginea de pe Linia 19 .

Puteți observa că imaginea a fost decupată pentru a prezenta doar corpul și fața.

6. Redimensionarea imaginii

Procesul de creștere sau micșorare a lățimii și înălțimii unei imagini este cunoscut sub numele de scalare sau pur și simplu redimensionare. Raportul de aspect, care este proporția dintre lățimea unei imagini și înălțimea acesteia, trebuie luat în considerare atunci când redimensionați o imagine. Neglijarea raportului de aspect poate avea ca rezultat imagini care au fost scalate, care par comprimate și distorsionate:

Imaginea noastră inițială este în stânga. În dreapta, veți vedea două imagini care au fost scalate fără a menține raportul de aspect, distorsionând proporția dintre lățimea imaginii și înălțimea acesteia. Când redimensionați imaginile, ar trebui să luați în considerare, în general, raportul de aspect.

Tehnica de interpolare folosită de algoritmul nostru de redimensionare trebuie să ia în considerare și obiectivul funcției de interpolare de a folosi aceste vecinătăți de pixeli fie pentru a crește, fie a micșora dimensiunea imaginii.

În general, micșorarea dimensiunii imaginii este mult mai eficientă. Acest lucru se datorează faptului că eliminarea pixelilor dintr-o imagine este tot ce trebuie să facă funcția de interpolare. Pe de altă parte, metoda de interpolare ar trebui să „umple golurile” dintre pixelii care nu existau anterior dacă dimensiunea imaginii ar fi crescută.

Avem imaginea noastră originală în stânga. Imaginea a fost redusă la jumătate din dimensiunea inițială în centru, dar în afară de aceasta, nu s-a înregistrat nicio pierdere a „calității” imaginii. Cu toate acestea, dimensiunea imaginii a fost îmbunătățită considerabil în partea dreaptă. Acum pare „explodat” și „pixelat”.

După cum am afirmat anterior, de obicei veți dori să reduceți dimensiunea unei imagini, mai degrabă decât să o măriți. Prin reducerea dimensiunii imaginii, analizăm mai puțini pixeli și trebuie să ne confruntăm cu mai puțin „zgomot”, ceea ce face ca algoritmii de procesare a imaginii să fie mai rapidi și mai precisi.

Translația și rotația sunt cele două transformări de imagine abordate până acum. Vom examina acum cum să redimensionăm o imagine.

Deloc surprinzător, ne vom redimensiona imaginile folosind metoda cv2.resize. După cum am indicat mai devreme, trebuie să luăm în considerare raportul de aspect al imaginii atunci când folosim această metodă. Dar înainte de a intra prea adânc în detalii, permiteți-mi să vă dau o ilustrare:

# python resize.py --image squirrel.jpg

# importul pachetelor necesare

import argparse

import cv2

# crearea obiectului parserului de argument și analiza argumentului

apObj = argparse. ArgumentParser ( )

apObj. add_argument ( '-k' , '--imagine' , necesar = Adevărat , Ajutor = 'calea imaginii' )

argumente = a caror ( apObj. parse_args ( ) )

# încărcați imaginea și afișați-o pe ecran

imagine = cv2. imcitit ( argumente [ 'imagine' ] )

cv2. imshow ( 'Original' , imagine )

# Pentru a preveni ca imaginea să apară înclinată, raportul de aspect

# trebuie luate în considerare sau deformate; prin urmare, ne dăm seama ce

# raportul dintre noua imagine și imaginea curentă.

# Să facem ca lățimea noii noastre imagini să fie de 160 de pixeli.

aspect = 160,0 / imagine. formă [ 1 ]

dimensiune = ( 160 , int ( imagine. formă [ 0 ] * aspect ) )

# această linie va afișa operațiunile reale de redimensionare

imagine redimensionată = cv2. redimensiona ( imagine , dimensiune , interpolare = cv2. INTER_ZONA )

cv2. imshow ( „Lățimea imaginii redimensionată” , imagine redimensionată )

# Ce se întâmplă dacă am vrea să schimbăm înălțimea imaginii? — folosind

# același principiu, putem calcula raportul de aspect pe baza

# pe înălțime și nu pe lățime. Să facem scalat

# înălțimea imaginii 70 pixeli.

aspect = 70,0 / imagine. formă [ 0 ]

dimensiune = ( int ( imagine. formă [ 1 ] * aspect ) , 70 )

# efectuează redimensionarea

imagine redimensionată = cv2. redimensiona ( imagine , dimensiune , interpolare = cv2. INTER_ZONA )

cv2. imshow ( „Înălțimea imaginii redimensionată” , imagine redimensionată )

cv2. waitTasta ( 0 )

Rândurile 1-14 , După importarea pachetelor noastre și configurarea analizatorului de argumente, vom încărca și vom afișa imaginea noastră.

Liniile 20 și 21: codificarea relevantă începe în aceste rânduri . Raportul de aspect al imaginii trebuie luat în considerare la redimensionarea acesteia. Proporția dintre lățimea și înălțimea imaginii este cunoscută sub numele de raport de aspect.

Înălțime lățime este raportul de aspect.

Dacă nu luăm în considerare raportul de aspect, rezultatele redimensionării noastre vor deveni distorsionate.

Pe Linia 20 , se face calculul raportului redimensionat. Oferim lățimea noii imagini ca 160 de pixeli în această linie de cod. Pur și simplu definim raportul (aspectratio) ca noua lățime (160 pixeli) împărțită la vechea lățime, pe care o accesăm folosind imaginea, pentru a calcula raportul dintre noua înălțime și vechea înălțime. formă[1].

Noile dimensiuni ale imaginii pe Linia 21 poate fi calculat acum că ne cunoaștem raportul. Încă o dată, noua imagine va avea o lățime de 160 de pixeli. După ce înmulțim vechea înălțime cu raportul nostru și transformăm rezultatul într-un număr întreg, se calculează înălțimea. Putem menține raportul de aspect original al imaginii efectuând această operație.

Linia 24 este locul în care imaginea este cu adevărat redimensionată. Imaginea pe care dorim să o redimensionăm este primul argument, iar al doilea este dimensiunile pe care le-am calculat pentru noua imagine. Metoda noastră de interpolare, care este algoritmul de redimensionare a imaginii reale, este ultimul parametru.

În sfârșit, pe Linia 25 , afișăm imaginea noastră la scară.

Ne redefinim raportul (aspectrația) pe Linia 31 . Înălțimea noii noastre imagini va fi de 70 de pixeli. Împărțim 70 la înălțimea inițială pentru a obține noul raport înălțime-înălțime originală.

Apoi, stabilim dimensiunile noii imagini. Noua imagine va avea o înălțime de 70 de pixeli, ceea ce este deja cunoscut. Putem păstra încă o dată raportul de aspect original al imaginii prin înmulțirea lățimii vechi cu raportul pentru a produce noua lățime.

Imaginea este apoi redimensionată Linia 35 , și este afișat pe Linia 36.

Aici, putem vedea că am redus lățimea și înălțimea imaginii noastre originale, păstrând în același timp raportul de aspect. Imaginea noastră ar părea distorsionată dacă raportul de aspect nu ar fi menținut.

Concluzie

În acest blog, am studiat diferitele concepte de bază de procesare a imaginii. Am văzut traducerea imaginilor cu ajutorul pachetului OpenCV. Am văzut metodele de mutare a imaginii în sus, în jos, la dreapta și la stânga. Aceste metode sunt foarte utile atunci când creăm un set de date de imagini similare pentru a le oferi ca set de date de antrenament, astfel încât aparatul va vedea imagini diferite chiar dacă sunt aceleași. Acest articol v-a învățat și cum să rotiți o imagine în jurul oricărui punct din spațiul cartezian folosind o matrice de rotație. Apoi ați descoperit cum OpenCV rotește imaginile folosind această matrice și ați văzut câteva ilustrații ale imaginilor care se rotesc.

Cele două operații aritmetice de imagine fundamentale (dar semnificative) de adunare și scădere au fost examinate în această secțiune. După cum puteți vedea, adăugarea și scăderea matricelor fundamentale reprezintă toate operațiunile aritmetice de imagine.

În plus, am folosit OpenCV și NumPy pentru a investiga particularitățile aritmeticii imaginii. Aceste restricții trebuie reținute, altfel riscați să obțineți rezultate neașteptate atunci când executați operații aritmetice pe imagini.

Este important să ne amintim că, deși NumPy efectuează o operație de modul și „înfășoară”, valorile de adunare și scădere OpenCV tăiate dincolo de intervalul [0, 255] pentru a se potrivi în interval. Când vă dezvoltați propriile aplicații de viziune computerizată, amintirea acestui lucru vă va ajuta să evitați vânătoarea de bug-uri complicate.

Întoarcerea imaginilor este, fără îndoială, una dintre ideile mai simple pe care le vom explora în acest curs. Flippingul este folosit frecvent în învățarea automată pentru a genera mai multe mostre de date de antrenament, rezultând clasificatoare de imagini mai puternice și mai fiabile.

De asemenea, am învățat cum să folosim OpenCV pentru a redimensiona o imagine. Este esențial să luați în considerare atât metoda de interpolare pe care o utilizați, cât și raportul de aspect al imaginii originale atunci când redimensionați una, astfel încât rezultatul să nu pară distorsionat.

În cele din urmă, este esențial să ne amintim că, dacă calitatea imaginii este o problemă, este întotdeauna cel mai bine să treceți de la o imagine mai mare la una mai mică. În cele mai multe cazuri, mărirea unei imagini creează artefacte și îi degradează calitatea.