Relatório de Qualidade da Reconstrução
Visão Geral
O MipMapEngine SDK gera um relatório de qualidade detalhado após a conclusão das tarefas de reconstrução, contendo informações do dispositivo, eficiência de reconstrução, configurações de parâmetros e qualidade dos resultados. O relatório é armazenado no formato JSON no arquivo report/report.json, juntamente com miniaturas de visualização para visualização rápida.
Estrutura do Relatório
1. Informações do Dispositivo
Registra a configuração de hardware usada para reconstrução:
| Campo | Tipo | Descrição |
|---|---|---|
cpu_name | string | Nome da CPU |
gpu_name | string | Nome da GPU |
Exemplo:
{
"cpu_name": "Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz",
"gpu_name": "NVIDIA GeForce RTX 3080"
}
2. Eficiência da Reconstrução
Registra o tempo de processamento para cada etapa (em minutos):
| Campo | Tipo | Descrição |
|---|---|---|
feature_extraction_time | float | Tempo de extração de características |
feature_match_time | float | Tempo de correspondência de características |
sfm_time | float | Tempo de ajuste de feixe |
at_time | float | Tempo total de AT |
reconstruction_time | float | Tempo total de reconstrução (excluindo AT) |
Exemplo:
{
"feature_extraction_time": 12.5,
"feature_match_time": 8.3,
"sfm_time": 15.2,
"at_time": 36.0,
"reconstruction_time": 48.6
}
3. Parâmetros de Reconstrução
Registra os parâmetros de entrada da tarefa e configuração:
Parâmetros da Câmera
"initial_camera_parameters": [
{
"camera_name": "DJI_FC6310",
"width": 5472,
"height": 3648,
"id": 0,
"parameters": [3850.5, 2736, 1824, -0.02, 0.05, 0.001, -0.001, 0.01]
}
]
Ordem da matriz de parâmetros: [f, cx, cy, k1, k2, p1, p2, k3]
f: Distância focalcx, cy: Coordenadas do ponto principalk1, k2, k3: Coeficientes de distorção radialp1, p2: Coeficientes de distorção tangencial
Outros Parâmetros
| Campo | Tipo | Descrição |
|---|---|---|
input_camera_count | int | Contagem de câmeras de entrada |
input_image_count | int | Contagem de imagens de entrada |
reconstruction_level | int | Nível de reconstrução (1=Ultra-alto, 2=Alto, 3=Médio) |
production_type | string | Tipo de produto |
max_ram | float | Uso máximo de RAM (GB) |
Informações do Sistema de Coordenadas
"production_cs_3d": {
"epsg_code": 4326,
"origin_offset": [0, 0, 0],
"type": 2
}
Tipos de sistema de coordenadas:
- 0: LocalENU (Leste-Norte-Cima local)
- 1: Local (Sistema de coordenadas local)
- 2: Geodetic (Sistema de coordenadas geodésico)
- 3: Projected (Sistema de coordenadas projetado)
- 4: ECEF (Centrado na Terra-Fixo na Terra)
4. Resultados da Reconstrução
Parâmetros da Câmera após AT
Registra os parâmetros intrínsecos otimizados da câmera:
"AT_camera_parameters": [
{
"camera_name": "DJI_FC6310",
"width": 5472,
"height": 3648,
"id": 0,
"parameters": [3852.1, 2735.8, 1823.6, -0.019, 0.048, 0.0008, -0.0009, 0.009]
}
]
Diferenças de Posição da Imagem
Registra a otimização de posição para cada imagem:
"image_pos_diff": [
{
"id": 0,
"pos_diff": 0.125
},
{
"id": 1,
"pos_diff": 0.087
}
]
Métricas de Qualidade
| Campo | Tipo | Descrição |
|---|---|---|
removed_image_count | int | Imagens removidas após AT |
residual_rmse | float | RMSE de resíduos de pontos de imagem |
tie_point_count | int | Contagem de pontos de ligação |
scene_area | float | Área da cena (metros quadrados) |
scene_gsd | float | Distância de amostragem do solo (metros) |
flight_height | float | Altura de voo (metros) |
block_count | int | Contagem de blocos de reconstrução |
5. Outras Informações
| Campo | Tipo | Descrição |
|---|---|---|
sdk_version | string | Versão do SDK |
Miniaturas de Visualização
A pasta thumbnail no diretório do relatório contém os seguintes arquivos de visualização:
1. Gráfico de Resíduos da Câmera
camera_{id}_residual.png - Imagem colorida de 24 bits
- Bom resultado de calibração: Os resíduos são semelhantes em tamanho em todas as posições com direções aleatórias
- Mau resultado de calibração: Resíduos grandes com padrões direcionais óbvios
Resíduos grandes não indicam necessariamente baixa precisão geral, pois isso reflete apenas a precisão interna da câmera. A precisão final deve considerar de forma abrangente a precisão das coordenadas do ponto de controle e a qualidade do modelo.
2. Mapa de Sobreposição
overlap_map.png - Imagem em escala de cinza de 8 bits
- Faixa de valor do pixel: 0-255
- Pode ser renderizado como mapa de cores para mostrar distribuição de sobreposição
- Usado para avaliar o design do caminho de voo e a qualidade da cobertura de imagem
3. Miniatura da Área de Levantamento
rgb_thumbnail.jpg - Imagem colorida de 32 bits
- Para visualização rápida do projeto
- Mostra a extensão da área de levantamento e os resultados da reconstrução
Exemplos de Interpretação do Relatório
Exemplo de Relatório Completo
{
"cpu_name": "Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz",
"gpu_name": "NVIDIA GeForce RTX 3080",
"feature_extraction_time": 12.5,
"feature_match_time": 8.3,
"sfm_time": 15.2,
"at_time": 36.0,
"reconstruction_time": 48.6,
"initial_camera_parameters": [{
"camera_name": "DJI_FC6310",
"width": 5472,
"height": 3648,
"id": 0,
"parameters": [3850.5, 2736, 1824, -0.02, 0.05, 0.001, -0.001, 0.01]
}],
"input_camera_count": 1,
"input_image_count": 156,
"reconstruction_level": 2,
"production_type": "all",
"production_cs_3d": {
"epsg_code": 4326,
"origin_offset": [0, 0, 0],
"type": 2
},
"production_cs_2d": {
"epsg_code": 3857,
"origin_offset": [0, 0, 0],
"type": 3
},
"max_ram": 28.5,
"AT_camera_parameters": [{
"camera_name": "DJI_FC6310",
"width": 5472,
"height": 3648,
"id": 0,
"parameters": [3852.1, 2735.8, 1823.6, -0.019, 0.048, 0.0008, -0.0009, 0.009]
}],
"removed_image_count": 2,
"residual_rmse": 0.68,
"tie_point_count": 125840,
"scene_area": 850000.0,
"scene_gsd": 0.025,
"flight_height": 120.5,
"block_count": 1,
"sdk_version": "3.0.1"
}
Métricas de Avaliação de Qualidade
Padrões de Qualidade Excelente
residual_rmse< 1.0 pixelsremoved_image_count/input_image_count< 5%tie_point_count> 10000- Diferença média de posição < 0.5 metros
Situações que Requerem Atenção
residual_rmse> 2.0 pixels: Possíveis erros sistemáticosremoved_image_count> 10%: Problemas de qualidade de imagem ou sobreposiçãotie_point_count< 5000: Pontos de características insuficientes, afetando a precisão
Ferramentas de Análise de Relatório
Exemplo de Análise Python
import json
import numpy as np
def analyze_quality_report(report_path):
with open(report_path, 'r', encoding='utf-8') as f:
report = json.load(f)
# Calcular métricas de eficiência
total_time = report['at_time'] + report['reconstruction_time']
images_per_minute = report['input_image_count'] / total_time
# Calcular métricas de qualidade
removal_rate = report['removed_image_count'] / report['input_image_count']
avg_pos_diff = np.mean([item['pos_diff'] for item in report['image_pos_diff']])
# Gerar relatório de análise
analysis = {
'efficiency': {
'total_time_minutes': total_time,
'images_per_minute': images_per_minute,
'area_per_hour': report['scene_area'] / (total_time / 60)
},
'quality': {
'residual_rmse': report['residual_rmse'],
'removal_rate_percent': removal_rate * 100,
'avg_position_diff_meters': avg_pos_diff,
'tie_points_per_image': report['tie_point_count'] / report['input_image_count']
},
'scale': {
'area_sqm': report['scene_area'],
'gsd_cm': report['scene_gsd'] * 100,
'flight_height_m': report['flight_height']
}
}
return analysis
# Exemplo de uso
analysis = analyze_quality_report('report/report.json')
print(f"Eficiência de processamento: {analysis['efficiency']['images_per_minute']:.1f} imagens/minuto")
print(f"Resíduo médio: {analysis['quality']['residual_rmse']:.2f} pixels")
print(f"Resolução do solo: {analysis['scale']['gsd_cm']:.1f} cm")
Visualização do Relatório de Qualidade
import matplotlib.pyplot as plt
from PIL import Image
def visualize_quality_report(report_dir):
# Ler dados do relatório
with open(f'{report_dir}/report.json', 'r') as f:
report = json.load(f)
# Criar gráficos
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 1. Gráfico de pizza de distribuição de tempo
times = [
report['feature_extraction_time'],
report['feature_match_time'],
report['sfm_time'],
report['reconstruction_time']
]
labels = ['Extração de Características', 'Correspondência de Características', 'Ajuste de Feixe', 'Reconstrução 3D']
axes[0, 0].pie(times, labels=labels, autopct='%1.1f%%')
axes[0, 0].set_title('Distribuição do Tempo de Processamento')
# 2. Histograma de diferença de posição
pos_diffs = [item['pos_diff'] for item in report['image_pos_diff']]
axes[0, 1].hist(pos_diffs, bins=20, edgecolor='black')
axes[0, 1].set_xlabel('Diferença de Posição (metros)')
axes[0, 1].set_ylabel('Contagem de Imagens')
axes[0, 1].set_title('Distribuição de Otimização de Posição de Imagem')
# 3. Mapa de sobreposição
overlap_img = Image.open(f'{report_dir}/thumbnail/overlap_map.png')
axes[1, 0].imshow(overlap_img, cmap='jet')
axes[1, 0].set_title('Distribuição de Sobreposição de Imagens')
axes[1, 0].axis('off')
# 4. Texto de métricas-chave
metrics_text = f"""
Imagens de entrada: {report['input_image_count']}
Imagens removidas: {report['removed_image_count']}
RMSE de resíduos: {report['residual_rmse']:.2f} px
Pontos de ligação: {report['tie_point_count']:,}
Área da cena: {report['scene_area']/10000:.1f} hectares
Resolução do solo: {report['scene_gsd']*100:.1f} cm
"""
axes[1, 1].text(0.1, 0.5, metrics_text, fontsize=12,
verticalalignment='center', family='monospace')
axes[1, 1].set_title('Métricas-Chave de Qualidade')
axes[1, 1].axis('off')
plt.tight_layout()
plt.savefig('quality_report_summary.png', dpi=150)
plt.show()
Verificação Automática de Qualidade
Configuração de Limiares de Qualidade
QUALITY_THRESHOLDS = {
'excellent': {
'residual_rmse': 0.5,
'removal_rate': 0.02,
'tie_points_per_image': 1000,
'pos_diff_avg': 0.1
},
'good': {
'residual_rmse': 1.0,
'removal_rate': 0.05,
'tie_points_per_image': 500,
'pos_diff_avg': 0.5
},
'acceptable': {
'residual_rmse': 2.0,
'removal_rate': 0.10,
'tie_points_per_image': 200,
'pos_diff_avg': 1.0
}
}
def assess_quality(report):
"""Avaliar automaticamente o nível de qualidade da reconstrução"""
# Calcular métricas
removal_rate = report['removed_image_count'] / report['input_image_count']
tie_points_per_image = report['tie_point_count'] / report['input_image_count']
pos_diff_avg = np.mean([item['pos_diff'] for item in report['image_pos_diff']])
# Avaliar nível
for level, thresholds in QUALITY_THRESHOLDS.items():
if (report['residual_rmse'] <= thresholds['residual_rmse'] and
removal_rate <= thresholds['removal_rate'] and
tie_points_per_image >= thresholds['tie_points_per_image'] and
pos_diff_avg <= thresholds['pos_diff_avg']):
return level
return 'poor'
Aplicações de Integração de Relatório
Monitoramento de Qualidade de Processamento em Lote
def batch_quality_monitor(project_dirs):
"""Monitoramento de qualidade de projeto em lote"""
results = []
for project_dir in project_dirs:
report_path = os.path.join(project_dir, 'report/report.json')
if os.path.exists(report_path):
with open(report_path, 'r') as f:
report = json.load(f)
quality_level = assess_quality(report)
results.append({
'project': project_dir,
'images': report['input_image_count'],
'area': report['scene_area'],
'gsd': report['scene_gsd'],
'rmse': report['residual_rmse'],
'quality': quality_level,
'time': report['at_time'] + report['reconstruction_time']
})
# Gerar relatório resumo
df = pd.DataFrame(results)
df.to_csv('batch_quality_report.csv', index=False)
# Estatísticas
print(f"Total de projetos: {len(results)}")
print(f"Excelente: {len(df[df['quality'] == 'excellent'])}")
print(f"Bom: {len(df[df['quality'] == 'good'])}")
print(f"Aceitável: {len(df[df['quality'] == 'acceptable'])}")
print(f"Ruim: {len(df[df['quality'] == 'poor'])}")
return df
Melhores Práticas
- Verificações regulares de relatório: Revisar métricas de qualidade após cada reconstrução
- Estabelecer linhas de base: Registrar métricas de qualidade de projetos típicos como referências
- Alertas de anomalias: Configurar scripts automatizados para detectar métricas anormais
- Análise de tendências: Rastrear tendências de métricas de qualidade ao longo do tempo
- Sugestões de otimização: Ajustar parâmetros de captura e processamento com base nas métricas do relatório
Dica: O relatório de qualidade é uma ferramenta importante para avaliar e otimizar fluxos de trabalho de reconstrução. É recomendado integrá-lo em fluxos de trabalho automatizados.