Skip to content

Commit 9188fb0

Browse files
committed
Merge pull request #1 from wendelscardua/sky-biometry-api
Sky biometry api
2 parents 242b93a + 4824386 commit 9188fb0

File tree

6 files changed

+41
-58
lines changed

6 files changed

+41
-58
lines changed

Gemfile

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ gem('magickly',
77
:ref => 'cd17608a9c4468da1f738815a96dc2a9473fc029')
88
#gem 'magickly', :path => '../magickly'
99

10+
gem 'face'
11+
1012
gem 'excon'
1113
gem 'faraday'
1214

@@ -25,7 +27,7 @@ end
2527
group :development, :test do
2628
gem 'rack-test', :require => 'rack/test'
2729
gem 'rspec'
28-
30+
gem 'pry'
2931
gem 'debugger', platforms: :mri_19
3032
gem 'byebug', platforms: :mri_20
3133
end
@@ -34,7 +36,3 @@ group :test do
3436
gem 'webmock', :require => 'webmock/rspec'
3537
gem 'vcr'
3638
end
37-
38-
group :production do
39-
gem 'newrelic_rpm', :require => false
40-
end

Gemfile.lock

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ GEM
2525
columnize (~> 0.8)
2626
debugger-linecache (~> 1.2)
2727
slop (~> 3.6)
28+
coderay (1.1.0)
2829
columnize (0.9.0)
2930
crack (0.4.2)
3031
safe_yaml (~> 1.0.0)
@@ -37,10 +38,15 @@ GEM
3738
descendants_tracker (0.0.4)
3839
thread_safe (~> 0.3, >= 0.3.1)
3940
diff-lcs (1.2.5)
41+
domain_name (0.5.20160128)
42+
unf (>= 0.0.5, < 1.0.0)
4043
dragonfly (0.9.15)
4144
multi_json (~> 1.0)
4245
rack
4346
excon (0.42.1)
47+
face (0.1.0)
48+
json (>= 1.4.6)
49+
rest-client (>= 1.6.1)
4450
faraday (0.9.0)
4551
multipart-post (>= 1.2, < 3)
4652
fastimage (1.6.6)
@@ -58,6 +64,8 @@ GEM
5864
tilt
5965
hashie (3.3.2)
6066
highline (1.6.21)
67+
http-cookie (1.0.2)
68+
domain_name (~> 0.5)
6169
httparty (0.13.3)
6270
json (~> 1.8)
6371
multi_xml (>= 0.5.2)
@@ -74,12 +82,14 @@ GEM
7482
json (1.8.1)
7583
jwt (1.2.0)
7684
kgio (2.9.2)
85+
method_source (0.8.2)
86+
mime-types (2.99)
7787
mini_portile (0.6.1)
7888
minitest (5.5.0)
7989
multi_json (1.10.1)
8090
multi_xml (0.5.5)
8191
multipart-post (2.0.0)
82-
newrelic_rpm (3.9.8.273)
92+
netrc (0.11.0)
8393
nokogiri (1.6.5)
8494
mini_portile (~> 0.6.0)
8595
oauth2 (1.0.0)
@@ -88,6 +98,10 @@ GEM
8898
multi_json (~> 1.3)
8999
multi_xml (~> 0.5)
90100
rack (~> 1.2)
101+
pry (0.10.3)
102+
coderay (~> 1.1.0)
103+
method_source (~> 0.8.1)
104+
slop (~> 3.4)
91105
rack (1.5.2)
92106
rack-attack (4.2.0)
93107
rack
@@ -99,6 +113,10 @@ GEM
99113
rake (10.4.2)
100114
rdoc (4.2.0)
101115
json (~> 1.4)
116+
rest-client (1.8.0)
117+
http-cookie (>= 1.0.2, < 2.0)
118+
mime-types (>= 1.16, < 3.0)
119+
netrc (~> 0.7)
102120
rspec (3.1.0)
103121
rspec-core (~> 3.1.0)
104122
rspec-expectations (~> 3.1.0)
@@ -121,6 +139,9 @@ GEM
121139
tilt (1.4.1)
122140
tzinfo (1.2.2)
123141
thread_safe (~> 0.1)
142+
unf (0.1.4)
143+
unf_ext
144+
unf_ext (0.0.7.2)
124145
unicorn (4.8.3)
125146
kgio (~> 2.6)
126147
rack
@@ -139,16 +160,20 @@ DEPENDENCIES
139160
debugger
140161
dragonfly (~> 0.9)
141162
excon
163+
face
142164
faraday
143165
fastimage
144166
haml
145167
jeweler
146168
magickly!
147-
newrelic_rpm
169+
pry
148170
rack-attack
149171
rack-test
150172
rspec
151173
sinatra (~> 1.2)
152174
unicorn
153175
vcr
154176
webmock
177+
178+
BUNDLED WITH
179+
1.10.6

lib/mustachio.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
module Mustachio
99
# FACE_POS_ATTRS = ['center', 'eye_left', 'eye_right', 'mouth_left', 'mouth_center', 'mouth_right', 'nose']
10-
REQUIRED_FACE_ATTRS = %w(mouth_left mouth_right nose)
10+
REQUIRED_FACE_ATTRS = %w(mouth_center nose)
1111
FACE_SPAN_SCALE = 2.0
1212

1313
class << self
@@ -72,7 +72,7 @@ def face_data_as_px(file_or_job, width, height)
7272
# TODO: make more robust by filtering out faces without all data
7373
new_faces = faces.map do |face|
7474
face_arr = face.map do |k, v|
75-
[k, { 'x' => (v['x'] * (width / 100.0)), 'y' => (v['y'] * (height / 100.0)) }]
75+
[k, { 'x' => (v['x'].to_f * (width.to_f / 100.0)), 'y' => (v['y'].to_f * (height.to_f / 100.0)) }]
7676
end
7777
Hash[face_arr]
7878
end

lib/mustachio/app.rb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ class App < Sinatra::Base
99
set :static, true
1010
use Rack::Attack
1111

12-
configure :production do
13-
require 'newrelic_rpm' if ENV['NEW_RELIC_ID']
14-
end
15-
16-
1712
def redirect_to_canonical_host
1813
app_host = ENV['MUSTACHIO_APP_DOMAIN']
1914
if app_host && request.host != app_host

lib/mustachio/factories.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
# resize to smaller than 900px, because Face.com downsizes the image to this anyway
77
# TODO move resize inside of Mustachio.face_data
88
faces = convert.image.thumb('900x900>').face_data_as_px(width, height)
9-
109
commands = ['-alpha Background -background Transparent']
1110
faces.each do |face|
1211
stache_num = case stache_num_param
@@ -31,7 +30,7 @@
3130
# of the upper lip, and the bottom-center of the stache
3231
# is mapped to the center of the mouth
3332

34-
rotation = Math.atan(( face['mouth_right']['y'] - face['mouth_left']['y'] ).to_f / ( face['mouth_right']['x'] - face['mouth_left']['x'] ).to_f ) / Math::PI * 180.0
33+
rotation = 90.0 - (Math.atan(( face['mouth_center']['y'] - face['nose']['y'] ).to_f / ( face['mouth_center']['x'] - face['nose']['x'] ).to_f ) / Math::PI * 180.0)
3534
desired_height = Math.sqrt(
3635
( face['nose']['x'] - face['mouth_center']['x'] ).to_f**2 +
3736
( face['nose']['y'] - face['mouth_center']['y'] ).to_f**2

lib/mustachio/rekognition.rb

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,61 +7,27 @@ class << self
77
REKOGNITION_SECRET = ENV['MUSTACHIO_REKOGNITION_SECRET'] || raise('please set MUSTACHIO_REKOGNITION_SECRET')
88

99

10-
def get_response(file, jobs)
11-
conn = Faraday.new :url => 'https://rekognition.com' do |faraday|
12-
faraday.request :multipart
13-
faraday.request :url_encoded
14-
faraday.adapter :excon
15-
end
16-
17-
payload = {
18-
:api_key => REKOGNITION_KEY,
19-
:api_secret => REKOGNITION_SECRET,
20-
:uploaded_file => Faraday::UploadIO.new(file, content_type(file)),
21-
:jobs => jobs,
22-
:name_space => '',
23-
:user_id => ''
24-
}
25-
26-
conn.post('/func/api/', payload)
27-
end
28-
29-
def json file, jobs = 'face'
30-
response = self.get_response(file, jobs)
31-
JSON.parse response.body
32-
end
33-
34-
def dims file
35-
`identify -format "%wx%h" #{file.path}`.strip.split('x').map(&:to_f)
10+
def get_response(file)
11+
client = Face.get_client(api_key: REKOGNITION_KEY, api_secret: REKOGNITION_SECRET)
12+
client.faces_detect(file: Faraday::UploadIO.new(file, content_type(file)))
3613
end
3714

3815
def content_type file
3916
`file -b --mime #{file.path}`.strip.split(/[:;]\s+/)[0]
4017
end
4118

4219
def validate_response(json)
43-
unless json['face_detection']
44-
usage = json['usage'] || {}
45-
msg = usage['status'] || 'failure.'
46-
raise Error.new("Rekognition API: #{msg}")
20+
unless json['status'] == 'success'
21+
msg = json['status']
22+
raise Error.new("SkyBiometry API: #{msg}")
4723
end
4824
end
4925

5026
def face_detection file
51-
json = self.json file, 'face_part'
27+
json = self.get_response file
5228
self.validate_response(json)
53-
width, height = self.dims file
5429

55-
json['face_detection'].map do |entry|
56-
mouth_left, mouth_right, nose = entry.values_at('mouth_l', 'mouth_r', 'nose').map do |dims|
57-
{
58-
'x' => ((dims['x'].to_f / width) * 100.0),
59-
'y' => ((dims['y'].to_f / height) * 100.0)
60-
}
61-
end
62-
63-
{ 'mouth_left' => mouth_left, 'mouth_right' => mouth_right, 'nose' => nose }
64-
end
30+
json['photos'].first['tags'].map {|entry| entry.slice('mouth_center', 'nose')}
6531
end
6632
end
6733
end

0 commit comments

Comments
 (0)