You are here

8 posts / 0 new
Last post
Faces Statistics #1
Tim Doyle's picture
by Tim Doyle
May 30, 2012 - 12:52am

I know many people do not use Aperture's Faces feature, but for those who do, there is little feedback from within Aperture to let you know how you're progressing as you go through the process of identifying people in your photos.

To provide a little more feedback, I've created this simple AppleScript. Place in your Aperture script folder and access from the script menu.

When run, it examines the Faces database table of the currently selected Aperture library and provides the count of total faces, which consists of user-added faces and detected faces. The detected faces are broken down into identified, unidentified, and rejected (things Aperture thought were faces, but which you said were not). The count of people identified is also given. Also, a percentage of “work completed” is listed - which is the inverse of the number of unidentified over the total. This percentage can be used to track your progress.

Feedback welcome!

Tim


– Aperture Faces Statistics
– © 2012, Tim Doyle


global Aperture_library_path
global Faces_database_path

set Aperture_library_path to “”
set Faces_database_path to my getApertureLibraryPath() & “Database/apdb/faces.db”

set totalFaces to my SQL_command(Faces_database_path, “select count(*) from RKDetectedFace;”, “”)
set rejectedFaces to my SQL_command(Faces_database_path, “select count(*) from RKDetectedFace where ignore='1';”, “”)
set unidentifiedFaces to my SQL_command(Faces_database_path, “select count(*) from RKDetectedFace where not exists (select * from RKFaceName where RKFaceName.faceKey = RKDetectedFace.faceKey) and ignore != '1';”, “”)
set userAddedFaces to my SQL_command(Faces_database_path, “select count(*) from RKDetectedFace where correlatedFaceKey is null;”, “”)
set identifiedFaces to totalFaces - rejectedFaces - unidentifiedFaces - userAddedFaces
set detectedFaces to totalFaces - userAddedFaces
set totalIdentified to userAddedFaces + identifiedFaces
set totalPeople to my SQL_command(Faces_database_path, “select count(*) from RKFaceName;”, “”)
set workCompletedPercent to round (((totalFaces - unidentifiedFaces) / totalFaces) * 100)

set msg to ¬
“Aperture Face Statistics” & character id 10 & character id 10 ¬
& “Work Completed: ” & workCompletedPercent & “%” & character id 10 & character id 10 ¬
& “Total Faces: ” & comma_delimit(totalFaces) & character id 10 ¬
& character id 9 & “Detected Faces: ” & comma_delimit(detectedFaces) & character id 10 ¬
& character id 9 & character id 9 & “Identified Faces: ” & comma_delimit(identifiedFaces) & character id 10 ¬
& character id 9 & character id 9 & “Unidentified Faces: ” & comma_delimit(unidentifiedFaces) & character id 10 ¬
& character id 9 & character id 9 & “Rejected Faces: ” & comma_delimit(rejectedFaces) & character id 10 ¬
& character id 9 & “User-Added Faces: ” & comma_delimit(userAddedFaces) & character id 10 ¬
& character id 9 & “Total Identified Faces: ” & comma_delimit(totalIdentified) & character id 10 ¬
& character id 10 ¬
& “Total People: ” & comma_delimit(totalPeople)

display dialog msg


on SQL_command(database_path, command_string, options)
try
return (do shell script “sqlite3 ” & options & ” ” & (quoted form of database_path) & ” '” & command_string & “'”)
on error eMsg number eNum
if eNum is 5 then
delay 5
try
return (do shell script “sqlite3 ” & options & ” ” & (quoted form of database_path) & ” '” & command_string & “'”) –Try it again, occasionally the DB is locked
on error eMsg number eNum
if eNum is 5 then
delay 30
return (do shell script “sqlite3 ” & options & ” ” & (quoted form of database_path) & ” '” & command_string & “'”) –Try it again, occasionally the DB is locked
else
display dialog eMsg
end if
end try
else
display dialog eMsg
end if
end try
end SQL_command

on getApertureLibraryPath()
if Aperture_library_path is “” then
set Aperture_library_path to do shell script “defaults read com.apple.Aperture LibraryPath”
– expand the '~' if it's in there
set Aperture_library_path to do shell script “echo ” & Aperture_library_path
if Aperture_library_path does not end with “/” then
set Aperture_library_path to Aperture_library_path & “/”
end if
end if
return Aperture_library_path
end getApertureLibraryPath

on comma_delimit(this_number)
set this_number to this_number as string
if this_number contains “E” then set this_number to number_to_text(this_number)
set the num_length to the length of this_number
set the this_number to (the reverse of every character of this_number) as string
set the new_num to “”
repeat with i from 1 to the num_length
if i is the num_length or (i mod 3) is not 0 then
set the new_num to (character i of this_number & the new_num) as string
else
set the new_num to (“,” & character i of this_number & the new_num) as string
end if
end repeat
return the new_num
end comma_delimit

Jim Stackhouse's picture
by Jim Stackhouse
June 12, 2012 - 6:06am

Tim,

Thanks for your effort. I have been looking for something like this. I have been using Faces and try to do it religiously. Like Places if you do it consistently the info can be really helpful.
Regarding your script. It worked as described. But I have a few questions.
My library says that work completed 52%
detected 22,933
identified 9.893
unidentified 11.381
rejected 1.659
user-added 569
total identified 10.462

Now I have gone through my entire library and feel like I am up-to-date - so the 52% work completed doesn’t seem right to me. I think the problem is all the unidentified faces. When I go through my unidentified faces I ‘skip’ lots of them because they are strangers/faces in the crowd/ individuals I don’t care to identify. If I ‘skip” them in Aperture do they still get count as unidentified. I guess if I right clicked and selected “not a face” they would be removed from the unidentified count? But that would be a pain and really slow me down. I guess I could also have a ‘face’ called ‘nobody’ and tag all these photos are ‘nobody’ so that they appear to be ‘identified’ in the counts.
I guess I would like to see the unidentified faces that I skipped separate from those that I have not reviewed (those are the truly ‘work remaining’).

Also would there be a way to modify the script to look a just a selection (project, folder, etc) and not the entire library??

Jim

Tim Doyle's picture
by Tim Doyle
June 13, 2012 - 12:19am

Hi Jim:

The original version posted above was missing the photos which were “skipped”. I will post the updated version which accounts for this as soon as I can.

Unfortunately, I am one of the many individuals who is experiencing a kernel panic after upgrading the Thunderbolt update last night. I want to play with Aperture but instead am headed to the Genius Bar today.

I can look into the possibility of statistics on a selection.

Thanks for your feedback!

Tim

Jim Stackhouse's picture
by Jim Stackhouse
June 13, 2012 - 12:29am

Tim,

Thanks for the update. No rush. Good luck at the Genius Bar. I would like to stop by just to see the new laptop. I think I might just ‘need’ one now.

Jim

Tim Doyle's picture
by Tim Doyle
June 13, 2012 - 2:57am

Here’s the updated version of the script, which takes into account skipped faces:

– Aperture Faces Statistics
– © 2012, Tim Doyle

global Aperture_library_path
global Faces_database_path

set Aperture_library_path to “”
set Faces_database_path to my getApertureLibraryPath() & “Database/apdb/faces.db”

set totalFaces to my SQL_command(Faces_database_path, “select count(*) from RKDetectedFace;”, “”)
set rejectedFaces to my SQL_command(Faces_database_path, “select count(*) from RKDetectedFace where ignore=’1’;”, “”)
set unidentifiedFaces to my SQL_command(Faces_database_path, “select count(*) from RKDetectedFace where not exists (select * from RKFaceName where RKFaceName.faceKey = RKDetectedFace.faceKey) and ignore != ‘1’ and rejected != ‘1’;”, “”)
set skippedUnidentifiedFaces to my SQL_command(Faces_database_path, “select count(*) from RKDetectedFace where not exists (select * from RKFaceName where RKFaceName.faceKey = RKDetectedFace.faceKey) and ignore != ‘1’ and rejected != ‘1’ and skippedInUnnamedFaces=’1’;”, “”)
set userAddedFaces to my SQL_command(Faces_database_path, “select count(*) from RKDetectedFace where correlatedFaceKey is null;”, “”)
set skippedFaces to my SQL_command(Faces_database_path, “select count(*) from RKDetectedFace where skippedInUnnamedFaces=’1’;”, “”)

set identifiedFaces to totalFaces - rejectedFaces - unidentifiedFaces - userAddedFaces
set detectedFaces to totalFaces - userAddedFaces
set totalIdentified to userAddedFaces + identifiedFaces
set totalPeople to my SQL_command(Faces_database_path, “select count(*) from RKFaceName;”, “”)
set workCompletedPercent to round (((totalFaces - unidentifiedFaces) / totalFaces) * 100)

set msg to ¬
“Aperture Face Statistics” & character id 10 & character id 10 ¬
& “Work Completed: ” & workCompletedPercent & “%” & character id 10 & character id 10 ¬
& “Total Faces: ” & comma_delimit(totalFaces) & character id 10 ¬
& character id 9 & “Detected Faces: ” & comma_delimit(detectedFaces) & character id 10 ¬
& character id 9 & character id 9 & “Identified Faces: ” & comma_delimit(identifiedFaces) & character id 10 ¬
& character id 9 & character id 9 & “Unidentified Faces: ” & comma_delimit(unidentifiedFaces) & character id 10 ¬
& character id 9 & character id 9 & character id 9 & “Skipped: ” & comma_delimit(skippedUnidentifiedFaces) & character id 10 ¬
& character id 9 & character id 9 & “Rejected Faces: ” & comma_delimit(rejectedFaces) & character id 10 ¬
& character id 9 & “User-Added Faces: ” & comma_delimit(userAddedFaces) & character id 10 ¬
& character id 9 & “Total Skipped Faces: ” & comma_delimit(skippedFaces) & character id 10 ¬
& character id 9 & “Total Identified Faces: ” & comma_delimit(totalIdentified) & character id 10 ¬
& character id 10 ¬
& “Total People: ” & comma_delimit(totalPeople)

display dialog msg

on SQL_command(database_path, command_string, options)
try
return (do shell script “sqlite3 ” & options & ” ” & (quoted form of database_path) & ” ‘” & command_string & “’”)
on error eMsg number eNum
if eNum is 5 then
delay 5
try
return (do shell script “sqlite3 ” & options & ” ” & (quoted form of database_path) & ” ‘” & command_string & “’”) –Try it again, occasionally the DB is locked
on error eMsg number eNum
if eNum is 5 then
delay 30
return (do shell script “sqlite3 ” & options & ” ” & (quoted form of database_path) & ” ‘” & command_string & “’”) –Try it again, occasionally the DB is locked
else
display dialog eMsg
end if
end try
else
display dialog eMsg
end if
end try
end SQL_command

on getApertureLibraryPath()
if Aperture_library_path is “” then
set Aperture_library_path to do shell script “defaults read com.apple.Aperture LibraryPath”
– expand the ‘~’ if it’s in there
set Aperture_library_path to do shell script “echo ” & Aperture_library_path
if Aperture_library_path does not end with “/” then
set Aperture_library_path to Aperture_library_path & “/”
end if
end if
return Aperture_library_path
end getApertureLibraryPath

on comma_delimit(this_number)
set this_number to this_number as string
if this_number contains “E” then set this_number to number_to_text(this_number)
set the num_length to the length of this_number
set the this_number to (the reverse of every character of this_number) as string
set the new_num to “”
repeat with i from 1 to the num_length
if i is the num_length or (i mod 3) is not 0 then
set the new_num to (character i of this_number & the new_num) as string
else
set the new_num to (“,” & character i of this_number & the new_num) as string
end if
end repeat
return the new_num
end comma_delimit

David Zeitlyn's picture
by David Zeitlyn
February 10, 2013 - 3:29am

Tim
your script works well and is really helpful but I cant see a way to either save the stats to a file or at least copy to the clipboard so I can paste into a doc or some sort.
Is there a quick hack of the script which could do this?
thanks
davidz

BonnieB's picture
by BonnieB
August 19, 2012 - 1:50pm

Looks like it’s working to me. Simple and helpful! Thank you, Tim.
How is “Skipped” different from “Total Skipped?”

Work Completed: 81%

Total Faces: 7,680
Detected Faces: 7,282
Identified Faces: 5,069
Unidentified Faces: 1,445
Skipped: 311
Rejected Faces: 768
User-Added Faces: 398
Total Skipped Faces: 619
Total Identified Faces: 5,467

Total People: 134

KurtAasen's picture
by KurtAasen
June 5, 2014 - 9:33pm

Hello

I am completely new in this but wanted to try this faces statistics.

Is it simply to copy your code into an Apple Script window and then save it to Aperture scripts folder?

When I copy your code into an Apple script window and try to compile it starts complaining first about those two first lines

– Aperture Faces Statistics
– © 2012, Tim Doyle

But I guess they are not supposed to be copied, right?

Next two lines are ok:

global Aperture_library_path
global Faces_database_path

But then it complains about the in

set Aperture_library_path to “”

Am i expected to replace the ”” or is it something else?

I am using a Norwegian keyboard if that can have an impact..

 

Pleace advice a complete newbie:-)

 

BR

 

 

Kurt Aasen

You may login with either your assigned username or your e-mail address.
Passwords are case-sensitive - Forgot your password?
randomness