v5.0.0

v5.0.0 é uma versão de grande porte. Os destaques: o link com o host OpenMV Protocol V2 reconstruído, uma API de câmera csi baseada em classes que escala para placas com múltiplas câmeras, um alvo de simulador executável, estimativa de pose única MoveNet, MicroPython 1.28 e um grande conjunto de correções de câmera, ML e ToF. Ela também traz uma série de mudanças incompatíveis de API — toda mudança visível ao usuário desde a v4.8.1 está listada abaixo, junto com exatamente como migrar.

Destaques

  • OpenMV Protocol V2. O link host/IDE foi reconstruído do zero: enquadrado, sequenciado, verificado por CRC, com canais multiplexados para stdio, a prévia do stream e dados do usuário. Um novo módulo protocol permite que scripts criem seus próprios transportes e canais de dados. Veja as mudanças no módulo protocol.

  • API de câmera csi baseada em classes. import sensor torna-se import csi / csi.CSI, com suporte nativo a múltiplas câmeras. Veja a migração para csi.

  • Alvo de simulador. O firmware agora é compilado e executa sob o simulador Arm FVP / QEMU (MPS2/MPS3), incluindo emulação de NPU, ROMFS e PSRAM — scripts de visão e ML podem rodar sem hardware conectado.

  • Estimativa de pose MoveNet. Um novo pós-processador MoveNet mais um modelo movenet_singlepose_192.tflite incluído na OpenMV AE3 e N6.

  • MicroPython 1.28 e ulab 6.12.0, ferramentas ST Edge AI 4.0 e o OpenMV SDK externalizado (veja as mudanças de compilação / ferramentas).

Novos recursos

Outras mudanças e melhorias

  • MicroPython atualizado para 1.28.0 a partir da base v4.8.1. Adiciona modo de cartão SD de alta velocidade no H5/H7/N6, clocking AHB5 em modo de baixo consumo e pinos JTAG controláveis como GPIOs na OPENMV_AE3.

  • ulab atualizado para 6.12.0 — operador % nativo em ndarrays (o auxiliar ml.utils.mod() foi removido; veja as mudanças na biblioteca de ML).

  • Ferramentas ST Edge AI atualizadas para 4.0 — afeta a compilação e o deploy de modelos ST no dispositivo.

  • ml.Model — o argumento nomeado load_to_fb foi removido; a memória do modelo é tratada automaticamente pelo alocador unificado.

  • image.Image.scale() in place — ampliar uma imagem in place (por exemplo img.scale(x_scale=2.0, y_scale=2.0)) agora faz o frame buffer crescer para acomodá-la em vez de falhar.

  • Buffer de stdio maior — o buffer de texto padrão para a IDE cresceu de 512 para 1024 bytes na OpenMV 2/3/4, Nicla Vision, AE3 e N6, de modo que rajadas maiores de print() não sejam truncadas.

  • Fluxo de eventos do host mais suave — eventos NOTIFY de stdout para o host são limitados a no máximo um por leitura do host, em vez de um por print() que cruza a marca-d’água do ring buffer.

  • Operações longas interrompíveis — laços longos de desenho de imagem, GPU (Nema/Dave2D) e espera de NPU agora atendem eventos em um intervalo determinístico, de modo que os scripts permanecem responsivos ao botão Stop da IDE durante trabalho pesado.

Correções de bugs

Câmera e sensores:

  • find_apriltags() não corrompe mais os resultados em placas com D-cache/GPU (N6, AE3), e agora funciona na AE3.

  • Corrigida a saída de imagem Bayer do ISP do STM32 N6 após a troca de formatos de pixel.

  • Corrigido o estouro verde do balanço de branco automático em cenas claras e um caso de estatísticas de AWB não inicializadas no primeiro quadro; elevado o clamp de gama do ISP do STM32 (de 32 para 63) para uma faixa mais ampla de gama/contraste/brilho.

  • A exposição automática do PS5520 não oscila mais sob luz intensa; o comportamento de AEC/AGC do PAG7936 foi reformulado (controle combinado, teto de ganho corrigido).

  • Restaurado o upload do firmware de autofoco do OV5640 na Portenta/Nicla (correção do MIMXRT I2C SUSPEND).

  • Corrigido um deadlock na captura da câmera quando um limite de taxa de quadros é combinado com a captura JPEG (STM32).

  • As leituras de csi.IOCTL_GENX320_READ_EVENTS_RAW do GenX320 não embaralham mais a prévia da IDE.

  • csi.IOCTL_LEPTON_SET_MODE do FLIR Lepton via csi.CSI.ioctl() agora funciona quando chamado com um único argumento.

Processamento de imagem:

  • Corrigida a mesclagem alfa de draw_image() / blend() quando uma máscara é fornecida.

  • Corrigida a ordenação de bits na codificação/decodificação de PNG de 1 bit (BINARY) e a decodificação de escala de cinza a partir de 1 bit.

  • Corrigidos os metadados de duração/FPS de gravação de mjpeg.Mjpeg.

  • Corrigido um estouro de pilha na decodificação de JPEG por software em placas com pilha pequena (OpenMV M7).

  • Corrigida a detecção automática de formato de arquivo JPEG/PNG em hosts não-ARM (simulador).

Time-of-Flight:

ML e sistema:

  • A NPU é limpa corretamente quando a inferência é interrompida na N6.

  • Restaurado o despertar de deep-sleep / standby na N6; corrigido o travamento de salto-para-o-bootloader da AE3.

  • Corrigidos vazamentos de memória no soft-reset (GPU Nema do STM32) e um frame buffer auxiliar coletado prematuramente.

  • Canais de protocolo Python personalizados agora sobrevivem a um soft-reboot, o transporte USB se recupera de reset de barramento / endpoints travados, e a inundação de interrupções USB SOF foi corrigida.

Suporte a hardware e placas

  • OpenMV N6 — Ethernet habilitada (rede cabeada); SRAM AXI da NPU (1,75 MB) mesclada em um pool transitório compartilhado para mais RAM entre inferências; despertar de deep-sleep/standby; modelos TFLite e cascatas Haar incluídos no ROMFS.

  • OpenMV AE3 — modelos e cascatas incluídos no ROMFS; cbor2 congelado no firmware.

  • Alif (AE3, N6) — despertar de baixo consumo via machine.RTC.

  • AprilTags de alta resoluçãofind_apriltags() em resolução plena do sensor na AE3, Arduino Giga e Arduino Portenta H7.

  • Alvos de simulador — MPS2_AN500 / MPS3_AN547 (Arm FVP / QEMU), com emulação de NPU, ROMFS e PSRAM.

Mudanças incompatíveis de API

Quebras de API visíveis ao usuário entre a v4.8.1 e a v5.0.0. Escopo: C-modules Python em modules/ e bibliotecas Python em scripts/libraries/.

Cada mudança é marcada com seu impacto:

  • major — a maioria dos scripts precisa de edições.

  • minor — API restrita; afeta apenas scripts que a usavam.

  • behavior — mesma API, resultados diferentes; reverifique os scripts ajustados.

  • tooling — afeta apenas a compilação a partir do código-fonte / forks downstream.

As mudanças são agrupadas por impacto nessa ordem — major primeiro, depois minor, behavior e tooling. Se você quer apenas portar seu código, vá direto à checklist de migração no final, para uma lista de tarefas condensada. Cada hash de commit aponta para seu diff no GitHub.

sensor substituído por csi (major)

Todos os exemplos oficiais foram reescritos para abandonar import sensor em favor de import csi. A antiga API funcional em nível de módulo (sensor.reset(), sensor.set_pixformat(), …) foi substituída pela API csi.CSI baseada em classes, que escala naturalmente para placas com múltiplas câmeras (csi0, csi1, …) e é obrigatória para todos os novos recursos (o kwarg stream=, streaming de múltiplos sensores, …).

A qstr sensor ainda está conectada em modules/py_csi.c para builds de firmware retrocompatíveis, mas não ganhará novos recursos, e todos os exemplos, docs e código de biblioteca agora assumem csi.

Commits: 945c5853c, 61f835b7e

De módulo para classe

Antes (sensor):

import sensor
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)
img = sensor.snapshot()

Depois (csi):

import csi
csi0 = csi.CSI()
csi0.reset()
csi0.pixformat(csi.RGB565)
csi0.framesize(csi.QVGA)
csi0.snapshot(time=2000)
img = csi0.snapshot()

Pares setter/getter unificados em acessores combinados

Na nova API, um método chamado sem argumentos retorna o valor atual; chamado com um valor, ele o define. Os prefixos set_*/get_* desapareceram. Os nomes dos métodos também perderam o sufixo ing onde ele era redundante (windowingwindow). A coluna da nova API aponta para a documentação de referência.

sensor (antigo)

csi.CSI (novo)

set_pixformat(fmt) / get_pixformat()

pixformat([fmt])

set_framesize(sz) / get_framesize()

framesize([sz])

set_framerate(fps) / get_framerate()

framerate([fps])

set_windowing(roi) / get_windowing()

window([roi])

set_framebuffers(n) / get_framebuffers()

framebuffers([n])

set_gainceiling(g)

gainceiling([g])

set_brightness(v)

brightness([v])

set_contrast(v)

contrast([v])

set_saturation(v)

saturation([v])

set_quality(v)

quality([v])

set_colorbar(b)

colorbar([b])

set_special_effect(e)

special_effect([e])

set_lens_correction(...)

lens_correction(...)

set_hmirror(b) / get_hmirror()

hmirror([b])

set_vflip(b) / get_vflip()

vflip([b])

set_transpose(b) / get_transpose()

transpose([b])

set_auto_rotation(b) / get_auto_rotation()

auto_rotation([b])

set_auto_gain(b, [db, ceiling]) / get_gain_db()

auto_gain(...) / gain_db()

set_auto_exposure(b, [us]) / get_exposure_us()

auto_exposure(...) / exposure_us()

set_auto_whitebal(b, [rgb]) / get_rgb_gain_db()

auto_whitebal(...) / rgb_gain_db()

set_auto_blc(b, [regs]) / get_blc_regs()

auto_blc(...) / blc_regs()

set_color_palette(p) / get_color_palette()

color_palette([p])

set_frame_callback(cb)

frame_callback(cb)

set_vsync_callback(cb)

vsync_callback(cb)

get_id()

cid()

Funções sem equivalente direto

sensor (removido)

O que usar no lugar

sensor.alloc_extra_fb(w, h, pixfmt) / sensor.dealloc_extra_fb()

image.Image (w, h, pixfmt) — uma imagem comum alocada no heap. O framebuffer não é mais fatiado para buffers do usuário.

sensor.skip_frames(time=..., frames=...)

csi.CSI.snapshot() — o pular quadros foi incorporado ao snapshot por meio de seus argumentos time= / frames=.

sensor.disable_delays(...) / sensor.disable_full_flush(...)

Movidos para o construtor de csi.CSI: csi.CSI(delays=False) / csi.CSI(fflush=False).

sensor.get_frame_available()

csi.CSI.readable()

sensor.get_fb()

Removido. A imagem retornada por csi.CSI.snapshot() é o handle canônico.

sensor.set_framebuffers(n, expand=True)

csi.CSI.framebuffers() — o argumento expand foi removido (veja os complementos de csi).

Novidades em csi.CSI

  • csi.CSI(stream=True|False) — um seletor em tempo de construção que escolhe qual CSI alimenta o framebuffer de prévia (substitui o kwarg update= por snapshot, veja os complementos de csi).

  • csi.CSI(cid=N) / csi.devices() — suporte a múltiplos CSI para placas com mais de um sensor de imagem.

módulo image — reformulação de assinaturas (major)

O módulo image teve a maior mudança de API depois de csi — assinaturas de desenho, objetos de resultado e vários detectores mudaram.

Argumentos de coordenadas devem ser tuplas

modules/py_image.c foi reescrito sobre mp_arg_parse_all. Todos os métodos de desenho / pixel que antes recebiam argumentos posicionais x, y, ... separados agora exigem essas coordenadas agrupadas em uma única tupla.

Commits: d18bbc472, 0c60c94b9 (PR #3061)

Antes

Depois

img.draw_arrow(x0, y0, x1, y1, color=...)

img.draw_arrow((x0, y0, x1, y1), color=...)

img.draw_line(x0, y0, x1, y1, ...)

img.draw_line((x0, y0, x1, y1), ...)

img.draw_cross(x, y, ...)

img.draw_cross((x, y), ...)

img.draw_circle(x, y, r, ...)

img.draw_circle((x, y, r), ...)

img.draw_rectangle(x, y, w, h, ...)

img.draw_rectangle((x, y, w, h), ...)

img.draw_string(x, y, "txt", ...)

img.draw_string((x, y), "txt", ...)

img.draw_ellipse(x, y, rx, ry, rot, ...)

img.draw_ellipse((x, y, rx, ry, rot), ...)

img.flood_fill(x, y, ...)

img.flood_fill((x, y), ...)

img.get_pixel(x, y, rgbtuple=...)

img.get_pixel((x, y), rgbtuple=...)

img.set_pixel(x, y, color)

img.set_pixel((x, y), color)

Todos são métodos de image.Image.

Objetos de resultado convertidos em attrtuple

Estes tipos agora são objetos attrtuple do MicroPython: similarity, statistics, percentile, threshold, line, circle, rect, qrcode, apriltag, datamatrix, barcode, displacement, kptmatch. O acesso a atributos sem parênteses agora é a forma canônica.

Commit: 3399d302e

Antes (estilo de método):

img.draw_cross(match.cx(), match.cy())
img.draw_rectangle(blob.rect())

Depois (estilo de atributo):

img.draw_cross((match.cx, match.cy))
img.draw_rectangle(blob.rect)

blob e histogram permanecem inalterados — mantêm seus tipos existentes e os acessores () (um attrtuple não consegue expressar os valores calculados sob demanda de um blob nem os acessores que recebem argumentos de um histograma).

Renomeação do parâmetro haar de find_features

image.Image.find_features()scale_factor= foi renomeado para scale=.

Commit: be4c5cd73

get_regression — agora sempre robusto, target_size adicionado

image.Image.get_regression() agora usa sempre a regressão robusta (Theil-Sen). O antigo caminho rápido de mínimos quadrados foi removido, então o argumento nomeado robust= desapareceu — o que antes exigia robust=True agora é o único comportamento. Um novo kwarg target_size=(w, h) (padrão (80, 60)) reduz a ROI por área antes do ajuste Theil-Sen O(N^2), de modo que ele sempre rode em um tamanho de imagem razoável; os pontos extremos da linha ajustada são mapeados de volta às coordenadas de origem. O exemplo linear_regression_robust.py foi removido e linear_regression_fast.py foi renomeado para linear_regression.py.

Commits: c7c2e69a0, 0ff2afa72

find_line_segments — novo algoritmo

image.Image.find_line_segments() — o antigo detector LSD foi substituído pelo ED-Lines, e ganhou um novo kwarg threshold=50. A saída de scripts previamente ajustados será diferente.

Commits: 87da2a7b7, 2c47b5735

Biblioteca de AprilTag substituída

image.Image.find_apriltags() — o detector de AprilTag foi substituído por uma nova implementação. O conjunto de famílias mudou:

Commit: e813bada7

complemento do módulo csi (minor)

Pequenos complementos de csi em cima de a migração para csi.

snapshot(update=…) removido

O kwarg update em csi.CSI.snapshot() desapareceu. Para impedir que um dispositivo CSI alimente o framebuffer de prévia, opte por não fazê-lo no momento da construção:

csi0 = csi.CSI(stream=False)                  # was: csi0.snapshot(update=False)
csi1.snapshot(blocking=False, image=fir_img)  # was: ...(update=False, ...)

Commits: 9a8077827, 26b79a2c5

argumento expand de framebuffers() removido

csi.CSI.framebuffers() — o terceiro argumento posicional (expand) desapareceu; a assinatura agora é framebuffers([count]).

Commit: 86cb3a5de

módulo protocol (minor)

Afeta apenas scripts que dirigiam o link com o host diretamente. Veja protocol.

timer_ms renomeado para poll_ms

protocol.init() — o argumento timer_ms foi renomeado para poll_ms.

protocol.init(..., poll_ms=10)   # was: timer_ms=10

Commits: 8a0635e8c, 95a290607

protocol.poll() removido

A tarefa de protocolo agora é agendada internamente. Chamadas a protocol.poll() lançarão AttributeError.

Commit: 8a0635e8c

argumento de configuração soft_reboot removido

protocol.init() — o argumento soft_reboot desapareceu. Todos os transportes atuais toleram soft-reboots, então o comportamento agora é incondicional.

Commit: 0bf766aa2

módulos display (minor)

A saída de TV agora passa por um objeto display.TVDisplay em vez do módulo independente tv. display também ganhou um ioctl() genérico.

Commits: f0accb389, 1a5a87121, 920c097a0, 9eac55098

módulo tof (behavior)

Mesma API de antes; os padrões e o tratamento de erros mudaram. Veja tof.

Timeout padrão alterado

tof.read_depth() e tof.snapshot() (chamados com timeout=-1) agora têm como padrão 100 ms em vez de esperar indefinidamente. Passe um valor maior explícito se você precisar do comportamento antigo.

Commit: b6772b80d

Recuperação automática

O driver agora faz um hard-reset do barramento I2C e do sensor em erros de medição/timeout. Os exemplos não chamam mais tof.reset() em seus tratadores de exceção — código de usuário que fazia recuperação manual deve removê-la (ela vai conflitar com a nova recuperação automática).

Commits: b6772b80d, 80ffaa5c3

Biblioteca de ML (behavior)

Mesma API, números diferentes — reverifique qualquer pipeline de ML ajustado.

O pré-processamento agora estica em vez de aplicar letterbox

Normalization agora usa image.SCALE_ASPECT_IGNORE (esticar) em vez de image.SCALE_ASPECT_EXPAND (letterbox). O pós-processamento de NMS também passou a usar escala independente em x/y.

Nota

Impacto. Detectores no estilo YOLO e regressores de pontos-chave geralmente melhoram. Os exemplos de BlazeFace, BlazePalm, FaceLandmarks e HandLandmarks agora exigem um recorte quadrado manual na ROI de entrada — os scripts de exemplo foram atualizados; código de usuário personalizado deve fazer o mesmo.

Commit: 68dc29a33

auxiliar ml.utils.mod() removido

O ulab 6.12.0 suporta % em ndarrays nativamente. Código que importava mod de ml.utils deve usar a % b.

Commits: 35ece5728, 82fbd858c

Compilação / ferramentas (tooling)

Nada disso afeta os scripts MicroPython. Compilar o firmware a partir do código-fonte agora requer o OpenMV SDK externo (1.6.0, anteriormente in-tree). Várias ferramentas de build in-tree foram removidas e a N6 migrou para a pilha TinyUSB; forks downstream devem revisar o histórico do repositório de firmware — notavelmente a assinatura de file_open() perdendo seu argumento buffered.

Checklist de migração

Para um port limpo para a v5.0.0, o trabalho típico é:

  1. Substitua import sensor por import csi; csi0 = csi.CSI() e traduza cada chamada set_*/get_* para seu acessor de csi.CSI (a migração para csi).

  2. Envolva os argumentos de coordenadas de img.draw_*, get_pixel() e set_pixel() em tuplas (as mudanças no módulo image).

  3. Remova os () dos acessores de resultado attrtuple se quiser a nova forma idiomática, ou deixe o estilo antigo como está, já que os attrtuples ainda suportam acessores chamáveis (as mudanças no módulo image).

  4. Audite find_line_segments(), get_regression() e qualquer escolha de família de find_apriltags() (as mudanças no módulo image).

  5. Renomeie timer_mspoll_ms nas chamadas a protocol.init(); remova protocol.poll() e soft_reboot= (as mudanças no módulo protocol).

  6. Para fluxos de trabalho de ML: revisite qualquer modelo que precisava de entrada com letterbox (as mudanças na biblioteca de ML).