Skip to content

Instantly share code, notes, and snippets.

@maxim75
Created August 28, 2015 14:27
Show Gist options
  • Save maxim75/1855640f87678e634ca0 to your computer and use it in GitHub Desktop.
Save maxim75/1855640f87678e634ca0 to your computer and use it in GitHub Desktop.
import datetime
import exifread
import glob
import sys
import os
import shutil
import fractions
import pyexiv2
from geopy.distance import vincenty
# 500 sec 200 meters
# "*.JPG" grouped 500 0 200
max_gap_seconds = int(sys.argv[3])
min_meters = int(sys.argv[4])
max_meters = int(sys.argv[5])
print "Group photos by date and distance"
print "Max gap (seconds): %d, Min dist (meters): %d, Max dist (meters): %d" % (max_gap_seconds, min_meters, max_meters)
def process_file(filepath):
# Open image file for reading (binary mode)
f = open(filepath, 'rb')
# Return Exif tags
tags = exifread.process_file(f)
if "GPS GPSLatitude" in tags and "GPS GPSLongitude" in tags and "EXIF DateTimeOriginal" in tags:
date_str = tags["EXIF DateTimeOriginal"].values
#print date_str
date_taken = datetime.datetime.strptime(date_str, '%Y:%m:%d %H:%M:%S')
lat_deg = tags["GPS GPSLatitude"].values
lng_deg = tags["GPS GPSLongitude"].values
lat = float(float(lat_deg[0].num)/lat_deg[0].den) + float(float(lat_deg[1].num)/lat_deg[1].den)/60 + (float(lat_deg[2].num)/lat_deg[2].den)/3600
lng = float(float(lng_deg[0].num)/lng_deg[0].den) + float(float(lng_deg[1].num)/lng_deg[1].den)/60 + (float(lng_deg[2].num)/lng_deg[2].den)/3600
location = (lat, lng)
else:
date_taken = None
location = None
#print date_taken, date_str
return {
"filepath": filepath,
"date_taken": date_taken,
"location": location
}
filepaths = glob.glob(sys.argv[1])
destination_filepath = sys.argv[2]
photo_list = []
for filepath in filepaths:
photo_details = process_file(filepath)
if(photo_details["date_taken"]):
photo_list.append(photo_details)
photo_list.sort(key=lambda r: r["date_taken"]) #
groups = {}
group_date = photo_list[0]["date_taken"]
groups[group_date] = [ photo_list[0] ]
distance_from_last_photo = 0.0
for i in range(1, len(photo_list)):
photo = photo_list[i]
previous_photo = photo_list[i-1]
gap_seconds = (photo["date_taken"] - previous_photo["date_taken"]).total_seconds()
dist = vincenty(photo["location"], previous_photo["location"]).meters
distance_from_last_photo = distance_from_last_photo + dist
print "File: %s Date: %s Seconds: %f Meters: %f" % (photo["filepath"], photo["date_taken"], gap_seconds, dist)
print "DIST %f" % distance_from_last_photo
if distance_from_last_photo < min_meters:
print "File %s is too close" % photo["filepath"]
elif gap_seconds < max_gap_seconds and dist < max_meters:
groups[group_date].append(photo)
distance_from_last_photo = 0
else:
group_date = photo["date_taken"]
groups[group_date] = [ photo ]
distance_from_last_photo = 0
print "New group: %s" % photo["date_taken"]
for date in groups:
dirname = date.strftime("%Y-%m-%d_%H%M%S")
dirpath = "%s/%s" % (destination_filepath, dirname)
if not os.path.exists(dirpath):
os.makedirs(dirpath)
print "GROUP", dirpath
photos = groups[date]
for photo in photos:
head, tail = os.path.split(photo["filepath"])
dest_filepath = "%s/%s" % (dirpath, tail)
print dest_filepath
shutil.copy2(photo["filepath"], dest_filepath)
#print photo["filepath"], photo["date_taken"]
# destination_filepath
#print glob.glob(sys.argv[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment