Leer imágenes con cv2.imread()
La función cv2.imread() carga una imagen desde disco y la devuelve como un array NumPy. Si la imagen no puede cargarse (ruta incorrecta, formato no soportado), devuelve None sin lanzar ninguna excepción, por lo que siempre es necesario verificar el resultado.
import cv2
# Lectura básica: devuelve array BGR uint8 o None
imagen = cv2.imread("foto.jpg")
# Siempre verificar que la carga fue exitosa
if imagen is None:
print("ERROR: no se pudo cargar la imagen. Verifica la ruta.")
else:
print(f"Imagen cargada: {imagen.shape}, dtype={imagen.dtype}")
Flags de lectura
El segundo argumento de imread() controla cómo se interpreta la imagen:
import cv2
# Color BGR (por defecto) — 3 canales
img_color = cv2.imread("foto.jpg", cv2.IMREAD_COLOR)
# Equivalente: cv2.imread("foto.jpg", 1)
print(f"Color: {img_color.shape}") # (alto, ancho, 3)
# Escala de grises — 1 canal
img_gris = cv2.imread("foto.jpg", cv2.IMREAD_GRAYSCALE)
# Equivalente: cv2.imread("foto.jpg", 0)
print(f"Grises: {img_gris.shape}") # (alto, ancho)
# Sin cambios: mantiene canal alfa si existe (BGRA)
img_rgba = cv2.imread("icono.png", cv2.IMREAD_UNCHANGED)
# Equivalente: cv2.imread("icono.png", -1)
print(f"Sin cambios: {img_rgba.shape}") # (alto, ancho, 4) si tiene alfa
# Leer en float (valores 0.0-1.0 en lugar de 0-255)
img_float = cv2.imread("foto.jpg", cv2.IMREAD_COLOR | cv2.IMREAD_ANYDEPTH)
Gestión de rutas con os.path y pathlib
import cv2
import os
from pathlib import Path
# Con os.path — compatible con Python 2 y 3
ruta = os.path.join("imagenes", "vacaciones", "playa.jpg")
img = cv2.imread(ruta)
# Con pathlib — preferida en Python 3.4+
ruta_p = Path("imagenes") / "vacaciones" / "playa.jpg"
img_p = cv2.imread(str(ruta_p))
# Rutas absolutas
ruta_abs = Path.home() / "Imágenes" / "foto.jpg"
img_abs = cv2.imread(str(ruta_abs))
# Verificar que el archivo existe antes de leer
archivo = Path("foto.jpg")
if not archivo.exists():
print(f"El archivo {archivo} no existe")
else:
img = cv2.imread(str(archivo))
Visualizar imágenes
cv2.imshow() — ventana nativa
cv2.imshow() abre una ventana del sistema operativo para mostrar la imagen. Requiere un waitKey() para que la ventana permanezca visible.
import cv2
imagen = cv2.imread("foto.jpg")
# Mostrar en ventana nativa
cv2.imshow("Mi imagen", imagen)
# Esperar tecla indefinidamente (0) o N milisegundos
tecla = cv2.waitKey(0)
print(f"Tecla pulsada: {tecla}")
# Cerrar todas las ventanas OpenCV
cv2.destroyAllWindows()
import cv2
# Bucle de visualización interactiva
imagen = cv2.imread("foto.jpg")
cv2.namedWindow("Imagen", cv2.WINDOW_NORMAL) # Ventana redimensionable
cv2.resizeWindow("Imagen", 800, 600)
cv2.imshow("Imagen", imagen)
while True:
tecla = cv2.waitKey(1) & 0xFF
if tecla == ord('q') or tecla == 27: # 'q' o Escape para salir
break
cv2.destroyAllWindows()
Matplotlib — recomendado para Jupyter
import cv2
import matplotlib.pyplot as plt
def mostrar_bgr(imagen, titulo="Imagen"):
"""Muestra una imagen BGR de OpenCV con Matplotlib."""
imagen_rgb = cv2.cvtColor(imagen, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(8, 6))
plt.imshow(imagen_rgb)
plt.title(titulo)
plt.axis("off")
plt.show()
def mostrar_gris(imagen, titulo="Imagen en grises"):
"""Muestra una imagen en escala de grises."""
plt.figure(figsize=(8, 6))
plt.imshow(imagen, cmap="gray")
plt.title(titulo)
plt.axis("off")
plt.colorbar(label="Intensidad")
plt.show()
# Usar las funciones de utilidad
img = cv2.imread("foto.jpg")
mostrar_bgr(img, "Foto original")
img_gris = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
mostrar_gris(img_gris, "Escala de grises")
Comparar varias imágenes en una figura
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("foto.jpg")
img_gris = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_bordes = cv2.Canny(img_gris, 50, 150)
img_invertida = cv2.bitwise_not(img)
imagenes = [
(img, "Original BGR"),
(img_gris, "Escala de grises"),
(img_bordes, "Bordes Canny"),
(img_invertida, "Invertida"),
]
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
for ax, (imagen, titulo) in zip(axes.flat, imagenes):
if len(imagen.shape) == 3:
ax.imshow(cv2.cvtColor(imagen, cv2.COLOR_BGR2RGB))
else:
ax.imshow(imagen, cmap="gray")
ax.set_title(titulo, fontsize=12)
ax.axis("off")
plt.suptitle("Comparación de procesamiento de imágenes", fontsize=14)
plt.tight_layout()
plt.show()
Guardar imágenes con cv2.imwrite()
cv2.imwrite() guarda un array NumPy como archivo de imagen. El formato se determina por la extensión del nombre de archivo.
import cv2
import numpy as np
img = cv2.imread("foto.jpg")
img_gris = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Guardar en PNG (sin pérdida)
cv2.imwrite("foto_gris.png", img_gris)
# Guardar en JPEG
cv2.imwrite("foto_copia.jpg", img)
# Verificar resultado: imwrite devuelve True si tuvo éxito
ok = cv2.imwrite("salida.png", img)
print(f"Guardado: {ok}")
Parámetros de calidad y compresión
import cv2
img = cv2.imread("foto.jpg")
# JPEG: calidad del 0 (peor) al 100 (mejor). Default: 95
cv2.imwrite("alta_calidad.jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 95])
cv2.imwrite("baja_calidad.jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 30])
# PNG: compresión del 0 (sin compresión) al 9 (máxima). Default: 3
cv2.imwrite("sin_compresion.png", img, [cv2.IMWRITE_PNG_COMPRESSION, 0])
cv2.imwrite("max_compresion.png", img, [cv2.IMWRITE_PNG_COMPRESSION, 9])
# WebP: calidad del 0 al 100
cv2.imwrite("imagen.webp", img, [cv2.IMWRITE_WEBP_QUALITY, 80])
Comparar tamaños de archivo según calidad
import cv2
import os
img = cv2.imread("foto.jpg")
calidades = [10, 30, 50, 70, 90, 95]
for q in calidades:
nombre = f"calidad_{q}.jpg"
cv2.imwrite(nombre, img, [cv2.IMWRITE_JPEG_QUALITY, q])
tamanio = os.path.getsize(nombre) / 1024 # KB
print(f"Calidad {q:3d}%: {tamanio:8.1f} KB")
Salida típica:
Calidad 10%: 156.3 KB
Calidad 30%: 312.7 KB
Calidad 50%: 487.2 KB
Calidad 70%: 720.1 KB
Calidad 90%: 1,521.6 KB
Calidad 95%: 2,183.4 KB
Formatos soportados
OpenCV admite los formatos más habituales:
| Formato | Extensión | Característica |
|---------|-----------|----------------|
| JPEG | .jpg, .jpeg | Compresión con pérdida, ideal para fotos |
| PNG | .png | Sin pérdida, soporta transparencia (alfa) |
| BMP | .bmp | Sin compresión, muy rápido de lectura |
| TIFF | .tiff, .tif | Sin pérdida, soporte de 16 bits por canal |
| WebP | .webp | Compresión moderna con y sin pérdida |
| PBM/PGM/PPM | .pbm, .pgm, .ppm | Formatos portables simples |
import cv2
img = cv2.imread("foto.jpg")
# Guardar en múltiples formatos
formatos = {
"bmp": ("foto.bmp", []),
"png": ("foto.png", [cv2.IMWRITE_PNG_COMPRESSION, 3]),
"webp": ("foto.webp", [cv2.IMWRITE_WEBP_QUALITY, 85]),
"tiff": ("foto.tiff", []),
}
for fmt, (nombre, params) in formatos.items():
cv2.imwrite(nombre, img, params)
print(f"Guardado {nombre}")
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, OpenCV es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de OpenCV
Explora más contenido relacionado con OpenCV y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
Leer imágenes con cv2.imread() y sus flags (COLOR, GRAYSCALE, UNCHANGED). Visualizar imágenes con cv2.imshow() en ventana nativa y con Matplotlib en Jupyter. Guardar imágenes con cv2.imwrite() con parámetros de calidad JPEG y compresión PNG. Manejar errores de lectura cuando el archivo no existe o la ruta es incorrecta. Trabajar con rutas de archivo usando os.path y pathlib.