是否有R函数可基于时间戳提取相机陷阱照片并按指定规则筛选?
用R筛选相机陷阱照片:按时间戳保留单张或第二张
嘿,完全没问题!R绝对能搞定这个需求,我会一步步给你讲清楚操作步骤,哪怕你是第一次碰R也能跟着做~
步骤1:安装并加载必要的工具包
首先我们需要几个帮我们处理文件和数据的包,打开R(或者RStudio),复制运行下面的代码(只需要装一次,以后用就不用再装了):
# 安装需要的包 install.packages(c("dplyr", "fs", "exifr")) # 加载包,每次用都要运行这句 library(dplyr) library(fs) library(exifr)
步骤2:设置你的照片文件夹路径
把下面代码里的路径换成你存放相机陷阱照片的实际路径(Windows用反斜杠\的话要写成双反斜杠\\,或者直接用正斜杠/):
# 替换成你的照片文件夹路径 photo_folder <- "C:/Users/你的名字/相机照片"
步骤3:获取照片信息并提取时间戳
这里分两种常见情况,你选适合自己的就行:
情况A:时间戳在文件名里
如果你的照片文件名里直接包含时间戳(比如camera_13:22:42_01.jpg),用下面的代码提取时间戳:
# 获取所有照片文件(支持jpg、jpeg、png,可根据你的照片格式调整) photo_files <- dir_ls(photo_folder, regexp = "\\.(jpg|jpeg|png)$", ignore.case = TRUE) # 从文件名提取时间戳(这里匹配HH:MM:SS格式,如果你文件名里的时间戳是其他格式,比如132242,要改正则) photo_info <- tibble( file_path = photo_files, file_name = path_file(file_path), timestamp = stringr::str_extract(file_name, "\\d{2}:\\d{2}:\\d{2}") )
情况B:从照片EXIF读取拍摄时间(更准确)
相机陷阱拍的照片一般在EXIF信息里存了准确的拍摄时间,用这个方法更靠谱:
# 获取所有照片文件 photo_files <- dir_ls(photo_folder, regexp = "\\.(jpg|jpeg|png)$", ignore.case = TRUE) # 读取EXIF里的拍摄时间 exif_data <- read_exif(photo_files, tags = "DateTimeOriginal") # 整理成包含文件路径和时间戳的表格 photo_info <- tibble( file_path = photo_files, timestamp = exif_data$DateTimeOriginal ) # 如果时间戳带日期(比如"2024:05:20 13:22:42"),只想保留时间部分的话,加下面这句: photo_info <- photo_info %>% mutate(timestamp = stringr::str_extract(timestamp, "\\d{2}:\\d{2}:\\d{2}"))
步骤4:筛选需要保留的照片
按时间戳分组,单张的保留,多张的只留第二张:
selected_photos <- photo_info %>% group_by(timestamp) %>% mutate(photo_order = row_number()) %>% # 给同一时间戳的照片按顺序编号 # 筛选规则:单张留第1张,多张留第2张 filter(photo_order == 1 | (n() > 1 & photo_order == 2)) %>% ungroup()
步骤5:把选中的照片复制到新文件夹
我们会在原文件夹里创建一个叫“筛选后的照片”的新文件夹,把目标照片复制进去:
# 创建输出文件夹 output_folder <- path(photo_folder, "筛选后的照片") dir_create(output_folder) # 如果文件夹已经存在,这句不会报错 # 复制照片到新文件夹 file_copy(selected_photos$file_path, output_folder, overwrite = FALSE)
一些注意事项
- 如果你的时间戳格式和我假设的不一样(比如是
13-22-42或者包含日期),需要调整stringr::str_extract里的正则表达式,你可以把你的文件名示例告诉我,我帮你改。 - 如果EXIF读取不到
DateTimeOriginal,可以试试换成CreateDate标签,把read_exif里的tags = "DateTimeOriginal"改成tags = "CreateDate"。 - 运行代码时如果报错,看看是不是路径写错了,或者照片格式没包含在正则里。
内容的提问来源于stack exchange,提问作者Research
相关产品推荐
相关产品推荐

