将带有 EXIF(时间)的图像从多个目录复制到新目标

Copy images with EXIF(time) to new destination from several directories

我有问题,下面是我的根树: 在我的根目录中,我有:

 ---dir1---sub1(images exif time 10:05:05 to 10:09:55)
        ---sub2(images exif time 10:11:15 to 10:15:42)
        ---sub3(images exif time 10:22:15 to 10:24:41)
        ---sub4(images exif time 10:28:15 to 10:35:40)


 ---dir2---sub1(images exif time 10:05:06 to 10:09:57)
        ---sub2(images exif time 10:11:15 to 10:15:40)
        ---sub3(images exif time 10:22:15 to 10:24:43)
        ---sub4(images exif time 10:28:15 to 10:35:40)
        ---sub5(images exif time 10:40:15 to 10:43:40)

 ---dir3---sub1(images exif time 10:05:05 to 10:09:54)
        ---sub2(images exif time 10:11:15 to 10:15:40)
        ---sub3(images exif time 10:22:15 to 10:24:41)
        ---sub4(images exif time 10:28:15 to 10:35:40)
        ---sub5(images exif time 10:40:15 to 10:43:42)

 ---dir4---sub1(images exif time 10:05:06 to 10:09:57)
        ---sub2(images exif time 10:11:15 to 10:15:40)
        ---sub3(images exif time 10:22:15 to 10:24:43)
        ---sub4(images exif time 10:28:15 to 10:35:40)
        ---sub5(images exif time 10:40:15 to 10:43:40)

 ---dir5---sub1(images exif time 10:05:05 to 10:09:54)
        ---sub2(images exif time 10:11:15 to 10:15:40)
        ---sub3(images exif time 10:22:15 to 10:24:41)
        ---sub4(images exif time 10:28:15 to 10:35:40)
        ---sub5(images exif time 10:40:15 to 10:43:42)

我的根目录中有 5 个目录,每个目录都包含子文件夹(带有图像),子文件夹的数量一直都不相同,我想做的是首先 - dir1 获取 sub1 并将其放入转到下一个目录(dir2)后到新的目标文件夹扫描子文件夹以检查exif(time)是否与dir1中的sub1相同并在转到下一个dir3后将其复制到同一目录并对所有其他dir-s执行相同的操作和子文件夹,并在创建 newdir2 后去从 dir1 中取出 sub2 并再次执行相同的循环直到结束...

类似于:

   ---newdir1---sub1(from dir1)
             ---sub1(from dir2)
             ---sub1(from dir3)
             ---sub1(from dir4)
             ---sub1(from dir5)

   ---newdir2---sub2(from dir1)
             ---sub2(from dir2)
             ---sub2(from dir3)
             ---sub2(from dir4)
             ---sub2(from dir5)

   ---newdir3---sub3(from dir1)
             ---sub3(from dir2)
             ---sub3(from dir3)
             ---sub3(from dir4)
             ---sub3(from dir5)

   ---newdir4---sub4(from dir1)
             ---sub4(from dir2)
             ---sub4(from dir3)
             ---sub4(from dir4)
             ---sub4(from dir5)

   ---newdir5---sub5(from dir2)
             ---sub5(from dir3)
             ---sub5(from dir4)
             ---sub5(from dir5)

我有一部分脚本可以按时间间隔将我的图像分类到字典中,如何将它加入我的脚本?让我的 sub-s 使用相同的密钥进入相同的目录 ??:

import os
import exifread
from datetime import datetime, timedelta

TIME_RANGE = 2

src_root = 'F:\gopro_egouts\gopro_img_test\2018-03-06'

dst_root = src_root + '-copie'

src_dirs_dict = {}

for cam_dir in os.listdir(src_root):
    laps_root = os.path.join(src_root, cam_dir)
    for lap_dir in os.listdir(laps_root):
        files_root = os.path.join(laps_root, lap_dir)
        min_time = None
        max_time = None
        for cam_file in os.listdir(files_root):
            with open(os.path.join(files_root, cam_file), 'rb') as f:
                tags = exifread.process_file(f, details=False, stop_tag="EXIF DateTimeOriginal")
                time_taken = tags.get("EXIF DateTimeOriginal")
                if time_taken:
                    file_time = datetime.strptime(str(time_taken), '%Y:%m:%d %H:%M:%S')
                    if min_time is not None:
                        if file_time < min_time:
                            min_time = file_time
                    else:
                        min_time = file_time

                    if max_time is not None:
                        if file_time > max_time:
                            max_time = file_time
                    else:
                        max_time = file_time


        is_key = None
        for key in src_dirs_dict.keys():
            if (min_time >= key[0] and min_time < key[1]) \
                    or (max_time >= key[0] and max_time < key[1]):
                is_key = key
                break
        min_time = min_time.replace(second=0)
        max_time = min_time + timedelta(minutes=TIME_RANGE)

        if is_key:

            key_min, key_max = is_key
            if min_time < key_min:
                key_min = min_time
            if max_time > key_max:
                key_max = max_time

            new_key = (key_min, key_max)

            if new_key == is_key:
                src_dirs_dict[new_key].append(files_root)
            else:

                src_dirs_dict[new_key] = src_dirs_dict.pop(is_key) + [files_root]
        else:
            new_key = (min_time, max_time)
            src_dirs_dict[new_key] = [files_root]


print(src_dirs_dict)

我的照片显示:

{(datetime.datetime(2018, 3, 6, 10, 31), datetime.datetime(2018, 3, 6, 10, 32)): ['F:\gopro_egouts\gopro_img_test\2018-03-06\CAM0101 1\Time Lapse 3',...

我有一个工作良好的脚本,但一个一个地获取子文件夹,当一些延时丢失时,我有一个问题,他混合我的子(自动从中获取下一个) next dir with wrong time),我必须从上面添加我的exif脚本到这里(如何修改它)...如何将它连接在一起???
任何帮助将不胜感激。

from collections import defaultdict
import shutil
import os
import re
src_root = r'F:\gp\gp_test\2018-03-06'

dst_root = src_root + '-copie'

#os.makedirs(dst_root, exist_ok=True)

src_dirname, src_folders, _ = next(os.walk(src_root))
src_folders = sorted(src_folders)

src_folders = [os.path.join(src_root, folder) for folder in src_folders]
print(src_folders)
job = defaultdict(list)

print('mes {} dossier cam'.format(len(src_folders)))

for folder in src_folders:
    print()
    dirname, src_sub_folders, _ = next(os.walk(os.path.join(src_dirname, folder)))
    src_sub_folders = sorted(src_sub_folders, key=lambda x: [re.search(r'(\D+)', x).group(1)] + list(map(int, re.findall(r'\d+', x))))
    print("mes 5 CAM avec {} time laps '{}'".format(len(src_sub_folders), folder))

    for index, sub_folder in enumerate(src_sub_folders, start=1):
        job['Time Lapse-{}'.format(index)].append(os.path.join(dirname, sub_folder))

#print()

for dst_folder, src_folders in sorted(job.items()):
    for index, src_folder in enumerate(src_folders, start=1):
        dst_new_folder = os.path.join(dst_root, dst_folder, 'CAM-{}'.format(index))
        print('{} -> {}'.format(src_folder, dst_new_folder))
        shutil.copytree(src_folder, dst_new_folder)
#shutil.rmtree(src_root)

for root, dirs, files in os.walk(dst_root):
    for f in files:
        prefix = os.path.basename(root)
        prefix1 = os.path.basename(src_root)
        os.rename(os.path.join(root, f), os.path.join(root, "{}-{}-{}".format(prefix1, prefix, f)))
        print("images rennomer ")

print("fini")
print("dossier supprimé")

如果这对用户来说不是很清楚,我真的很抱歉,但英语不是我最擅长的语言......

简而言之,您拥有在多个相机上拍摄的同一组事件的图像。

目前先按摄像头分组,再按事件分组:

├── Camera1
│   ├── Event1
│   ├── Event2
│   ├── Event3
│   ├── Event4
│   └── Event5
├── Camera2
│   ├── Event1
│   ├── Event2
│   ├── Event3
│   ├── Event4
│   └── Event5
├── Camera3
│   ├── Event1
│   ├── Event2
│   ├── Event3
│   ├── Event4
│   └── Event5
├── Camera4
│   ├── Event1
│   ├── Event2
│   ├── Event3
│   ├── Event4
│   └── Event5
└── Camera5
    ├── Event1
    ├── Event2
    ├── Event3
    ├── Event4
    └── Event5

...其中一些事件可能会丢失并且事件编号可能不匹配,因为一个或多个事件可能不会被所有摄像机记​​录下来。

并且您希望同一组图像首先按事件分组,然后按相机分组:

├── Event1
│   ├── Camera1
│   ├── Camera2
│   ├── Camera3
│   ├── Camera4
│   └── Camera5
├── Event2
│   ├── Camera1
│   ├── Camera2
│   ├── Camera3
│   ├── Camera4
│   └── Camera5
├── Event3
│   ├── Camera1
│   ├── Camera2
│   ├── Camera3
│   ├── Camera4
│   └── Camera5
├── Event4
│   ├── Camera1
│   ├── Camera2
│   ├── Camera3
│   ├── Camera4
│   └── Camera5
└── Event5
    ├── Camera1
    ├── Camera2
    ├── Camera3
    ├── Camera4
    └── Camera5

这是个主意...我有点像 "thinking aloud" pseudo-code:

Create the output directories {Event1..EventN}/Camera{1..N}
MissingDirectory=false
for each input directory Camera{1..N}
    if this directory has the full number of subdirectories
        copy all subdirectories to output area
    else
        MissingDirectory=true
    end if
end for

if MissingDirectory
    for each output Event directory
        get times of all files from all cameras for current event
        sort list and take median time of current event
    end for
    for each un-copied input directory
        get the mean time of all the files in it
        assign this directory's files to output directory with nearest median time
    end for
endif

您可以将 EXIF 时间转换为自午夜 (s) 以来的纯秒数:

s = (hours*3600) + (minutes*60) + seconds

这是获取图像拍摄时间(从午夜开始的秒数)的方法:

import exifread

def getImageTime(filename):
    "Read EXIF data of given file and return time in seconds since midnight"
    f=open(filename,'rb')
    tags=exifread.process_file(f)
    DateTime=tags["EXIF DateTimeOriginal"].printable
    # DateTime looks like: "2013:03:09 08:59:50"
    Time=DateTime.split()[-1]
    # Time looks like: "08:59:50"
    h,m,s=Time.split(":")
    # Return seconds since midnight: 32390
    return (int(h)*3600) + (int(m)*60) + int(s)

s=getImageTime("image.jpg")
print(s)

经过深思熟虑,如果将其中一个摄像机设置为与其他摄像机相差 20 分钟,这将不会很好地工作,因为它来自所有序列的所有图像都倾向于放入第一个或最后一个目录。需要更多思考...