Índice:
- Etapa 1: Diagrama de Circuito
- Etapa 2: Lista de peças
- Etapa 3: Teoria
- Etapa 4: notas de design
- Etapa 5: formas de onda de tempo
- Etapa 6: agarrador de quadro
- Etapa 7: Software
- Etapa 8: Obtenção de uma imagem colorida
Vídeo: Faça sua própria câmera: 8 etapas
2024 Autor: John Day | [email protected]. Última modificação: 2024-01-30 11:37
Este instrutível explica como fazer uma câmera monocromática usando um sensor de imagem Omnivision OV7670, um microcontrolador Arduino, alguns fios de ligação e software Processing 3.
Um software experimental para a obtenção de uma imagem colorida também é apresentado.
Pressione a tecla “c” para capturar uma imagem de 640 * 480 pixels … pressione a tecla “s” para salvar a imagem em arquivo. As imagens sucessivas são numeradas sequencialmente, caso você deseje criar um filme de lapso de tempo curto.
A câmera não é rápida (cada varredura leva 6,4 segundos) e só é adequada para uso em iluminação fixa.
O custo, excluindo o Arduino e o PC, é inferior a uma xícara de café.
Imagens
As peças componentes, sem fiação de jumper, são mostradas na foto de abertura.
A segunda foto é uma captura de tela mostrando o software da câmera Arduino e o pegador de quadros Processing 3. A inserção mostra como a câmera está conectada.
O vídeo demonstra a câmera em ação. Quando a tecla de captura “c” é pressionada, há um breve flash seguido por uma explosão de atividade enquanto a imagem é digitalizada. A imagem aparece automaticamente na janela de exibição assim que a digitalização for concluída. As imagens aparecem na pasta de processamento após cada pressionamento da tecla “s”. O vídeo termina percorrendo rapidamente cada uma das três imagens salvas.
Etapa 1: Diagrama de Circuito
O diagrama de circuito, para todas as versões desta câmera, é mostrado na foto 1.
As fotos 2, 3 mostram como os fios dos jumpers e os componentes são conectados.
Sem o suporte de alumínio, as imagens ficam de lado.
Aviso
Programe seu Arduino ANTES de conectar qualquer fio de ponte ao chip da câmera OV7670. Isso impedirá que os pinos de saída de 5 volts de um programa anterior destruam o chip da câmera OV7670 de 3v3 volts.
Etapa 2: Lista de peças
As seguintes partes foram obtidas em
- 1 único Módulo de Câmera VGA OV7670 300KP para arduino DIY KIT
- 1 único suporte de câmera completo com porcas e parafusos
- 1 apenas UNO R3 para arduino MEGA328P 100% ATMEGA16U2 original com cabo USB
As seguintes peças foram obtidas localmente
- 18 cabos de jumper Arduino macho-fêmea
- 3 cabos Jumper fêmea-fêmea Arduinin apenas
- 1 apenas mini tábua de pão
- 4 resistores apenas 4k7 ohm 1/2 watt
- 1 único suporte de alumínio de sucata.
Você também precisará das seguintes planilhas de dados:
- https://web.mit.edu/6.111/www/f2016/tools/OV7670_20…
- https://www.haoyuelectronics.com/Attachment/OV7670%…
Etapa 3: Teoria
Chip de câmera OV7670
A saída padrão do chip da câmera OV7670 compreende um sinal de vídeo YUV (4: 2: 2) e 3 formas de onda de temporização. Outros formatos de saída são possíveis programando os registros internos por meio de um barramento compatível com I2C.
O sinal de vídeo YUV (4: 2: 2) (foto 1) é uma sequência contínua de pixels monocromáticos (preto e branco) separados por U (diferença de cor azul) e V (diferença de cor vermelha) informações de cor.
Este formato de saída é conhecido como YUV (4: 2: 2), pois cada grupo de 4 bytes contém 2 bytes monocromáticos e 2 bytes de cores.
Monocromático
Para obter uma imagem monocromática, devemos amostrar a cada segundo byte de dados.
Um Arduino tem apenas 2K de memória de acesso aleatório, mas cada quadro compreende 640 * 2 * 480 = 307, 200 bytes de dados. A menos que adicionemos um frame-grabber ao OV7670, todos os dados devem ser enviados ao PC linha por linha para processamento.
Existem duas possibilidades:
Para cada um dos 480 quadros sucessivos, podemos capturar uma linha para o Arduino em alta velocidade antes de enviá-la para o PC a 1 Mbps. Tal abordagem faria com que o OV7670 trabalhasse a toda velocidade, mas levaria muito tempo (bem mais de um minuto).
A abordagem que adotei é diminuir a velocidade do PCLK para 8µS e enviar cada amostra conforme ela chega. Essa abordagem é significativamente mais rápida (6,4 segundos).
Etapa 4: notas de design
Compatibilidade
O chip da câmera OV7670 é um dispositivo de 3v3 volts. A folha de dados indica que tensões acima de 3,5 volts danificarão o chip.
Para evitar que seu Arduino de 5 volts destrua o chip da câmera OV7670:
- O sinal de clock externo (XCLK) do Arduino deve ser reduzido a um nível seguro por meio de um divisor de tensão.
- Os resistores pull-up Arduino I2C internos para 5 volts devem ser desabilitados e substituídos por resistores pull-up externos para a alimentação de 3v3 volts.
- Programe seu Arduino ANTES de conectar quaisquer fios de jumper, pois alguns dos pinos ainda podem ser programados como uma saída de um projeto anterior !!! (Aprendi isso da maneira mais difícil … felizmente comprei dois porque eram muito baratos).
Relógio externo
O chip da câmera OV7670 requer um clock externo na faixa de frequência de 10Mhz a 24MHz.
A frequência mais alta que podemos gerar de um Arduino de 16 MHz é de 8 MHz, mas parece funcionar.
Link serial
Leva pelo menos 10 uS (microssegundos) para enviar 1 byte de dados através de um link serial de 1 Mbps (milhão de bits por segundo). Este tempo é composto da seguinte forma:
- 8 bits de dados (8us)
- 1 bit inicial (1uS)
- 1 bit de parada (1uS)
Relógio interno
A frequência do clock interno do pixel (PCLK) dentro do OV7670 é definida por bits [5: 0] dentro do registrador CLKRC (veja a foto 1). [1]
Se definirmos os bits [5: 0] = B111111 = 63 e aplicá-los à fórmula acima:
- F (relógio interno) = F (relógio de entrada) / (Bit [5: 0} +1)
- = 8000000/(63+1)
- = 125000 Hz ou
- = 8uS
Uma vez que estamos apenas amostrando cada segundo byte de dados, um intervalo PCLK de 8uS resulta em uma amostra de 16uS que é tempo suficiente para transmitir 1 byte de dados (10uS) deixando 6uS para processamento.
Taxa de quadros
Cada quadro de vídeo VGA compreende 784 * 510 pixels (elementos de imagem) dos quais 640 * 480 pixels são exibidos. Como o formato de saída YUV (4: 2: 2) tem uma média de 2 bytes de dados por pixel, cada quadro levará 784 * 2 * 510 * 8 uS = 6,4 segundos.
Esta câmera NÃO é rápida !!!
Posicionamento horizontal
A imagem pode ser movida horizontalmente se alterarmos os valores HSTART e HSTOP, mantendo uma diferença de 640 pixels.
Ao mover sua imagem para a esquerda, é possível que o valor HSTOP seja menor que o valor HSTART!
Não se assuste … tem tudo a ver com estouros de contador, conforme explicado na foto 2.
Registros
O OV7670 tem 201 registradores de oito bits para controlar coisas como ganho, balanço de branco e exposição.
Um byte de dados permite apenas 256 valores no intervalo de [0] a [255]. Se precisarmos de mais controle, devemos colocar vários registradores em cascata. Dois bytes nos dão 65536 possibilidades … três bytes nos dão 16, 777, 216.
O registro AEC (Controle de Exposição Automática) de 16 bits mostrado na foto 3 é um exemplo e é criado pela combinação de partes dos três registros a seguir.
- AECHH [5: 0] = AEC [15:10]
- AECH [7: 2] = AEC [9: 2]
- COM1 [1: 0] = AEC [1: 0]
Esteja avisado … os endereços de registro não estão agrupados!
Efeitos colaterais
Uma taxa de quadros lenta introduz uma série de efeitos colaterais indesejados:
Para a exposição correta, o OV7670 espera funcionar a uma taxa de quadros de 30 fps (quadros por segundo). Como cada quadro leva 6,4 segundos, o obturador eletrônico abre 180 vezes mais do que o normal, o que significa que todas as imagens ficarão superexpostas, a menos que alteremos alguns valores de registro.
Para evitar a superexposição, configurei todos os bits de registro AEC (controle de exposição automática) para zero. Mesmo assim, um filtro de densidade neutra é necessário na frente da lente quando a iluminação é forte.
Uma longa exposição também parece afetar os dados de UV. Como ainda não encontrei combinações de registro que produzam cores corretas … considero isso um trabalho em andamento.
Observação
[1]
A fórmula mostrada na folha de dados (foto 1) está correta, mas o intervalo mostra apenas bits [4: 0]?
Etapa 5: formas de onda de tempo
A nota no canto inferior esquerdo do diagrama "Tempo do quadro VGA" (foto 1) diz:
Para YUV / RGB, tp = 2 x TPCLK
As Figuras 1, 2 e 3 verificam a (s) folha (s) de dados e confirmam que o Omnivision trata cada 2 bytes de dados como sendo o equivalente a 1 pixel.
As formas de onda do osciloscópio também verificam se HREF permanece BAIXO durante os intervalos de apagamento.
A Fig.4 confirma que a saída XCLK do Arduino é de 8 MHz. A razão pela qual vemos uma onda senoidal, em vez de uma onda quadrada, é que todos os harmônicos estranhos são invisíveis para meu osciloscópio de amostragem de 20 MHz.
Etapa 6: agarrador de quadro
O sensor de imagem dentro de um chip de câmera OV7670 compreende uma matriz de 656 * 486 pixels, dos quais uma grade de 640 * 480 pixels é usada para a foto.
Os valores de registro HSTART, HSTOP, HREF e VSTRT, VSTOP, VREF são usados para posicionar a imagem sobre o sensor. Se a imagem não estiver posicionada corretamente sobre o sensor, você verá uma faixa preta sobre uma ou mais bordas, conforme explicado na seção “Design Notes”.
O OV7670 examina cada linha da imagem, um pixel de cada vez, começando do canto superior esquerdo até atingir o pixel inferior direito. O Arduino simplesmente passa esses pixels para o PC por meio do link serial, conforme mostrado na foto 1.
A tarefa dos pegadores de quadro é capturar cada um desses 640 * 480 = 307200 pixels e exibir o conteúdo em uma janela de "imagem"
O processamento 3 consegue isso usando as quatro linhas de código a seguir !!
Linha de código 1:
byte byteBuffer = novo byte [maxBytes + 1]; // onde maxBytes = 307200
O código subjacente nesta declaração cria:
- uma matriz de bytes 307201 chamada “byteBuffer [307201]”
- O byte extra é para um caractere de terminação (alimentação de linha).
Linha de código 2:
tamanho (640, 480);
O código subjacente nesta declaração cria:
- uma variável chamada “largura = 640;”
- uma variável chamada “altura = 480”;
- uma matriz de 307200 pixels chamada “pixels [307200]”
- uma janela de “imagem” de 640 * 480 pixels na qual o conteúdo da matriz de pixels é exibido. Esta janela de “imagem” é continuamente atualizada a uma taxa de quadros de 60 fps.
Linha de código 3:
byteCount = myPort.readBytesUntil (lf, byteBuffer);
O código subjacente nesta declaração:
- armazena os dados de entrada localmente até ver um caractere “lf” (avanço de linha).
- depois disso, ele despeja os primeiros 307200 bytes de dados locais na matriz byteBuffer .
- Ele também salva o número de bytes recebidos (307201) em uma variável chamada “byteCount”.
Linha de código 4:
pixels = cor (byteBuffer );
Quando colocado em um loop for-next, o código subjacente nesta instrução:
- copia o conteúdo do array “byteBuffer ” para o array “pixels ”
- cujo conteúdo aparece na janela da imagem.
Teclas:
O agarrador de quadros reconhece as seguintes teclas:
- ‘C’ = captura a imagem
- ‘S’ = salvar a imagem em arquivo.
Etapa 7: Software
Baixe e instale cada um dos seguintes pacotes de software, se ainda não estiver instalado:
- “Arduino” de
- “Java 8” em https://java.com/en/download/ [1]
- "Processando 3” em
Instalando o esboço do Arduino:
- Remova todos os fios de jumper OV7670 [2]
- Conecte um cabo USB ao seu Arduino
- Copie o conteúdo de “OV7670_camera_mono_V2.ino“(anexado) em um “esboço” do Arduino e salve.
- Faça upload do esboço para o seu Arduino.
- Desconecte o Arduino
- Agora você pode reconectar com segurança os fios de jumper OV7670
- Reconecte o cabo USB.
Instalando e executando o esboço de processamento
- Copie o conteúdo de “OV7670_camera_mono_V2.pde” (anexado) em um “esboço” de processamento e salve.
- Clique no botão "executar" no canto superior esquerdo … uma janela de imagem preta aparecerá
- Clique na janela de imagem “preta”
- Pressione a tecla “c” para capturar uma imagem. (aproximadamente 6,4 segundos).
- Pressione a tecla “s” para salvar a imagem em sua pasta de processamento
- Repita as etapas 4 e 5
- Clique no botão “parar” para sair do programa.
Notas
[1]
O processamento 3 requer Java 8
[2]
Este é um passo de segurança “apenas uma vez” para evitar danos ao chip da câmera OV7670.
Até que o esboço “OV7670_camera_mono.ini” tenha sido carregado em seu Arduino, os resistores pull-up internos são conectados a 5 volts, além de haver a possibilidade de que algumas das linhas de dados do Arduino possam ser saídas de 5 volts … todos os quais são fatais para o chip de câmera 3v3 volts OV7670.
Uma vez que o Arduino tenha sido programado, não há necessidade de repetir esta etapa e os valores do registro podem ser alterados com segurança.
Etapa 8: Obtenção de uma imagem colorida
O software a seguir é puramente experimental e foi publicado na esperança de que algumas das técnicas sejam úteis. As cores parecem estar invertidas … Ainda não encontrei as configurações de registro corretas. Se você encontrar uma solução, por favor poste seus resultados
Se quisermos obter uma imagem colorida, todos os bytes de dados devem ser capturados e as seguintes fórmulas aplicadas.
O OV7670 usa as seguintes fórmulas para converter informações de cores RGB (vermelho, verde, azul) em 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)
As seguintes fórmulas podem ser usadas para converter YUV (4: 2: 2) de volta para a cor RGB: [2]
- R = Y + 1,402 * (Cr - 128)
- G = Y - 0,344136 * (Cb -128) - 0,714136 * (Cr -128)
- B = Y + 1,772 * (Cb -128)
O software anexo é simplesmente uma extensão do software monocromático:
- Uma solicitação de captura “c” é enviada ao Arduino
- O Arduino envia os bytes pares (monocromáticos) para o PC
- O PC salva esses bytes em um array
- Em seguida, o Arduino envia os bytes ímpares (croma) para o PC.
- Esses bytes são salvos em um segundo array … agora temos a imagem inteira.
- As fórmulas acima agora são aplicadas a cada grupo de quatro bytes de dados UYVY.
- Os pixels de cor resultantes são então colocados na matriz “pixels ”
- O PC varre a matriz “pixels ” e uma imagem aparece na janela “imagem”.
O software Processing 3 exibe rapidamente cada varredura e os resultados finais:
- A foto 1 mostra os dados de croma U&V da varredura 1
- A foto 2 mostra os dados de luminância Y1 e Y2 da varredura 2
- A foto 3 mostra a imagem colorida… só uma coisa está errada… a bolsa deveria ser verde !!
Vou postar um novo código assim que tiver resolvido este programa …
Referências:
[1]
www.haoyuelectronics.com/Attachment/OV7670%… (página 33)
[2]
en.wikipedia.org/wiki/YCbCr (conversão JPEG)
Clique aqui para ver meus outros instructables.
Recomendado:
Faça sua própria máquina de coquetel cru: 5 etapas (com fotos)
Faça sua própria máquina de coquetel bruto: Neste projeto, mostrarei como combinei um Arduino Nano, um LCD, um codificador rotativo, três bombas peristálticas com acionadores de motor, uma célula de carga e alguns pedaços de madeira para criar um produto bruto, mas Máquina de Coquetel funcional. Ao longo do caminho vou des
Faça sua própria iluminação ambiente com o Raspberry Pi Zero: 5 etapas (com fotos)
Faça sua própria iluminação ambiente com o Raspberry Pi Zero: Neste projeto, mostrarei como combinar um Raspberry Pi Zero com algumas peças complementares para adicionar um efeito de iluminação ambiente à sua TV que aprimore a experiência de visualização. Vamos começar
Faça sua própria matriz LED RGB 15x10: 10 etapas
Faça sua própria matriz de LEDs RGB 15x10: Nesta série de vídeos, apresentarei como construir uma matriz de LEDs RGB 15x10. Esta Matriz tem uma largura de 1,5m e uma altura de 1m. Ele consiste em LEDs PL9823 RGB, que são uma alternativa barata aos LEDs WS2812 comuns. Vou falar sobre os desafios que
Faça sua própria câmera deslizante motorizada: 6 etapas (com fotos)
Faça seu próprio controle deslizante de câmera motorizada: Neste projeto, mostrarei como reaproveitei dois tripés de câmera antigos para criar um controle deslizante de câmera motorizada. O sistema mecânico consiste principalmente em alumínio e aço inoxidável, o que torna o controle deslizante robusto e com uma aparência bastante decente. O
Faça sua própria câmera suspensa com iluminação LED !: 5 etapas (com fotos)
Faça seu próprio equipamento de câmera suspensa com iluminação LED !: Neste projeto, mostrarei como criar um equipamento simples de câmera suspensa. O equipamento pode não apenas segurar a câmera logo acima do objeto que você deseja filmar, mas também possui um monitor para observar a filmagem e iluminação LED para