Created
August 28, 2015 14:27
-
-
Save maxim75/1855640f87678e634ca0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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