-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgetfaces.py
executable file
·111 lines (100 loc) · 5.06 KB
/
getfaces.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sqlite3
import os.path
from PIL import Image
import piexif
import argparse
# Commandline Handling
parser = argparse.ArgumentParser(description='Export faces from Lightroom DB')
parser.add_argument('-d', '--database', help='Input Database', required=True)
parser.add_argument('-o', '--output', help='Output Directory', required=True)
parser.add_argument('-n', '--name', help='Name of Person', required=True)
parser.add_argument('-ee', '--exclude_extensions', help='File extensions to exclude', required=False)
parser.add_argument('-cf', '--clipping_factor', help='Space around the face', required=False)
args = parser.parse_args()
# Transform extension Argument to exclude
if args.exclude_extensions is not None:
excludeExtensions = args.exclude_extensions
excludeExtensions = excludeExtensions.split(",")
excludeExtensions = ', '.join('"{0}"'.format(w) for w in excludeExtensions)
else:
excludeExtensions = ''
# set the space around the face
if args.clipping_factor is not None and args.clipping_factor.isdigit():
clipping_factor = int(args.clipping_factor)
else: # default
clipping_factor = 75
# Add trailing slash to output path if missing
output_path = os.path.join(args.output, '')
# get the working directory
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# load the Lightroom Database
db_path = os.path.join(BASE_DIR, args.database)
conn = sqlite3.connect(db_path)
conn.row_factory = sqlite3.Row
cursor = conn.execute(
'select Folder.pathFromRoot, File.baseName, File.extension, File.folder,Hist.*, Faces.*, kwf.*,kw.*,rf.* from Adobe_libraryImageFaceProcessHistory AS Hist inner join Adobe_images AS Img ON Hist.image = Img.id_local inner join AgLibraryFile AS File on Img.rootFile = File.id_local inner join AgLibraryFolder AS Folder on File.folder = Folder.id_local inner join AgLibraryFace AS Faces on Hist.image = Faces.image inner join AgLibraryKeywordFace As kwf on Faces.id_local = kwf.face inner join AgLibraryKeyword as kw on kwf.tag = kw.id_local inner join AgLibraryRootFolder as rf on Folder.rootFolder = rf.id_local where lc_name like "' + args.name + '" and lower(File.extension) not in (' + excludeExtensions.lower() + ') order by dateCreated ')
# iterate over all images the contain the face
for row in cursor:
img = Image.open(row['absolutePath'] + row['pathFromRoot'] + row['baseName'] + '.' + row['extension'])
print (row['absolutePath'] + row['pathFromRoot'] + row['baseName'] + '.' + row['extension'])
x_size, y_size = img.size
orientation = ""
if "exif" in img.info:
exif_dict = piexif.load(img.info["exif"])
if piexif.ImageIFD.Orientation in exif_dict["0th"]:
orientation = exif_dict["0th"].pop(piexif.ImageIFD.Orientation)
if orientation == 2:
img = img.transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 3:
img = img.rotate(180)
elif orientation == 4:
img = img.rotate(180).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 5:
img = img.rotate(-90).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 6:
img = img.rotate(-90, expand=True)
elif orientation == 7:
img = img.rotate(90).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 8:
img = img.rotate(90, expand=True)
else:
exif_dict = ""
exif_bytes = piexif.dump(exif_dict)
# Workaround to fix orientation Problems
img.save('temp.' + row['extension'], exif=exif_bytes)
img2 = Image.open('temp.' + row['extension'])
x_new_size, y_new_size = img2.size
# calculate Image Size based on Image orientation
if orientation == 6 or orientation == 8 or orientation == -1:
top_x = row['tl_x'] * y_size
top_y = row['tl_y'] * x_size
bottom_x = row['br_x'] * y_size
bottom_y = row['br_y'] * x_size
else:
top_x = row['tl_x'] * x_size
top_y = row['tl_y'] * y_size
bottom_x = row['br_x'] * x_size
bottom_y = row['br_y'] * y_size
# Extend the Clipping
while True:
d_top_x = int(top_x - clipping_factor)
d_top_y = int(top_y - clipping_factor)
d_bottom_x = int(bottom_x + clipping_factor)
d_bottom_y = int(bottom_y + clipping_factor)
# Check if Clipping Frame ist bigger then actual Image
if (d_top_x >= 0 and d_top_y >= 0 and d_bottom_x < x_new_size and d_bottom_y < y_new_size):
top_x = int(top_x - clipping_factor)
top_y = int(top_y - clipping_factor)
bottom_x = int(bottom_x + clipping_factor)
bottom_y = int(bottom_y + clipping_factor)
break
# decrement factor till it fits
clipping_factor -= 1
# finaly - crop the image
img3 = img2.crop((top_x, top_y, bottom_x, bottom_y))
# dump the old exif data to the image
exif_bytes = piexif.dump(exif_dict)
# save me! now!
img3.save(output_path + row['name'] + "_" + row['baseName'] + '_neu' + '.' + row['extension'], exif=exif_bytes)