Era inevitabile – il rilascio di OpenCV 3 era destinato a rompere la compatibilità all’indietro con alcune funzioni di OpenCV 2.4.X: cv2.findContours
e cv2.normalize
mi vengono in mente così su due piedi.
Come ti assicuri che il tuo codice funzioni indipendentemente dalla versione di OpenCV che il tuo ambiente di produzione sta usando?
Beh, la risposta breve è che avrete bisogno di creare dichiarazioni if
intorno a ciascuna delle funzioni incriminate (o astrarre le funzioni in un metodo separato che gestisca la chiamata della funzione appropriata in base alla vostra versione di OpenCV).
Per fare questo, dovrete essere in grado di controllare la vostra versione di OpenCV dall’interno del vostro Python – e questo è esattamente ciò che il resto di questo blog vi mostrerà come fare!
Cercate il codice sorgente di questo post?
Salta direttamente alla sezione Downloads
La versione di OpenCV è contenuta in una speciale variabile cv2.__version__
, alla quale puoi accedere in questo modo:
$ python>>> import cv2>>> cv2.__version__'3.0.0'
La variabile cv2.__version__
è semplicemente una stringa che puoi dividere in versione maggiore e minore:
>>> (major, minor, _) = cv2.__version__.split(".")>>> major'3'>>> minor'0'
Ovviamente, dover eseguire questa operazione ogni volta che hai bisogno di controllare la versione di OpenCV è un po’ doloroso. Per risolvere questo problema, ho aggiunto tre nuove funzioni al mio pacchetto imutils, una serie di funzioni di comodo per rendere più semplici le funzioni base di elaborazione delle immagini con OpenCV e Python.
Puoi vedere le mie funzioni is_cv2
, is_cv3
e check_opencv_version
qui sotto:
def is_cv2(): # if we are using OpenCV 2, then our cv2.__version__ will start # with '2.' return check_opencv_version("2.")def is_cv3(): # if we are using OpenCV 3.X, then our cv2.__version__ will start # with '3.' return check_opencv_version("3.")def is_cv4(): # if we are using OpenCV 3.X, then our cv2.__version__ will start # with '4.' return check_opencv_version("4.")def check_opencv_version(major, lib=None): # if the supplied library is None, import OpenCV if lib is None: import cv2 as lib # return whether or not the current OpenCV version matches the # major version number return lib.__version__.startswith(major)
Il codice qui è abbastanza semplice – sto semplicemente controllando se la stringa cv2.__version__
inizia con un 2
, indicando che stiamo usando OpenCV 2.X, un 3
, per indicare che stiamo usando OpenCV 3, o un 4
, per indicare che stiamo usando OpenCV 4.
Anche queste funzioni sono già state incluse nel pacchetto imutils, che potete installare usando pip:
$ pip install imutils
Se avete già installato imutils
, potete aggiornare all’ultima versione usando:
$ pip install --upgrade imutils
Verificare la vostra versione di OpenCV: un esempio del mondo reale
Ora che sappiamo come controllare la nostra versione di OpenCV usando Python e che abbiamo definito un paio di funzioni di comodo per facilitare il controllo della versione, vediamo come possiamo usare queste funzioni in un esempio del mondo reale.
Il nostro obiettivo è quello di rilevare i contorni nella seguente immagine:
Per rilevare i contorni in un’immagine, dovremo usare la funzione cv2.findContours
. Tuttavia, come sappiamo, la firma di ritorno di cv2.findContours
è cambiata leggermente tra la versione 3 e la 2.4 di OpenCV (la versione OpenCV 3 di cv2.findContours
restituisce un valore extra nella tupla) – quindi dovremo eseguire un controllo sulla nostra versione di OpenCV prima di fare una chiamata a cv2.findContours
per assicurarci che il nostro script non dia errore. Diamo un’occhiata a come possiamo fare questo controllo:
# import the necessary packagesfrom __future__ import print_functionimport imutilsimport cv2# load the Tetris block image, convert it to grayscale, and threshold# the imageprint("OpenCV Version: {}".format(cv2.__version__))image = cv2.imread("tetris_blocks.png")gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)thresh = cv2.threshold(gray, 225, 255, cv2.THRESH_BINARY_INV)# check to see if we are using OpenCV 2.X or OpenCV 4if imutils.is_cv2() or imutils.is_cv4():(cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# check to see if we are using OpenCV 3elif imutils.is_cv3():(_, cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# draw the contours on the imagecv2.drawContours(image, cnts, -1, (240, 0, 159), 3)cv2.imshow("Image", image)cv2.waitKey(0)
Come potete vedere, tutto quello che dobbiamo fare è fare una chiamata a is_cv2
, is_cv4
e is_cv3
e poi avvolgere il nostro codice specifico della versione all’interno dei blocchi di dichiarazione if
– questo è tutto!
Ora quando vado ad eseguire il mio script usando OpenCV 2.4, funziona senza problemi:
E lo stesso vale per OpenCV 3:
Sommario
In questo post del blog abbiamo imparato come controllare la nostra versione di OpenCV usando Python. La versione di OpenCV è inclusa in una speciale variabile stringa chiamata cv2.__version__
. Tutto quello che dobbiamo fare è controllare questa variabile e saremo in grado di determinare la nostra versione di OpenCV.
Infine, ho definito alcuni metodi di convenienza all’interno del pacchetto imutils per rendere il controllo della versione di OpenCV più facile e più pitonico. Considerate di controllare la libreria se vi trovate ad aver bisogno di controllare costantemente le versioni di OpenCV.