Tabla de contenido:

Crea tu propia cámara: 8 pasos
Crea tu propia cámara: 8 pasos

Video: Crea tu propia cámara: 8 pasos

Video: Crea tu propia cámara: 8 pasos
Video: 8 PRIMEROS PASOS con tu CÁMARA para GRABAR VÍDEO cómo un PRO! 2024, Mes de julio
Anonim
Image
Image
Haz tu propia cámara
Haz tu propia cámara

Este instructivo explica cómo hacer una cámara monocromática usando un sensor de imagen Omnivision OV7670, un microcontrolador Arduino, algunos cables de puente y el software Processing 3.

También se presenta un software experimental para la obtención de una imagen en color.

Presione la tecla "c" para capturar una imagen de 640 * 480 píxeles … presione la tecla "s" para guardar la imagen en el archivo. Las imágenes sucesivas se numeran secuencialmente si desea crear una película de lapso de tiempo corto.

La cámara no es rápida (cada escaneo tarda 6,4 segundos) y solo es adecuada para su uso en iluminación fija.

El costo, excluyendo su Arduino y PC, es menos que una taza de café.

Imagenes

Los componentes, sin cableado de puente, se muestran en la foto de apertura.

La segunda foto es una captura de pantalla que muestra el software de la cámara Arduino y el capturador de fotogramas Processing 3. El recuadro muestra cómo está conectada la cámara.

El video muestra la cámara en acción. Cuando se presiona la tecla de captura “c”, hay un breve destello seguido de una ráfaga de actividad mientras se escanea la imagen. La imagen aparece automáticamente en la ventana de visualización una vez que se completa el escaneo. A continuación, se ve que las imágenes aparecen en la carpeta Procesamiento después de cada pulsación de la tecla "s". El video concluye recorriendo rápidamente cada una de las tres imágenes guardadas.

Paso 1: diagrama de circuito

Diagrama de circuito
Diagrama de circuito
Diagrama de circuito
Diagrama de circuito
Diagrama de circuito
Diagrama de circuito

El diagrama del circuito, para todas las versiones de esta cámara, se muestra en la foto 1.

Las fotos 2, 3 muestran cómo están conectados los puentes-cables y los componentes.

Sin el soporte de aluminio, las imágenes quedan de lado.

Advertencia

Programe su Arduino ANTES de conectar cualquier cable de puente al chip de la cámara OV7670. Esto evitará que los pines de salida de 5 voltios de un programa anterior destruyan el chip de la cámara OV7670 de 3v3 voltios.

Paso 2: Lista de piezas

Lista de partes
Lista de partes

Las siguientes piezas se obtuvieron de

  • 1 solo módulo de cámara VGA OV7670 300KP para arduino DIY KIT
  • 1 solo soporte de cámara completo con tuercas y pernos
  • 1 solo UNO R3 para arduino MEGA328P 100% original ATMEGA16U2 con cable USB

Las siguientes partes se obtuvieron localmente

  • 18 cables de puente anly Arduino macho-hembra
  • 3 solo cables de puente Arduinin hembra-hembra
  • 1 solo mini tablero de pan
  • 4 resistencias de solo 4K7 ohmios 1/2 vatio
  • 1 solo soporte de aluminio de desecho.

También necesitará las siguientes hojas de datos:

  • https://web.mit.edu/6.111/www/f2016/tools/OV7670_20…
  • https://www.haoyuelectronics.com/Attachment/OV7670%…

Paso 3: teoría

Teoría
Teoría

Chip de cámara OV7670

La salida predeterminada del chip de la cámara OV7670 comprende una señal de video YUV (4: 2: 2) y 3 formas de onda de sincronización. Son posibles otros formatos de salida programando los registros internos a través de un bus compatible con I2C.

La señal de video YUV (4: 2: 2) (foto 1) es una secuencia continua de píxeles monocromáticos (blanco y negro) separados por información de color U (diferencia de color azul) y V (diferencia de color rojo).

Este formato de salida se conoce como YUV (4: 2: 2) ya que cada grupo de 4 bytes contiene 2 bytes monocromáticos y 2 bytes de color.

Monocromo

Para obtener una imagen monocromática debemos muestrear cada segundo byte de datos.

Un Arduino solo tiene 2K de memoria de acceso aleatorio, pero cada cuadro comprende 640 * 2 * 480 = 307, 200 bytes de datos. A menos que agreguemos un capturador de fotogramas al OV7670, todos los datos deben enviarse a la PC línea por línea para su procesamiento.

Hay dos posibilidades:

Para cada uno de los 480 cuadros sucesivos, podemos capturar una línea al Arduino a alta velocidad antes de enviarla a la PC a 1 Mbps. Tal enfoque haría que el OV7670 funcionara a toda velocidad, pero llevaría mucho tiempo (más de un minuto).

El enfoque que he adoptado es reducir la velocidad de PCLK a 8uS y enviar cada muestra como viene. Este enfoque es significativamente más rápido (6,4 segundos).

Paso 4: Notas de diseño

Notas de Diseño
Notas de Diseño
Notas de Diseño
Notas de Diseño
Notas de Diseño
Notas de Diseño

Compatibilidad

El chip de la cámara OV7670 es un dispositivo de 3v3 voltios. La hoja de datos indica que los voltajes superiores a 3,5 voltios dañarán el chip.

Para evitar que su Arduino de 5 voltios destruya el chip de la cámara OV7670:

  • La señal de reloj externo (XCLK) del Arduino debe reducirse a un nivel seguro mediante un divisor de voltaje.
  • Las resistencias pull-up internas Arduino I2C a 5 voltios deben desactivarse y reemplazarse con resistencias pull-up externas al suministro de 3v3 voltios.
  • Programe su Arduino ANTES de conectar cualquier puente, ya que algunos de los pines aún pueden estar programados como una salida de un proyecto anterior. (Aprendí esto de la manera difícil … afortunadamente compré dos porque eran muy baratos).

Reloj externo

El chip de la cámara OV7670 requiere un reloj externo en el rango de frecuencia de 10Mhz a 24MHz.

La frecuencia más alta que podemos generar a partir de un Arduino de 16 MHz es de 8 MHz, pero parece funcionar.

Enlace serial

Se necesitan al menos 10 uS (microsegundos) para enviar 1 byte de datos a través de un enlace en serie de 1 Mbps (millones de bits por segundo). Este tiempo se compone de la siguiente manera:

  • 8 bits de datos (8us)
  • 1 bit de inicio (1uS)
  • 1 bit de parada (1uS)

Reloj interno

La frecuencia del reloj de píxeles interno (PCLK) dentro del OV7670 se establece mediante bits [5: 0] dentro del registro CLKRC (ver foto 1). [1]

Si establecemos bits [5: 0] = B111111 = 63 y lo aplicamos a la fórmula anterior, entonces:

  • F (reloj interno) = F (reloj de entrada) / (Bit [5: 0} +1)
  • = 8000000/(63+1)
  • = 125000 Hz o
  • = 8uS

Dado que solo estamos muestreando cada segundo byte de datos, un intervalo PCLK de 8uS da como resultado una muestra de 16uS que es tiempo suficiente para transmitir 1 byte de datos (10uS) dejando 6uS para su procesamiento.

Cuadros por segundo

Cada cuadro de video VGA comprende 784 * 510 píxeles (elementos de imagen) de los cuales se muestran 640 * 480 píxeles. Dado que el formato de salida YUV (4: 2: 2) tiene un promedio de 2 bytes de datos por píxel, cada cuadro tomará 784 * 2 * 510 * 8 uS = 6.4 segundos.

¡Esta cámara NO es rápida!

Posicionamiento horizontal

La imagen se puede mover horizontalmente si cambiamos los valores HSTART y HSTOP manteniendo una diferencia de 640 píxeles.

Al mover la imagen a la izquierda, es posible que el valor de HSTOP sea menor que el valor de HSTART.

No se alarme … todo tiene que ver con los desbordamientos del mostrador, como se explica en la foto 2.

Registros

El OV7670 tiene 201 registros de ocho bits para controlar aspectos como la ganancia, el balance de blancos y la exposición.

Un byte de datos solo permite 256 valores en el rango [0] a [255]. Si necesitamos más control, entonces debemos conectar en cascada varios registros. Dos bytes nos dan 65536 posibilidades … tres bytes nos dan 16, 777, 216.

El registro AEC (Control automático de exposición) de 16 bits que se muestra en la foto 3 es un ejemplo y se crea combinando partes de los siguientes tres registros.

  • AECHH [5: 0] = AEC [15:10]
  • AECH [7: 2] = AEC [9: 2]
  • COM1 [1: 0] = AEC [1: 0]

Tenga cuidado … ¡las direcciones de registro no están agrupadas!

Efectos secundarios

Una velocidad de fotogramas lenta introduce una serie de efectos secundarios no deseados:

Para una exposición correcta, el OV7670 espera trabajar a una velocidad de fotogramas de 30 fps (fotogramas por segundo). Dado que cada fotograma tarda 6,4 segundos, el obturador electrónico está abierto 180 veces más de lo normal, lo que significa que todas las imágenes estarán sobreexpuestas a menos que modifiquemos algunos valores de registro.

Para evitar la sobreexposición, configuré todos los bits de registro AEC (control de exposición automática) a cero. Aun así, se necesita un filtro de densidad neutra delante de la lente cuando la iluminación es brillante.

Una exposición prolongada también parece afectar los datos UV. Como todavía tengo que encontrar combinaciones de registros que produzcan los colores correctos … considero que esto es un trabajo en progreso.

Nota

[1]

¿La fórmula que se muestra en la hoja de datos (foto 1) es correcta pero el rango solo muestra bits [4: 0]?

Paso 5: formas de onda de sincronización

Formas de onda de sincronización
Formas de onda de sincronización
Formas de onda de sincronización
Formas de onda de sincronización
Formas de onda de sincronización
Formas de onda de sincronización

La nota en la esquina inferior izquierda del diagrama "VGA Frame Timing" (foto 1) dice:

Para YUV / RGB, tp = 2 x TPCLK

Las figuras 1, 2 y 3 verifican la (s) hoja (s) de datos y confirman que Omnivision trata cada 2 bytes de datos como el equivalente a 1 píxel.

Las formas de onda del osciloscopio también verifican que HREF permanece BAJO durante los intervalos de supresión.

La figura 4 confirma que la salida XCLK del Arduino es de 8 MHz. La razón por la que vemos una onda sinusoidal, en lugar de una onda cuadrada, es que todos los armónicos impares son invisibles para mi osciloscopio de muestreo de 20MHz.

Paso 6: capturador de fotogramas

Capturador de fotogramas
Capturador de fotogramas

El sensor de imagen dentro de un chip de cámara OV7670 comprende una matriz de 656 * 486 píxeles de los cuales se usa una cuadrícula de 640 * 480 píxeles para la foto.

Los valores de registro HSTART, HSTOP, HREF y VSTRT, VSTOP, VREF se utilizan para colocar la imagen sobre el sensor. Si la imagen no está colocada correctamente sobre el sensor, verá una banda negra sobre uno o más bordes, como se explica en la sección "Notas de diseño".

El OV7670 escanea cada línea de la imagen un píxel a la vez comenzando desde la esquina superior izquierda hasta que alcanza el píxel inferior derecho. El Arduino simplemente pasa estos píxeles a la PC a través del enlace serial como se muestra en la foto 1.

La tarea de los capturadores de fotogramas es capturar cada uno de estos 640 * 480 = 307200 píxeles y mostrar el contenido en una ventana de "imagen".

Processing 3 logra esto usando las siguientes cuatro líneas de código !!

Línea de código 1:

byte byteBuffer = nuevo byte [maxBytes + 1]; // donde maxBytes = 307200

El código subyacente en esta declaración crea:

  • una matriz de bytes de 307201 llamada "byteBuffer [307201]"
  • El byte extra es para un carácter de terminación (salto de línea).

Línea de código 2:

tamaño (640, 480);

El código subyacente en esta declaración crea:

  • una variable llamada "ancho = 640;"
  • una variable llamada "altura = 480";
  • una matriz de 307200 píxeles llamada "píxeles [307200]"
  • una ventana de “imagen” de 640 * 480 píxeles en la que se muestra el contenido de la matriz de píxeles . Esta ventana de "imagen" se actualiza continuamente a una velocidad de fotogramas de 60 fps.

Línea de código 3:

byteCount = myPort.readBytesUntil (lf, byteBuffer);

El código subyacente en esta declaración:

  • almacena los datos entrantes localmente hasta que ve un carácter "lf" (salto de línea).
  • después de lo cual, vuelca los primeros 307200 bytes de datos locales en la matriz byteBuffer .
  • También guarda el número de bytes recibidos (307201) en una variable llamada "byteCount".

Línea de código 4:

píxeles = color (byteBuffer );

Cuando se coloca en un bucle for-next, el código subyacente en esta declaración:

  • copia el contenido de la matriz "byteBuffer " en la matriz "píxeles"
  • cuyo contenido aparece en la ventana de la imagen.

Pulsaciones de tecla:

El capturador de fotogramas reconoce las siguientes pulsaciones de teclas:

  • "C" = capturar la imagen
  • "S" = guardar la imagen en un archivo.

Paso 7: software

Descargue e instale cada uno de los siguientes paquetes de software si aún no están instalados:

  • "Arduino" de
  • "Java 8" de https://java.com/en/download/ [1]
  • "Procesando 3" de

Instalación del boceto de Arduino:

  • Quite todos los cables de puente del OV7670 [2]
  • Conecte un cable USB a su Arduino
  • Copie el contenido de "OV7670_camera_mono_V2.ino" (adjunto) en un "boceto" de Arduino y guárdelo.
  • Sube el boceto a tu Arduino.
  • Desenchufe el Arduino
  • Ahora puede volver a conectar de forma segura los cables de puente OV7670
  • Vuelva a conectar el cable USB.

Instalación y ejecución del boceto de procesamiento

  • Copie el contenido de “OV7670_camera_mono_V2.pde” (adjunto) en un “boceto” de procesamiento y guárdelo.
  • Haga clic en el botón "ejecutar" de la parte superior izquierda … aparecerá una ventana de imagen negra
  • Haga clic en la ventana de imagen "negra"
  • Presione la tecla “c” para capturar una imagen. (aproximadamente 6,4 segundos).
  • Presione la tecla "s" para guardar la imagen en su carpeta de procesamiento
  • Repita los pasos 4 y 5.
  • Haga clic en el botón "detener" para salir del programa.

Notas

[1]

El procesamiento 3 requiere Java 8

[2]

Este es un paso de seguridad "solo una vez" para evitar dañar el chip de su cámara OV7670.

Hasta que se cargue el boceto "OV7670_camera_mono.ini" en su Arduino, las resistencias pull-up internas están conectadas a 5 voltios, además existe la posibilidad de que algunas de las líneas de datos de Arduino sean salidas de 5 voltios … todas las cuales son fatales para el chip de cámara OV7670 de 3v3 voltios.

Una vez que se ha programado el Arduino, no es necesario repetir este paso y los valores de registro se pueden cambiar de forma segura.

Paso 8: obtención de una imagen en color

Obtener una imagen en color
Obtener una imagen en color
Obtener una imagen en color
Obtener una imagen en color
Obtener una imagen en color
Obtener una imagen en color

El siguiente software es puramente experimental y se publica con la esperanza de que algunas de las técnicas resulten útiles. Los colores parecen estar invertidos… todavía tengo que encontrar la configuración de registro correcta. Si encuentra una solución, publique sus resultados

Si queremos obtener una imagen en color, se deben capturar todos los bytes de datos y aplicar las siguientes fórmulas.

El OV7670 utiliza las siguientes fórmulas para convertir la información de color RGB (rojo, verde, azul) en YUV (4: 2: 2): [1]

  • Y = 0,31 * R + 0,59 * G + 0,11 * B
  • U = B - Y
  • V = R - Y
  • Cb = 0,563 * (B-Y)
  • Cr = 0,713 * (R-Y)

Las siguientes fórmulas se pueden utilizar para convertir YUV (4: 2: 2) de nuevo a color RGB: [2]

  • R = Y + 1,402 * (Cr - 128)
  • G = Y - 0,344136 * (Cb -128) - 0,714136 * (Cr -128)
  • B = Y + 1.772 * (Cb -128)

El software adjunto es simplemente una extensión del software monocromo:

  • Se envía una solicitud de captura "c" al Arduino
  • El Arduino envía los bytes pares (monocromáticos) a la PC
  • La PC guarda estos bytes en una matriz
  • A continuación, el Arduino envía los bytes impares (croma) a la PC.
  • Estos bytes se guardan en una segunda matriz … ahora tenemos la imagen completa.
  • Las fórmulas anteriores ahora se aplican a cada grupo de cuatro bytes de datos UYVY.
  • Los píxeles de color resultantes se colocan en la matriz "píxeles ".
  • La PC escanea la matriz de “píxeles ” y aparece una imagen en la ventana de “imagen”.

El software Processing 3 muestra brevemente cada escaneo y los resultados finales:

  • La foto 1 muestra los datos de croma U y V del escaneo 1
  • La foto 2 muestra los datos de luminancia Y1 e Y2 del escaneo 2
  • La foto 3 muestra la imagen en color … solo una cosa está mal … ¡¡la bolsa debe ser verde !!

Publicaré un nuevo código una vez que haya resuelto este programa …

Referencias:

[1]

www.haoyuelectronics.com/Attachment/OV7670%… (página 33)

[2]

en.wikipedia.org/wiki/YCbCr (conversión JPEG)

Haga clic aquí para ver mis otros instructivos.

Recomendado: