AI智能标注与检测平台
首次训练需要安装 Python 和 PyTorch(需联网,约 15 分钟)。
开箱即用的拍照检测页面,无需登录、无需 API Key。
页面地址:
微信扫一扫打开拍照检测页面
服务地址:
加载中...
| 端点 | POST /api/detect/json |
| Content-Type | application/json |
| image | String, base64编码图片 (可为 data:image 格式) |
| confidence | Float (可选, 默认0.35), 置信度阈值 |
| X-API-Key | 请求头传此值鉴权 |
| success | 是否成功 |
| annotated_url | 标注后全图路径 /crops/full_xxx.jpg |
| detections | 检测列表: label(阳性/阴性), confidence, crop_url |
| processing_time_ms | 推理耗时(毫秒) |
curl -X POST {API_URL}/api/detect/json \
-H "Content-Type: application/json" \
-H "X-API-Key: {YOUR_API_KEY}" \
-d '{
"image": "data:image/jpeg;base64,/9j/4AAQ...",
"confidence": 0.35
}'
async function detect(imageBase64, confidence = 0.35, apiKey) {
const res = await fetch('{API_URL}/api/detect/json', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey },
body: JSON.stringify({ image: imageBase64, confidence })
});
const data = await res.json();
if (!res.ok) throw new Error(data.error || data.message);
return data;
}
下面是一份可独立运行的 HTML 文件,适合嵌入到其他应用中。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Multi-Detect 拍照推理</title>
<style>
* { margin:0;padding:0;box-sizing:border-box; }
body { font-family:sans-serif;background:#1a1a2e;color:#e0e0e0;min-height:100vh;padding:20px; }
h1 { color:#e94560;margin-bottom:16px; }
.controls { display:flex;gap:12px;flex-wrap:wrap;margin-bottom:16px; }
button,input { padding:10px 20px;border:1px solid #0f3460;border-radius:6px;background:#16213e;color:#e0e0e0;cursor:pointer;font-size:14px; }
button:hover { border-color:#e94560; }
video { width:100%;max-width:480px;border-radius:8px;border:1px solid #0f3460; }
canvas { display:none; }
#result { margin-top:16px; }
#result img { max-width:100%;border-radius:8px;border:1px solid #0f3460; }
.crop-card { display:inline-block;margin:8px;background:#16213e;border-radius:8px;overflow:hidden;border:1px solid #0f3460;vertical-align:top; }
.crop-card img { width:200px;height:160px;object-fit:contain;display:block;background:#0d1120; }
.crop-card .info { padding:8px;font-size:13px; }
.crop-card .label { color:#e94560;font-weight:600; }
.crop-card .conf { color:#2ecc71; }
.status { color:#a0a0c0;font-size:13px;margin:8px 0; }
</style>
</head>
<body>
<h1>Multi-Detect 拍照推理</h1>
<div class="controls">
<button id="btn-camera">打开摄像头</button>
<button id="btn-capture" disabled>拍照检测</button>
<input type="file" id="file-input" accept="image/*">
</div>
<video id="video" autoplay playsinline></video>
<canvas id="canvas"></canvas>
<div class="status" id="status"></div>
<div id="result"></div>
<script>
const API_URL = '{API_URL}';
const API_KEY = '{YOUR_API_KEY}';
const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
document.getElementById('btn-camera').onclick = async () => {
const s = await navigator.mediaDevices.getUserMedia({ video: { facingMode:'environment' } });
video.srcObject = s; video.style.display = 'block';
document.getElementById('btn-capture').disabled = false;
};
document.getElementById('btn-capture').onclick = () => {
canvas.width = video.videoWidth; canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0);
detectWith(canvas.toDataURL('image/jpeg', 0.85));
};
document.getElementById('file-input').onchange = () => {
const f = document.getElementById('file-input').files[0];
if (!f) return;
const r = new FileReader();
r.onload = () => detectWith(r.result);
r.readAsDataURL(f);
};
async function detectWith(img) {
document.getElementById('status').textContent = '检测中...';
try {
const r = await fetch(API_URL + '/api/detect/json', {
method:'POST',
headers:{ 'Content-Type':'application/json', 'X-API-Key': API_KEY },
body: JSON.stringify({ image: img })
});
const d = await r.json();
if (d.success) {
document.getElementById('status').textContent = '完成 ' + d.processing_time_ms + 'ms';
let html = d.annotated_url ? '<img src="' + d.annotated_url + '">' : '';
if (d.detections) {
html += d.detections.map(x => {
const pct = x.confidence > 0 ? (x.confidence*100).toFixed(1)+'%' : '';
return '<div class="crop-card"><img src="'+x.crop_url+'"><div class="info"><span class="label">'+x.label+'</span><span class="conf">'+pct+'</span></div></div>';
}).join('');
}
document.getElementById('result').innerHTML = html;
} else throw new Error(d.error || '检测失败');
} catch(e) { document.getElementById('status').textContent = '错误: '+e.message; }
}
</script>
</body>
</html>
backend_data/images/ 目录backend_data/datasets/ 目录切换到训练标签页,系统会自动检测训练环境。如提示「Python 未安装」,点击「安装环境」按钮,系统将自动在线安装所需依赖(需联网,约 15 分钟)。
rotate_data.bat 生成旋转增强数据prepare_marking.bat 裁剪物品生成标记数据集| 轮数 | 训练迭代次数,推荐 500-1000 |
| 批次 | 每批处理的图片数,显存不足时降低(如 8 或 4) |
| 学习率 | 模型更新步长,默认 0.0005 适用于大多数场景 |
| 图片尺寸 | 输入分辨率,推荐 640,大尺寸需更多显存 |
训练过程中实时显示 Loss(损失值)和 mAP(平均精度)。Loss 持续下降、mAP 持续上升说明训练正常。
backend_data/crops/ 目录卡片上显示两个数值:左侧为物品检出置信度,色彩条为阴阳性分类置信度。绿色≥70%、黄色 40-70%、红色<40%。滑块只影响分类结果的显示门槛,不影响模型内部计算。
| Ctrl+S | 保存当前标注 |
| Ctrl+Z | 撤销上一个操作 |
| Delete | 删除选中的多边形 |
| 鼠标滚轮 | 缩放画布 / 灯箱图片放大缩小 |
| 空格+拖拽 | 平移画布 |
| 双击图片 | 灯箱中显示或闭合多边形 |
| Esc | 关闭弹窗 / 灯箱 |
train_yolo26.bat(脚本已内置 TDR 修复)。setup_training.bat 重新安装训练环境,或在 config.json 中手动配置 Python 路径。自定义项目在前端各处的显示名称。