4.17. Controlos do sensor

Para além de pixformat() e framesize(), a classe CSI expõe um conjunto de controlos por sensor que quase todas as aplicações acabam por utilizar – orientação de montagem, exposição, ganho, balanço de brancos e alguns auxiliares de depuração. Cada um mapeia diretamente para um conceito do sensor abordado anteriormente; a API apenas fornece um identificador Python para a escrita de registo que o driver efetua por baixo.

Todos os métodos abaixo atuam sobre o sensor subjacente. Todos enviam escritas de registo pelo barramento de controlo I2C do sensor, pelo que o custo é de microssegundos e a nova definição entra em vigor na próxima exposição – tipicamente o próximo snapshot().

4.17.1. Orientação

A câmara não sabe de que lado foi montada. Dois sinalizadores de inversão aplicados no sensor orientam corretamente a imagem antes de qualquer pixel sair do chip:

csi0.hmirror(True)
csi0.vflip(True)

hmirror() inverte da esquerda para a direita e vflip() inverte de cima para baixo. Em conjunto, cobrem os casos que surgem na prática: uma placa montada de cabeça para baixo (ambos os sinalizadores True), uma placa atrás de um espelho de face prateada (apenas hmirror), ou uma que observa uma cena refletida por baixo (apenas vflip).

Como a inversão ocorre na lógica de leitura do sensor, não há custo para a CPU nem sobrecarga de memória – o fotograma aterra no framebuffer já orientado.

4.17.2. Exposição

A exposição é o tempo de integração – quanto tempo o fotodíodo em cada pixel acumula carga antes de a linha ser lida, em microssegundos. O driver começa com o ciclo de autoexposição do sensor ativo, pelo que a câmara tenta manter o valor médio dos pixels próximo de um alvo. Desativar o ciclo fixa a exposição num valor escolhido pela aplicação:

csi0.auto_exposure(False, exposure_us=8000)

Uma exposição fixa é a escolha certa quando o brilho da cena é estável e a aplicação precisa de desfocagem de movimento previsível ou intensidade fotograma a fotograma consistente para limiarização. Ler a exposição atual – seja ela definida pelo ciclo ou pela aplicação – é uma chamada separada:

us = csi0.exposure_us()

Chamar auto_exposure() com True e sem valor de exposição devolve o controlo ao ciclo.

4.17.3. Ganho

O ganho é o amplificador aplicado à tensão do pixel antes de chegar ao ADC, em decibéis. Tal como a exposição, o driver começa com o ciclo de ganho automático ativo. Dois padrões surgem com frequência. Limitar o teto permite que o ciclo se adapte à iluminação, mas impede-o de amplificar o ruído indefinidamente em cenas com pouca luz:

csi0.auto_gain(True, gain_db_ceiling=16)

Fixar um ganho constante é a medida certa quando a aplicação também fixa a exposição – a estabilidade do ganho é importante para aplicações que comparam valores de pixel fotograma a fotograma, como o rastreamento de cor:

csi0.auto_gain(False, gain_db=0)

O ganho atual é lido através de gain_db(). Sempre que a aplicação desativa o ganho automático, deve também desativar o balanço de brancos automático e a exposição automática – caso contrário, os ciclos de controlo ainda ativos irão distorcer a imagem de formas que anulam o ganho fixo.

4.17.4. Balanço de brancos

O balanço de brancos é o ganho por canal que o ISP aplica aos canais vermelho, verde e azul provenientes da fase de debayering, de modo que um objeto branco pareça branco sob qualquer cor de luz. O ciclo de balanço de brancos automático calcula esses três ganhos a partir das estatísticas por região que o ISP recolhe em cada fotograma e aplica-os no fotograma seguinte.

A maioria das aplicações deixa o ciclo ativo. O rastreamento de cor é a exceção mais comum – os ganhos são também o que o ciclo irá ajustar para seguir um objeto colorido; por isso, se a aplicação está a tentar encontrar uma mancha vermelha, o ciclo irá silenciosamente reduzir o canal vermelho e a mancha deixará de corresponder. Bloquear o ciclo resolve isso:

csi0.auto_whitebal(False)

Passe um tuplo explícito (r, g, b) em decibéis para uma calibração de cor reprodutível – os mesmos ganhos entre placas e sessões:

csi0.auto_whitebal(False, rgb_gain_db=(0.0, 0.0, 0.0))

Os ganhos atuais são lidos como um tuplo através de rgb_gain_db().

4.17.5. Limite de taxa de fotogramas

Os sensores funcionam à sua taxa de fotogramas nativa por padrão – 30 a 60 fotogramas por segundo na maioria dos modelos, muito mais nos sensores de alta velocidade quando o framesize é suficientemente pequeno. Limitar a taxa permite que a aplicação regule a câmara ao ritmo que o processamento a jusante consegue acompanhar:

csi0.framerate(15)

Nos sensores que suportam controlo de taxa por hardware, a chamada também prolonga o orçamento de exposição por fotograma, o que pode ajudar em condições de pouca luz; nos restantes, o driver simplesmente ignora os fotogramas extra ao nível do framebuffer.

4.17.6. Padrão de teste

O padrão de teste de barras de cor está integrado na maioria dos sensores e é útil para separar um problema de captura de imagem de um problema de saída. Ativá-lo ignora a matriz de fotodíodos e envia um padrão fixo pelo mesmo caminho de dados de pixel:

csi0.colorbar(True)

Se o padrão de teste parecer correto mas a imagem ao vivo não, a falha está na ótica ou no front-end analógico do sensor; se mesmo o padrão de teste estiver corrompido, o problema encontra-se algures no barramento de dados de pixel ou na configuração de pixformat() / framesize(). Passe False para regressar à imagem ao vivo.

Consulte csi.CSI para a API completa, incluindo os comandos ioctl() específicos do sensor que expõem controlos exclusivos de famílias de sensores particulares.