To było nieuniknione – wydanie OpenCV 3 musiało złamać wsteczną kompatybilność z niektórymi funkcjami OpenCV 2.4.X: cv2.findContours
i cv2.normalize
przychodzą mi na myśl z głowy.
Jak więc zapewnić, że Twój kod będzie działał bez względu na to, której wersji OpenCV używa Twoje środowisko produkcyjne?
Więc, krótka odpowiedź jest taka, że będziesz musiał utworzyć if
deklaracje wokół każdej z nieprawidłowych funkcji (lub wyabstrahować funkcje do oddzielnej metody, która obsługuje wywołanie odpowiedniej funkcji w oparciu o wersję OpenCV).
Aby to zrobić, będziesz musiał być w stanie sprawdzić wersję OpenCV z poziomu Pythona – i to jest dokładnie to, co reszta tego bloga pokaże Ci jak to zrobić!
Szukasz kodu źródłowego do tego posta?
Skocz od razu do sekcji Downloads
Wersja OpenCV jest zawarta w specjalnej zmiennej cv2.__version__
, do której można uzyskać dostęp w następujący sposób:
$ python>>> import cv2>>> cv2.__version__'3.0.0'
Zmienna cv2.__version__
jest po prostu ciągiem znaków, który można podzielić na wersję główną i mniejszą:
>>> (major, minor, _) = cv2.__version__.split(".")>>> major'3'>>> minor'0'
Oczywiście, konieczność wykonywania tej operacji za każdym razem, gdy trzeba sprawdzić wersję OpenCV jest trochę bolesna. Aby rozwiązać ten problem, dodałem trzy nowe funkcje do mojego pakietu imutils, serii wygodnych funkcji ułatwiających podstawowe funkcje przetwarzania obrazu za pomocą OpenCV i Pythona.
Możesz zobaczyć moje funkcje is_cv2
, is_cv3
, i check_opencv_version
poniżej:
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)
Kod tutaj jest dość prosty – po prostu sprawdzam, czy łańcuch cv2.__version__
zaczyna się od 2
, wskazując, że używamy OpenCV 2.X, a 3
, aby wskazać, że używamy OpenCV 3, lub 4
, aby wskazać, że używamy OpenCV 4.
Ponownie, funkcje te zostały już zawarte w pakiecie imutils, który można zainstalować za pomocą pip:
$ pip install imutils
Jeśli masz już imutils
zainstalowane, możesz zaktualizować je do najnowszej wersji za pomocą:
$ pip install --upgrade imutils
Sprawdzanie wersji OpenCV: a real-world example
Teraz, gdy wiemy już, jak sprawdzić wersję OpenCV za pomocą Pythona, a także zdefiniowaliśmy kilka funkcji ułatwiających sprawdzanie wersji, zobaczmy, jak możemy użyć tych funkcji w rzeczywistym przykładzie.
Naszym celem jest wykrycie konturów na poniższym obrazie:
Aby wykryć kontury w obrazie, będziemy musieli użyć funkcji cv2.findContours
. Jednakże, jak wiemy, sygnatura zwracana przez cv2.findContours
zmieniła się nieco pomiędzy wersją 3 i 2.4 OpenCV (wersja OpenCV 3 funkcji cv2.findContours
zwraca dodatkową wartość w tuple) – dlatego też będziemy musieli wykonać sprawdzenie naszej wersji OpenCV przed wywołaniem funkcji cv2.findContours
, aby upewnić się, że nasz skrypt nie popełni błędu. Przyjrzyjmy się, jak możemy to sprawdzić:
# 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)
Jak widać, wszystko, co musimy zrobić, to wywołać is_cv2
, is_cv4
i is_cv3
, a następnie zawinąć nasz kod specyficzny dla wersji wewnątrz bloków instrukcji if
– to wszystko!
Teraz, gdy wykonuję mój skrypt przy użyciu OpenCV 2.4, działa on bez problemu:
I tak samo jest w przypadku OpenCV 3:
Podsumowanie
W tym wpisie na blogu dowiedzieliśmy się, jak sprawdzić wersję OpenCV za pomocą Pythona. Wersja OpenCV jest zawarta w specjalnej zmiennej łańcuchowej o nazwie cv2.__version__
. Wszystko, co musimy zrobić, to sprawdzić tę zmienną i będziemy w stanie określić naszą wersję OpenCV.
Na koniec, zdefiniowałem kilka wygodnych metod wewnątrz pakietu imutils, aby ułatwić sprawdzanie wersji OpenCV i uczynić je bardziej Pythonic. Rozważ sprawdzenie tej biblioteki, jeśli znajdziesz się w potrzebie ciągłego sprawdzania wersji OpenCV.
.