Saltar al contenido principal

Operaciones aritméticas

info

Todo el código de ejemplo se encuentra en Google Colab para su ejecución directa. Si no puedes ejecutar OpenCV localmente, puedes usar Google Colab junto con matplotlib para visualizar imágenes. Además las imágenes que se utilizarán en los ejemplos son imagen1.jpg y imagen2.jpg.

Objetivo

  • Aprender diversas operaciones aritméticas con imágenes en OpenCV.
  • Comprender cómo funcionan la suma, resta y combinación de imágenes.
  • Aplicar operaciones bit a bit (AND, OR, NOT, XOR).

Conceptos clave

  • Operaciones aritméticas: Permiten modificar valores de píxeles entre imágenes o con escalares.
  • Saturación: Mecanismo que evita que los valores de píxel salgan del rango [0, 255].
    Ejemplo: 250 + 20255 en lugar de 270.
  • Sin saturación: Los valores que sobrepasan 255 se reinician desde 0 por desbordamiento.
    Ejemplo: 250 + 2014.
  • Fusión (blending): Mezcla dos imágenes asignándoles diferentes pesos, útil para transparencias y efectos de superposición.

Funciones principales en OpenCV

  • cv.add(): Suma dos imágenes con saturación.
  • cv.subtract(): Resta dos imágenes con saturación.
  • cv.addWeighted(): Fusión ponderada de dos imágenes.
  • cv.bitwise_and(), cv2.bitwise_or(), cv2.bitwise_xor(), cv2.bitwise_not(): Operaciones bit a bit.

Adición de imágenes con saturación

La suma de imágenes se usa para combinar detalles de dos imágenes. Con saturación, los valores se limitan a 255, evitando distorsiones brillantes y manteniendo un resultado visualmente más natural.

import cv2 as cv

img1 = cv.imread('imagen1.jpg')
img2 = cv.imread('imagen2.jpg')

# Redimensionar img2 para que coincida con las dimensiones de img1
img2 = cv.resize(img2, (img1.shape[1], img1.shape[0]))

# Suma con saturación
suma = cv.add(img1, img2)

cv.imshow('Img1', img1)
cv.imshow('Img2', img2)
cv.imshow('Suma', suma)
cv.waitKey(0)
cv.destroyAllWindows()

Adición de imágenes sin saturación

La suma sin saturación utiliza el operador +. Es más rápida, pero puede causar efectos indeseados por desbordamiento, generando colores extraños. Se usa solo con fines educativos o en casos donde el desbordamiento sea intencional.

import cv2 as cv

img1 = cv.imread('imagen1.jpg')
img2 = cv.imread('imagen2.jpg')

# Redimensionar img2 para que coincida con las dimensiones de img1
img2 = cv.resize(img2, (img1.shape[1], img1.shape[0]))

# Suma sin saturación
suma = img1 + img2

cv.imshow('Img1', img1)
cv.imshow('Img2', img2)
cv.imshow('Suma', suma)
cv.waitKey(0)
cv.destroyAllWindows()

Resta de imágenes con saturación

La resta de imágenes es útil para detectar cambios o diferencias entre dos imágenes (por ejemplo, en visión por computadora para identificar objetos nuevos). Con saturación, los valores negativos se fijan en 0, evitando que aparezcan tonos irreales.

import cv2 as cv

img1 = cv.imread('imagen1.jpg')
img2 = cv.imread('imagen2.jpg')

# Redimensionar img2 para que coincida con las dimensiones de img1
img2 = cv.resize(img2, (img1.shape[1], img1.shape[0]))

# Resta con saturación
resta = cv.subtract(img1, img2)

cv.imshow('Img1', img1)
cv.imshow('Img2', img2)
cv.imshow('Resta', resta)
cv.waitKey(0)
cv.destroyAllWindows()

Resta de imágenes sin saturación

La resta sin saturación utiliza el operador -. Puede generar artefactos extraños porque los valores negativos se convierten en números grandes por desbordamiento. Es menos usada en aplicaciones prácticas, pero útil para comprender cómo se manipulan los valores de píxeles.

import cv2 as cv

img1 = cv.imread('imagen1.jpg')
img2 = cv.imread('imagen2.jpg')

# Redimensionar img2 para que coincida con las dimensiones de img1
img2 = cv.resize(img2, (img1.shape[1], img1.shape[0]))

# Resta sin saturación
resta = img1 - img2

cv.imshow('Img1', img1)
cv.imshow('Img2', img2)
cv.imshow('Resta', resta)
cv.waitKey(0)
cv.destroyAllWindows()

Fusión de imágenes

La fusión combina dos imágenes asignando un peso a cada una. Se utiliza para crear efectos de transparencia, superposiciones artísticas o marcas de agua. Al ajustar los pesos (alpha, beta), se controla qué imagen domina en el resultado final.

import cv2 as cv

img1 = cv.imread('imagen2.jpg')
img2 = cv.imread('imagen1.jpg')

# Redimensionar img2 para que coincida con las dimensiones de img1
img2 = cv.resize(img2, (img1.shape[1], img1.shape[0]))

alpha = 0.7
beta = 0.3
fused = cv.addWeighted(
img1, # img1: primera imagen
alpha, # alpha: peso de img1
img2, # img2: segunda imagen
beta, # beta: peso de img2
0) # gamma: valor escalar añadido a cada píxel, 0 es sin cambio

cv.imshow('Img1', img1)
cv.imshow('Img2', img2)
cv.imshow('Fusión', fused)
cv.waitKey(0)
cv.destroyAllWindows()

Operaciones bit a bit

Estas operaciones actúan a nivel binario de cada píxel, permitiendo crear máscaras, recortes o combinaciones lógicas entre imágenes. Son muy usadas para segmentación y detección de regiones de interés.

Operación AND

Se utiliza para conservar solo las áreas comunes entre dos imágenes. Muy útil en enmascaramiento.

import cv2 as cv

img1 = cv.imread('imagen1.jpg')
img2 = cv.imread('imagen2.jpg')

# Redimensionar img2 para que coincida con las dimensiones de img1
img2 = cv.resize(img2, (img1.shape[1], img1.shape[0]))

# AND: conserva solo los píxeles donde ambas imágenes tienen valores
bit_and = cv.bitwise_and(img1, img2)

cv.imshow('Img1', img1)
cv.imshow('Img2', img2)
cv.imshow('AND', bit_and)
cv.waitKey(0)
cv.destroyAllWindows()

Operación OR

Se utiliza para combinar regiones de interés de dos imágenes, conservando cualquier área que esté activa en alguna de ellas.

import cv2 as cv

img1 = cv.imread('imagen1.jpg')
img2 = cv.imread('imagen2.jpg')

# Redimensionar img2 para que coincida con las dimensiones de img1
img2 = cv.resize(img2, (img1.shape[1], img1.shape[0]))

# OR: conserva píxeles donde al menos una imagen tiene valor
bit_or = cv.bitwise_or(img1, img2)

cv.imshow('Img1', img1)
cv.imshow('Img2', img2)
cv.imshow('OR', bit_or)
cv.waitKey(0)
cv.destroyAllWindows()

Operación XOR

Se utiliza para detectar diferencias exclusivas entre dos imágenes. Se conserva solo lo que no coincide.

import cv2 as cv

img1 = cv.imread('imagen1.jpg')
img2 = cv.imread('imagen2.jpg')

# Redimensionar img2 para que coincida con las dimensiones de img1
img2 = cv.resize(img2, (img1.shape[1], img1.shape[0]))

# XOR: conserva píxeles donde solo una imagen tiene valor
bit_xor = cv.bitwise_xor(img1, img2)

cv.imshow('Img1', img1)
cv.imshow('Img2', img2)
cv.imshow('XOR', bit_xor)
cv.waitKey(0)
cv.destroyAllWindows()

Operación NOT

Se utiliza para invertir los píxeles de una imagen, creando un efecto negativo. Es útil para resaltar contraste o preparar datos para otras transformaciones.

import cv2 as cv

img1 = cv.imread('imagen1.jpg')
img2 = cv.imread('imagen2.jpg')

# Redimensionar img2 para que coincida con las dimensiones de img1
img2 = cv.resize(img2, (img1.shape[1], img1.shape[0]))

# NOT: invierte los píxeles
bit_not_1 = cv.bitwise_not(img1)
bit_not_2 = cv.bitwise_not(img2)

cv.imshow('Img1', img1)
cv.imshow('Img2', img2)
cv.imshow('Operación NOT - Imagen 1', bit_not_1)
cv.imshow('Operación NOT - Imagen 2', bit_not_2)
cv.waitKey(0)
cv.destroyAllWindows()