v5.0.0

A v5.0.0 é uma versão principal. Em destaque: a reconstruída ligação host OpenMV Protocol V2, uma API de câmara csi baseada em classes que escala para placas com múltiplas câmaras, um alvo simulador executável, estimação de pose individual com MoveNet, MicroPython 1.28, e um grande conjunto de correções para câmara, ML e ToF. Inclui também várias alterações incompatíveis de API — todas as alterações visíveis ao utilizador desde a v4.8.1 estão listadas abaixo, juntamente com as instruções de migração.

Destaques

  • OpenMV Protocol V2. A ligação host/IDE foi reconstruída de raiz: com frames, sequenciamento, verificação CRC, e canais multiplexados para stdio, pré-visualização de stream e dados do utilizador. Um novo módulo protocol permite que os scripts criem os seus próprios transportes e canais de dados. Consulte as alterações do módulo protocol.

  • API de câmara csi baseada em classes. import sensor passa a ser import csi / csi.CSI, com suporte nativo a múltiplas câmaras. Consulte a migração csi.

  • Alvo simulador. O firmware agora compila 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 correr sem hardware ligado.

  • Estimação de pose MoveNet. Um novo pós-processador MoveNet mais um modelo movenet_singlepose_192.tflite incluído no OpenMV AE3 e N6.

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

Novas funcionalidades

Outras alterações e melhorias

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

  • ulab atualizado para 6.12.0 — operador % nativo em ndarrays (o auxiliar ml.utils.mod() é removido; consulte as alterações da biblioteca ML).

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

  • ml.Model — o argumento de palavra-chave load_to_fb foi removido; a memória do modelo é gerida automaticamente pelo alocador unificado.

  • image.Image.scale() em-lugar — escalar uma imagem para cima em-lugar (por exemplo img.scale(x_scale=2.0, y_scale=2.0)) agora aumenta o buffer de fotograma para caber em vez de falhar.

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

  • Fluxo de eventos do host mais suave — eventos stdout NOTIFY para o host são limitados a no máximo um por leitura do host em vez de um por print() que ultrapasse o limiar do buffer circular.

  • Operações longas interrompíveis — ciclos de espera longos de desenho de imagem, GPU (Nema/Dave2D) e NPU agora processam eventos num intervalo determinístico, para que os scripts permaneçam responsivos ao botão Stop do IDE durante trabalho intensivo.

Correções de erros

Câmara e sensores:

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

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

  • Corrigido o problema de sobrexposição do balanço de branco automático com tons de verde em cenas brilhantes e um caso de estatísticas AWB do primeiro fotograma não inicializado; aumentado o limite de gamma do ISP STM32 (32 para 63) para um intervalo mais amplo de gamma/contraste/brilho.

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

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

  • Corrigido um impasse na captura da câmara quando um limite de taxa de fotogramas é combinado com captura JPEG (STM32).

  • As leituras csi.IOCTL_GENX320_READ_EVENTS_RAW do GenX320 já não perturbam a pré-visualização do IDE.

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

Processamento de imagem:

  • Corrigido o alpha blending de draw_image() / blend() quando é fornecida uma máscara.

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

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

  • Corrigido um stack overflow de descodificação de JPEG por software em placas com pilha reduzida (OpenMV M7).

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

Time-of-Flight:

  • tof.read_depth() já não levanta exceção em erros de medição transitórios e recupera automaticamente de falhas de bus; o tempo limite padrão de tof.read_depth() / tof.snapshot() é agora 100 ms (consulte as alterações tof).

  • Corrigida a corrupção de dados de profundidade em múltiplas zonas do VL53L5CX / VL53L8CX.

ML e sistema:

  • O NPU é limpo corretamente quando a inferência é interrompida no N6.

  • Restaurado o wakeup de sono profundo/standby no N6; corrigido o bloqueio de salto para bootloader no AE3.

  • Corrigidas fugas de memória no soft-reset (STM32 Nema GPU) e um buffer de fotograma auxiliar recolhido prematuramente.

  • Os canais de protocolo Python personalizados agora sobrevivem a um soft-reboot, o transporte USB recupera de reset de bus/endpoints bloqueados, e as interrupções USB SOF em excesso estão corrigidas.

Hardware e suporte a placas

  • OpenMV N6 — Ethernet ativada (rede com fio); AXI SRAM do NPU (1,75 MB) integrada num pool transitório partilhado para mais RAM entre inferências; wakeup de sono profundo/standby; modelos TFLite incluídos e cascatas Haar na ROMFS.

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

  • Alif (AE3, N6) — wakeup de baixo consumo com machine.RTC.

  • AprilTags de alta resoluçãofind_apriltags() com resolução total do sensor no AE3, Arduino Giga e Arduino Portenta H7.

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

Alterações incompatíveis de API

Alterações de API visíveis ao utilizador entre a v4.8.1 e a v5.0.0. Âmbito: módulos C Python em modules/ e bibliotecas Python em scripts/libraries/.

Cada alteração está marcada com o seu impacto:

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

  • menor — API restrita; afeta apenas scripts que a usaram.

  • comportamento — mesma API, resultados diferentes; verifique novamente os scripts ajustados.

  • ferramentas — afeta apenas a compilação a partir da fonte/forks derivados.

As alterações estão agrupadas por impacto nessa ordem — principal primeiro, depois menor, comportamento e ferramentas. Se apenas pretende portar o seu código, salte para o checklist de migração no final para uma lista de tarefas condensada. Cada hash de commit liga ao respetivo diff no GitHub.

sensor substituído por csi (principal)

Todos os exemplos oficiais foram reescritos para abandonar import sensor em favor de import csi. A API funcional ao nível do módulo legada (sensor.reset(), sensor.set_pixformat(), …) é substituída pela API csi.CSI baseada em classes, que escala naturalmente para placas com múltiplas câmaras (csi0, csi1, …) e é necessária para todas as novas funcionalidades (o kwarg stream=, streaming multi-sensor, …).

O qstr sensor ainda está ligado em modules/py_csi.c para compilações de firmware retrocompatíveis, mas não receberá novas funcionalidades, e todos os exemplos, documentação e código de biblioteca assumem agora csi.

Commits: 945c5853c, 61f835b7e

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 simplificados em acessores combinados

Na nova API, um método chamado sem argumentos devolve o valor atual; chamado com um valor, define-o. Os prefixos set_*/get_* foram removidos. Os nomes dos métodos também perderam o sufixo ing onde era redundante (windowingwindow). A coluna da nova API liga 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 em alternativa

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

image.Image (w, h, pixfmt) — uma imagem alocada normalmente na heap. O buffer de fotograma já não é dividido para buffers do utilizador.

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

csi.CSI.snapshot() — skip-frames integrado no snapshot através dos seus argumentos time= / frames=.

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

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

sensor.get_frame_available()

csi.CSI.readable()

sensor.get_fb()

Removido. A imagem devolvida por csi.CSI.snapshot() é o handle canónico.

sensor.set_framebuffers(n, expand=True)

csi.CSI.framebuffers() — o argumento expand foi removido (consulte os seguimentos csi).

Novidades em csi.CSI

  • csi.CSI(stream=True|False) — um seletor em tempo de construção que escolhe qual CSI alimenta o buffer de fotograma de pré-visualização (substitui o kwarg update= por captura, consulte os seguimentos csi).

  • csi.CSI(cid=N) / csi.devices() — suporte multi-CSI para placas com mais de um sensor de imagem.

Módulo image — reformulação da assinatura (principal)

O módulo image viu a alteração de API mais ampla após csi — assinaturas de desenho, objetos de resultado e vários detetores foram alterados.

Os argumentos de coordenadas devem ser tuplos

modules/py_image.c foi reescrito sobre mp_arg_parse_all. Todos os métodos de desenho/pixel que anteriormente aceitavam argumentos posicionais separados x, y, ... agora exigem que essas coordenadas sejam agrupadas num único tuplo.

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 para attrtuple

Estes tipos são agora 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 com método):

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

Depois (estilo com atributo):

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

blob e histogram permanecem inalterados — mantêm os seus tipos existentes e acessores () (um attrtuple não consegue exprimir os valores calculados de forma preguiçosa de um blob ou os acessores que aceitam 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() usa agora sempre a regressão robusta (Theil-Sen). O antigo caminho rápido de mínimos quadrados foi removido, pelo que o argumento de palavra-chave robust= desaparece — o que antes exigia robust=True é agora o único comportamento. Um novo kwarg target_size=(w, h) (predefinição (80, 60)) escala a ROI por área antes do ajuste Theil-Sen O(N^2) para que este corra sempre num tamanho de imagem razoável; os extremos da linha ajustada são mapeados de volta para as coordenadas de origem. O exemplo linear_regression_robust.py foi eliminado 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 detetor LSD foi substituído pelo ED-Lines, e ganhou um novo kwarg threshold=50. Os resultados de scripts previamente ajustados serão diferentes.

Commits: 87da2a7b7, 2c47b5735

Biblioteca AprilTag substituída

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

Commit: e813bada7

Seguimento do módulo csi (menor)

Seguimentos menores do csi sobre a migração csi.

snapshot(update=…) removido

O kwarg update em csi.CSI.snapshot() foi removido. Para impedir que um dispositivo CSI alimente o buffer de fotograma de pré-visualização, opte por não o fazer em tempo de 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) foi removido; a assinatura é agora framebuffers([count]).

Commit: 86cb3a5de

Módulo protocol (menor)

Afeta apenas scripts que controlavam diretamente a ligação host. Consulte 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. As chamadas a protocol.poll() irão lançar AttributeError.

Commit: 8a0635e8c

Argumento de configuração soft_reboot removido

protocol.init() — o argumento soft_reboot foi removido. Todos os transportes atuais toleram soft-reboots, pelo que o comportamento é agora incondicional.

Commit: 0bf766aa2

Módulos display (menor)

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

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

Módulo tof (comportamento)

Mesma API de antes; os valores predefinidos e o tratamento de erros alteraram-se. Consulte tof.

Tempo limite predefinido alterado

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

Commit: b6772b80d

Recuperação automática

O driver agora reinicia por hardware o bus I2C e o sensor em erros de medição/timeout. Os exemplos já não chamam tof.reset() nos seus tratadores de exceção — o código do utilizador que fazia recuperação manual deve removê-la (entrará em conflito com a nova recuperação automática).

Commits: b6772b80d, 80ffaa5c3

Biblioteca ML (comportamento)

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

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

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

Nota

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

Commit: 68dc29a33

Auxiliar ml.utils.mod() removido

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

Commits: 35ece5728, 82fbd858c

Compilação / ferramentas (ferramentas)

Nada disto afeta os scripts MicroPython. Compilar firmware a partir da fonte requer agora o OpenMV SDK externo (1.6.0, anteriormente integrado na árvore). Várias ferramentas de compilação integradas foram removidas e o N6 migrou para a pilha TinyUSB; os forks derivados devem rever o histórico do repositório de firmware — nomeadamente a assinatura file_open() que eliminou o argumento buffered.

Checklist de migração

Para uma portabilização limpa para a v5.0.0, o trabalho típico é:

  1. Substituir import sensor por import csi; csi0 = csi.CSI() e traduzir cada chamada set_*/get_* para o acessor csi.CSI correspondente (a migração csi).

  2. Envolver os argumentos de coordenadas de img.draw_*, get_pixel() e set_pixel() em tuplos (as alterações do módulo image).

  3. Remover () dos acessores de resultado attrtuple se quiser a nova forma idiomática, ou deixar o estilo antigo como está, pois os attrtuples ainda suportam acessores chamáveis (as alterações do módulo image).

  4. Auditar find_line_segments(), get_regression() e qualquer escolha de família find_apriltags() (as alterações do módulo image).

  5. Renomear timer_mspoll_ms nas chamadas a protocol.init(); remover protocol.poll() e soft_reboot= (as alterações do módulo protocol).

  6. Para fluxos de trabalho de ML: rever qualquer modelo que necessitava de entrada com letterbox (as alterações da biblioteca ML).