Avaliação de Qualidade
O QualityChecker é a última etapa do pipeline. Avalia a qualidade da digital processada usando 3 métricas complementares.
Região de Análise
A avaliação usa o centro 85% da imagem (descartando 15% de margem):
margin = int(500 * 0.075) # 37px de cada lado
roi = canvas[margin:-margin, margin:-margin] # ~426x426Isso evita que o fundo cinza e bordas afetem as métricas.
Métricas
1. Sharpness (Nitidez)
Mede a nitidez geral usando a variância do Laplacian:
laplacian = cv2.Laplacian(roi, cv2.CV_64F)
sharpness = laplacian.var()- Alto (>500): Imagem nítida, cristas bem definidas
- Médio (100-500): Qualidade aceitável
- Baixo (<100): Imagem borrada, cristas indistinguíveis
O Laplacian detecta mudanças rápidas de intensidade — cristas papilares nítidas produzem alta variância.
2. Contrast (Contraste Local)
Mede a variação de intensidade em blocos locais de 32×32 pixels:
block_size = 32
stds = []
for y in range(0, h - block_size, block_size):
for x in range(0, w - block_size, block_size):
block = roi[y:y+block_size, x:x+block_size]
stds.append(block.std())
contrast = np.mean(stds)- Alto (>40): Bom contraste entre cristas e vales
- Médio (20-40): Contraste aceitável
- Baixo (<20): Pouca diferenciação — digital "lavada"
3. Ridge Clarity (Clareza das Cristas)
Usa filtros Gabor em 8 orientações para detectar padrões de crista:
orientations = np.arange(0, np.pi, np.pi / 8) # 0°, 22.5°, 45°, ... 157.5°
max_response = 0
for theta in orientations:
kernel = cv2.getGaborKernel(
ksize=(21, 21),
sigma=4.0,
theta=theta,
lambd=8.0, # frequência típica de cristas
gamma=0.5,
psi=0
)
response = cv2.filter2D(roi, cv2.CV_64F, kernel)
max_response = max(max_response, response.var())
ridge_clarity = max_responseFiltros Gabor são sintonizados na frequência e orientação das cristas papilares. A resposta máxima indica a presença de padrões regulares de crista.
- Alto (>500): Cristas claras e regulares
- Médio (100-500): Cristas parcialmente visíveis
- Baixo (<100): Sem padrão de crista detectável
Score Composto
As 3 métricas são normalizadas e combinadas com pesos iguais:
# Normalizar cada métrica para 0-50
s = min(sharpness / 100, 1.0) * 50 # sharpness / threshold × 50
c = min(contrast / 30, 1.0) * 50 # contrast / threshold × 50
r = min(ridge_clarity / 30, 1.0) * 50 # ridge_clarity / threshold × 50
# Score final 0-100
score = min(0.35 * s + 0.30 * c + 0.35 * r, 100.0)
# Pesos: 35% sharpness, 30% contrast, 35% ridge clarityInterpretação do Score
| Score | Classificação | Uso recomendado |
|---|---|---|
| 80-100 | Excelente | Comparação biométrica confiável |
| 60-80 | Bom | Adequado para a maioria dos usos |
| 40-60 | Aceitável | Uso limitado, recaptura recomendada |
| 0-40 | Insuficiente | Recaptura obrigatória |
O limiar padrão de aceitação é 40 (min_quality_score), configurável via variável de ambiente.
Parâmetros
| Parâmetro | Padrão | Efeito |
|---|---|---|
sharpness_threshold | 100.0 | Divisor para normalização de nitidez |
contrast_threshold | 30.0 | Divisor para normalização de contraste |
min_quality_score | 40.0 | Limiar para is_acceptable |