红外相机数据整理
准备、组织数据
数据路径结构
数据必须以下述的文件结构进行存放。
|- project_name
| |- collection_name_1
| |- deployment_name_1
| |- sub_dir
| |- filename_1
| |- filename_1
| |- filename_2
| |- filename_3
| |- deployment_name_2
| |- filename_1
| |- filename_2
| |- filename_3
| |- ...
| |- trap_info.csv
| |- collection_name_2
| |- deployment_name_1
| |- ...
| |- ...
| |- trap_info.csv
| |- ...
注
此步中 deployment 路径下可以有子路径,后者在后续步骤(serval align
)中会被合并至 deployment 路径中(如 deployment_name_1/sub_dir/filename_1 会被合并为 deployment_name_1/sub_dir-filename_1)。
数据文件命名
不存在强制的命名规则, 但推荐遵照 文件命名习惯 对数据文件、路径进行命名.
数据路径示例
|- Yunta
| |- 202009-202012
| |- 4001
| |- IMAG0001.JPG
| |- IMAG0002.JPG
| |- IMAG0003.JPG
| |- YT_TQL
| |- IMAA0001.JPG
| |- IMAA0002.JPG
| |- ...
| |- trap_info.csv
| |- 202101-202004
| |- 4001
| |- ...
| |- ...
| |- trap_info.csv
| |- ...
trap_info
推荐使用脚本自动生成带有 deployment 信息的 trap_info 模板。
数据预处理
注意
此节内容为进入 trapper 工作流 的前置内容,部分操作会对文件名、路径结构进行变动,操作前请确认;如无需关心 trapper 入库流程,可跳过并直接阅读 Tag 相关处理方法
重命名 deployment
使用 serval rename
对 deployment 进行重命名 (即从 deployment_name 到 deployment_id,具体可参见文件命名习惯中的 deployment_name 部分)。
提示
可先使用 --dryrun
选项预览将要进行的重命名, 如
生成 deployments table
使用脚本处理、合并(多个 collection 时)trap_info,生成deployments table (deployments.csv)。
整理 resource 路径结构
使用 serval align 调整 deployment 下的路径结构(将 deployment 下所有子路径中的文件拆出并重命名)。
例
注
跨平台数据处理时,若路径名、文件名中存在中文字符,可能会引入潜在的解码问题(如使用 trapper client 进行打包),故推荐在此步时完成编码统一。
Linux 用户可直接用 convmv
统一编码至 UTF-8,如 convmv -f gbk -t utf-8 -r -i /path/to/data --notest
以上步骤均完成后,即可得到如下的数据路径结构,可继续进行 Trapper 工作流
|- project_name
| |- collection_name_1
| |- deployment_id_1
| |- sub_dir-filename_a
| |- filename_a
| |- filename_b
| |- filename_c
| |- deployment_id_2
| |- filename_d
| |- filename_e
| |- filename_f
| |- ...
| |- collection_name_2
| |- deployment_id_3
| |- ...
| |- ...
| |- ...
|- deployments.csv
Tag 相关处理方法
简单介绍一下 serval 中媒体 tag 相关功能。
提示
使用 serval --help
(或直接使用 serval
) 可查看帮助文档,子命令同理,如 serval observe --help
(或直接 serval observe
);使用 serval --version
可查看当前版本号。
教程
如需 更傻瓜、更人话、图文并茂、Windows 友好的 教程,可出门左转鹀老师懒人指南。
注
默认文件编码为 UTF-8,即 serval 只接受 UTF-8 编码的输入文件,生成 UTF-8 编码的输出文件。 对非 UTF-8 编码的输入文件(如独立捕获分析时使用非 serval 生成的 csv 文件),需转换成 UTF-8 编码后输入,比如使用 Excel或使用记事本
从文件中提取 tag
使用 observe
子命令可从(digikam 打标签流程后的)媒体或 xmp 文件中读取物种、个体 tag 及时间信息
输入 serval observe
查看使用方法:
Usage: serval observe [OPTIONS] <MEDIA_DIR>
Arguments:
<MEDIA_DIR>
Options:
-o, --output <OUTPUT_DIR> Output directory [default: ./serval_output/serval_observe]
-x, --xmp Read from XMP files
-s, --subject Include Subject metadata
-m, --modified-time Include file modified time
--video Video only
--image Image only
-d, --debug Debug mode
-i, --independent Temporal independence analysis after retrieving
-h, --help Print help
相关选项解释如下:
--output, -o
需在--output
(或 -o
) 选项后提供结果的输出路径,默认值为./serval_observe
(即当前工作路径下的 serval_observe),路径不存在时程序会自动创建
--xmp
从 xmp 文件(.xmp)中读取 tag
--subject
读取 metadata 中 Subject 内容(针对部分旧数据)
--modified-time
同时读取文件的修改时间(用于补充分析部分媒体时间)
--image
只读取图片文件中的 tag
--video
只读取视频文件中的 tag
--debug
Debug 模式
--independent, -i
读取结束后自动启动独立捕获分析
示例
该命令会遍历目标路径(/mnt/data/diqing
)中的所有目标文件(默认为图片和视频)并提取元数据中的物种、个体 tag(Xmp.digiKam.Tagslist)和时间信息(DateTimeOriginal、DateTimeDigitized),结果(tags.csv)会输出到指定路径(/mnt/data/diqing/tag-info
)中,指定路径不存在时 serval 会自动创建。
从 xmp 文件中提取 tag,提取结束后进入独立捕获分析流程。
独立捕获分析
基于 serval observe
输出的 tags.csv
进行独立捕获分析。
提示
对于非 serval observe
输出的 csv 文件,用户可按 tags.csv 的格式编辑后进行独立捕获分析,但需注意:
- 所需的 csv 文件表头为 path, datetime_original, species(或 individual)
- path 的作用是区分 deployment,须为符合平台路径规范的文件路径(如 Windows 下的
C:\data\demo\deployment_name
,注意路径分隔符为\
) - datetime_original 的格式为
yyyy-mm-dd HH:MM:SS
,如2024-04-15 05:47:41
(而不是2024-4-15 5:47:41
)
使用方法为:
Usage: serval capture [OPTIONS] <CSV_PATH>
Arguments:
<CSV_PATH> Path for tags.csv
Options:
-o, --output <OUTPUT_DIR> Output directory [default: ./serval_capture]
-h, --help Print help
示例
> serval capture ./test/tags_merge.csv --output ./test/demo
Input the Minimum Time Difference (when considering records as independent) in minutes (e.g. 30): 30
The Minimum Time Difference should be compared with?
1) Last independent record 2) Last record
Enter a selection (e.g. 1): 1
Perform analysis on:
1) species 2) individual
Enter a selection: 1
Here is a sample of the file path (/home/wsyxbcl/Documents/Jiatang_volunteer_data/JT_trapper/JiaTang-align/JT202311-202401/bs02_20231211-20231219_jt202311-202401/BS02_20231211-20231219_JT202311-202401-BS020001.JPG.xmp)
1): home
2): wsyxbcl
3): Documents
4): Jiatang_volunteer_data
5): JT_trapper
6): JiaTang-align
7): JT202311-202401
8): bs02_20231211-20231219_jt202311-202401
Select the number corresponding to the deployment: 8
shape: (2_546, 4)
[snip]
Saved to ./test/demo/Species_temporal_independent.csv
shape: (579, 3)
[snip]
Saved to ./test/demo/Species_temporal_independent_count.csv
基于 tag 提取媒体文件
serval extract
命令可根据目标 tag 对媒体进行筛选,并复制至指定路径,复制时可保持原有的路径结构以方便后续数据处理。
使用方法为:
Usage: serval extract [OPTIONS] --filter-type <FILTER> --value <VALUE> <CSV_PATH>
Arguments:
<CSV_PATH> Path for tags.csv
Options:
-f, --filter-type <FILTER> Specify the filter type [possible values: species, path, individual, rating, custom]
-v, --value <VALUE> The target value (or substring for the path filter), use "ALL_VALUES" for all non-empty values
--rename Enable rename rename mode (including tags in filenames)
--use-subdir Use subdirectories to organize resources
--subdir-type <SUBDIR_TYPE> Specify the type used when creating subdirectories [default: species] [possible values: species, path, individual, rating, custom]
-o, --output <OUTPUT_DIR> Set the output directory [default: ./serval_output/serval_extract]
-h, --help Print help
<FILTER>
决定根据 tags.csv 中的何种信息进行筛选,目前支持的选项有 path-regex
,species
, individual
和 rating
;
<VALUE>
为提取目标值,当 --filter-type
为 path-regex
时,包含 <VALUE>
的路径会被筛选出;
之后根据命令行提示选取输出路径结构即可。
自动建立子文件夹
可输入 --use-subdir
使用子文件夹对媒体进行分组,默认为按物种;如需按个体、评级、路径或自定义项分子文件夹,可使用 --subdir-type
进行指定。
示例
> serval extract ./tags_demo.csv --filter-value "Pallas's cat" --filter-type species --output /mnt/data/manul
Here is a sample of the file path (/mnt/data/DiQing/202303-202308/6001/animal/Ere 0305.JPG):
0): File Only (no directory)
1): /mnt/data/DiQing/202303-202308/6001/animal
2): /mnt/data/DiQing/202303-202308/6001
3): /mnt/data/DiQing/202303-202308
4): /mnt/data/DiQing
5): /mnt/data
6): /mnt
Select the top level directory to keep: 4
[snip]
./tags_demo.csv
中所有 species 为 "Pallas's cat" 的媒体文件并复制到 /mnt/data/manul
路径下(路径不存在时程序会自动新建)。选取子路径结构时,选取的是想要保留的最上级路径,如此例中选择 4(/mnt/data/DiQing
),则 /mnt/data/DiQing/202303-202308/6001/animal/Ere 0305.JPG
会被复制至 /mnt/data/manul/DiQing/202303-202308/6001/animal/Ere 0305.JPG
;同理如选择 1(/mnt/data/DiQing/202303-202308/6001/animal
),则图片被复制至/mnt/data/manul/Ere 0305.JPG
;如选 0(File Only (no directory)),则所有子路径被忽略,所有图片被直接复制至/mnt/data/manul
,文件名相同的情况会自动添加后缀以避免重名。
> serval extract -f rating -v 5 ./test/rating_extract_demo/tags.csv
Here is a sample of the file path (/home/wsyxbcl/Serval/test/camtrap_data/SEE20298.JPG):
0): File Only (no directory)
1): /home/wsyxbcl/Serval/test/camtrap_data
2): /home/wsyxbcl/Serval/test
3): /home/wsyxbcl/Serval
4): /home/wsyxbcl
5): /home
6): /
Select the top level directory to keep: 0
[snip]
./serval_extract
中。
> serval extract -f rating -v 5 --use-subdir ./tags_JiaTang-align_xmp_20250224225601_patched.csv
Here is a sample of the file path (/home/wsyxbcl/Documents/Jiatang_volunteer_data/JT_trapper/JiaTang-align/JT202311-202401/cr03_20231212-20240123_jt202311-202401/CR03_20231212-20240123_JT202311-202401-IMG_0621.mp4.xmp):
0): File Only (no directory)
1): /home/wsyxbcl/Documents/Jiatang_volunteer_data/JT_trapper/JiaTang-align/JT202311-202401/cr03_20231212-20240123_jt202311-202401
2): /home/wsyxbcl/Documents/Jiatang_volunteer_data/JT_trapper/JiaTang-align/JT202311-202401
3): /home/wsyxbcl/Documents/Jiatang_volunteer_data/JT_trapper/JiaTang-align
4): /home/wsyxbcl/Documents/Jiatang_volunteer_data/JT_trapper
5): /home/wsyxbcl/Documents/Jiatang_volunteer_data
6): /home/wsyxbcl/Documents
7): /home/wsyxbcl
8): /home
9): /
Select the top level directory to keep: 2
Copying to ./serval_output/serval_extract/JT202311-202401/cr03_20231212-20240123_jt202311-202401/Tibetan fox/CR03_20231212-20240123_JT202311-202401-IMG_0621.mp4
Copying to ./serval_output/serval_extract/JT202311-202401/cw01_20231114-20240103_jt202311-202401/Tibetan fox/CW01_20231114-20240103_JT202311-202401-DSCF0117.JPG
Copying to ./serval_output/serval_extract/JT202311-202401/cw01_20231114-20240103_jt202311-202401/Domestic yak/CW01_20231114-20240103_JT202311-202401-DSCF0117.JPG
Copying to ./serval_output/serval_extract/JT202311-202401/cw01_20231114-20240103_jt202311-202401/Unidentified/CW01_20231114-20240103_JT202311-202401-DSCF0118.AVI
[snip]
sidecar 文件
当 tags.csv 中目标文件为 xmp 格式时(如 IMG0001.jpg.xmp
),serval 会自动寻找对应的媒体文件(即 IMG0001.jpg
)并复制。
当 tags.csv 中目标文件为媒体(如 IMG0001.jpg
),除复制媒体本身外,serval 会同时寻找对应的 xmp 文件(即 IMG0001.jpg.xmp
)并复制,xmp 文件不存在时会提示并跳过。
同名文件
输出路径中存在文件同名问题时,serval 会自动重命名
准备同步至 trapper classifications
修正 Tags
使用脚本自动根据 tagdict 和 taglist 修正 tag。对于输出中的 UNKNOWN
tag,若为误标,可直接编辑 tags.csv
完成更正;若为 taglist 中未包含的物种,需更新 taglist(同时更新 trapper 内物种库及对应 classificator 的物种列表);若为 tagdict 中未涵盖异名(或其他处理),更新 tagdict。确定输出结果中无 UNKNOWN
后,进行下一步。
示例
> python ./maze-taxonomy/patch_tags.py ~/AngSai/tags.csv -o ~/AngSai/tags_patched.csv
SYNONYM: Leopard cat -> Common leopard cat
CASE INSENSITIVE: Eurasian Sparrowhawk -> Eurasian sparrowhawk
SYNONYM: Commom leopard -> Common leopard
SYNONYM: Yellow-billed chough -> Alpine chough
SYNONYM: Falconiformes spp. -> Bird spp.
SYNONYM: Hodgeson's redstart -> Hodgson's redstart
SYNONYM: Moutain Finch -> Bird spp.
SYNONYM: Himalayan vulture -> Himalayan griffon
CASE INSENSITIVE: Altai Weasel -> Altai weasel
SYNONYM: Horse -> Domestic horse
[snip]
处理 AI 分包结果
对使用 megadetector 进行过分包过的数据集,若想将 AI 分包结果(主要为观察类型和识别框位置)同步至 trapper,需准备好AI分包结果文件(如 AI-result.csv 和 AI-result_orgnaized.csv,前者为 AI 识别结果,后者为根据序列信息调整后的媒体位置信息),参考此流程进行处理,包括媒体文件名修正(匹配原始数据和分包并 serval align 后的媒体文件名)分包结果标签化和标注框相对位置计算(目前的分包程序为绝对坐标,trapper 及 camtrap-dp 使用相对坐标)。得到的 tags-ai.csv 文件可使用与 tags.csv 相同的流程合并至 observation table(如下),导入 trapper 时需勾选 AI 相关选项,详见 trapper 工作流。
合并至 observation table
使用脚本所需文件为 tags.csv
和 trapper 导出的 media.csv
,observations.csv
(注意导出时需勾选 _id
选项)。输出的 csv 文件即为和 tags.csv
同步后的 observation table,可用于将标签信息导入trapper