DMS: como funciona o eye tracking automotivo com Python

DMS: como funciona o eye tracking automotivo com Python

Quando li no Sapo.pt que o Japão vai obrigar todos os carros novos vendidos a partir de setembro de 2031 a terem um sistema de monitorização do condutor (DMS), minha primeira reação não foi pensar em segurança viária — foi pensar em computer vision rodando em tempo real dentro de um veículo. E aí mora o ponto interessante que pouca gente comenta: essa regulação é, na prática, um enorme empurrão regulatório para a indústria de IA embarcada.

Vamos desmontar essa decisão técnica. O Japão vai exigir câmeras infravermelhas instaladas na coluna de direção ou no tablier, monitorando para onde o motorista olha, durante quanto tempo, e disparando alertas progressivos (visual → sonoro → vibração no volante ou banco). Parece simples no papel, mas quem já trabalhou com detecção de olhar sabe que isso envolve inferência contínua de modelos de visão computacional com latência de poucos milissegundos — em hardware automotivo limitado e em condições absurdas de operação.

Por que essa medida importa para quem trabalha com tech

Na minha experiência lidando com pipelines de visão computacional, posso dizer: um DMS de produção não é um cv2.CascadeClassifier jogado num Raspberry Pi. É um sistema que precisa sobreviver a óculos escuros, máscaras, variação de luz brutal, motorista com olhos puxados (estamos falando do Japão, lembra?), criança no banco de trás bloqueando parcialmente a câmera e reflexos no para-brisa.

E o pior de tudo: tudo isso com falsos positivos mínimos, porque ninguém quer um carro que apita toda vez que você olha para o velocímetro. Esse trade-off entre sensibilidade e especificidade é exatamente o tipo de problema que devs de ML passam noites resolvendo.

A stack técnica real por trás de um DMS moderno

Quando você olha sistemas como o EyeSight da Subaru, o Driver Attention Monitor da Honda ou o sistema que a UE já implementou efetivamente este verão, a stack costuma ser surpreendentemente parecida:

  • Câmera IR (infravermelha) — opera em ~850nm ou 940nm, invisível ao olho humano, funciona bem à noite e atravessa a maioria dos óculos de sol
  • Sensor ToF ou estéreo (em sistemas premium) — para estimar distância e posição 3D da cabeça
  • SoC dedicado — chips como o TDA4VM da Texas Instruments ou soluções da NXP e Renesas, otimizados para visão e baixo consumo (5–15W)
  • Modelo de IA — CNN leve (MobileNet, EfficientNet customizada) rodando detecção de landmarks faciais com inferência a 30–60 FPS
  • Algoritmo de gaze estimation — calcula o vetor de olhar a partir dos landmarks oculares e da pose da cabeça
  • Classificador de estado — determina se o motorista está atento, distraído, dormindo ou ausente

Esse último classificador é o mais interessante tecnicamente. Geralmente é um modelo temporal — não basta o frame atual. Ele analisa os últimos 2–3 segundos para detectar padrões como piscadas longas (microsleep), desvios sustentados de olhar ou sinais de fadiga. Modelos baseados em LSTM ou Transformer leve já dominam essa camada.

Por que IR e não RGB? A resposta técnica

Você pode perguntar: “Por que não usar uma câmera RGB normal, que é mais barata?” A resposta vem em três cenários que matam qualquer sistema RGB:

  1. Noturno: sem luz, a câmera RGB vira cega. IR ilumina o rosto com LEDs próprios.
  2. Luz solar direta: o rosto fica estourado ou subexposto. IR ignora luz visível.
  3. Óculos de sol polarizados: muitos óculos bloqueiam luz visível quase totalmente. IR atravessa a maioria dos filtros comerciais.

Subaru, BMW, Mercedes e Volvo já usam IR há anos. Tesla, curiosamente, ainda usa uma câmera RGB no cabin camera e tem desempenho pior em condições adversas — o Japão, ao exigir DMS como baseline, está implicitamente forçando o padrão IR como novo mínimo regulatório.

Na Prática: implementando um protótipo de eye tracking com Python

Quer entender como isso funciona de verdade? Vou te mostrar um protótipo funcional usando MediaPipe Face Mesh da Google, que entrega 468 landmarks faciais incluindo os contornos dos olhos e íris. Você consegue testar isso no seu notebook em 10 minutos.

import cv2
import mediapipe as mp
import numpy as np
from scipy.spatial import distance as dist

# Inicializa MediaPipe Face Mesh
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(
    max_num_faces=1,
    refine_landmarks=True,  # habilita landmarks de íris
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5
)

# Índices dos landmarks ao redor dos olhos (Face Mesh)
LEFT_EYE = [362, 382, 381, 380, 374, 373, 390, 249, 263, 466, 388, 387, 386, 385, 384, 398]
RIGHT_EYE = [33, 7, 163, 144, 145, 153, 154, 155, 133, 173, 157, 158, 159, 160, 161, 246]

def eye_aspect_ratio(eye_landmarks):
    """Calcula o EAR (Eye Aspect Ratio) usado para detectar piscadas."""
    v1 = dist.euclidean(eye_landmarks[1], eye_landmarks[5])
    v2 = dist.euclidean(eye_landmarks[2], eye_landmarks[4])
    h  = dist.euclidean(eye_landmarks[0], eye_landmarks[3])
    return (v1 + v2) / (2.0 * h)

def get_gaze_direction(iris_center, eye_corners):
    """Estima direção do olhar baseado na posição da íris."""
    eye_left, eye_right = eye_corners
    eye_width = eye_right[0] - eye_left[0]
    if eye_width == 0:
        return "indeterminado"
    ratio = (iris_center[0] - eye_left[0]) / eye_width
    if ratio < 0.35: return "esquerda"
    if ratio > 0.65: return "direita"
    return "frente"

# Parâmetros de detecção de sono/distração
EAR_THRESHOLD = 0.21
CONSEC_FRAMES = 30
counter = 0

cap = cv2.VideoCapture(0)
while cap.isOpened():
    ret, frame = cap.read()
    if not ret: break
    rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    results = face_mesh.process(rgb)

    if results.multi_face_landmarks:
        lm = results.multi_face_landmarks[0].landmark
        h, w = frame.shape[:2]

        left_eye  = [(int(lm[i].x*w), int(lm[i].y*h)) for i in LEFT_EYE[:6]]
        right_eye = [(int(lm[i].x*w), int(lm[i].y*h)) for i in RIGHT_EYE[:6]]
        ear = (eye_aspect_ratio(left_eye) + eye_aspect_ratio(right_eye)) / 2.0

        iris = (
            int((lm[468].x + lm[473].x) / 2 * w),
            int((lm[468].y + lm[473].y) / 2 * h)
        )
        corners = ((int(lm[33].x*w),  int(lm[33].y*h)),
                   (int(lm[263].x*w), int(lm[263].y*h)))
        gaze = get_gaze_direction(iris, corners)

        if ear < EAR_THRESHOLD:
            counter += 1
            if counter >= CONSEC_FRAMES:
                cv2.putText(frame, "ALERTA: SONO DETECTADO!", (10, 30),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
        else:
            counter = 0

        cv2.putText(frame, f"EAR: {ear:.2f} | Olhar: {gaze}",
                    (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2)
        cv2.circle(frame, iris, 3, (0, 255, 0), -1)

    cv2.imshow("DMS Prototype", frame)
    if cv2.waitKey(5) & 0xFF == ord('q'): break

cap.release()
cv2.destroyAllWindows()

Esse é o esqueleto de um DMS real. Em produção, você ainda adicionaria:

  • Filtro de Kalman para suavizar a estimativa de gaze entre frames
  • Modelo temporal (LSTM/Transformer) ao invés de threshold fixo para EAR
  • Compensação de pose de cabeça (yaw, pitch, roll) com solvePnP
  • Calibração individual por motorista nos primeiros 30 segundos
  • Treinamento com datasets diversos (etnia, óculos, idade, iluminação)

Erros comuns que devs cometem ao implementar DMS

1. Usar RGB achando que “é mais barato”

Vi projetos que tentaram economizar com webcam normal. Resultado: falha total à noite, sensibilidade absurda à luz do sol e falso positivo toda vez que o motorista coloca óculos escuros. IR não é opcional em produção automotiva — é requisito.

2. Confiar cegamente no threshold fixo de EAR

O EAR_THRESHOLD = 0.21 que coloquei no exemplo é didático, não realista. Cada pessoa tem um EAR baseline diferente, e ele varia com iluminação, câmera e ângulo. Você precisa de calibração por usuário ou de um modelo adaptativo. Sistemas sérios usam redes neurais profundas treinadas em datasets como UTA-RLDD, Driver Drowsiness Dataset ou YawDD.

3. Ignorar a distração cognitiva (“off-road gaze”)

O olho pode estar aberto e olhando fixamente a estrada, mas o motorista está pensando em outra coisa (conversa hands-free, preocupação pessoal, sonolento mas acordado). Por isso DMS modernos monitoram tempo contínuo de foco na estrada — se você passa mais de 3 segundos sem olhar para a região frontal do painel, mesmo com olhos abertos, dispara alerta. Isso é muito mais difícil de detectar do que olhos fechados e exige modelos temporais.

4. Subestimar latência de inferência

Se seu pipeline leva 200ms para detectar que o motorista está distraído, e o carro está a 90km/h, ele percorreu 5 metros nesse tempo. Em sistemas ADAS, latência acima de 100ms é inaceitável. É por isso que DMS usa chips especializados e modelos quantizados (INT8 ou INT4), muitas vezes compilados com TensorRT ou ONNX Runtime Mobile.

5. Tratar privacidade como afterthought

Esse é o ponto mais delicado. Um sistema grava imagens do seu rosto continuamente. Quem tem acesso? Onde ficam armazenados? São processados localmente ou enviados para a nuvem? A UE já exige processamento local e anonimização. O Japão, ao copiar o modelo, deve seguir o mesmo caminho. Para devs, isso significa projetar com privacy-by-design: nada de imagem bruta saindo do dispositivo, só metadados (EAR, gaze vector, estado). Vale ler o GDPR automotivo e a ISO 21434 antes de começar.

Implicações para o ecossistema dev

Quando uma regulação como essa entra em vigor, ela cria ondas em várias direções:

  • Demanda por engenheiros de visão computacional embarcada — uma das áreas mais carentes no Brasil e no mundo
  • Crescimento de datasets de fadiga e distração ao volante — oportunidade para projetos acadêmicos, startups e competições tipo Kaggle
  • Explosão de edge AI automotiva — chips como Jetson Orin Nano, Google Coral e SoCs automotivos vão bombar
  • Pipelines de privacidade veicular — anonimização, federated learning e differential privacy aplicados a telemetria
  • Otimização de modelos — TinyML, quantização, pruning, distillation viraram habilidades obrigatórias

Se você é dev e quer surfar essa onda, comece estudando MediaPipe e OpenCV, depois mergulhe em modelos robustos de gaze estimation como ETH-XGaze, GazeFollow e o paper Few-Shot Gaze Estimation. Tem material de qualidade zero disponível e o mercado está aquecido.

Perguntas frequentes (FAQ)

DMS é a mesma coisa que ADAS?

Não. ADAS (Advanced Driver Assistance Systems) é o guarda-chuva que inclui controle de cruzeiro adaptativo, frenagem automática, detecção de faixa e companhia. DMS é um módulo específico dentro do ADAS, focado em monitorar o condutor — e não o ambiente externo.

É possível burlar um DMS cobrindo a câmera?

Tecnicamente sim, mas o sistema detecta isso (ausência de face por X segundos dispara alerta crítico). E cobrir intencionalmente pode ser considerado adulteração, com implicações legais e perda de garantia do veículo.

Modelos mais antigos (pré-2031) precisam ser adaptados?

Não obrigatoriamente. Segundo a reportagem do Sapo.pt, carros já em produção com homologação anterior têm um período de transição até 2033. Depois disso, todos os modelos vendidos no Japão precisarão ter o sistema integrado de fábrica.

Qual a diferença entre o DMS do Japão e o da UE?

A UE implementou efetivamente este verão (2024), com foco mais em atenção direta — olhos fechados e uso de celular. O Japão está adotando abordagem mais ampla, incluindo fadiga e distração cognitiva, com cronograma mais longo (entra em vigor em 2031) para permitir adaptação da indústria.

Esse sistema funciona bem com máscaras e óculos de sol?

Justamente por isso câmeras IR são obrigatórias. Elas enxergam através da maioria dos óculos escuros comerciais e funcionam bem mesmo com máscara, já que o que importa para gaze tracking são os olhos — não a boca.

Conclusão

O Japão, ao seguir o caminho da UE e tornar o DMS obrigatório, está muito mais do que protegendo motoristas. Está criando um mercado massivo para IA embarcada, visão computacional de baixo consumo e todo um ecossistema de privacidade veicular. Para quem é dev, é uma janela rara: uma regulação que vai gerar demanda qualificada pelos próximos 10 anos.

Na próxima vez que você ler sobre carros autônomos ou segurança viária, lembre-se: por trás de cada alerta sonoro no volante tem um modelo de IA rodando inferência contínua a 30 FPS, lutando contra oclusão, variação de luz e reflexos — tudo num chip que consome menos energia que uma lâmpada de LED. É isso que me fascina nessa área, e é isso que pouca gente enxerga quando o assunto aparece no noticiário.

Gostou? Me segue no GitHub e deixa um comentário se tiver dúvida ou quiser aprofundar algum ponto.

Y

Yuri Sousa

Front-End Developer / Designer

Desenvolvedor apaixonado por criar experiências digitais acessíveis e visualmente perfeitas. Escrevo sobre desenvolvimento web, design e tecnologia.