fix(label-studio): 图片 URL 按实际的 DOCUMENT_ROOT 生成(--document-root)
原先任务里的图片 URL 固定是 /data/local-files/?d=images/<图名>,隐含假设输出目录就是 LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT。服务器上 DOCUMENT_ROOT=/home/deep/labeling, Label Studio 会去找 /home/deep/labeling/images/<图名>,11211 张图全部 404。 - 新增 --document-root,缺省读 LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT;URL 写成相对它的 路径,Local files 存储路径随之算好并打印。 - 输出目录在 DOCUMENT_ROOT 之外时,在 DOCUMENT_ROOT 里建同名软链接指过去,产出仍留在 runs/,不用手动复制;DOCUMENT_ROOT 里已有同名真目录或指向别处的软链接时报错,不覆盖。 - 更正此前"软链接解析后会落到 DOCUMENT_ROOT 外面"的说法:核对 Label Studio 1.23.0 源码,safe_join 用 abspath、存储路径用 normpath 做字符串前缀比较,都不解析软链接。 - 测试照搬 localfiles_data() 的判定逐个任务验证能否被服务,并加入旧 URL 在 /home/deep/labeling 下全部 404 的回归用例。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
891f930de2
commit
7dd0f89d18
@@ -644,6 +644,26 @@ runs/boxes_shap_label_studio/ # 同时也是 Label Studio 的 DOCUMENT_ROOT
|
||||
|
||||
### 导入 Label Studio
|
||||
|
||||
**图片 URL 必须按 Label Studio 实际的 `DOCUMENT_ROOT` 生成。** 任务里写的是
|
||||
`/data/local-files/?d=<相对路径>/images/<图名>.png`,Label Studio 把 `d` 拼到
|
||||
`LABEL_STUDIO_LOCAL_FILES_DOCUMENT_ROOT` 后面找文件,相对路径错了就是整个项目 404。
|
||||
脚本缺省读这个环境变量,也可以用 `--document-root` 显式指定:
|
||||
|
||||
```bash
|
||||
# DOCUMENT_ROOT 统一放标注项目,产出仍留在 runs/
|
||||
uv run python scripts/prepare_label_studio.py --source runs/boxes_shap \
|
||||
--document-root /home/deep/labeling
|
||||
```
|
||||
|
||||
| 情形 | 做法 | 图片 URL |
|
||||
|---|---|---|
|
||||
| 没设 DOCUMENT_ROOT | 输出目录自己当 DOCUMENT_ROOT | `?d=images/…` |
|
||||
| 输出目录在 DOCUMENT_ROOT 之下 | 直接用 | `?d=<相对路径>/images/…` |
|
||||
| 输出目录在 DOCUMENT_ROOT 之外 | 在 DOCUMENT_ROOT 里建同名软链接指向它 | `?d=boxes_shap_label_studio/images/…` |
|
||||
|
||||
DOCUMENT_ROOT 里已有同名的**真目录**(比如手动复制过去的一份)时脚本会报错,不会覆盖它。
|
||||
Local files 存储的绝对路径填 `<DOCUMENT_ROOT>/<访问路径>/images`,脚本打印的步骤里已经算好。
|
||||
|
||||
脚本结束时会打印带实际路径的导入步骤:设置 `LABEL_STUDIO_LOCAL_FILES_*` 环境变量启动、
|
||||
粘贴 labeling config、添加 Local files 存储(**只保存不要 Sync**,否则每张图多出一个空任务)、
|
||||
导入 `tasks.json`。
|
||||
@@ -652,8 +672,10 @@ runs/boxes_shap_label_studio/ # 同时也是 Label Studio 的 DOCUMENT_ROOT
|
||||
|
||||
- **为什么是扁平结构**:`label-studio-converter import yolo` 只认 `<input>/{images,labels,classes.txt}`,
|
||||
且 `os.listdir` 不递归,看不见子目录。
|
||||
- **硬链接而不是软链接**:Label Studio 读本地文件时会检查路径是否在 `DOCUMENT_ROOT` 之下,
|
||||
软链接解析后可能落到外面。
|
||||
- **软链接可以用**:Label Studio(1.23.0 核对过源码)拼文件路径用 `safe_join`(`abspath`),
|
||||
存储路径做 `normpath` 后按字符串前缀比较,都**不解析软链接**,所以 DOCUMENT_ROOT 里放一个
|
||||
指向 `runs/` 的软链接就能访问,不必复制。存储路径也必须是 DOCUMENT_ROOT 的**子目录**,
|
||||
与 DOCUMENT_ROOT 相同会被拒绝,这正是要填到 `…/images` 的原因。
|
||||
- **框作为 predictions 而不是 annotations**:它们是模型生成的。审核员修改提交后才成为 annotation,
|
||||
哪些审过一目了然,导出时也只导出 annotation,没审过的框不会混进去。
|
||||
- **不传 `--image-dims`**:图片尺寸有 3,223 种,传了会把同一个宽高写进每条标注。
|
||||
|
||||
Reference in New Issue
Block a user