246 lines
11 KiB
HTML
246 lines
11 KiB
HTML
{% extends "layout.html" %}
|
|
|
|
{% block content %}
|
|
<div class="container">
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<nav aria-label="breadcrumb" class="mb-3">
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{{ url_for('index') }}"><i class="bi bi-house"></i> 首页</a></li>
|
|
<li class="breadcrumb-item active" aria-current="page"><i class="bi bi-file-earmark-text"></i> 检测报告</li>
|
|
</ol>
|
|
</nav>
|
|
|
|
<div class="card">
|
|
<div class="card-header bg-dark text-white d-flex justify-content-between align-items-center">
|
|
<h5 class="card-title mb-0"><i class="bi bi-clipboard-data"></i> 检测报告详情</h5>
|
|
<a href="{{ url_for('index') }}" class="btn btn-sm btn-outline-light"><i class="bi bi-arrow-left"></i> 返回</a>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="report-info-card">
|
|
<h6 class="border-bottom pb-2 mb-3"><i class="bi bi-info-circle"></i> 基本信息</h6>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="info-item">
|
|
<span class="info-label"><i class="bi bi-calendar-event"></i> 检测时间:</span>
|
|
<span class="info-value">{{ report.timestamp }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="info-item">
|
|
<span class="info-label"><i class="bi bi-box-seam"></i> 使用模型:</span>
|
|
<span class="info-value">{{ report.model_path }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-3">
|
|
<div class="col-md-6">
|
|
<div class="info-item">
|
|
<span class="info-label"><i class="bi bi-sliders"></i> 置信度阈值:</span>
|
|
<span class="info-value">{{ report.confidence_threshold }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="info-item">
|
|
<span class="info-label"><i class="bi bi-film"></i> 处理视频数量:</span>
|
|
<span class="info-value">{{ report.statistics.total_videos }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-3">
|
|
<div class="col-md-6">
|
|
<div class="info-item">
|
|
<span class="info-label"><i class="bi bi-images"></i> 总帧数:</span>
|
|
<span class="info-value">{{ report.statistics.total_frames }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="info-item">
|
|
<span class="info-label"><i class="bi bi-eye"></i> 检测帧数:</span>
|
|
<span class="info-value">{{ report.statistics.detected_frames }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="report-stats-card">
|
|
<h6 class="border-bottom pb-2 mb-3"><i class="bi bi-bar-chart"></i> 检测统计</h6>
|
|
<div class="chart-container">
|
|
<canvas id="detectionChart"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h4>检测统计</h4>
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<canvas id="detectionChart"></canvas>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<canvas id="framesChart"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header bg-dark text-white">
|
|
<h5 class="card-title mb-0"><i class="bi bi-camera-video"></i> 视频检测结果</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="table-responsive">
|
|
<table class="table table-striped table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th><i class="bi bi-film"></i> 视频名称</th>
|
|
<th><i class="bi bi-images"></i> 总帧数</th>
|
|
<th><i class="bi bi-eye"></i> 检测帧数</th>
|
|
<th><i class="bi bi-bar-chart"></i> 检测率</th>
|
|
<th><i class="bi bi-gear"></i> 操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for video in report.statistics.detection_results %}
|
|
<tr>
|
|
<td>{{ video.video_name }}</td>
|
|
<td>{{ video.total_frames }}</td>
|
|
<td>{{ video.detections|length }}</td>
|
|
<td>
|
|
{% if video.total_frames %}
|
|
{% set detection_rate = (video.detections|length / video.total_frames * 100)|round(2) %}
|
|
<div class="progress" style="height: 20px;">
|
|
<div class="progress-bar {% if detection_rate < 5 %}bg-success{% elif detection_rate < 15 %}bg-warning{% else %}bg-danger{% endif %}"
|
|
role="progressbar" style="width: {{ detection_rate }}%;"
|
|
aria-valuenow="{{ detection_rate }}" aria-valuemin="0" aria-valuemax="100">
|
|
{{ detection_rate }}%
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
-
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<a href="{{ url_for('view_video_results', video_folder=video.video_name.split('.')[0]) }}" class="btn btn-sm btn-primary">
|
|
<i class="bi bi-search"></i> 查看详情
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
// 检测统计图表
|
|
const detectionCtx = document.getElementById('detectionChart').getContext('2d');
|
|
const framesCtx = document.getElementById('framesChart').getContext('2d');
|
|
|
|
// 计算检测到的各类别数量
|
|
const classStats = {};
|
|
{% for video in report.statistics.detection_results %}
|
|
{% for detection in video.detections %}
|
|
{% for item in detection.detections %}
|
|
const classId = item.class_id;
|
|
const className = item.class_name;
|
|
if (!classStats[classId]) {
|
|
classStats[classId] = {
|
|
count: 0,
|
|
name: className
|
|
};
|
|
}
|
|
classStats[classId].count += 1;
|
|
{% endfor %}
|
|
{% endfor %}
|
|
{% endfor %}
|
|
|
|
// 准备图表数据
|
|
const classLabels = [];
|
|
const classCounts = [];
|
|
for (const classId in classStats) {
|
|
classLabels.push(classStats[classId].name);
|
|
classCounts.push(classStats[classId].count);
|
|
}
|
|
|
|
// 创建检测类别分布图表
|
|
new Chart(detectionCtx, {
|
|
type: 'pie',
|
|
data: {
|
|
labels: classLabels,
|
|
datasets: [{
|
|
label: '检测数量',
|
|
data: classCounts,
|
|
backgroundColor: [
|
|
'rgba(255, 99, 132, 0.7)',
|
|
'rgba(54, 162, 235, 0.7)',
|
|
'rgba(255, 206, 86, 0.7)',
|
|
'rgba(75, 192, 192, 0.7)',
|
|
'rgba(153, 102, 255, 0.7)'
|
|
],
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
plugins: {
|
|
title: {
|
|
display: true,
|
|
text: '检测类别分布'
|
|
},
|
|
legend: {
|
|
position: 'bottom'
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// 创建帧统计图表
|
|
new Chart(framesCtx, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: ['总帧数', '检测帧数', '保存帧数'],
|
|
datasets: [{
|
|
label: '帧数统计',
|
|
data: [
|
|
{{ report.statistics.total_frames }},
|
|
{{ report.statistics.detected_frames }},
|
|
{{ report.statistics.saved_frames }}
|
|
],
|
|
backgroundColor: [
|
|
'rgba(54, 162, 235, 0.7)',
|
|
'rgba(255, 99, 132, 0.7)',
|
|
'rgba(75, 192, 192, 0.7)'
|
|
],
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
plugins: {
|
|
title: {
|
|
display: true,
|
|
text: '帧处理统计'
|
|
},
|
|
legend: {
|
|
display: false
|
|
}
|
|
},
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true
|
|
}
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %} |