Operadores BITWISE (AND-OR-NOT-XOR) con OpenCV y Python

Por Administrador

CONTENIDO

  • AND ( cv2.bitwise_and )
  • NOT ( cv2.bitwise_not )
  • OR ( cv2.bitwise_or )
  • XOR ( cv2.bitwise_xor )
  • cv2.bitwise_and y mask

En este post vamos con el tema de Operadotes Bitwise AND, OR, NOT y XOR, en OpenCV y Python. Para ello, las imágenes que vamos a utilizar para aplicar cada uno de los operadores, las construiremos a continuación:

import cv2
import numpy as np

img1 = np.zeros((400,600), dtype=np.uint8)
img1[100:300,200:400] = 255
img2 = np.zeros((400,600), dtype=np.uint8)
img2 = cv2.circle(img2,(300,200),125,(255),-1)

cv2.imshow('img1',img1)
cv2.imshow('img2',img2)

cv2.waitKey(0)
cv2.destroyAllWindows()

En la línea 1 y 2 importamos openCV con import cv2, y numpy con import numpy as np. En la línea 4 creamos una imagen de ceros (por lo que se visualizará de color negro) con 400 pixeles de alto y 600 de ancho, cabe resaltar que aquí estamos creando una imagen que posee un único canal, no como cuando creábamos una imagen en BGR y especificábamos 3 canales. En la línea 5 estamos creando un rectángulo dentro de la imagen img1, este rectángulo tendrá color blanco por lo que asignamos 255.

En la línea 6 construiremos otra imagen de ceros img2, tal y como lo hicimos en la línea 4, con las mismas dimensiones. Luego en la línea 7 le agregamos un círculo en la parte central de la imagen con cv2.circle. (Si quieres tener más información de como utilizar esta y otras funciones de dibujo, dale clic al link). Ahora visualicemos las imágenes creadas.

Figura 1: Visualización de img1 e img2

AND ( cv2.bitwise_and )

Para poder entender como funciona este operador en OpenCV, debemos recordar su tabla de verdad, en ella cuando existía al menos un valor en 0 o falso, su salida era falsa. Solo había salida 1 o verdadero cuando todas sus entradas eran 1 o verdaderas. Pues bien, esto es lo mismo que se aplica en OpenCV,  con la diferencia que en vez de 1, se utiliza 255. Esto para poder representar blanco y negro. 

Figura 2: Tabla de verdad del operador AND, y como trabaja en OpenCV.

Para emplear cv2.bitwise_and, se necesita especificar:

  • Imagen 1 (Primera matriz o escalar)
  • Imagen 2 (Segunda matriz o escalar)

Ahora realicemos un pequeño programa para visualizar el resultado de aplicar cv2.bitwise_and, a dos imágenes en blanco y negro:

import cv2
import numpy as np

img1 = np.zeros((400,600), dtype=np.uint8)
img1[100:300,200:400] = 255
img2 = np.zeros((400,600), dtype=np.uint8)
img2 = cv2.circle(img2,(300,200),125,(255),-1)

AND = cv2.bitwise_and(img1,img2)
cv2.imshow('AND', AND)

cv2.waitKey(0)
cv2.destroyAllWindows()

Hemos añadido en la línea 9 la función cv2.bitwise_and a las imágenes que habíamos construido, img1e img2. Entonces obtenemos:

Figura 3: Imagen resultante de aplicar cv2.bitwise_and, a las imágenes de la figura1

NOT ( cv2.bitwise_not )

En el operador NOT, cuando una entrada es verdadera o 1, su salida es falso o  0, y viceversa. En OpenCV se realiza el mismo procedimiento, con la diferencia que en vez de 1 se emplea 255, como he dicho antes, para poder visualizar el resultado o salida en colores blanco y negro, veamos:

Figura 4: Tabla de verdad del operador NOT, y como trabaja en OpenCV.

Para emplear el operador NOT, OpenCV usa cv2.bitwise_not en donde se necesita especificar:

  • Imagen (Matriz o escalar)

Veamos un ejemplo de como emplear esta función:

import cv2
import numpy as np

img1 = np.zeros((400,600), dtype=np.uint8)
img1[100:300,200:400] = 255
img2 = np.zeros((400,600), dtype=np.uint8)
img2 = cv2.circle(img2,(300,200),125,(255),-1)

NOT = cv2.bitwise_not(img1)
cv2.imshow('NOT', NOT)

cv2.waitKey(0)
cv2.destroyAllWindows()

Ahora en la línea 9 hemos aplicado la función cv2.bitwise_not, para ello procedemos a entregar la imagen a la cual va afectar dicha función,  en este caso  img1. La visualización sería la siguiente:

Figura 5: Imagen resultante de aplicar cv2.bitwise_not, a la imagen ‘img1’ de la figura1

OR ( cv2.bitwise_or )

Al igual que con AND y NOT, necesitamos recordar el funcionamiento del operador OR. Para ello cuando al menos uno de los valores de entrada es verdadero o 1, su salida también lo es. Es únicamente falso o 0, cuando todas sus entradas son 0 o falso.

Figura 6: Tabla de verdad del operador OR, y como funciona en OpenCV.

Para emplear cv2.bitwise_or, se necesita especificar:

  • Imagen 1 (Primera matriz o escalar)
  • Imagen 2 (Segunda matriz o escalar)

Veamos a continuación un ejemplo del uso de esta función:

import cv2
import numpy as np

img1 = np.zeros((400,600), dtype=np.uint8)
img1[100:300,200:400] = 255
img2 = np.zeros((400,600), dtype=np.uint8)
img2 = cv2.circle(img2,(300,200),125,(255),-1)

OR = cv2.bitwise_or(img1,img2)
cv2.imshow('OR', OR)

cv2.waitKey(0)
cv2.destroyAllWindows()

Como se puede apreciar en la línea 9, el proceso para usar esta función es similar al de AND. Entonces el resultado sería el siguiente:

Figura 7: Imagen resultante de aplicar cv2.bitwise_or, a las imágenes de la figura1

XOR ( cv2.bitwise_xor )

Finalmente veremos el operador XOR, en este sus salidas toman el valor de falso o 0 cuando ambas entradas poseen el mismo valor, mientras que es verdadero o 1 en los demás casos.

Figura 8: Tabla de verdad del operador XOR, y como funciona en OpenCV.

Para emplear cv2.bitwise_xor, se necesita especificar:

  • Imagen 1 (Primera matriz o escalar)
  • Imagen 2 (Segunda matriz o escalar)

Ejemplo de aplicación de esta función:

import cv2
import numpy as np

img1 = np.zeros((400,600), dtype=np.uint8)
img1[100:300,200:400] = 255
img2 = np.zeros((400,600), dtype=np.uint8)
img2 = cv2.circle(img2,(300,200),125,(255),-1)

XOR = cv2.bitwise_xor(img1,img2)
cv2.imshow('XOR', XOR)

cv2.waitKey(0)
cv2.destroyAllWindows()

En la línea 9 podemos ver como se está utilizando la función, cv2.bitwise_xor, en ella especificamos las imágenes img1 e img2. La visualización entonces es:

Figura 9: Imagen resultante de aplicar cv2.bitwise_xor, a las imágenes de la figura1

cv2.bitwise_and y mask

Podemos usar la función cv2.bitwise_and, para que se visualicen únicamente ciertas áreas de una imagen, mientras que otras permanezcan en negro. Para ello vamos a utilizar una imagen en blanco y negro, como las construidas anteriormente, y cualquier imagen a color. A continuación vamos con un ejemplo empleando video streaming:

import cv2
import numpy as np

captura = cv2.VideoCapture(0)
mask = np.zeros((480,640),dtype=np.uint8)
mask = cv2.circle(mask,(320,240),125,(255),-1)
#mask=cv2.bitwise_not(mask)
cv2.imshow('mask',mask)
while (captura.isOpened()):
  ret,frame = captura.read()
  
  if ret == True:

    imgMask = cv2.bitwise_and(frame,frame,mask=mask)
    cv2.imshow('video',imgMask)

    if cv2.waitKey(1) & 0xFF == ord('s'):
      break
  else: break
captura.release()
cv2.destroyAllWindows()

El código es similar a los que hemos visto en este post. En la línea 4 iniciamos con la captura del video streaming, en la línea 5 creamos una imagen mask del mismo alto y ancho que la imagen que obtendremos en el video streaming. En la línea 6 estamos creando un círculo que se presentará en el centro de mask y visualizamos en la línea 8.

NOTA: Luego de que pruebes el código, puedes descomentar la línea 7 y analizar lo que ha sucedido en la imagen mask  e imgMask.

En la línea 10 obtenemos frame que es la imagen con la que vamos a trabajar (Si quieres recordar como realizar un video streaming en OpenCV, puedes revisar mi post anterior). En la línea 14 aplicamos la función cv2.bitwise_and, la diferencia aquí con lo que hemos tratado en este post, es que tanto para la primera y segunda imagen especificamos frame, que es la imagen a color del video, seguido de esto escribimos mask=mask, que corresponde a la imagen que tenemos en la línea 7. Visualicemos:

Figura 10: Izq. Imagen utilizada como máscara para el video streming, Der. Imagen del video resultante al aplicar cv2.bitwise_and, con mask

Como podemos ver en la figura 10, a la izquierda tenemos la presencia de una imagen en blanco y negro, en donde presenta un círculo blanco. Al usar cv2.bitwise_and especificando como primer y segundo argumento la misma imagen, seguido de una máscara, obtenemos la visualización de la derecha. Entonces, la primera imagen está actuando como una máscara, en donde la región blanca nos permitirá visualizar a frame, que corresponde a  la presencia del círculo. Mientras que lo demás se visualizará en negro.

Puedes ver otra aplicación a este procedimiento en el video: DETECCIÓN DE COLORES en OPENCV [en 4 Pasos] – Parte1

Referencias:

#infoOmes