Segmentação
O FingerSegmenter é a segunda etapa do pipeline. Isola o dedo do fundo da imagem, removendo background, outros dedos e artefatos.
Algoritmo
1. Expansão e Crop
A bounding box da detecção de pele é expandida em 35% (bbox_expand) para garantir contexto suficiente para o GrabCut:
# Expandir bbox
expanded = expand_bbox(bbox, factor=0.35, image_shape=bgr.shape)
# Recortar a região
crop = bgr[y:y+h, x:x+w]
skin_crop = skin_mask[y:y+h, x:x+w]2. GrabCut (Principal)
O GrabCut é um algoritmo iterativo de segmentação que modela foreground e background como Gaussian Mixture Models:
# Inicializar máscara GrabCut com hints da detecção de pele
gc_mask = np.full(crop.shape[:2], cv2.GC_PR_BGD, dtype=np.uint8)
gc_mask[skin_crop > 0] = cv2.GC_PR_FGD # pele = provável foreground
# Forçar borda como background definitivo
gc_mask[:5, :] = cv2.GC_BGD
gc_mask[-5:, :] = cv2.GC_BGD
gc_mask[:, :5] = cv2.GC_BGD
gc_mask[:, -5:] = cv2.GC_BGD
# Executar GrabCut (5 iterações)
bgd_model = np.zeros((1, 65), np.float64)
fgd_model = np.zeros((1, 65), np.float64)
cv2.grabCut(crop, gc_mask, None, bgd_model, fgd_model, 5, cv2.GC_INIT_WITH_MASK)
# Extrair foreground
finger_mask = np.where(
(gc_mask == cv2.GC_FGD) | (gc_mask == cv2.GC_PR_FGD), 255, 0
).astype(np.uint8)3. Fallback Morfológico
Se o GrabCut falhar (exceção ou resultado vazio), usa processamento morfológico:
# Fallback: erosão + dilatação da máscara de pele
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
finger_mask = cv2.erode(skin_crop, kernel, iterations=2)
finger_mask = cv2.dilate(finger_mask, kernel, iterations=2)4. Seleção do Contorno do Dedo
Com vários contornos no foreground, seleciona o mais "parecido com um dedo":
# Score = área × aspect ratio
for contour in contours:
area = cv2.contourArea(contour)
x, y, w, h = cv2.boundingRect(contour)
aspect = max(w, h) / max(min(w, h), 1)
score = area * aspect # favorece formas alongadasO contorno com maior score é selecionado e usado como máscara binária final.
5. Validação
Verifica que o foreground cobre pelo menos 2% do crop. Se for menor, lança SegmentationError.
Parâmetros
| Parâmetro | Padrão | Efeito |
|---|---|---|
bbox_expand | 0.35 | Mais contexto para o GrabCut |
grabcut_iters | 5 | Mais iterações = mais preciso, mais lento |
use_grabcut | true | false usa apenas morfologia (mais rápido) |
Saída
crop: Imagem BGR recortada da região do dedofinger_mask: Máscara binária do dedo isolado
Performance
| Método | Tempo (640x480) | Precisão |
|---|---|---|
| GrabCut (5 iters) | ~200ms | Alta |
| Morfologia (fallback) | ~5ms | Média |
TIP
Para aplicações em tempo real ou com restrições de CPU, desative o GrabCut com FINGERPRINT_USE_GRABCUT=false. A segmentação morfológica é 40x mais rápida, com qualidade razoável.