Sigmoidal
  • Home
  • Pós-Graduação
  • Blog
  • Sobre Mim
  • Contato
Sem Resultado
Ver Todos Resultados
  • English
  • Home
  • Pós-Graduação
  • Blog
  • Sobre Mim
  • Contato
Sem Resultado
Ver Todos Resultados
Sigmoidal
Sem Resultado
Ver Todos Resultados

YOLO para detecção de objetos em imagens térmicas

Carlos Melo por Carlos Melo
agosto 17, 2026
em Deep Learning, Tutoriais, Visão Computacional, Youtube
0
12
VIEWS
Publicar no LinkedInCompartilhar no FacebookCompartilhar no Whatsapp

Uma pessoa vista de cima, em uma imagem térmica e parcialmente coberta pela vegetação, não se parece com a pessoa que um detector generalista aprendeu a reconhecer. A classe continua sendo person. O padrão visual não. Sensor, perspectiva, escala e pose mudam ao mesmo tempo, e o modelo responde com o vocabulário que tem: uma assinatura quente vira broccoli, um corpo alongado vira airplane, ou simplesmente nada é detectado.

Esse descompasso não é um detalhe de implementação. É o problema central de especializar um detector a um domínio operacional. Eu vi essa diferença na prática muito antes de treinar redes: fui piloto da Força Aérea Brasileira durante 16 anos, trabalhei em busca e salvamento na Amazônia e atuei com ciência de dados e planejamento de missões no Comando de Operações Aeroespaciais. Em uma busca, o tempo avança, a área se expande e a qualidade da percepção decide o que a equipe consegue priorizar.

Neste artigo, você vai acompanhar um projeto completo de YOLO para detecção de objetos em imagens térmicas: partir de um YOLOv8s treinado no COCO, medir o que ele faz no conjunto POP (Partially Occluded Person), adaptar os pesos ao domínio e inspecionar o resultado. O notebook público reúne treinamento e inferência. Os números e as figuras abaixo saem dessa execução.

Se você quer percorrer esse tipo de pipeline em projetos com dados aéreos reais, o Bootcamp de Visão Computacional Aplicada a Drones é uma especialização prática, hands-on, em Data Science e Inteligência Artificial aplicada a drones, com modelos no estado da arte.

💻

Código do Artigo

Acesse o código-fonte deste artigo gratuitamente.

Informe seu email para acessar o código:

✓ Seu código está pronto!

Abrir no Google Colab →

Por que o YOLO para detecção de objetos em imagens térmicas precisa de adaptação?

Um modelo como YOLO, treinado em conjuntos enormes de fotografias comuns, é um excelente ponto de partida. Ele já viu a classe person em contextos frequentes: perspectiva horizontal, corpo em proporções familiares, textura de roupa, objetos relativamente grandes no quadro e cenas urbanas ou cotidianas.

Uma missão de busca com drone inverte quase todas essas condições. A câmera olha do nadir. O sensor registra radiação térmica, não luz refletida. A pessoa ocupa uma fração pequena do frame. A pose pode ser deitada. Parte do corpo desaparece sob a copa. Para nós, continua sendo uma pessoa. Para o modelo, é um padrão que ele talvez nunca tenha associado a essa classe.

Por isso, a primeira pergunta não é “qual versão da YOLO eu baixo?”. É: o dado de treinamento representa a aparência da missão? A resolução preserva o alvo? As divisões evitam vazamento entre cenas do mesmo voo? Esse raciocínio é o mesmo que aparece quando você treina YOLO em um conjunto personalizado, só que aqui a mudança de domínio é mais brusca do que trocar de objeto em fotografias convencionais.

O que o conjunto POP representa?

O POP foi publicado como conjunto de dados de imagens infravermelhas para detecção de pessoas parcialmente ocluídas em ambientes complexos, com aplicação explícita em busca e salvamento. A coleta usou um DJI Matrice 30T, com gimbal no nadir, em alturas próximas de 30, 50 e 70 metros.

No arquivo oficial que o notebook baixa e verifica por SHA-256, as divisões ficam assim:

def load_coco(split):
    path = POP_ROOT / split / "Annotations" / f"{split}.json"
    return json.loads(path.read_text(encoding="utf8"))

summary_rows = []
for split in ("train", "val", "test"):
    coco = load_coco(split)
    summary_rows.append({
        "split": split,
        "images": len(coco["images"]),
        "boxes": len(coco["annotations"]),
    })

pd.DataFrame(summary_rows)
   split  images  boxes
0  train    5548  18425
1    val    2320   6546
2   test     900   1840

São 8.768 imagens e 26.811 caixas. O ponto metodológico mais importante não é o volume: as divisões são organizadas por cena. Frames vizinhos de um mesmo trecho de voo podem ser quase idênticos. Se você embaralha arquivos ao acaso, parte do teste mede memória visual, não generalização.

Antes de qualquer treinamento, o notebook fixa alguns casos do conjunto de teste e desenha as anotações de referência. Essa ordem importa. Os exemplos não foram escolhidos depois de ver onde o modelo adaptado ficou mais convincente.

Seis imagens térmicas de teste do POP com as caixas de ground truth em vermelho

Casos fixados no conjunto de teste. Observe a escala dos alvos, as poses e a oclusão pela vegetação.

O ponto de partida funciona no domínio original?

Antes de concluir que o detector “não serve” para o termal, confirmamos que ele reconhece pessoas no tipo de imagem em que foi treinado. Carregamos o YOLOv8s com pesos do COCO e aplicamos a fotografia clássica do ônibus da Ultralytics, na mesma resolução que usaremos depois (imgsz=1280).

coco_model = YOLO("yolov8s.pt")
bus_result = coco_model.predict(
    source=str(BUS_PATH),
    imgsz=1280,
    conf=0.25,
    verbose=False,
)[0]
YOLOv8s treinado no COCO detectando pessoas em uma fotografia convencional de um ônibus

O modelo localiza as pessoas com confiança alta. O baseline está intacto: a arquitetura e os pesos fazem o que se espera no domínio original. O problema ainda não apareceu.

A mesma classe, outra distribuição

Agora mudamos tudo de uma vez e mantemos o mesmo detector, a mesma resolução e o mesmo limiar de confiança.

coco_demo_results = coco_model.predict(
    source=[str(path) for path in DEMO_IMAGES],
    imgsz=1280,
    conf=0.25,
    verbose=False,
)

for result, path in zip(coco_demo_results, DEMO_IMAGES):
    classes = [result.names[int(class_id)] for class_id in result.boxes.cls]
    print(path.name, classes if classes else "nenhuma detecção")
T1_0000_30.291.JPG ['broccoli']
T2_0000_50.15.JPG ['airplane']
T1_0076_29.613.JPG ['airplane', 'kite']
T1_0229_50.226.JPG nenhuma detecção
T2_0065_50.496.JPG ['airplane', 'airplane']
T2_0194_47.334.JPG nenhuma detecção
Mesmo YOLOv8s do COCO aplicado às imagens térmicas do POP: classes incorretas ou ausência de detecção

Nenhuma das seis cenas produz person. O modelo não está “quebrado”. Ele está encaixando uma imagem fora da sua distribuição nas categorias que conhece. Uma mancha clara e compacta se aproxima de broccoli. Um corpo alongado, visto de cima, se aproxima de airplane. Em outros casos, o escore não atravessa o limiar.

Essa é a definição prática de mudança de domínio. Trocar o nome da classe no vocabulário humano não altera o espaço visual em que o detector foi treinado.

A tentação seguinte é atualizar a geração do modelo. O notebook repete as mesmas seis cenas com YOLO11s, também treinado no COCO. Nas imagens inspecionadas, a incompatibilidade permanece: a geração mais recente não remove, por si só, a distância entre fotografias terrestres e imagens térmicas aéreas.

Se você já estuda detecção de objetos, vale contrastar este resultado com a introdução ao YOLOv9: o avanço de arquitetura importa, mas não substitui dados que representem a missão. O mesmo princípio atravessa o artigo sobre Data Science para Drones, em que a modalidade e a escala do alvo definem o problema muito antes da escolha da rede.

Essa é também a diferença entre usar um modelo pronto e construir um projeto. No Bootcamp de Visão Computacional Aplicada a Drones, o caso térmico é um dos projetos da especialização. O percurso completo avança para a fusão entre o óptico e o termal, quando um único canal deixa evidência incompleta.

Converter, validar e medir a escala

O POP entrega anotações em COCO JSON. O treinamento com Ultralytics espera labels no formato YOLO: classe e caixa normalizada pelo centro, largura e altura. Uma conversão descuidada troca coordenadas, classes ou escalas e destrói o treinamento de forma silenciosa.

def yolo_line(annotation, image_width, image_height):
    x, y, width, height = annotation["bbox"]

    center_x = (x + width / 2) / image_width
    center_y = (y + height / 2) / image_height
    norm_width = width / image_width
    norm_height = height / image_height

    values = [center_x, center_y, norm_width, norm_height]
    assert all(0 <= value <= 1 for value in values)

    return "0 " + " ".join(f"{value:.6f}" for value in values)

Depois da conversão, o notebook confere as três divisões (5.548 / 2.320 / 900 imagens) e verifica as 26.811 coordenadas no intervalo [0, 1]. Só então olhamos a escala dos alvos.

boxes[["width_px", "height_px", "relative_area_pct"]].describe(
    percentiles=[0.25, 0.5, 0.75, 0.9]
)
           width_px     height_px  relative_area_pct
count  26811.000000  26811.000000       26811.000000
mean      42.303085     49.242662           0.180428
50%       38.000000     44.000000           0.125351
90%       71.000000     86.000000           0.434494

A mediana é uma caixa de 38 por 44 pixels, ocupando cerca de 0,13% da imagem. Mesmo no percentil 90, a área relativa permanece abaixo de 0,5%. Se a resolução de entrada for reduzida por hábito, a informação do alvo desaparece antes de o detector começar a trabalhar.

Histograma da altura das bounding boxes no POP, concentrado em alvos pequenos

A distribuição da altura justifica imgsz=1280: a resolução precisa conversar com o tamanho do objeto.

Transfer learning com hipóteses explícitas

A adaptação mantém a família YOLOv8s. Assim, o ganho observado vem dos dados, não de uma troca de arquitetura. Partimos dos pesos do COCO, elevamos a resolução, limitamos o número de épocas e interrompemos quando a validação deixa de melhorar.

Em imagens térmicas, também desativamos a variação de matiz e saturação. Esses augmentations fazem sentido em RGB. Aqui, eles alterariam um sinal que não está organizado como cor.

EPOCHS = 100
PATIENCE = 20
IMGSZ = 1280
BATCH = 8

model = YOLO("yolov8s.pt")
train_results = model.train(
    data=str(DATA_YAML),
    epochs=EPOCHS,
    patience=PATIENCE,
    imgsz=IMGSZ,
    batch=BATCH,
    optimizer="SGD",
    lr0=0.001,
    pretrained=True,
    hsv_h=0.0,
    hsv_s=0.0,
    save=True,
    save_period=5,
)

A execução desta configuração parou por early stopping na época 49. A melhor época pela métrica principal de validação foi a 29. O last.pt e o best.pt não são sinônimos: um guarda o estado mais recente, o outro guarda o estado que deve seguir para avaliação e inferência.

print("Última epoch registrada:", int(history.tail(1).iloc[0]["epoch"]))
print("Melhor epoch pela métrica principal:", int(history.loc[best_index, "epoch"]))
Última epoch registrada: 49
Melhor epoch pela métrica principal: 29
Curvas de mAP na validação ao longo do treinamento do YOLOv8s no POP

A melhor época ocorre antes da última registrada. Treinar é acompanhar o processo e escolher o estado que merece ser levado adiante.

No conjunto de teste completo (900 imagens, 1.840 instâncias), o checkpoint selecionado obteve mAP50 = 0,808 e mAP50-95 = 0,437, com precisão 0,82 e recall 0,72. Essa medida agregada confirma que o comportamento não depende apenas das poucas cenas da demonstração. Ela também não substitui a inspeção visual: não diz, sozinha, qual pose foi fácil nem onde apareceu um falso positivo.

Inspeção visual: a arquitetura é a mesma, os pesos não

A comparação mais honesta isola o efeito dos pesos. Mesma família YOLOv8s, mesma imagem, mesma região. À esquerda, o modelo do COCO escreve broccoli 0.33. À direita, o modelo adaptado ao POP escreve person 0.86.

YOLOv8s COCO: [('broccoli', 0.33)]
YOLOv8s POP:  [('person', 0.86)]
YOLOv8s COCO rotula a pessoa como broccoli 0.33; o mesmo YOLOv8s adaptado ao POP detecta person 0.86

A arquitetura não ganhou olhos novos. Ela recebeu exemplos de outro domínio. O modelo generalista responde com a experiência visual que teve. O modelo adaptado aprendeu como uma pessoa aparece naquele sensor, naquela perspectiva e naquela escala.

A mesma comparação, agora com ground truth, generalista e modelo do POP lado a lado, mostra o recorte ampliado do alvo. A cena abaixo é uma pessoa em pé; o notebook repete o painel para deslocamento e pose deitada.

Comparação em uma cena com pessoa em pé: ground truth, YOLO11s COCO e YOLOv8s adaptado ao POP

Uma cena não prova superioridade universal da YOLOv8s. Ela torna visível uma afirmação mais precisa: dados representativos alteram o que o detector é capaz de associar à classe person. Uma avaliação séria combina essa leitura com a métrica do teste e com a análise dos erros restantes, sobretudo quando a oclusão aumenta e o alvo se aproxima do limite da resolução.

Se você quiser ver o mesmo tipo de raciocínio em outro domínio aéreo, o projeto mais antigo de vigilância com drones e Deep Learning mostra a outra ponta do problema: colocar o detector dentro de um fluxo que produz uma saída utilizável, não apenas uma caixa em um notebook.

Do ramo térmico ao projeto completo

O que este artigo demonstra é um recorte deliberado: uma modalidade, um domínio, um detector adaptado. Isso basta para tornar o efeito da especialização mensurável e visível. Não basta quando a vegetação apaga a silhueta no óptico ou quando o residual térmico se mistura ao terreno.

A imagem óptica oferece textura, contorno e contexto. A imagem térmica preserva contraste de temperatura quando a iluminação visível é ruim. Nenhum dos dois sensores é completo. A fusão só faz sentido se as duas observações se referem ao mesmo lugar no mesmo instante e se a arquitetura aprende o que aproveitar de cada ramo.

Esse é o passo seguinte no Bootcamp de Visão Computacional Aplicada a Drones: uma especialização prática em Data Science e Inteligência Artificial aplicada a drones, com projetos hands-on e modelos no estado da arte. Além da adaptação térmica, o treinamento cobre a fusão óptica e termal e outros problemas com dados aéreos reais. O foco não é pilotagem. É a cadeia que vai do dataset à avaliação.

Takeaways

  • A classe pode ser a mesma e o domínio, outro. person em uma fotografia terrestre não é o mesmo padrão visual que person em uma imagem térmica aérea, pequena e parcialmente ocluída.
  • Trocar a geração do detector não fecha automaticamente o gap. Nas cenas inspecionadas, YOLO11s treinado no COCO permanece incompatível com o domínio térmico, como o YOLOv8s generalista.
  • O dataset precisa representar a dificuldade da missão. No POP, splits por cena, oclusão e alvos de dezenas de pixels são parte do problema, não um detalhe de formatação.
  • A resolução de entrada é uma hipótese sobre o tamanho do objeto. Com mediana de 38×44 pixels e área relativa próxima de 0,13%, reduzir demais a imagem apaga o alvo antes do treino.
  • best.pt e last.pt respondem a perguntas diferentes. Nesta execução, a melhor época de validação foi a 29; a última registrada foi a 49.
  • Métrica agregada e inspeção visual se complementam. O teste chega a mAP50 de 0,808; a cena broccoli 0.33 versus person 0.86 mostra o que essa métrica significa no quadro.

O notebook completo, com conversão, treinamento, curvas e comparação visual, está no gate no início deste artigo. Se você quiser aprofundar esse tipo de projeto em uma especialização prática, o caminho é o Bootcamp de Visão Computacional Aplicada a Drones.

CompartilharCompartilharEnviar
Post Anterior

Data Science para Drones

Carlos Melo

Carlos Melo

Engenheiro de Visão Computacional graduado em Ciências Aeronáuticas pela Academia da Força Aérea (AFA) e Mestre em Engenharia Aeroespacial pelo Instituto Tecnológico de Aeronáutica (ITA).

Relacionado Artigos

Tutoriais

Aplicação do SLAM para criação de mapas 3D: do conceito ao ORB-SLAM3

por Carlos Melo
agosto 13, 2026
Data Science

Data Science para Drones

por Carlos Melo
agosto 13, 2026
Machine Learning

Modelos de Árvore em Machine Learning: Guia Completo

por Carlos Melo
julho 16, 2026
Data Science

Imputação de Dados Ausentes com Scikit-Learn

por Carlos Melo
julho 9, 2026
Machine Learning

Pipelines no Scikit-Learn: Transformações sem Data Leakage

por Carlos Melo
julho 6, 2026

Deixe um comentário Cancelar resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Últimos dias para o Curso de Inteligência Artificial para Drones Últimos dias para o Curso de Inteligência Artificial para Drones Últimos dias para o Curso de Inteligência Artificial para Drones

Mais Populares

  • Cientista de Dados: Salário em 2026 (Júnior, Pleno e Sênior)

    100 compartilhamentos
    Compartilhar 40 Tweet 25
  • Geometria da Formação de Imagens: Matrizes, Transformações e Sistemas de Coordenadas

    445 compartilhamentos
    Compartilhar 178 Tweet 111
  • Fundamentos da Formação da Imagem

    213 compartilhamentos
    Compartilhar 85 Tweet 53
  • Introdução ao MediaPipe e Pose Estimation

    575 compartilhamentos
    Compartilhar 230 Tweet 144
  • O Que é Amostragem e Quantização no Processamento de Imagens

    69 compartilhamentos
    Compartilhar 28 Tweet 17
  • Em Alta
  • Comentários
  • Mais Recente
Como Tratar Dados Ausentes com Pandas

Como Tratar Dados Ausentes com Pandas

agosto 13, 2019
Introdução ao MediaPipe e Pose Estimation

Introdução ao MediaPipe e Pose Estimation

julho 15, 2023
Como usar o DALL-E 2 para gerar imagens a partir de textos

Como usar o DALL-E 2 para gerar imagens a partir de textos

dezembro 25, 2022

ORB-SLAM 3: Tutorial Completo para Mapeamento 3D e Localização em Tempo Real

abril 10, 2023
Como Analisar Ações da Bolsa com Python

Como Analisar Ações da Bolsa com Python

15
Setembro Amarelo: Análise do Suicídio no Brasil, com Data Science

Setembro Amarelo: Análise do Suicídio no Brasil, com Data Science

13
Como Aprender Data Science?

Como Aprender Data Science?

9
Qual o Cenário de Data Science no Brasil hoje?

Qual o Cenário de Data Science no Brasil hoje?

8

YOLO para detecção de objetos em imagens térmicas

agosto 17, 2026

Aplicação do SLAM para criação de mapas 3D: do conceito ao ORB-SLAM3

agosto 13, 2026

Data Science para Drones

agosto 13, 2026

Modelos de Árvore em Machine Learning: Guia Completo

julho 16, 2026
Instagram Youtube LinkedIn Twitter
Sigmoidal

O melhor conteúdo técnico de Data Science, com projetos práticos e exemplos do mundo real.

Seguir no Instagram

Categorias

  • Aeroespacial
  • Artigos
  • Blog
  • Carreira
  • Cursos
  • Data Science
  • Deep Learning
  • Destaques
  • Entrevistas
  • IA Generativa
  • Livros
  • Machine Learning
  • Notícias
  • Python
  • Sinais Biomédicos
  • Teoria
  • Tutoriais
  • Visão Computacional
  • Youtube

Navegar por Tags

algebra-linear camera calibration carreira chatgpt cientista de dados cnn computer vision Cursos dados desbalanceados data science data science na prática decision tree deep learning deploy detecção de objetos gradient descent IA generativa inteligência artificial jupyter kaggle keras livros machine learning matplotlib openai opencv pandas profissão python pytorch random forest reconstrução 3d redes neurais redes neurais convolucionais regressão linear regressão logística salário scikit-learn sklearn tensorflow tutorial visão computacional vídeo youtube árvore de decisão

© 2024 Sigmoidal - Aprenda Data Science, Visão Computacional e Python na prática.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In

Add New Playlist

Sem Resultado
Ver Todos Resultados
  • Home
  • Pós-Graduação
  • Blog
  • Sobre Mim
  • Contato
  • English

© 2024 Sigmoidal - Aprenda Data Science, Visão Computacional e Python na prática.