Det var uundgåeligt – OpenCV 3-udgaven var nødt til at bryde bagudkompatibiliteten med nogle OpenCV 2.4.X-funktioner: cv2.findContours
og cv2.normalize
falder mig lige i øjnene.
Så hvordan sikrer du, at din kode vil fungere, uanset hvilken version af OpenCV dit produktionsmiljø bruger?
Det korte svar er, at du skal oprette if
-erklæringer omkring hver af de ulovlige funktioner (eller abstrahere funktionerne til en separat metode, der håndterer at kalde den relevante funktion baseret på din OpenCV-version).
For at gøre dette skal du kunne kontrollere din OpenCV-version fra din bruger Python – og det er præcis, hvad resten af denne blog vil vise dig, hvordan du kan gøre!
Søger du kildekoden til dette indlæg?
Spring direkte til download-sektionen
OpenCV-versionen er indeholdt i en særlig cv2.__version__
-variabel, som du kan få adgang til på denne måde:
$ python>>> import cv2>>> cv2.__version__'3.0.0'
cv2.__version__
-variablen er simpelthen en streng, som du kan opdele i major- og minor-versionen:
>>> (major, minor, _) = cv2.__version__.split(".")>>> major'3'>>> minor'0'
Det er selvfølgelig lidt besværligt at skulle udføre denne operation, hver gang du har brug for at tjekke din OpenCV-version. For at løse dette problem har jeg tilføjet tre nye funktioner til min imutils-pakke, en række bekvemmelighedsfunktioner, der skal gøre grundlæggende billedbehandlingsfunktioner med OpenCV og Python lettere.
Du kan se mine is_cv2
, is_cv3
og check_opencv_version
-funktioner nedenfor:
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 her er ret ligetil – jeg kontrollerer simpelthen, om cv2.__version__
-strengen starter med et 2
, hvilket indikerer, at vi bruger OpenCV 2.X, et 3
, for at indikere, at vi bruger OpenCV 3, eller et 4
, for at indikere, at vi bruger OpenCV 4.
Disse funktioner er allerede blevet inkluderet i pakken imutils, som du kan installere ved hjælp af pip:
$ pip install imutils
Hvis du allerede har imutils
installeret, kan du opgradere til den nyeste version ved hjælp af:
$ pip install --upgrade imutils
Kontrol af din OpenCV-version: Nu hvor vi ved, hvordan vi kan kontrollere vores OpenCV-version ved hjælp af Python, samt har defineret et par bekvemmelighedsfunktioner for at gøre versionskontrollen lettere, lad os se, hvordan vi kan bruge disse funktioner i et eksempel fra den virkelige verden.
Vores mål her er at detektere konturer i følgende billede:
For at registrere konturer i et billede skal vi bruge cv2.findContours
-funktionen. Men som vi ved, er retursignaturen for cv2.findContours
ændret en smule mellem version 3 og 2.4 af OpenCV (OpenCV 3-versionen af cv2.findContours
returnerer en ekstra værdi i tuplen) – derfor skal vi foretage en kontrol af vores OpenCV-version, inden vi foretager et kald til cv2.findContours
for at sikre, at vores script ikke giver fejl. Lad os se på, hvordan vi kan foretage denne kontrol:
# 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, skal vi blot foretage et kald til is_cv2
, is_cv4
og is_cv3
og derefter pakke vores versionsspecifikke kode ind i if
-erklæringsblokkene – det er det hele!
Nu, når jeg går til at udføre mit script med OpenCV 2.4, virker det uden problemer:
Og det samme gælder for OpenCV 3:
Summary
I dette blogindlæg lærte vi, hvordan vi kan kontrollere vores OpenCV-version ved hjælp af Python. OpenCV-versionen er inkluderet i en særlig strengvariabel ved navn cv2.__version__
. Alt vi skal gøre er at kontrollere denne variabel, og vi vil kunne bestemme vores OpenCV-version.
Endeligt har jeg defineret et par bekvemmelighedsmetoder inde i imutils-pakken for at gøre det nemmere og mere pythonisk at kontrollere din OpenCV-version. Overvej at tjekke biblioteket ud, hvis du finder dig selv nødt til konsekvent at kontrollere OpenCV-versioner.