5.34. Conclusão

O módulo image é a maior API que a câmara expõe, e o capítulo acabou de cobrir o seu esboço: como uma imagem é representada em memória, como a câmara lê e escreve pixels individuais, como desenha em fotogramas capturados, como os transforma aritmética e geometricamente, como os classifica por limiar e filtra, como extrai medições e deteções deles, como descodifica símbolos impressos a partir deles, como compara uma imagem com outra, e como obtém os resultados de e para a câmara.

O conjunto de ferramentas é vasto de propósito. Um pipeline de visão por computador clássico a correr numa câmara embebida pequena faz a maior parte do seu trabalho antes de qualquer coisa chegar a um modelo de aprendizagem automática, quando existe um – o limiar limpa a entrada, os filtros reduzem o ruído, as regiões estreitam a pesquisa, os detetores de manchas e linhas localizam candidatos, a pontuação de semelhança decide se o candidato é interessante, e a camada de I/O entrega o resultado a qualquer coisa que execute a próxima etapa. Cada página deste capítulo cobriu uma dessas operações; o pipeline certo para qualquer aplicação é uma sequência delas composta na ordem que o problema exige.

5.34.1. O padrão de pipeline

A maioria das aplicações não triviais da câmara seguem o mesmo esboço. Capturar um fotograma a partir do sensor. Pré-processá-lo: converter formatos, equalizar o histograma, borrar o ruído. Localizar as regiões ou características de interesse: deteção de manchas, deteção de linhas, correspondência de templates, descodificação de códigos. Analisar o que foi encontrado: medições geométricas, pontuação de semelhança, estatísticas. Decidir o que fazer com base na análise: acionar um GPIO, reportar um payload, capturar e registar, passar o fotograma a um modelo de ML. Enviar a decisão ou o artefacto capturado: guardar, codificar, enviar, desenhar de volta no fotograma para a pré-visualização do IDE.

Nenhuma página do capítulo cobriu todos os passos; o capítulo cobriu os blocos de construção que o pipeline compõe. Escolher quais os blocos a usar e em que ordem é o trabalho do script da aplicação.

5.34.2. Para onde o capítulo conduz

O módulo image trata as imagens como imagens – pixels, regiões, desenho, deteções. Muito do trabalho com dados capturados não se enquadra nessa perspetiva. Calcular estatísticas sobre um array numérico arbitrário, executar aritmética vetorizada em dados brutos do sensor, aplicar uma transformação matricial personalizada que não tem um método no módulo de imagem por detrás, preparar dados para um modelo de aprendizagem automática que quer um layout de tensor específico – tudo isso é trabalho para uma biblioteca de arrays numéricos, não uma de processamento de imagem.

O próximo capítulo cobre exatamente isso. O módulo ulab.numpy fornecido com MicroPython na câmara é um subconjunto do NumPy, e duas pontes ligam-no ao módulo image: to_ndarray() copia os pixels de um fotograma para um ndarray para trabalho numérico, e o construtor Image aceita um ndarray para construir uma nova imagem a partir do resultado, pronta a mostrar, guardar ou alimentar de volta à biblioteca de imagem. Os dois módulos compõem-se – cada um faz o que o outro não faz, e juntos cobrem o trabalho numérico e de imagem que uma aplicação de visão embebida necessita.