Operaciones aritméticas
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 + 20
→ 255 en lugar de 270. - Sin saturación: Los valores que sobrepasan 255 se reinician desde 0 por desbordamiento.
Ejemplo:250 + 20
→ 14. - 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.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0])
img2 = cv.imread(filename[1])
# 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)
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
axes[0].imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
axes[0].set_title("Imagen 1")
axes[0].axis("off")
axes[1].imshow(cv.cvtColor(img2, cv.COLOR_BGR2RGB))
axes[1].set_title("Imagen 2")
axes[1].axis("off")
axes[2].imshow(suma)
axes[2].set_title("Suma con saturación")
axes[2].axis("off")
plt.show()
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.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0])
img2 = cv.imread(filename[1])
# 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
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
axes[0].imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
axes[0].set_title("Imagen 1")
axes[0].axis("off")
axes[1].imshow(cv.cvtColor(img2, cv.COLOR_BGR2RGB))
axes[1].set_title("Imagen 2")
axes[1].axis("off")
axes[2].imshow(suma)
axes[2].set_title("Suma sin saturación")
axes[2].axis("off")
plt.show()
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.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0])
img2 = cv.imread(filename[1])
# 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)
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
axes[0].imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
axes[0].set_title("Imagen 1")
axes[0].axis("off")
axes[1].imshow(cv.cvtColor(img2, cv.COLOR_BGR2RGB))
axes[1].set_title("Imagen 2")
axes[1].axis("off")
axes[2].imshow(resta)
axes[2].set_title("Resta con saturación")
axes[2].axis("off")
plt.show()
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.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0])
img2 = cv.imread(filename[1])
# 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
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
axes[0].imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
axes[0].set_title("Imagen 1")
axes[0].axis("off")
axes[1].imshow(cv.cvtColor(img2, cv.COLOR_BGR2RGB))
axes[1].set_title("Imagen 2")
axes[1].axis("off")
axes[2].imshow(resta)
axes[2].set_title("Resta sin saturación")
axes[2].axis("off")
plt.show()
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.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0])
img2 = cv.imread(filename[1])
# 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
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
axes[0].imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
axes[0].set_title("Imagen 1")
axes[0].axis("off")
axes[1].imshow(cv.cvtColor(img2, cv.COLOR_BGR2RGB))
axes[1].set_title("Imagen 2")
axes[1].axis("off")
axes[2].imshow(fused)
axes[2].set_title("Imágenes fusionadas")
axes[2].axis("off")
plt.show()
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.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0])
img2 = cv.imread(filename[1])
# 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)
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
axes[0].imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
axes[0].set_title("Imagen 1")
axes[0].axis("off")
axes[1].imshow(cv.cvtColor(img2, cv.COLOR_BGR2RGB))
axes[1].set_title("Imagen 2")
axes[1].axis("off")
axes[2].imshow(bit_and)
axes[2].set_title("Operación AND")
axes[2].axis("off")
plt.show()
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.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0])
img2 = cv.imread(filename[1])
# 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)
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
axes[0].imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
axes[0].set_title("Imagen 1")
axes[0].axis("off")
axes[1].imshow(cv.cvtColor(img2, cv.COLOR_BGR2RGB))
axes[1].set_title("Imagen 2")
axes[1].axis("off")
axes[2].imshow(bit_or)
axes[2].set_title("Operación OR")
axes[2].axis("off")
plt.show()
Operación XOR
Se utiliza para detectar diferencias exclusivas entre dos imágenes. Se conserva solo lo que no coincide.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0])
img2 = cv.imread(filename[1])
# 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)
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
axes[0].imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
axes[0].set_title("Imagen 1")
axes[0].axis("off")
axes[1].imshow(cv.cvtColor(img2, cv.COLOR_BGR2RGB))
axes[1].set_title("Imagen 2")
axes[1].axis("off")
axes[2].imshow(bit_xor)
axes[2].set_title("Operación XOR")
axes[2].axis("off")
plt.show()
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.
- Python (PC con entorno gráfico)
- Python (Google Colab)
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()
import cv2 as cv
import matplotlib.pyplot as plt
from google.colab import files
# Subir archivo desde tu PC
uploaded = files.upload()
filename = list(uploaded.keys())
img1 = cv.imread(filename[0])
img2 = cv.imread(filename[1])
# 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)
# Cantidad de plot a generar
fig, axes = plt.subplots(1, 4, figsize=(18, 6))
axes[0].imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
axes[0].set_title("Imagen 1")
axes[0].axis("off")
axes[1].imshow(cv.cvtColor(img2, cv.COLOR_BGR2RGB))
axes[1].set_title("Imagen 2")
axes[1].axis("off")
axes[2].imshow(bit_not_1)
axes[2].set_title("Operación NOT - Imagen 1")
axes[2].axis("off")
axes[3].imshow(bit_not_2)
axes[3].set_title("Operación NOT - Imagen 2")
axes[3].axis("off")
plt.show()