v5.0.1#

A v5.0.1 é uma versão de manutenção sobre a v5.0.0 — o módulo legado sensor passa a ser uma camada de compatibilidade Python sobre csi, as imagens carregadas no buffer de fotograma pré-visualizam agora como fotogramas de câmara, os codificadores JPEG perdem o seu limite de saída de 1 MB e tratam corretamente o overflow, e há um conjunto de correções de câmara, protocolo, rede e biblioteca de ML. Não introduz alterações incompatíveis de API para scripts escritos contra csi; as poucas alterações de comportamento estão listadas em alterações incompatíveis de API.

Destaques#

  • O módulo sensor é agora um módulo Python congelado construído sobre csi. Imprime um aviso de obsolescência ao ser importado; algumas funções que o módulo csi não consegue suportar lançam agora OSError. Consulte as alterações do módulo sensor.

  • As imagens carregadas pré-visualizam como fotogramas de câmara. Uma imagem colocada no buffer de fotograma com copy_to_fb=True (image.Image, image.ImageIO.read(), fir.snapshot(), tof.snapshot()) é descarregada para o IDE — com tudo o que for desenhado nela — quando a imagem seguinte sobrescreve o buffer de fotograma, em vez de imediatamente. Consulte as alterações da 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 overflow, tanto no caminho por software como por hardware, é tratado em vez de se escreverem ficheiros truncados, e guardar uma imagem comprimida com a outra extensão comprimida lança uma exceção em vez de escrever lixo.

  • Novo protocol.poll() e seis novos widgets CBOR (text, lineedit, pushbutton, spinbox, radio, waveform) para protocol.CBORChannel.

  • Pós-processador YOLO Pro, suporte para FLIR Lepton 3.1R / UW, leituras em rajada do IMU, CAN no OpenMV N6 e um alvo de simulador com capacidade de rede.

Novas funcionalidades#

  • YoloPro — um novo pós-processador para modelos de deteção de objetos YOLO Pro da Edge Impulse, mais um exemplo yolo_pro_detector.py. (f3f150ebd, ea7bbb398)

  • protocol.poll() — executa uma iteração da tarefa de protocolo a pedido, para transportes personalizados que não são acionados pela interrupção USB nem pelo temporizador poll_ms. protocol.init() também pode ser chamado novamente para reinicializar a pilha. (c00c215f9, f849ffb1b)

  • Mais widgets de canal CBOR — protocol.CBORChannel.add() ganha text (string estática), lineedit (string gravável), pushbutton (ação momentânea), spinbox (entrada numérica por passos), radio (grupo de opções) e waveform (série temporal 1D com argumentos sample_rate, series e typecode; atribua bytes de amostras intercaladas para a transmitir). (8016d29ba)

  • csi.CUSTOM — csi.CSI.framesize() devolve agora uma constante utilizável depois de definida uma resolução (w, h) personalizada, em vez de um inteiro anónimo. (af8841654)

  • Leitura em rajada do IMU — imu.__read_reg() aceita um buffer gravável opcional e preenche-o a partir de registos consecutivos numa única transação. (244ca480a)

  • FLIR Lepton 3.1R e Lepton UW são reconhecidos pelo driver do Lepton, incluindo os seus modos de ganho radiométrico. (0fc356632)

  • Rede no simulador — o alvo QEMU MPS2_AN500 tem agora lwIP e uma NIC em modo de utilizador, com requests, mqtt e sensor congelados no firmware, e um teste unitário de rede. (23546dfb1, 61d187305, 15096c3a2)

  • Exemplo de API compatível com OpenAI — openai_compatible.py captura um JPEG e envia-o por POST para um endpoint de chat-completions para descrição da cena. (79033c6aa)

  • Exemplos LoRa SX126x — o driver lora-sx126x da micropython-lib (com lora-sync / lora-async) está congelado no firmware do OpenMV RT1062, com exemplos de emissor/recetor/ping-pong/stream de imagem para ligar um módulo SX1261 ou SX1262 ao bus SPI. Este suporte é uma contribuição da comunidade; a OpenMV não vende hardware LoRa. (19576e1b1)

Outras alterações e melhorias#

  • Reescrita da biblioteca requests — as respostas com transferência em chunks são descodificadas, é exposto um argumento timeout (predefinição 5 s), os 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 estado por posição, o dicionário headers do chamador é copiado (pelo que auth já não se propaga a pedidos posteriores), e o corpo é lido em blocos para um bytearray. (889f0b096)

  • mqtt importa ssl de forma diferida, pelo que o módulo e as ligações simples (sem TLS) funcionam em compilações sem suporte 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 ajustam o buffer ao tamanho codificado antes de a imagem ser escrita, pelo que as capturas de sensores grandes com qualidade elevada já não falham. (aa1ca6776)

  • Limpeza do pós-processamento de ML — a geração de caixas delimitadoras está normalizada entre os pós-processadores Darknet, Edge Impulse e Ultralytics, e a saída do YOLOv8 é transposta após a aplicação do limiar, ficando armazenada com uma linha por deteção, como nos outros modelos. (b5c7853f2, c45f99cad)

  • Encerramento seguro do PAG7936 — uma nova flag de paragem do sensor coloca o PAG7936 em suspensão antes de alternar RESET/PWDN, corrigindo bloqueios quando o sensor é usado com um cabo de extensão. O driver também seleciona o seu conjunto de registos 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 ImageIO atende agora os eventos pendentes enquanto aguarda o intervalo entre fotogramas, em vez de dormir em WFI. (a54790193)

  • Atualizações do submódulo MicroPython — suporte completo de rede no port QEMU, machine.mem_backup no STM32 através da SRAM de backup/registos BKP, controlo de fluxo por hardware do SDIO mantido desativado no STM32F4, e reutilização de atributos MPU para regiões não cacheáveis. (31ada5626, ab61d27a6, 06bddf13a)

  • differential-translation.py captura através do seu objeto csi.CSI em vez do módulo sensor obsoleto, e o espaçamento das importações nos exemplos foi normalizado. (68c866e7f, 9ceff4513)

Correções de erros#

Câmara e sensores:

  • Definir duas resoluções (w, h) personalizadas seguidas deixava o sensor no primeiro tamanho enquanto csi.CSI.width() / height() reportavam o segundo; o caminho rápido de «sem alteração» exclui agora os tamanhos personalizados. (cfbb70156)

  • csi.CSI.lens_correction() interpretava radi e coef como booleanos, pelo que os valores passados ao driver não eram os fornecidos. (ab44b3a77)

  • PAG7936: definir a exposição e o ganho consecutivamente fazia com que um sobrescrevesse o outro (ambos partilham um único modo manual e os registos de leitura têm um atraso de um fotograma); o driver inicializa agora os registos manuais apenas ao entrar no modo manual e escreve só o controlo que está a ser definido. (e7a18c0a0)

  • A captura BAYER do PAG7936 e do PS5520 no OpenMV N6 falhava com «Failed to initialize the CSI interface» em qualquer tamanho que não fosse a resolução completa, porque o ISP do N6 não consegue redimensionar Bayer em bruto. Os sensores funcionam agora num modo nativo correspondente ao tamanho pedido 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 gravação de imagens:

  • Codificador JPEG por software: o overflow do buffer de saída era sempre fatal porque o caminho de realloc estava desativado; agora aumenta o buffer (metade do seu tamanho de cada vez) quando é o seu proprietário, recua de forma limpa quando a memória se esgota e ajusta o resultado. jpeg_write / mjpeg_write já não escrevem o buffer após uma codificação falhada. (28e1110be)

  • Codificadores JPEG por hardware (STM32): o overflow devolvia uma imagem parcialmente codificada com o tamanho da alocação, produzindo ficheiros truncados sem marcador EOI (por exemplo, uma captura de 5 MP com qualidade 100 com a metade inferior em branco). Agora reportam o overflow, libertam o buffer em caso de falha e ajustam-no em caso de sucesso. (22ce9619c)

  • O codificador VC8000 produzia silenciosamente croma 4:2:0 para todos os pedidos; a subamostragem diferente de 4:2:0 recorre agora ao codec de HW que a suporta. (71f2be7f2)

  • image.Image.save() de uma imagem PNG como .jpg escrevia até 1 MB de heap não inicializada, e de uma imagem JPEG como .png escrevia um ficheiro vazio. Ambos lançam agora uma exceção; uma imagem que já esteja no formato de destino continua a ser copiada tal como está. (6c1fdf822)

  • png_write verifica agora o valor devolvido pelo compressor e comprime antes de criar o ficheiro, pelo que uma falha já não deixa um ficheiro vazio para trás. (557f52d66)

Módulo image:

  • image.Image.get_pixel() com rgbtuple=True em imagens BAYER e YUV escrevia o pixel convertido para além de uma variável local da pilha, num deslocamento controlado pelo chamador. (13f2a17b6)

  • gif.Gif.add_frame() removeu um ramo de conversão Bayer/YUV inalcançável; apenas são aceites imagens GRAYSCALE e RGB565, como a API Python já impunha. (f20d99d96)

Protocolo:

  • Registar um canal dinâmico com todas as posições já em uso causava uma escrita fora dos limites; o ID do canal é agora verificado primeiro, e é verificado estaticamente que os IDs de canal reservados cabem na tabela de canais. (68f635d1f)

  • Os objetos de canal dinâmico sobreviviam a um soft-reset nos root pointers, pelo que o GC continuava a percorrer 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 em falta de CAN e Encoder no soft-reset. (7cb9d3dc2)

Hardware e suporte a placas#

  • OpenMV N6 — o CAN está agora ativado (machine.CAN). (294f0febd, 91e1c9573)

  • OpenMV AE3 — o driver SPI sdcard está congelado no firmware para o socket microSD do AE3 Battery Shield. (a258f4814)

  • OpenMV RT1062 — lora-sx126x / lora-sync / lora-async congelados no firmware (consulte Novas funcionalidades).

  • FLIR Lepton 3.1R / UW — reconhecidos pelo driver do Lepton em todas as placas compatíveis com Lepton.

  • PAG7936 — paragem de encerramento seguro, seleção de interface em tempo de execução, correção de exposição/ganho e captura BAYER no N6.

  • PS5520 — captura BAYER no N6 em tamanhos nativos.

  • Simulador (MPS2_AN500) — rede.

  • Todas as placas — o módulo de compatibilidade sensor está congelado no manifesto de todas as placas.

Alterações incompatíveis de API#

A v5.0.1 não introduz alterações incompatíveis nas APIs csi ou image. Os scripts que corriam na v5.0.0 correm sem alterações, com as seguintes alterações de comportamento.

Módulo sensor (comportamento)#

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. Consulte sensor.

Commit: 5e3d40631

  • import sensor imprime WARNING: The sensor module is deprecated and will be removed in a future release. Please use the csi module instead. no terminal.

  • O objeto csi.CSI oculto é criado na importação, pelo que a ausência de câmara lança agora uma exceção em import sensor em vez de em sensor.reset().

  • Estas funções lançam agora OSError porque csi nã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_fb já lançavam exceção na v5.0.0.) Utilize csi.CSI(delays=False) / csi.CSI(fflush=False) para as duas últimas.

  • Os tamanhos de fotograma que csi não exporta (QQCIF, QQSIF, QQQQVGA, HQQQQVGA, HQQQVGA, HQQVGA, B64X32, B64X64, B128X64, B128X128, B160X160, B320X320, LCD, QQVGA2) são agora tuplos (w, h) passados como resoluções personalizadas. get_framesize() devolve o tuplo que foi definido enquanto a câmara ainda estiver nesse tamanho, pelo que as verificações de igualdade com as constantes continuam a funcionar.

  • ioctl() reencaminha no máximo quatro argumentos após o pedido.

  • sleep() / shutdown() lançam OSError em caso de falha, como antes (o RuntimeError do csi é traduzido).

Migre para csi — consulte a tabela de migração da v5.0.0.

Carregamento de imagens no buffer de fotograma (comportamento)#

As funções que carregam uma imagem no buffer de fotograma — 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 — enviavam a nova imagem imediatamente para a pré-visualização do IDE, pelo que tudo o que fosse desenhado na imagem devolvida nunca era visto. Agora marcam o buffer de fotograma como pendente e descarregam-no, com tudo o que nele for desenhado, imediatamente antes de a imagem seguinte o sobrescrever — o mesmo comportamento de csi.CSI.snapshot().

Commits: 87b6db5ee, 7b1a35c2f, f773c740d

Os ciclos que leem uma sequência de imagens não precisam de alterações e mostram agora o que desenham. Um script que carrega uma única imagem e termina tem de a descarregar 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 ML (comportamento)#

Afeta apenas código que cria subclasses ou copia os pós-processadores fornecidos. YoloV8 transpõe agora a saída do modelo após a aplicação do limiar, pelo que as deteções sobreviventes são armazenadas com uma linha por caixa (bb[:, 4:]), em conformidade 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 sofrem alterações.

Commits: c45f99cad, b5c7853f2

Módulo protocol (menor)#

protocol.poll() está de volta. A v5.0.0 removeu-o quando a tarefa de protocolo passou para o temporizador; regressa como forma explícita de acionar a tarefa para transportes personalizados. Nada mais mudou — os scripts que nunca o chamaram não são afetados.

Commit: c00c215f9

Compilação / ferramentas (ferramentas)#

Nada disto afeta scripts MicroPython. py_image.c foi dividido, com os objetos descritores (cascade, keypoints, LBP, keypoint match) a passarem para py_image_descriptor.c e os objetos de estatísticas (similarity, statistics, percentile, threshold, histogram) para py_image_stats.c. A API de codificação da imlib foi alinhada com o resto da imlib: jpeg_compress / png_compress devolvem 0 em caso de sucesso e -1 em caso de erro, e jpeg_compress perdeu o seu argumento realloc (o redimensionamento depende da propriedade do buffer). OMV_PROTOCOL_MAX_CHANNELS passou a OMV_PROTOCOL_CHANNEL_MAX em omv_protocol_channel.h, e os ports chamam agora py_protocol_init0() na inicialização. A definição 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 changelogs de release vazios completam o conjunto. Consulte o histórico do repositório do firmware para detalhes relevantes para forks.

Checklist de migração#

  • Ainda usa import sensor? Funciona, com um aviso. Passe para csi (migração v5.0.0); substitua disable_delays / disable_full_flush pelos argumentos do construtor csi.CSI() e remova as chamadas a get_fb / rotação automática.

  • Carrega uma única imagem com copy_to_fb=True e espera vê-la? Adicione img.flush() após o carregamento.

  • Copiou o pós-processador YOLOv8? Indexe a saída após o limiar por linha (bb[:, 4:]) em vez de por coluna.

  • Compara csi0.framesize() depois de definir um tuplo? Devolve agora csi.CUSTOM.

  • Tudo o resto: regrave o firmware e execute.