
Cámara en la Raspberry Pi: streaming en vivo con Python
Si conectas una cámara a la Raspberry Pi y la pones en marcha sin darle un respiro, la imagen puede salir completamente rosa o violeta — no es un cable mal puesto ni un sensor estropeado, es que el algoritmo de balance de blancos automático (AWB) todavía no ha tenido tiempo de calibrarse. Con solo dos segundos de pausa en el código (time.sleep(2)) el problema desaparece casi siempre. Aquí tienes el proceso completo, paso a paso, para montar una cámara real en tu Raspberry Pi, programarla con Python y Flask, y verla en directo desde cualquier dispositivo de tu red, para que lo repitas tú mismo.
El problema que resuelve
Muchos proyectos de robótica y visión artificial (seguimiento de objetos, clasificación de imágenes, control remoto de un robot) necesitan “ver” lo que hace la Raspberry Pi sin estar físicamente delante de la pantalla conectada a ella. La solución más sencilla es montar un pequeño servidor web con Flask que retransmita lo que ve la cámara, de forma que cualquier ordenador o móvil de tu misma red WiFi pueda abrir un navegador y ver la imagen en directo.
Lo que necesitas antes de empezar
- Una Raspberry Pi con puerto de cámara CSI (prácticamente todos los modelos desde la Pi 2 en adelante) y Raspberry Pi OS instalado.
- Un módulo de cámara compatible (en este ejemplo, un sensor IMX219, como la Camera Module v2 oficial).
- La Raspberry Pi apagada antes de manipular el cable de la cámara.
- Conocimientos básicos de Python: variables, funciones, bucles
while. - Acceso a la terminal de la Raspberry Pi (directamente o por SSH).
Paso 1 — Conecta físicamente el módulo de cámara
Con la Raspberry Pi apagada y desenchufada, localiza el puerto CSI (el conector alargado de plástico, normalmente entre el puerto HDMI y el jack de audio, o cerca de los puertos USB según el modelo). Levanta con cuidado la pestaña de plástico del conector, introduce el cable plano de la cámara con los contactos metálicos mirando hacia el lado correcto (consulta el manual de tu modelo concreto, porque la orientación varía entre la Pi 4, la Pi 5 y las versiones Zero), y vuelve a bajar la pestaña para que quede bien sujeto. Si más adelante el sistema no encuentra la cámara, revisa primero este cable: es la causa más habitual.
Paso 2 — Comprueba que el sistema detecta la cámara
Enciende la Raspberry Pi y abre una terminal. En las versiones actuales de Raspberry Pi OS la cámara se detecta automáticamente a través de la librería libcamera, sin necesidad de activarla a mano en raspi-config como en versiones antiguas. Ejecuta:
libcamera-hello --list-cameras
(en sistemas más recientes puede llamarse rpicam-hello). Si aparece el nombre de tu sensor — en este ejemplo, imx219 — la cámara está bien conectada y reconocida.
Paso 3 — Averigua la dirección IP de tu Raspberry Pi
Para ver la cámara desde otro dispositivo de tu red, necesitas la IP de la Raspberry Pi. Consíguela con:
hostname -I
Apunta el número que aparece (algo como 192.168.1.108): lo vas a necesitar en el paso final.
Paso 4 — Crea el script y entiende sus tres piezas
Copia este código en un archivo, por ejemplo web_stream.py:
python
import io
import time
from flask import Flask, Response
from picamera2 import Picamera2
app = Flask(__name__)
picam = Picamera2()
config = picam.create_preview_configuration(main={"size": (1280, 720)})
picam.configure(config)
picam.start()
time.sleep(2) # deja que la cámara calibre el color antes de capturar
def generate_frames():
while True:
stream = io.BytesIO()
picam.capture_file(stream, format='jpeg')
stream.seek(0)
frame = stream.read()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
@app.route('/')
def index():
return """
<html>
<head><title>Streaming Raspberry Pi</title></head>
<body>
<h1>Cámara Raspberry Pi - En Vivo</h1>
<img src="/video_feed" />
</body>
</html>
"""
@app.route('/video_feed')
def video_feed():
return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
try:
app.run(host='0.0.0.0', port=5000, threaded=True)
finally:
picam.stop()
picam.close()
Antes de ejecutarlo, fíjate en que este código tiene tres partes con trabajos distintos: la cámara (se enciende y se configura), la función generate_frames() (un bucle que hace fotos sin parar y las va entregando), y el servidor Flask (publica esas fotos en dos direcciones web para que cualquiera de tu red las pueda ver).
Paso 5 — No te saltes el segundo de espera
Fíjate en la línea time.sleep(2), justo después de picam.start(). Si te pasa que la imagen sale con un tono rosa o violeta muy raro, no te asustes: es que el sensor todavía no ha calibrado el balance de blancos ni la exposición automática nada más encenderse. Darle un par de segundos de margen antes de capturar el primer fotograma resuelve el problema casi siempre. Si sigue saliendo raro, prueba a subir la pausa a 3 o 4 segundos.
Paso 6 — Entiende cómo se fabrica un “vídeo” con fotos sueltas
En generate_frames() no hay ningún vídeo real: hay un bucle que nunca termina, que hace una foto, la guarda un instante en memoria y la entrega con yield. Tu navegador recibe esas fotos una detrás de otra tan rápido que las interpretas como una imagen en movimiento — esta técnica se llama streaming MJPEG, y es una de las formas más sencillas de retransmitir vídeo por la web sin librerías complicadas.
Paso 7 — Ejecuta el script y lee el mensaje del terminal
python3 web_stream.py
Verás primero varias líneas de libcamera confirmando qué sensor ha detectado, y después el aviso de Flask:
* Running on http://127.0.0.1:5000
* Running on http://192.168.1.108:5000
La primera dirección solo funciona dentro de la propia Raspberry Pi. La segunda, con tu IP real del Paso 3, es la que vas a usar desde otro dispositivo.
Paso 8 — Ábrelo en el navegador desde otro dispositivo
Desde un ordenador o un móvil conectado a la misma red WiFi, escribe en el navegador la dirección completa con el puerto: http://192.168.1.108:5000 (sustituyendo por tu IP real). Debería aparecer la página con la imagen en directo. En la terminal de la Raspberry Pi verás una línea por cada petición que llega (GET /video_feed HTTP/1.1 200) — buena señal de que todo funciona.
Paso 9 — Detén el programa correctamente
Para parar el servidor, pulsa Ctrl+C. El bloque finally del código libera la cámara automáticamente. Si alguna vez cierras el programa de otra forma y la cámara queda “ocupada”, el siguiente intento de usarla puede fallar con un error de tipo “Device or resource busy” — reiniciar la Raspberry Pi lo soluciona.


Avisos
- Este servidor solo es visible dentro de tu propia red local. No lo expongas directamente a internet: el propio mensaje de Flask lo advierte (“this is a development server, do not use it in a production deployment”).
- Un error frecuente es que el script no encuentre la cámara: casi siempre se debe a un cable CSI mal encajado o a tener otro programa usando la cámara a la vez.
Idea para llevarte a casa
Un streaming de vídeo por la web, por sofisticado que parezca, puede ser tan sencillo como un bucle que hace una foto, la entrega, y vuelve a empezar — la diferencia entre una imagen fija y un “vídeo en directo” está solo en la velocidad y en cómo el navegador interpreta ese flujo continuo. Y el detalle del segundo de espera antes de capturar es un buen recordatorio de que el hardware, a diferencia del código, no responde al instante: a veces la solución a un fallo no es más código, es más paciencia.




