v5.0.1#
v5.0.1 é uma versão de manutenção sobre a v5.0.0 — o módulo legado sensor se torna uma camada de compatibilidade em Python sobre csi, imagens carregadas no frame buffer agora são pré-visualizadas como quadros da câmera, os codificadores JPEG perdem seu limite de saída de 1 MB e tratam o estouro corretamente, e há um conjunto de correções de câmera, protocolo, rede e biblioteca de ML. Ela não introduz nenhuma mudança incompatível de API para scripts escritos com base em csi; as poucas mudanças de comportamento estão listadas em mudanças incompatíveis de API.
Destaques#
O módulo
sensoragora é um módulo Python congelado construído sobrecsi. Ele imprime um aviso de obsolescência na importação; algumas funções que o módulocsinão consegue suportar agora levantamOSError. Veja as mudanças no módulo sensor.Imagens carregadas são pré-visualizadas como quadros da câmera. Uma imagem colocada no frame buffer com
copy_to_fb=True(image.Image,image.ImageIO.read(),fir.snapshot(),tof.snapshot()) é descarregada para a IDE — com qualquer coisa desenhada nela — quando a próxima imagem sobrescreve o frame buffer, em vez de imediatamente. Veja as mudanças na pré-visualização.Reformulação do codificador JPEG. O limite de 1 MB do buffer de saída desapareceu (o buffer é dimensionado a partir da memória livre), o estouro tanto no caminho de software quanto no de hardware é tratado em vez de gravar arquivos truncados, e salvar uma imagem comprimida com a outra extensão comprimida levanta uma exceção em vez de gravar lixo.
Novo
protocol.poll()e seis novos widgets CBOR (text,lineedit,pushbutton,spinbox,radio,waveform) paraprotocol.CBORChannel.Pós-processador YOLO Pro, suporte a FLIR Lepton 3.1R / UW, leituras em rajada do IMU, CAN na OpenMV N6 e um alvo de simulador com suporte a rede.
Novos recursos#
YoloPro— um novo pós-processador para modelos de detecção de objetos YOLO Pro da Edge Impulse, mais um exemployolo_pro_detector.py. (f3f150ebd, ea7bbb398)protocol.poll()— executa uma iteração da tarefa do protocolo sob demanda, para transportes personalizados que não são acionados pela interrupção USB nem pelo timerpoll_ms.protocol.init()também pode ser chamado novamente para reinicializar a pilha. (c00c215f9, f849ffb1b)Mais widgets de canal CBOR —
protocol.CBORChannel.add()ganhatext(string estática),lineedit(string gravável),pushbutton(ação momentânea),spinbox(entrada numérica em passos),radio(grupo de opções) ewaveform(série temporal 1D com os argumentossample_rate,seriesetypecode; atribua bytes de amostras intercaladas para transmiti-la). (8016d29ba)csi.CUSTOM—csi.CSI.framesize()agora retorna uma constante utilizável depois que uma resolução(w, h)personalizada foi definida, em vez de um inteiro anônimo. (af8841654)Leitura em rajada do IMU —
imu.__read_reg()aceita um buffer gravável opcional e o preenche a partir de registradores consecutivos em uma única transação. (244ca480a)FLIR Lepton 3.1R e Lepton UW são reconhecidos pelo driver do Lepton, incluindo seus modos de ganho radiométrico. (0fc356632)
Rede no simulador — o alvo QEMU
MPS2_AN500agora tem lwIP e uma NIC em modo usuário, comrequests,mqttesensorcongelados no firmware, e um teste unitário de rede. (23546dfb1, 61d187305, 15096c3a2)Exemplo de API compatível com OpenAI —
openai_compatible.pycaptura um JPEG e o envia para um endpoint de chat-completions para descrição da cena. (79033c6aa)Exemplos LoRa SX126x — o driver
lora-sx126xda micropython-lib (comlora-sync/lora-async) está congelado no firmware da OpenMV RT1062, com exemplos de emissor/receptor/ping-pong/streaming de imagem para ligar um módulo SX1261 ou SX1262 ao barramento SPI. Este é um suporte contribuído pela comunidade; a OpenMV não vende hardware LoRa. (19576e1b1)
Outras mudanças e melhorias#
Reescrita da biblioteca
requests— respostas com transferência em chunks são decodificadas, um argumentotimeout(padrão 5 s) é exposto, corpos JSON e string são serializados/codificados corretamente, os cabeçalhos são analisados sem distinção entre maiúsculas e minúsculas e a linha de status por posição, o dicionárioheadersdo chamador é copiado (de modo queauthnão vaza mais para requisições posteriores) e o corpo é lido em blocos para umbytearray. (889f0b096)mqttimportasslsob demanda, de modo que o módulo e as conexões simples (sem TLS) funcionam em builds sem suporte a SSL. (c2e0899e8)Buffer de saída JPEG dimensionado a partir da memória livre em vez de um limite fixo de 1 MB; os codificadores reduzem o buffer ao tamanho codificado antes de a imagem ser gravada, de modo que capturas de sensores grandes em alta qualidade não falham mais. (aa1ca6776)
Limpeza do pós-processamento de ML — a geração de bounding boxes foi padronizada entre os pós-processadores Darknet, Edge Impulse e Ultralytics, e a saída do YOLOv8 é transposta após a aplicação do limiar, de modo que é armazenada uma linha por detecção, como nos outros modelos. (b5c7853f2, c45f99cad)
Desligamento seguro do PAG7936 — uma nova flag de parada do sensor coloca o PAG7936 em repouso antes de alternar RESET/PWDN, corrigindo travamentos quando o sensor é usado com um cabo de extensão. O driver também seleciona seu conjunto de registradores MIPI CSI-2 ou paralelo a partir do endereço I2C do sensor em tempo de execução, em vez de em tempo de compilação. (10026530c, f6acf14ec, 5f0251c74)
O ritmo de reprodução do
ImageIOagora atende aos eventos pendentes enquanto aguarda o intervalo entre quadros, em vez de dormir emWFI. (a54790193)Atualizações do submódulo MicroPython — suporte completo a rede no port QEMU,
machine.mem_backupno STM32 via SRAM de backup/registradores BKP, controle de fluxo de hardware do SDIO mantido desabilitado no STM32F4 e reutilização de atributos da MPU para regiões não cacheáveis. (31ada5626, ab61d27a6, 06bddf13a)differential-translation.pycaptura por meio de seu objetocsi.CSIem vez do módulosensorobsoleto, e o espaçamento das importações nos exemplos foi normalizado. (68c866e7f, 9ceff4513)
Correções de bugs#
Câmera e sensores:
Definir duas resoluções
(w, h)personalizadas em sequência deixava o sensor no primeiro tamanho enquantocsi.CSI.width()/height()informavam o segundo; o caminho rápido de “sem mudança” agora exclui tamanhos personalizados. (cfbb70156)csi.CSI.lens_correction()interpretavaradiecoefcomo booleanos, de modo que os valores passados ao driver não eram os fornecidos. (ab44b3a77)PAG7936: definir exposição e ganho em sequência fazia um sobrescrever o outro (ambos compartilham um único modo manual e os registradores de leitura ficam um quadro atrasados); o driver agora inicializa os registradores manuais apenas ao entrar no modo manual e escreve somente o controle que está sendo definido. (e7a18c0a0)
A captura BAYER do PAG7936 e do PS5520 na OpenMV N6 falhava com “Failed to initialize the CSI interface” em qualquer tamanho diferente da resolução completa, porque o ISP da N6 não consegue redimensionar Bayer bruto. Os sensores agora operam em um modo nativo correspondente ao tamanho solicitado para BAYER (PS5520: VGA, HD, SXGA-M, FHD, QHD, WQXGA2; QVGA não tem modo nativo e não é suportado). (fe6790055, b7622b245)
Codificação e salvamento de imagens:
Codificador JPEG de software: o estouro do buffer de saída era sempre fatal porque o caminho de realloc estava desabilitado; agora ele aumenta o buffer (metade do seu tamanho por vez) quando é o proprietário dele, recua de forma limpa quando a memória acaba e reduz o resultado ao tamanho final.
jpeg_write/mjpeg_writenão gravam mais o buffer após uma codificação com falha. (28e1110be)Codificadores JPEG de hardware (STM32): o estouro retornava uma imagem parcialmente codificada com o tamanho da alocação, produzindo arquivos truncados sem marcador EOI (por exemplo, uma captura de 5 MP com qualidade 100 e a metade inferior em branco). Agora eles informam o estouro, liberam o buffer em caso de falha e o reduzem em caso de sucesso. (22ce9619c)
O codificador VC8000 produzia silenciosamente croma 4:2:0 para toda requisição; a subamostragem diferente de 4:2:0 agora recorre ao codec de HW que a suporta. (71f2be7f2)
image.Image.save()de uma imagem PNG como.jpggravava até 1 MB de heap não inicializado, e de uma imagem JPEG como.pnggravava um arquivo vazio. Ambos agora levantam uma exceção; uma imagem que já está no formato de destino continua sendo copiada como está. (6c1fdf822)png_writeagora verifica o valor de retorno do compressor e comprime antes de criar o arquivo, de modo que uma falha não deixa mais um arquivo vazio para trás. (557f52d66)
Módulo image:
image.Image.get_pixel()comrgbtuple=Trueem imagens BAYER e YUV gravava o pixel convertido além de uma variável local da pilha, em um deslocamento controlado pelo chamador. (13f2a17b6)gif.Gif.add_frame()teve um ramo inalcançável de conversão Bayer/YUV removido; apenas imagens GRAYSCALE e RGB565 são aceitas, como a API Python já impunha. (f20d99d96)
Protocolo:
Registrar um canal dinâmico com todos os slots já em uso causava uma escrita fora dos limites; o ID do canal agora é verificado primeiro, e os IDs de canal reservados são verificados estaticamente para caber na tabela de canais. (68f635d1f)
Objetos de canal dinâmico sobreviviam a um soft reset nos root pointers, de modo que o GC continuava varrendo blocos de heap obsoletos da execução anterior; a tabela agora é limpa na inicialização. (ef0ebb03b, e23641145)
Ports:
i.MX RT: adicionada a desinicialização de CAN e Encoder que faltava no soft reset. (7cb9d3dc2)
Suporte a hardware e placas#
OpenMV N6 — CAN agora está habilitado (
machine.CAN). (294f0febd, 91e1c9573)OpenMV AE3 — o driver SPI
sdcardestá congelado no firmware para o soquete microSD do AE3 Battery Shield. (a258f4814)OpenMV RT1062 —
lora-sx126x/lora-sync/lora-asynccongelados no firmware (veja Novos recursos).FLIR Lepton 3.1R / UW — reconhecidos pelo driver do Lepton em todas as placas compatíveis com Lepton.
PAG7936 — parada para desligamento seguro, seleção de interface em tempo de execução, correção de exposição/ganho e captura BAYER na N6.
PS5520 — captura BAYER na N6 em tamanhos nativos.
Simulador (MPS2_AN500) — rede.
Todas as placas — o módulo de compatibilidade
sensorestá congelado no manifesto de todas as placas.
Mudanças incompatíveis de API#
A v5.0.1 não introduz nenhuma mudança incompatível nas APIs csi ou image. Scripts que rodavam na v5.0.0 rodam sem alterações, com as seguintes mudanças de comportamento.
módulo sensor (behavior)#
O módulo nativo sensor (modules/py_csi.c) foi removido e substituído por um módulo Python congelado que implementa a mesma API sobre csi. Veja sensor.
Commit: 5e3d40631
import sensorimprimeWARNING: The sensor module is deprecated and will be removed in a future release. Please use the csi module instead.no terminal.O objeto
csi.CSIoculto é criado na importação, de modo que uma câmera ausente agora levanta um erro emimport sensorem vez de emsensor.reset().Estas funções agora levantam
OSErrorporquecsinão tem equivalente:get_fb(),alloc_extra_fb(),dealloc_extra_fb(),set_auto_rotation(),get_auto_rotation(),disable_delays(),disable_full_flush(). (As duas funções*_extra_fbjá levantavam exceção na v5.0.0.) Usecsi.CSI(delays=False)/csi.CSI(fflush=False)para as duas últimas.Os framesizes que
csinão exporta (QQCIF,QQSIF,QQQQVGA,HQQQQVGA,HQQQVGA,HQQVGA,B64X32,B64X64,B128X64,B128X128,B160X160,B320X320,LCD,QQVGA2) agora são tuplas(w, h)repassadas como resoluções personalizadas.get_framesize()retorna a tupla que foi definida enquanto a câmera ainda estiver nesse tamanho, de modo que as verificações de igualdade com as constantes continuam funcionando.ioctl()repassa no máximo quatro argumentos após a requisição.sleep()/shutdown()levantamOSErrorem caso de falha, como antes (oRuntimeErrordecsié traduzido).
Migre para csi — veja a tabela de migração da v5.0.0.
Carregamento de imagens no frame buffer (behavior)#
As funções que carregam uma imagem no frame buffer — image.Image com copy_to_fb=True, image.Image.copy() / image.Image.scale() e as conversões to_* com copy_to_fb=True, image.ImageIO.read(), fir.snapshot() e tof.snapshot() com copy_to_fb=True — costumavam enviar a nova imagem para a prévia da IDE imediatamente, de modo que qualquer coisa desenhada na imagem retornada nunca era vista. Agora elas marcam o frame buffer como pendente e o descarregam, com tudo o que foi desenhado nele, logo antes de a próxima imagem sobrescrevê-lo — o mesmo comportamento de csi.CSI.snapshot().
Commits: 87b6db5ee, 7b1a35c2f, f773c740d
Loops que leem um fluxo de imagens não precisam de nenhuma mudança e agora mostram seus desenhos. Um script que carrega uma única imagem e para deve descarregá-la explicitamente:
img = image.Image("example.bmp", copy_to_fb=True)
img.flush() # new: send it to the IDE preview now
time.sleep_ms(1000)
Biblioteca de ML (behavior)#
Afeta apenas código que herda de ou copia os pós-processadores fornecidos. YoloV8 agora transpõe a saída do modelo após a aplicação do limiar, de modo que as detecções sobreviventes são armazenadas uma linha por caixa (bb[:, 4:]), em consonância com os pós-processadores Darknet e Edge Impulse, em vez de uma coluna por caixa (bb[4:, :]). Os resultados públicos ((x, y, w, h), score) não mudaram.
módulo protocol (minor)#
protocol.poll() está de volta. A v5.0.0 o removeu quando a tarefa do protocolo passou para o timer; ele retorna como uma forma explícita de acionar a tarefa para transportes personalizados. Nada mais mudou — scripts que nunca o chamaram não são afetados.
Commit: c00c215f9
Compilação / ferramentas (tooling)#
Nada disto afeta scripts MicroPython. py_image.c foi dividido, com os objetos descritores (cascade, keypoints, LBP, keypoint match) movidos para py_image_descriptor.c e os objetos de estatísticas (similarity, statistics, percentile, threshold, histogram) para py_image_stats.c. A API de codificadores do imlib foi alinhada com o restante do imlib: jpeg_compress / png_compress retornam 0 em caso de sucesso e -1 em caso de erro, e jpeg_compress perdeu seu argumento realloc (o redimensionamento é condicionado à propriedade do buffer). OMV_PROTOCOL_MAX_CHANNELS passou a ser OMV_PROTOCOL_CHANNEL_MAX em omv_protocol_channel.h, e os ports agora chamam py_protocol_init0() na inicialização. O define de placa OMV_PAG7936_MIPI_CSI2 desapareceu (a interface é selecionada em tempo de execução). Atualizações de dependências do CI e uma correção para changelog de release vazio completam o conjunto. Veja o histórico do repositório do firmware para detalhes relevantes a forks.
Checklist de migração#
Ainda usa
import sensor? Funciona, com um aviso. Migre paracsi(migração da v5.0.0); substituadisable_delays/disable_full_flushpelos argumentos do construtorcsi.CSI()e remova as chamadas aget_fb/ rotação automática.Carrega uma única imagem com
copy_to_fb=Truee espera vê-la? Adicioneimg.flush()após o carregamento.Copiou o pós-processador YOLOv8? Indexe a saída filtrada pelo limiar por linha (
bb[:, 4:]) em vez de por coluna.Compara
csi0.framesize()depois de definir uma tupla? Agora ele retornacsi.CUSTOM.Todo o resto: regrave o firmware e execute.