Det var oundvikligt – OpenCV 3-utgåvan var tvungen att bryta bakåtkompatibiliteten med vissa OpenCV 2.4.X-funktioner: cv2.findContours
och cv2.normalize
kommer jag att tänka på direkt i mitt huvud.
Så hur säkerställer du att din kod kommer att fungera oavsett vilken version av OpenCV din produktionsmiljö använder?
Det korta svaret är att du måste skapa if
-angivelser runt var och en av de felande funktionerna (eller abstrahera funktionerna till en separat metod som hanterar anropandet av lämplig funktion baserat på din OpenCV-version).
För att kunna göra detta måste du kunna kontrollera din OpenCV-version från din Python-användning – och det är precis vad resten av den här bloggen kommer att visa dig hur du ska göra!
Söker du källkoden till det här inlägget?
Hoppa direkt till nedladdningsavsnittet
OpenCV-versionen finns i en speciell cv2.__version__
-variabel, som du kan komma åt så här:
$ python>>> import cv2>>> cv2.__version__'3.0.0'
cv2.__version__
-variabeln är helt enkelt en sträng som du kan dela upp i major- och minor-versionen:
>>> (major, minor, _) = cv2.__version__.split(".")>>> major'3'>>> minor'0'
Att behöva göra den här operationen varje gång du behöver kontrollera din OpenCV-version är naturligtvis lite jobbigt. För att lösa detta problem har jag lagt till tre nya funktioner till mitt imutils-paket, en serie bekvämlighetsfunktioner för att underlätta grundläggande bildbehandlingsfunktioner med OpenCV och Python.
Du kan se mina is_cv2
, is_cv3
och check_opencv_version
-funktioner nedan:
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)
Koden här är ganska okomplicerad – jag kontrollerar helt enkelt om cv2.__version__
-strängen börjar med ett 2
, vilket indikerar att vi använder OpenCV 2.X, ett 3
, för att indikera att vi använder OpenCV 3, eller ett 4
, för att indikera att vi använder OpenCV 4.
Dessa funktioner har redan inkluderats i imutils-paketet, som du kan installera med hjälp av pip:
$ pip install imutils
Om du redan har imutils
installerat kan du uppgradera till den senaste versionen med hjälp av:
$ pip install --upgrade imutils
Kontrollera din OpenCV-version: Nu när vi vet hur vi kan kontrollera vår OpenCV-version med hjälp av Python samt definierat ett par bekvämlighetsfunktioner för att göra versionskontrollen enklare, låt oss se hur vi kan använda dessa funktioner i ett exempel från den verkliga världen.
Vårt mål här är att upptäcka konturer i följande bild:
För att upptäcka konturer i en bild måste vi använda funktionen cv2.findContours
. Som vi vet har dock retursignaturen för cv2.findContours
ändrats något mellan version 3 och 2.4 av OpenCV (OpenCV 3-versionen av cv2.findContours
returnerar ett extra värde i tupeln) – därför måste vi utföra en kontroll av vår OpenCV-version innan vi anropar cv2.findContours
för att se till att vårt skript inte ger fel. Låt oss ta en titt på hur vi kan göra denna kontroll:
# 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)
Som du kan se är allt vi behöver göra att göra ett anrop till is_cv2
, is_cv4
och is_cv3
och sedan linda in vår versionsspecifika kod inuti if
-anvisningsblocken – det är allt!
När jag nu går till att exekvera mitt skript med OpenCV 2.4 fungerar det utan problem:
Det samma gäller för OpenCV 3:
Sammanfattning
I det här blogginlägget har vi lärt oss hur vi kan kontrollera vår OpenCV-version med Python. OpenCV-versionen ingår i en speciell strängvariabel som heter cv2.__version__
. Allt vi behöver göra är att kontrollera denna variabel så kan vi bestämma vår OpenCV-version.
Slutligt har jag definierat några bekvämlighetsmetoder inom imutils-paketet för att göra det enklare och mer pythoniskt att kontrollera din OpenCV-version. Överväg att kolla in biblioteket om du upptäcker att du konsekvent behöver kontrollera OpenCV-versioner.