?¿Problemas al usar cv2.findContours? | OpenCV y Python

Por Administrador

cv2.findContours es una herramienta poderosísima en visión por computador, que me ha permitido compartirles algunas aplicaciones tales como:

Sí, han sido muchos tutoriales en los que la hemos utilizado, y no es que solo haya empleado esta función, sino que juega un papel muy importante en el proceso de construcción de cada una de estas aplicaciones. Si quieres profundizar un poquito más sobre esta función te dejo este post: ?‍? CONTORNOS y como DIBUJARLOS en OpenCV y Python.

Si sigues este blog o mi canal de youtube, podrás haber visto que en ciertas ocasiones la función me ha devuelto 3 valores, y en otras 2. Pero, ¿por qué se da esto?, la respuesta es:  la versión de OpenCV instalada. Pero antes de continuar con los errores más comunes que aparecen al emplear esta función en distintas versiones de OpenCV, te recomendaré usar help.

¡Help!

¡Ayudaaaa!. Help es una función de Python que nos permite visualizar la documentación de módulos, funciones, entre otros. Por lo que es una herramienta que nos permitirá descubrir los secretos escondidos de cv2.findContours o cualquier otra función. Está bien, está bien, secretos no tan escondidos sino su documentación.

Para emplear esta función, vamos al terminal de python e importamos OpenCV, para luego usar help. Es decir:

import cv2
help(cv2.findContours)

Veamos lo que obtendríamos:

Figura 1: Terminal.

En la figura 1, en la sección en rosa tenemos la importación de OpenCV y la función help, mientras que la sección verde tenemos la documentación de cv2.findContours de OpenCV. Recuerda que esto es netamente informativo.

Entonces podremos usar esta función para tener conocimiento por ejemplo de cuantos valores da de vuelta cv2.findContours, como veremos más adelante.

Si quieres usar esta función para otros módulos o funciones, lo único que debes hacer es cambiar el argumento de help por la función que desees.

ValueError: too many values to unpack (expected 2)

Este error se da cuando estamos usando OpenCV 3, y en esta versión cv2.findContours devuelve 3 valores, pero nosotros hemos puesto en la programación que devuelve 2, por lo tanto obtenemos: ValueError: too many values to unpack (expected 2). Es decir que en nuestro programa tenemos una línea como esta (fíjate en lo que devuelve la función):

cnts, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

En este caso hemos digitado que la función devolverá cnts, _. Sin embargo hemos obtenido el siguiente error:

    cnts, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
ValueError: too many values to unpack (expected 2)

Para corregir este error lo que debemos hacer es añadir un valor en el resultado de la función, es decir:

_, cnts, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

¡Y listo!.  Como te decía es debido a que cv2.findContours devuelve 3 valores: image, contours y hierarchy. Podemos comprobarlo con la función help. 

Figura 2: Utilizamos la función help para obtener información de cv2.findContours de OpenCV.

Como se puede ver en la figura 2, he importado OpenCV, luego impreso la versión instalada que en este caso es la 3.4.13, y finalmente he aplicado help. Puedes ver que en el resultado de esta última obtenemos que la función devuelve image, contours y hierarchy. 

ValueError: not enough values to unpack (expected 3, got 2)

Este error se da en cambio cuando usamos OpenCV 4. En esta versión cv2.findContours devuelve 2 valores, pero nosotros hemos puesto en la programación que devuelve 3, por lo tanto obtenemos: ValueError: not enough values to unpack (expected 3, got 2). Lo que quiere decir que no existen suficientes valores a desempaquetar.

Veámoslo nuevamente con un ejemplo. Podríamos en nuestro programa tener una línea como esta (fíjate en lo que devuelve la función):

_, cnts, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

En este caso hemos digitado que la función devolverá _, cnts, _. Sin embargo hemos obtenido el siguiente error:

    _, cnts, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
ValueError: not enough values to unpack (expected 3, got 2)

Para corregir este error lo que debemos hacer es quitar el primer valor en el resultado de la función, es decir:

cnts, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

¡Y así podremos corregir el error!.  cv2.findContours en OpenCV 4 devuelve 2 valores: contours y hierarchy. Podemos comprobarlo con la función help.

Figura 3: Utilizamos la función help para obtener información de cv2.findContours de OpenCV.

Como se puede ver en la figura 3, he importado OpenCV, luego impreso la versión instalada que en este caso es la 4.4.0, y finalmente he aplicado help. Puedes ver que en el resultado de esta última obtenemos que la función devuelve contours y hierarchy. 

Y esto ha sido todo en este post. Como puedes ver estos errores se dan por la versión de OpenCV instalada, sin embargo podemos corregirlos muy facilemente. ¡Nos vemos en el siguiente video o tutorial!.