Catalog · How the catalog works
onnx-pascal
ONNX wrapper pascal
- ★ 2 on GitHub
Anyone may press Interesting, signed in or not. It helps others find this project.
README
ONNXDemo — visão computacional em Delphi com ONNX Runtime
Aplicação console Win64 que roda modelos ONNX de visão sem Python, OpenCV ou
qualquer wrapper: apenas onnxruntime.dll e a VCL para abrir e salvar imagem.
O binding para a C API 1.28 é escrito à mão e vive em delphi/src/ONNX.*.pas.
| Tarefa | Modelo de exemplo | Resultado |
|---|---|---|
classify |
SqueezeNet, YOLO26-cls | top-K classes com probabilidade |
detect |
YOLO26 | caixas + classe + score |
segment |
YOLO26-seg | caixas + máscara por instância |
pose |
YOLO26-pose | caixas + 17 keypoints + esqueleto |
obb |
YOLO26-obb | caixas rotacionadas + ângulo |
face |
SCRFD (buffalo_l) | caixas + 5 landmarks faciais |
embed |
ArcFace (buffalo_l) | vetor 512-D para comparar rostos |
text |
PP-OCRv6_medium_det (PaddleOCR) | linhas de texto como caixas rotacionadas |
--ocr |
PP-OCRv6_medium_det + _rec | texto lido, linha a linha, em ordem de leitura |
Requisitos
- Windows x64
- Delphi 12 (BDS 23.0) — a Community Edition serve. O projeto usa só VCL e RTL, sem componentes de terceiros.
- Python 3.11+ — opcional, necessário apenas para exportar os modelos.
- ~3 GB livres (modelos + venv).
A Community Edition não compila por linha de comando. Todos os builds abaixo são feitos abrindo o
.dprojno IDE e pressionando Shift+F9.
Passo a passo
Os passos 1–3 já produzem um executável funcionando. Os passos 4–7 baixam os modelos de cada tarefa; faça só os que interessarem.
1. Clonar
git clone <url-do-repositorio> onnx-pascal
cd onnx-pascalO repositório contém apenas código, scripts e documentação — nenhum binário. O
.gitignore exclui de propósito o runtime, os modelos, as imagens e a galeria.
2. ONNX Runtime 1.28.1
Baixe o pacote oficial da Microsoft e coloque a DLL ao lado do executável:
curl -L -o ort.zip https://github.com/microsoft/onnxruntime/releases/download/v1.28.1/onnxruntime-win-x64-1.28.1.zip
unzip -j ort.zip "*/lib/onnxruntime.dll" -d delphi/bin/
rm ort.zipSem PowerShell/curl, baixe manualmente de
github.com/microsoft/onnxruntime/releases
(tag v1.28.1, arquivo onnxruntime-win-x64-1.28.1.zip) e copie
lib/onnxruntime.dll para delphi/bin/.
A versão importa pouco.
delphi/src/ONNX.CApi.pasmapeia a tabela da structOrtApiconferida contra oonnxruntime_c_api.hda 1.28.1, mas só usa slots que existem desde muito antes. O programa negocia a versão da API com a DLL: aceita da 1.16 em diante, e uma mais nova também funciona, porque a tabela só cresce no fim.
Opcional: GPU (DirectML)
O zip acima é só CPU (e a variante gpu_cuda serve apenas para NVIDIA). Para
rodar em qualquer GPU DirectX 12 — AMD, NVIDIA ou Intel — use a
onnxruntime.dll do pacote Windows ML da Microsoft, que traz o provider
DirectML embutido:
curl -L -o winml.zip https://api.nuget.org/v3-flatcontainer/microsoft.windows.ai.machinelearning/2.4.89/microsoft.windows.ai.machinelearning.2.4.89.nupkgunzip -j winml.zip "runtimes/win-x64/native/onnxruntime.dll" "runtimes/win-x64/native/DirectML.dll" -d delphi/bin/dml/O .nupkg é um zip comum. As duas DLLs vão para a subpasta dml/, sem
substituir a do passo anterior: na CPU a build oficial 1.28.1 é ~40% mais
rápida que a 1.27.1 do Windows ML, então o programa só carrega a de dml/
quando recebe --gpu. Acrescente --gpu a qualquer comando:
./ONNXDemo.exe --ocr imagem/ocr_exemplo.png --gpuNuma RX 9070 XT, contra a CPU:
| GPU | CPU | |
|---|---|---|
YOLO26x, bus.jpg (inferência) |
34 ms | 570 ms |
OCR completo, ocr_exemplo.png (98 linhas) |
3,7 s | 16,1 s |
As saídas coincidem com as da CPU. Sem a DLL certa, --gpu avisa e segue na
CPU.
Formatos variáveis custam caro no DirectML. Ele otimiza o grafo para o primeiro formato de entrada que a sessão vê; formatos novos rodam bem mais devagar. Isso pesa no reconhecedor de texto, cuja largura muda a cada linha — por isso, com
--gpu, o OCR lê em lotes de 6 (ver--rec-batch).
3. Compilar
- Abra
delphi/ONNXDemo.dprojno Delphi 12 - Selecione a plataforma Windows 64-bit
- Shift+F9 (Build)
O executável sai em delphi/bin/ONNXDemo.exe. Confira:
cd delphi/bin && ./ONNXDemo.exe --help4. Ambiente Python (para exportar modelos)
Só é necessário se você for gerar os modelos YOLO26. Se alguém já te passou os
.onnx, pule para o passo 6.
cd python && py -m venv .venv.venv/Scripts/python -m pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu.venv/Scripts/python -m pip install ultralytics onnx onnxslim onnxruntimeO PyTorch vem do índice CPU-only de propósito: ~250 MB em vez de ~3 GB, e é suficiente para exportar ONNX.
5. Modelos YOLO26
cd python && .venv/Scripts/python export_models.pyO script baixa os pesos oficiais do release
ultralytics/assets v8.4.0,
exporta com opset=12 e imprime o SHA256 de cada .pt. Os .onnx saem
organizados por tamanho em delphi/bin/yolo/<n|s|m|l|x>/, cada pasta com as
cinco tarefas — 25 modelos ao todo, o que permite comparar velocidade e
acurácia entre tamanhos.
Para gerar só um recorte da matriz:
cd python && .venv/Scripts/python export_models.py --sizes n,s --tasks detect,poseOs hashes esperados estão em python/PROCEDENCIA.md — compare, se quiser conferir a integridade.
Para gerar também as variantes sem NMS-free (que exercitam o caminho de supressão de não-máximos):
cd python && .venv/Scripts/python export_raw.pyNão existe
.onnxoficial de YOLO26. A Ultralytics distribui só.pt, então qualquer.onnxpronto encontrado na internet é export de terceiro, sem garantia de que os argumentos e o formato de saída sejam os esperados. Exporte você mesmo.Atenção:
.pté pickle do Python e executa código ao carregar. Baixe apenas das fontes oficiais. O.onnxé protobuf, só dado — risco bem menor.
6. Modelos faciais
O pacote buffalo_l da InsightFace traz o detector e o reconhecedor com
pré-processamento consistente entre si:
curl -L -o buffalo_l.zip https://github.com/deepinsight/insightface/releases/download/v0.7/buffalo_l.zipunzip -j buffalo_l.zip det_10g.onnx w600k_r50.onnx -d delphi/bin/face/det_10g.onnx (17 MB) é o detector SCRFD com 5 landmarks; w600k_r50.onnx
(174 MB) é o ArcFace que gera o vetor de 512 dimensões. O zip traz ainda
2d106det.onnx (106 pontos 2D), 1k3d68.onnx (68 pontos 3D) e
genderage.onnx, que este projeto ainda não usa.
Os pesos da InsightFace são licenciados apenas para pesquisa não-comercial. Para produto, é preciso trocar o modelo ou licenciar.
7. Detecção e leitura de texto (PaddleOCR)
O PP-OCRv6_medium_det é o detector mais preciso da família PP-OCRv6 e o
PP-OCRv6_medium_rec, o reconhecedor mais preciso. Ao contrário do YOLO26,
ambos têm .onnx oficial, publicado pela própria PaddlePaddle:
mkdir -p delphi/bin/ocrcurl -L -o delphi/bin/ocr/PP-OCRv6_medium_det.onnx https://huggingface.co/PaddlePaddle/PP-OCRv6_medium_det_onnx/resolve/main/inference.onnxcurl -L -o delphi/bin/ocr/PP-OCRv6_medium_rec.onnx https://huggingface.co/PaddlePaddle/PP-OCRv6_medium_rec_onnx/resolve/main/inference.onnxcurl -L -o delphi/bin/ocr/PP-OCRv6_medium_rec.yml https://huggingface.co/PaddlePaddle/PP-OCRv6_medium_rec_onnx/resolve/main/inference.ymlO .yml do reconhecedor é obrigatório: o .onnx devolve índices, e o
dicionário de 18.708 caracteres (50 idiomas, acentos do português incluídos)
só existe nesse arquivo. Salve-o com o mesmo nome do modelo — o programa o
procura ali.
| modelo | Hmean médio | parâmetros | .onnx |
|---|---|---|---|
| PP-OCRv6_medium_det | 86,2 | 15,5 M | 62 MB |
| PP-OCRv6_small_det | 84,1 | — | — |
| PP-OCRv6_tiny_det | 80,6 | — | — |
| PP-OCRv5_server_det | 81,6 | — | — |
| reconhecedor | acurácia média | parâmetros | .onnx |
|---|---|---|---|
| PP-OCRv6_medium_rec | 83,2 | 19 M | 77 MB |
| PP-OCRv6_small_rec | 81,3 | — | — |
| PP-OCRv6_tiny_rec | 73,5 | — | — |
| PP-OCRv5_server_rec | 78,1 | — | — |
Números dos model cards. Os irmãos small e tiny (repositórios
PaddlePaddle/PP-OCRv6_small_det_onnx, ..._small_rec_onnx etc.) têm as
mesmas cabeças e rodam sem mudar nada — trocam acurácia por velocidade. Use
--ocr-det/--ocr-rec e baixe o .yml do reconhecedor escolhido.
O detector não traz metadados: a tarefa é deduzida da saída única [1, 1, H, W].
Os limiares padrão do programa são os do inference.yml que acompanha o
modelo (thresh 0.2, box_thresh 0.45, unclip_ratio 1.4, lado menor ≥ 736).
8. Imagens de teste
mkdir -p delphi/bin/imagem && cd delphi/bin/imagemcurl -L -O https://ultralytics.com/images/bus.jpg -O https://ultralytics.com/images/zidane.jpg -O https://ultralytics.com/images/boats.jpgcurl -L -O https://github.com/ageitgey/face_recognition/raw/master/examples/obama.jpg -O https://github.com/ageitgey/face_recognition/raw/master/examples/obama2.jpg -O https://github.com/ageitgey/face_recognition/raw/master/examples/biden.jpgcurl -L -o ocr_exemplo.png https://cdn-uploads.huggingface.co/production/uploads/681c1ecd9539bdde5ae1733c/3ul2Rq4Sk5Cn-l69D695U.pngbus.jpg (ônibus + 4 pessoas), zidane.jpg (2 rostos), boats.jpg (marina
aérea, para OBB), o trio Obama/Biden (duas fotos da mesma pessoa + uma de
outra, para validar reconhecimento facial) e ocr_exemplo.png, a página de
exemplo do model card do PP-OCRv6.
Uso
Inferência
Modelo e imagem são obrigatórios; o argumento terminado em .onnx é tomado
como modelo, o outro como imagem. Sem argumentos, o programa imprime a ajuda.
./ONNXDemo.exe yolo/n/yolo26n.onnx imagem/bus.jpg./ONNXDemo.exe yolo/x/yolo26x-seg.onnx imagem/bus.jpg --conf=0.4./ONNXDemo.exe squeezenet/squeezenet1_1.onnx imagem/dog.jpg --labels=squeezenet/labels.txt --topk=10./ONNXDemo.exe ocr/PP-OCRv6_medium_det.onnx imagem/ocr_exemplo.pngA tarefa é lida dos metadados do .onnx e o layout da saída é decidido pelo
shape real do tensor em tempo de execução — não há nada a configurar. Use
--task só para forçar.
As imagens anotadas vão para saida/, nunca junto das entradas.
Texto
As linhas saem em ordem de leitura, cada uma com score e retângulo rotacionado. Na imagem anotada só o contorno é desenhado — rótulo em cada linha cobriria o próprio texto.
| opção | padrão | efeito |
|---|---|---|
--conf |
0,45 | score médio mínimo dentro da caixa (box_thresh) |
--db-thr |
0,2 | limiar que binariza o mapa de probabilidade |
--unclip |
1,4 | quanto a caixa cresce sobre a região detectada |
--det-side |
736 | limite de lado no redimensionamento |
--det-limit |
min |
min: lado menor ≥ limite; max: lado maior ≤ limite |
--max-det |
3000 | máximo de regiões examinadas |
Em fotos grandes, --det-limit=max --det-side=960 fica bem mais rápido, ao
custo de perder texto pequeno.
OCR
./ONNXDemo.exe --ocr imagem/ocr_exemplo.pngDetecta as linhas, recorta cada uma reta e a lê. O console lista cada linha
com a confiança da detecção e da leitura; o texto completo vai para
saida/<imagem>_ocr.txt (UTF-8) e saida/<imagem>_ocr.png mostra a imagem com
as caixas ao lado do texto lido, cada um na sua posição.
| opção | padrão | efeito |
|---|---|---|
--ocr-det |
ocr/PP-OCRv6_medium_det.onnx |
detector |
--ocr-rec |
ocr/PP-OCRv6_medium_rec.onnx |
reconhecedor |
--ocr-dict |
o .yml ao lado do reconhecedor |
dicionário de caracteres |
--rec-thr |
0 | descarta linhas lidas com confiança menor |
--rec-batch |
6 com --gpu, 1 na CPU |
linhas por execução do reconhecedor |
O pipeline oficial do PaddleX lê as linhas em lotes de 6, ordenadas pela
proporção, com padding até a mais larga do lote. Como o reconhecedor olha a
linha inteira, esse padding muda a leitura de uma linha ou outra (1 em 98 no
documento de exemplo): --rec-batch=6 reproduz o PaddleOCR de fábrica,
--rec-batch=1 lê cada linha isolada. Na GPU os lotes são ~3× mais rápidos;
na CPU são mais lentos, daí o padrão diferente.
As opções de detecção de texto da tabela anterior também valem aqui.
Limitação: não há classificador de orientação de linha (o PaddleOCR o trata como um terceiro modelo opcional). Texto de cabeça para baixo, ou vertical escrito de baixo para cima, sai como lixo — igual ao PaddleOCR com
use_textline_orientation=False. Noocr_exemplo.png, é o caso da anotação vertical do arXiv na margem.
O reconhecedor também roda sozinho sobre uma imagem que já seja uma linha recortada:
./ONNXDemo.exe ocr/PP-OCRv6_medium_rec.onnx linha.png --task=rec --labels=ocr/PP-OCRv6_medium_rec.ymlRostos
./ONNXDemo.exe --enroll="Obama" imagem/obama.jpg./ONNXDemo.exe --query imagem/obama2.jpg./ONNXDemo.exe --compare imagem/obama.jpg imagem/biden.jpg./ONNXDemo.exe --listA galeria é um arquivo de texto (faces.gallery), uma linha por rosto:
nome, origem e o vetor. Inspecionável e diffável.
A galeria contém dados biométricos, tratados como dados pessoais sensíveis pela LGPD. O
.gitignorea exclui. Se o uso for além de pessoal, veja consentimento e retenção com quem cuida disso.
ONNXDemo.exe --help lista todas as opções.
Verificação
Rode a bateria de regressão:
cd delphi && ./run_tests.shOu confira manualmente estes valores, que são estáveis entre máquinas:
| comando | esperado |
|---|---|
yolo26x.onnx imagem/bus.jpg |
5 objetos: bus 98,0% + 4 person |
yolo26x-pose.onnx imagem/zidane.jpg |
2 person, 8 de 17 keypoints visíveis |
yolo26x-obb.onnx imagem/boats.jpg |
~179 ship, ângulos 21–26° |
squeezenet1_1.onnx imagem/dog.jpg |
Samoyed 99,88% |
--compare imagem/obama.jpg imagem/obama2.jpg |
cosseno ≈ 0,77 → mesma pessoa |
--compare imagem/obama.jpg imagem/biden.jpg |
cosseno ≈ −0,04 → diferentes |
PP-OCRv6_medium_det.onnx imagem/ocr_exemplo.png |
98 linhas; a 1ª com 88,8% |
PP-OCRv6_medium_det.onnx imagem/bus.jpg |
8 linhas (letreiro, "cero", "emisiones"…) |
--ocr imagem/ocr_exemplo.png |
1ª linha: Algorithms for the Markov Entropy Decomposition |
O dog.jpg é a imagem canônica do PyTorch, cuja resposta documentada é
Samoyed: se der outra coisa, o pré-processamento está errado em algum ponto.
A detecção e a leitura de texto têm referência própria em python/ocr_ref.py,
que transcreve o pré e o pós-processamento do PaddleX com OpenCV. Em PNG o
resultado coincide (98 linhas, scores iguais até a 2ª casa). Em JPEG as caixas
coincidem, mas regiões de contraste baixo podem mudar alguns pontos de score:
o decodificador JPEG da VCL e o resize bilinear em ponto flutuante diferem do
OpenCV em ±1 nível de cinza, e o letreiro de LED do bus.jpg é sensível a
isso (74% aqui, 58% no Python).
Os valores de referência do pipeline facial (caixa, os 5 landmarks e as
primeiras posições do vetor), gerados pela implementação Python, estão em
python/referencia_face.json.
Estrutura
.
????????? delphi/
??? ????????? ONNXDemo.dpr composition root: s?? amarra as pe??as
??? ????????? src/ 31 units ??? ver delphi/README.md
??? ????????? run_tests.sh bateria de regress??o
??? ????????? bin/
??? ????????? onnxruntime.dll (passo 2)
??? ????????? yolo/n|s|m|l|x/ (passo 5) ??? 5 tarefas por tamanho
??? ????????? face/ (passo 6)
??? ????????? ocr/ (passo 7) ??? 2 modelos + dicion??rio .yml
??? ????????? imagem/ entradas (passo 8)
??? ????????? saida/ tudo que o programa gera
????????? python/
????????? export_models.py pesos oficiais ??? ONNX
????????? export_raw.py variantes end2end=False
????????? face_ref.py refer??ncia do pipeline facial
????????? verificar_face.py confere a refer??ncia facial ponta a ponta
????????? ocr_ref.py refer??ncia do OCR PP-OCRv6 (detec????o + leitura)
????????? dump_cols.py inspeciona o tensor cru de sa??da
????????? dump_obb.py idem, focado na cabe??a OBB
????????? PROCEDENCIA.md SHA256 dos pesos e ambiente do exportOs scripts em python/ não fazem parte do produto: servem para gerar os
modelos e para inspecionar o formato real das saídas de uma cabeça — útil ao
escrever ou ajustar um decoder.
A arquitetura interna, o mapeamento SOLID e as decisões de projeto estão em delphi/README.md.
Solução de problemas
Nao foi possivel carregar onnxruntime.dll (erro Win32 126)
A DLL não está ao lado do .exe. Refaça o passo 2.
onnxruntime.dll ... e antiga demais
DLL anterior à 1.16. Baixe a do passo 2.
AVISO: esta onnxruntime.dll ... nao tem DirectML
--gpu com a DLL só-CPU. Use a do Windows ML (passo 2, "Opcional: GPU").
Tarefa "unknown" nao suportada
O .onnx não traz metadados e o formato não foi dedutível. Force com
--task=detect (ou segment, pose, obb, classify, text).
Nenhuma saida com formato de predicao (rank 2 ou 3)
Export com cabeça não decodificada. Reexporte com export_models.py.
Dicionario do reconhecedor nao encontrado
Falta o inference.yml do reconhecedor, salvo como
ocr/PP-OCRv6_medium_rec.yml (passo 7), ou use --ocr-dict=ARQ.
Dicionario com N caracteres nao combina com a saida
O .yml é de outro reconhecedor. Cada modelo tem o seu.
Detector de rostos nao encontrado
Passo 6 não foi feito, ou use --face-detect=CAMINHO.
Resultado sai vazio ou absurdo
Quase sempre é pré-processamento. Rode o modelo pelo python/dump_cols.py
para ver o tensor cru e comparar com o que o decoder espera.
Licenças
| componente | licença |
|---|---|
| este código | MIT — veja LICENSE |
| ONNX Runtime | MIT (Microsoft) |
| YOLO26 / Ultralytics | AGPL-3.0 — uso comercial exige licença da Ultralytics |
| InsightFace buffalo_l | apenas pesquisa não-comercial |
| PaddleOCR PP-OCRv6 | Apache-2.0 — uso comercial permitido |
O código deste repositório é MIT e não contém nem redistribui modelo nenhum:
os .onnx são baixados pelo passo a passo acima e ficam fora do versionamento.
As licenças de YOLO26 e InsightFace se aplicam aos pesos, não a este código,
e restringem uso comercial. A arquitetura isola cada modelo atrás de um decoder,
então trocá-los é uma unit — mas convém decidir isso antes de construir em cima.

