Het was onvermijdelijk – de OpenCV 3-release moest wel de achterwaartse compatibiliteit met sommige OpenCV 2.4.X-functies verbreken: cv2.findContours
en cv2.normalize
schieten me zo te binnen.
Hoe zorgt u er dus voor dat uw code werkt, ongeacht welke versie van OpenCV uw productie-omgeving gebruikt?
Wel, het korte antwoord is dat je if
statements moet maken rond elk van de overtredende functies (of de functies weg abstraheren naar een aparte methode die de juiste functie aanroept op basis van je OpenCV versie).
Om dit te doen, moet je in staat zijn om je OpenCV versie te controleren vanuit je Python – en dat is precies wat de rest van deze blog je zal laten zien hoe dat moet!
Op zoek naar de broncode van dit bericht?
Spring direct naar de Downloads Sectie
De OpenCV versie zit in een speciale cv2.__version__
variabele, die u als volgt kunt benaderen:
$ python>>> import cv2>>> cv2.__version__'3.0.0'
De cv2.__version__
variabele is simpelweg een string die u kunt splitsen in de major en minor versies:
>>> (major, minor, _) = cv2.__version__.split(".")>>> major'3'>>> minor'0'
Natuurlijk is het een beetje vervelend om deze operatie uit te moeten voeren elke keer dat u uw OpenCV versie wilt controleren. Om dit probleem op te lossen, heb ik drie nieuwe functies toegevoegd aan mijn imutils pakket, een serie gemaksfuncties om basis beeldverwerkingsfuncties met OpenCV en Python eenvoudiger te maken.
U kunt mijn is_cv2
, is_cv3
, en check_opencv_version
functies hieronder zien:
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)
De code hier is vrij eenvoudig – ik controleer gewoon of de cv2.__version__
string begint met een 2
, om aan te geven dat we OpenCV 2.X gebruiken, een 3
, om aan te geven dat we OpenCV 3 gebruiken, of een 4
, om aan te geven dat we OpenCV 4 gebruiken.
Ook deze functies zijn al opgenomen in het imutils pakket, dat u kunt installeren met pip:
$ pip install imutils
Als u imutils
al heeft geinstalleerd, kunt u upgraden naar de laatste versie met:
$ pip install --upgrade imutils
Het controleren van uw OpenCV versie: een voorbeeld uit de echte wereld
Nu we weten hoe we onze OpenCV versie kunnen controleren met Python en een paar handige functies hebben gedefinieerd om de versiecontrole te vergemakkelijken, laten we eens kijken hoe we deze functies kunnen gebruiken in een voorbeeld uit de echte wereld.
Het doel is om contouren te detecteren in de volgende afbeelding:
Om contouren in een afbeelding te detecteren, moeten we de functie cv2.findContours
gebruiken. Maar, zoals we weten, is de return signature van cv2.findContours
iets veranderd tussen versie 3 en 2.4 van OpenCV (de OpenCV 3 versie van cv2.findContours
retourneert een extra waarde in de tuple) – dus we moeten onze OpenCV versie controleren voordat we cv2.findContours
aanroepen om er zeker van te zijn dat ons script niet fout gaat. Laten we eens kijken hoe we deze controle kunnen uitvoeren:
# 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)
Zoals u kunt zien, hoeven we alleen is_cv2
, is_cv4
en is_cv3
aan te roepen en dan onze versie-specifieke code in de if
statement blokken te wikkelen – dat is alles!
Als ik nu mijn script uitvoer met OpenCV 2.4, werkt het zonder problemen:
En hetzelfde geldt voor OpenCV 3:
Samenvatting
In deze blogbijdrage hebben we geleerd hoe we onze OpenCV-versie kunnen controleren met behulp van Python. De OpenCV versie is opgenomen in een speciale string variabele met de naam cv2.__version__
. Alles wat we hoeven te doen is deze variabele te controleren en we zullen in staat zijn om onze OpenCV versie te bepalen.
Ten slotte heb ik een paar handige methoden gedefinieerd in het imutils pakket om het controleren van je OpenCV versie gemakkelijker en meer Pythonisch te maken. Overweeg de bibliotheek te bekijken als je consequent OpenCV-versies moet controleren.