Am 15.03.21 um 14:37 schrieb Harry van der Wolf:


Op ma 15 mrt. 2021 om 11:55 schreef 'Kay F. Jahnke' via hugin and other free panoramic software <[email protected] <mailto:[email protected]>>:


    Bear with me... it's a python script and the exiv2 module has changed
    quite a bit, I'll need some time to get it running again.


No problem. You gave me a hint that I should have thought about myself. So thanks. Really. :)

Hey, you're impatient! Never mind, find my script attached. I think the pyexiv2 module changed with the move to python3, so I had to expend a bit of work to get it to run again. But I've used the method for many years to good effect. Goes without saying you use my scripts at your own risk ;)

You'll need python3 and the pyexiv2 module, which you can get via pip3:

pip3 install pyexiv2

the just launch my script with a bunch of images, like:

bracket.py 3 *.JPG *.jpg

You should see output like this (I made a trial set)

IMG_20190624_112027_0.jpg has no CanonFi.BracketMode EXIF tag
using time proximity as sole criterion
IMG_20190624_112027_1.jpg has no CanonFi.BracketMode EXIF tag
using time proximity as sole criterion
IMG_20190624_112027_2.jpg has no CanonFi.BracketMode EXIF tag
using time proximity as sole criterion
distance 0:00:00
append ((datetime.datetime(2019, 6, 24, 11, 20, 27), 'IMG_20190624_112027_0.jpg'), (datetime.datetime(2019, 6, 24, 11, 20, 27), 'IMG_20190624_112027_1.jpg'))
distance 0:00:00
append ((datetime.datetime(2019, 6, 24, 11, 20, 27), 'IMG_20190624_112027_1.jpg'), (datetime.datetime(2019, 6, 24, 11, 20, 27), 'IMG_20190624_112027_2.jpg'))
distance 386 days, 22:08:21
distance 0:00:00
append ((datetime.datetime(2020, 7, 15, 9, 28, 48), 'IMG_3078.JPG'), (datetime.datetime(2020, 7, 15, 9, 28, 48), 'IMG_3079.JPG'))
distance 0:00:00
append ((datetime.datetime(2020, 7, 15, 9, 28, 48), 'IMG_3079.JPG'), (datetime.datetime(2020, 7, 15, 9, 28, 48), 'IMG_3080.JPG'))
distance 0:00:20
distance 0:00:00
append ((datetime.datetime(2020, 7, 15, 9, 29, 8), 'IMG_3081.JPG'), (datetime.datetime(2020, 7, 15, 9, 29, 8), 'IMG_3082.JPG'))
distance 0:00:01
append ((datetime.datetime(2020, 7, 15, 9, 29, 8), 'IMG_3082.JPG'), (datetime.datetime(2020, 7, 15, 9, 29, 9), 'IMG_3083.JPG'))
---------------------------------
processing group ['IMG_20190624_112027_0.jpg', 'IMG_20190624_112027_1.jpg', 'IMG_20190624_112027_2.jpg']
processing group ['IMG_3078.JPG', 'IMG_3079.JPG', 'IMG_3080.JPG']
processing group ['IMG_3081.JPG', 'IMG_3082.JPG', 'IMG_3083.JPG']

so in this case, three folders were created and the images belonging together were moved there.

This works well even for large folders (hundreads of files) and is quite fast as well.

Kay

--
A list of frequently asked questions is available at: 
http://wiki.panotools.org/Hugin_FAQ
--- You received this message because you are subscribed to the Google Groups "hugin and other free panoramic software" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/hugin-ptx/25453bd3-a0b5-3677-6d87-b9dc8fef8a37%40yahoo.com.
#! /usr/bin/env python3

#          bracket.py - collect AEBs into separate folders
#  
#          Copyright 2021 by Kay F. Jahnke
#  
#  bracket.py is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published
#  by the Free Software Foundation, either version 3 of the License,
#  or (at your option) any later version.
#  
#  it is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#  
#  You should have received a copy of the GNU General Public License
#  along with pv.  If not, see <http://www.gnu.org/licenses/>.
#
#
# this script takes a time duration in seconds as it's first parameter
# and any number of image files after that. All images which were taken
# less than the specified number of seconds apart and have the AEB tag
# set are considered part of a bracket. All bracketed shots are moved to
# a folder named after the first and last of their members.
# The test for membership in an AEB is hardcoded for my canon camera;
# if this tag (Exif.CanonFi.BracketMode) is not found, formation of
# groups is done by time only.
# The files are moved, there is no backup.

import sys
import pyexiv2
from datetime import datetime
import os

try :
    maximum_distance = float ( sys.argv[1] )
except :
    print ( 'move bracketed images taken at close intervals into common subfolder' )
    print ( 'usage: %s <seconds> <files>' % sys.argv[0] )
    sys.exit ( -1 )

# first we create a list of (datetime, filename) tuples

times = []

for img in sys.argv[2:]:
    try :
        exiv_img = pyexiv2.core.Image(img)
        metadata = exiv_img.read_exif()
        original_time=metadata [ "Exif.Photo.DateTimeOriginal" ]
        dt = datetime.strptime(original_time,'%Y:%m:%d %H:%M:%S')
        try :
            # if we can access the Exif.CanonFi.BracketMode tag,
            # we can narrow down the list of candidates to such
            # images which have been taken in AEB mode.
            bracket_mode = metadata [ "Exif.CanonFi.BracketMode" ]
            if bracket_mode == "1" :
                pair =  ( dt , img )
                times.append ( pair )
        except KeyError :
            print ( '%s has no CanonFi.BracketMode EXIF tag' % img )
            print ( 'using time proximity as sole criterion' )
            pair = ( dt , img )
            times.append ( pair )
    except KeyError :
        # ignore files without DateTimeOriginal
        print ( '%s has no DateTimeOriginal EXIF tag' % img )
    except IOError as e :
        print ( e )

# we sort by time and pair img[i] with img[i+1]

times.sort( key=lambda pair: pair[0])
pairs = zip ( times[:-1] , times[1:] )

# now we pick all 'close' pairs - the pairs which are less than
# maximum_distance seconds apart

close = []

for p in pairs :
    distance = p[1][0] - p[0][0]
    print ( "distance %s" % distance )
    if (     distance.days == 0
         and distance.seconds < maximum_distance ) :
        close.append ( p )
        print ( "append %s" % str(p) )

# finally we group those files which occur in one or more pairs

groups = []
g = []

for p in close :
    if g and p[0][1] == g[-1] :
        # first member of pair is last member in the group?
        # append the second member of this pair as well
        g.append ( p[1][1] )
    else :
        if g :
            # if there is a group, we save it
            groups.append ( g )
        # and start a new group with the current pair
        g = [ p[0][1] , p[1][1] ]

if g :
    # if there is a group, we save it
    groups.append ( g )

print ( '---------------------------------' )

# the files constituting a group are all moved to
# a common subfolder. This way it's easiest to doublecheck
# if the grouping has to be manually altered.

for g in groups :
    
    print ( 'processing group' , g )

    part1, ext = os.path.splitext(g[0])
    part2, ext = os.path.splitext(g[-1])
    groupname = part1 + '_' + part2

    groupdirname = groupname # + '.dir'

    os.mkdir ( groupdirname )
    for fn in g :
        os.rename ( fn , groupdirname + '/' + fn )

    

Reply via email to