Comprobando tu versión de OpenCV usando Python

opencv_versions_header

Era inevitable – la versión de OpenCV 3 estaba destinada a romper la compatibilidad con algunas funciones de OpenCV 2.4.X: cv2.findContours y cv2.normalize me vienen a la cabeza.

Entonces, ¿cómo te aseguras de que tu código funcionará independientemente de la versión de OpenCV que utilice tu entorno de producción?

Bueno, la respuesta corta es que necesitarás crear declaraciones if alrededor de cada una de las funciones ofensivas (o abstraer las funciones a un método separado que se encargue de llamar a la función apropiada basada en tu versión de OpenCV).

Para hacer esto, necesitarás ser capaz de comprobar tu versión de OpenCV desde tu uso de Python – ¡y eso es exactamente lo que el resto de este blog te mostrará cómo hacer!

¿Buscas el código fuente de este post?

Ir a la sección de descargas

La versión de OpenCV está contenida dentro de una variable especial cv2.__version__, a la que puedes acceder así:

$ python>>> import cv2>>> cv2.__version__'3.0.0'

La variable cv2.__version__ es simplemente una cadena que puedes dividir en las versiones mayor y menor:

>>> (major, minor, _) = cv2.__version__.split(".")>>> major'3'>>> minor'0'

Por supuesto, tener que realizar esta operación cada vez que necesites comprobar tu versión de OpenCV es un poco molesto. Para resolver este problema, he añadido tres nuevas funciones a mi paquete imutils, una serie de funciones de conveniencia para facilitar las funciones básicas de procesamiento de imágenes con OpenCV y Python.

Puedes ver mis funciones is_cv2 , is_cv3 , y check_opencv_version a continuación:

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)

El código aquí es bastante sencillo – simplemente estoy comprobando si la cadena cv2.__version__ comienza con un 2 , indicando que estamos usando OpenCV 2.X, un 3 , para indicar que estamos usando OpenCV 3, o un 4 , para indicar que estamos usando OpenCV 4.

Además, estas funciones ya han sido incluidas en el paquete imutils, que puedes instalar usando pip:

$ pip install imutils

Si ya tienes imutils instalado, puedes actualizar a la última versión usando:

$ pip install --upgrade imutils

Comprobando tu versión de OpenCV: un ejemplo del mundo real

Ahora que sabemos cómo comprobar nuestra versión de OpenCV utilizando Python, así como que hemos definido un par de funciones de conveniencia para facilitar la comprobación de la versión, vamos a ver cómo podemos utilizar estas funciones en un ejemplo del mundo real.

Nuestro objetivo aquí es detectar contornos en la siguiente imagen:

Figura 1: Vamos a utilizar OpenCV 2.4.X y OpenCV 3 para detectar los contornos de los bloques del Tetris.
Figura 1: Vamos a utilizar OpenCV 2.4.X y OpenCV 3 para detectar los contornos de los bloques de Tetris.

Para detectar los contornos en una imagen, tendremos que utilizar la función cv2.findContours. Sin embargo, como sabemos, la firma de retorno de cv2.findContours ha cambiado ligeramente entre la versión 3 y la 2.4 de OpenCV (la versión de OpenCV 3 de cv2.findContours devuelve un valor extra en la tupla) – por lo que tendremos que realizar una comprobación a nuestra versión de OpenCV antes de hacer una llamada a cv2.findContours para asegurarnos de que nuestro script no da error. Echemos un vistazo a cómo podemos hacer esta comprobación:

# 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)

Como puedes ver, todo lo que necesitamos hacer es una llamada a is_cv2 , is_cv4 , y is_cv3 y luego envolver nuestro código específico de la versión dentro de los bloques de declaración if – ¡eso es todo!

Ahora cuando voy a ejecutar mi script usando OpenCV 2.4, funciona sin problema:

Figura 2: Nuestra llamada a cv2.findContours funciona en OpenCV 2.4.X.
Figura 2: Nuestra llamada a cv2.findContours funciona en OpenCV 2.4.X.

Y lo mismo ocurre con OpenCV 3:

Figura 3: Y lo mismo ocurre con OpenCV 3 ya que estamos utilizando las funciones is_cv2 e is_cv3 para detectar las versiones de OpenCV con Python.
Figura 3: Y lo mismo ocurre con OpenCV 3 ya que estamos utilizando las funciones is_cv2 e is_cv3 para detectar las versiones de OpenCV con Python.

Resumen

En esta entrada del blog hemos aprendido a comprobar nuestra versión de OpenCV utilizando Python. La versión de OpenCV se incluye en una variable de cadena especial llamada cv2.__version__ . Todo lo que tenemos que hacer es comprobar esta variable y seremos capaces de determinar nuestra versión de OpenCV.

Por último, he definido algunos métodos de conveniencia dentro del paquete imutils para hacer la comprobación de su versión de OpenCV más fácil y más Python. Considere la posibilidad de comprobar la biblioteca si usted se encuentra con la necesidad de comprobar constantemente las versiones de OpenCV.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.