findaface 0.0.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 078e59a9d21bbb4aa72fc81bee801b69019bda64
4
- data.tar.gz: 54ed12825955454be42fb02732374bd57f623edb
3
+ metadata.gz: 7f96dc6603d1aedf09e21aa75755408409479d85
4
+ data.tar.gz: e65f03a7a0efb180a31e35aef2fa2b29e2c47f7c
5
5
  SHA512:
6
- metadata.gz: bf0b6163665258ddd0da8c272075f8893d0ce4f0479c788ae885ab18550c4fb47df67aae52abc0048417b946c27027957de921dd43a7a3ab56e64b7feeded4cf
7
- data.tar.gz: 49220350b083ec128c7e813e4a9d0be6fae629a6839792acc9c76f9ffb5948a27b0625cd6e264b922af73caa752dc8818cef8924a89899fe0f7c451e2f0d9140
6
+ metadata.gz: 5a0c7ed26464b1130f89b5c03a57035f31a523494ea0a74b70c9a3b4a627f9e3c3f03060abde40f1b3b4a8033e524d265d264f33bf04843e2bcef2ce188542ae
7
+ data.tar.gz: 16adb61b23f56c9bb24dcacc1af8610ad92003d1debd93aa898245fb0e084214fe3af9d9c4b54721b11f09d170258f5a4c36bbac01bee065ec8b8042e9898e54
data/README.md CHANGED
@@ -1,11 +1,10 @@
1
1
  # Findaface
2
2
 
3
- When given a path to a picture, this gem attempts to determins whether it contains
4
- faces and thus might be appropriate for a profile image. It is looking for faces bigger than 80 pixels squared.
3
+ When given a path to a picture, this gem attempts to determins whether it contains any faces and thus might be appropriate for a profile image. It is looking for faces bigger than 80 pixels squared.
5
4
 
6
5
  It is a modified then gemified version of George Ogata's [find-face](https://github.com/howaboutwe/find-face). If you want a CLI that indicates where the biggest face in an image is, then use the original.
7
6
 
8
- This gem simply compiles an executable to detect a face then calls it externally, so you won't have to include the humongous OpenCV library into your Ruby process, which can cause memory leak / bloat or even crash. This is what [Paperclip](https://github.com/thoughtbot/paperclip) does for ImageMagick. We also support [posix-spawn](https://github.com/rtomayko/posix-spawn) to mitigate the overhead of fork-exec.
7
+ This gem simply compiles an executable to detect a face then calls it externally, so you won't have to include the humongous OpenCV library into your Ruby process, which can cause a memory leaks / bloat or even a crash. This is what [Paperclip](https://github.com/thoughtbot/paperclip) does for ImageMagick. We also support [posix-spawn](https://github.com/rtomayko/posix-spawn) to mitigate the overhead of fork-exec.
9
8
 
10
9
  ## Installation
11
10
 
@@ -52,11 +51,11 @@ $ gem install findaface
52
51
  ## Usage
53
52
 
54
53
  ```
55
- puts Findaface.has_face?('path/to/me.jpg')
54
+ puts Findaface.new.has_face?('path/to/me.jpg')
56
55
  => true
57
- puts Findaface.has_face?('path/to/me_in_a_group.jpg')
58
- => false
59
- puts Findaface.has_face?('path/to/my_cat.jpg')
56
+ puts Findaface.new.has_face?('path/to/me_in_a_group.jpg')
57
+ => true
58
+ puts Findaface.new.has_face?('path/to/my_cat.jpg')
60
59
  => false
61
60
  ```
62
61
 
@@ -84,10 +83,10 @@ Basically the scale factor is used to create your scale pyramid. More explanatio
84
83
  * max_size: Objects bigger than this are ignored.
85
84
 
86
85
  ### Using multiple cascades
87
- If you add multiple cascades then they will be applied in turn. If any of the cascades matche,
88
- findaface returns true.
86
+ If you add multiple cascades then they will be applied in turn. If any of the cascades match, then findaface returns true. You should add cascades before the first call to `has_face?` (unless you also want the default cascade to be applied).
89
87
  ```
90
- Findaface.add_cascade(
88
+ findaface = Findaface.new
89
+ findaface.add_cascade(
91
90
  {
92
91
  cascade:'haarcascades/haarcascade_mcs_nose.xml',
93
92
  fussyness:6,
@@ -96,7 +95,7 @@ Findaface.add_cascade(
96
95
  max_size: 512,
97
96
  }
98
97
  )
99
- Findaface.add_cascade(
98
+ findaface.add_cascade(
100
99
  {
101
100
  cascade:'haarcascades/haarcascade_eye.xml',
102
101
  fussyness:6,
@@ -106,9 +105,11 @@ Findaface.add_cascade(
106
105
  }
107
106
  )
108
107
 
109
- puts Findaface.has_face?('path/to/nose_or_eye.jpg')
108
+ puts findaface.has_face?('path/to/nose.jpg')
109
+ => true
110
+ puts findaface.has_face?('path/to/eye.jpg')
110
111
  => true
111
- puts Findaface.has_face?('path/to/mouth.jpg')
112
+ puts findaface.has_face?('path/to/mouth.jpg')
112
113
  => false
113
114
  ```
114
115
 
@@ -27,6 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "rspec", "~> 2.14"
28
28
  spec.add_development_dependency "pry"
29
29
  spec.add_development_dependency "pry-doc"
30
- spec.add_development_dependency "pry-debugger"
31
30
  spec.add_development_dependency "awesome_print"
32
31
  end
@@ -1,49 +1,49 @@
1
1
  require 'findaface/version'
2
2
  require 'posix/spawn'
3
3
 
4
- module Findaface
4
+ class Findaface
5
5
  LIB_PATH = File.dirname(File.expand_path(__FILE__))
6
6
  EXECUTABLE = File.join(LIB_PATH, '../ext/findaface/findaface')
7
7
  DEFAULT_CASCADE = {
8
- cascade:'haarcascades/haarcascade_frontalface_alt2.xml',
9
- fussyness:4,
10
- max_size: 512,
11
- min_size: 80,
12
- scale_factor: 1.05,
13
- }
8
+ cascade:'haarcascades/haarcascade_frontalface_alt2.xml',
9
+ fussyness:4,
10
+ max_size: 512,
11
+ min_size: 80,
12
+ scale_factor: 1.05,
13
+ }
14
14
  DEFAULT_OPTIONS = DEFAULT_CASCADE.keys
15
15
 
16
- class << self
17
- attr_reader :cascades
18
- end
16
+ class << self
17
+ attr_reader :cascades
18
+ end
19
19
 
20
- def self.has_face?(path)
20
+ def has_face?(path)
21
21
  raise "#{path} file does not exist" unless File.exists?(path)
22
- add_cascade(DEFAULT_CASCADE) if @cascades.nil?
23
- commands = @cascades.map { |opts| build_command(opts, path) }
24
- commands.each { |cmd| return true if POSIX::Spawn::system cmd }
25
- false
22
+ add_cascade(DEFAULT_CASCADE) if @cascades.nil?
23
+ commands = @cascades.map { |opts| build_command(opts, path) }
24
+ commands.each { |cmd| return true if POSIX::Spawn::system cmd }
25
+ false
26
26
  end
27
27
 
28
- def self.add_cascade(options)
28
+ def add_cascade(options)
29
29
  raise "Invalid setting. Got #{options.keys.sort}, require #{DEFAULT_OPTIONS}" unless options.keys.sort == DEFAULT_OPTIONS
30
- @cascades ||= []
31
- @cascades << options
32
- end
30
+ @cascades ||= []
31
+ @cascades << options
32
+ end
33
33
 
34
- private
34
+ private
35
35
 
36
- def self.build_command(options, path)
36
+ def build_command(options, path)
37
37
  "#{EXECUTABLE} " +
38
- "--cascade=#{cascade_path(options[:cascade])} " +
39
- "--fussyness=#{options[:fussyness]} " +
40
- "--scale_factor=#{options[:scale_factor]} " +
41
- "--min_size=#{options[:min_size]} " +
42
- "--max_size=#{options[:max_size]} " +
43
- "#{path} > /dev/null 2>&1"
44
- end
38
+ "--cascade=#{cascade_path(options[:cascade])} " +
39
+ "--fussyness=#{options[:fussyness]} " +
40
+ "--scale_factor=#{options[:scale_factor]} " +
41
+ "--min_size=#{options[:min_size]} " +
42
+ "--max_size=#{options[:max_size]} " +
43
+ "#{path}" # > /dev/null 2>&1"
44
+ end
45
45
 
46
- def self.cascade_path(cascade_path)
46
+ def cascade_path(cascade_path)
47
47
  File.join(LIB_PATH, cascade_path)
48
- end
48
+ end
49
49
  end
@@ -1,3 +1,3 @@
1
- module Findaface
2
- VERSION = '0.0.6'
1
+ class Findaface
2
+ VERSION = '1.0.0'
3
3
  end
@@ -0,0 +1,18 @@
1
+ = False Negatives
2
+ ![spec/test_photos/approval/real/real-05.jpg](spec/test_photos/approval/real/real-05.jpg)
3
+ ![spec/test_photos/approval/real/real-06.jpg](spec/test_photos/approval/real/real-06.jpg)
4
+ ![spec/test_photos/approval/real/real-08.jpg](spec/test_photos/approval/real/real-08.jpg)
5
+ ![spec/test_photos/approval/real/real-15.jpg](spec/test_photos/approval/real/real-15.jpg)
6
+ ![spec/test_photos/approval/real/real-24.jpg](spec/test_photos/approval/real/real-24.jpg)
7
+ ![spec/test_photos/approval/real/real-28.jpg](spec/test_photos/approval/real/real-28.jpg)
8
+ ![spec/test_photos/approval/real/real-29.jpg](spec/test_photos/approval/real/real-29.jpg)
9
+ ![spec/test_photos/approval/real/real-33.jpg](spec/test_photos/approval/real/real-33.jpg)
10
+ ![spec/test_photos/approval/real/real-34.jpg](spec/test_photos/approval/real/real-34.jpg)
11
+ ![spec/test_photos/approval/real/real-35.jpg](spec/test_photos/approval/real/real-35.jpg)
12
+ ![spec/test_photos/approval/real/real-36.jpg](spec/test_photos/approval/real/real-36.jpg)
13
+ ![spec/test_photos/approval/real/real-38.jpg](spec/test_photos/approval/real/real-38.jpg)
14
+ ![spec/test_photos/approval/real/real-40.jpg](spec/test_photos/approval/real/real-40.jpg)
15
+ ![spec/test_photos/approval/real/real-41.jpg](spec/test_photos/approval/real/real-41.jpg)
16
+ ![spec/test_photos/approval/real/real-43.jpg](spec/test_photos/approval/real/real-43.jpg)
17
+ ![spec/test_photos/approval/real/real-45.jpg](spec/test_photos/approval/real/real-45.jpg)
18
+ ![spec/test_photos/approval/real/real-50.jpg](spec/test_photos/approval/real/real-50.jpg)
@@ -2,53 +2,69 @@ require_relative '../lib/findaface.rb'
2
2
 
3
3
  describe Findaface, "has_face?" do
4
4
 
5
+ let(:face) { 'spec/photos/face.jpg' }
6
+ let(:eye) { 'spec/photos/eye.jpg' }
7
+ let(:nose) { 'spec/photos/nose.jpg' }
8
+ let(:fruit) { 'spec/photos/fruit.jpg' }
9
+
5
10
  it "finds faces" do
6
- Dir['spec/test_photos/has_face/*'].each do |path|
7
- Findaface.has_face?(path).should be_true
8
- end
11
+ Findaface.new.has_face?(face).should be_true
9
12
  end
10
13
 
11
14
  it "doesn't give false positives" do
12
- Dir['spec/test_photos/no_face/*'].each do |path|
13
- Findaface.has_face?(path).should be_false
14
- end
15
+ Findaface.new.has_face?(eye).should_not be_true
15
16
  end
16
17
 
17
- it "returns false for photos with small faces" do
18
- Dir['spec/test_photos/small_faces/*'].each do |path|
19
- Findaface.has_face?(path).should be_false
18
+ context "with custom cascade options" do
19
+ before :each do
20
+ @nose_detecter = Findaface.new
21
+ @nose_detecter.add_cascade({
22
+ cascade:'haarcascades/haarcascade_mcs_nose.xml',
23
+ fussyness: 7,
24
+ scale_factor: 1.05,
25
+ min_size: 80,
26
+ max_size: 512,
27
+ })
28
+ end
29
+
30
+ it "finds a nose" do
31
+ @nose_detecter.has_face?(nose).should be_true
32
+ end
33
+
34
+ it "doesn't give false positives" do
35
+ @nose_detecter.has_face?(eye).should_not be_true
20
36
  end
21
37
  end
22
38
 
23
- context "with multiple cascades" do
24
- it "can detect a nose, eye, and face" do
25
- Findaface.add_cascade(
26
- {
27
- cascade:'haarcascades/haarcascade_mcs_nose.xml',
28
- fussyness:7,
29
- scale_factor: 1.044,
30
- min_size: 100,
31
- }
32
- )
33
- Findaface.add_cascade(
34
- {
35
- cascade:'haarcascades/haarcascade_eye.xml',
36
- fussyness:7,
37
- scale_factor: 1.05,
38
- min_size: 100,
39
- }
40
- )
41
- Findaface.add_cascade(
42
- {
43
- cascade:'haarcascades/haarcascade_frontalface_detault.xml',
44
- fussyness:7,
45
- scale_factor: 1.05,
46
- min_size: 100,
47
- }
48
- )
49
- Dir['spec/test_photos/eye_nose_face/*'].each do |path|
50
- Findaface.has_face?(path).should be_true
51
- end
52
- end
53
- end
39
+ context "with multiple cascades" do
40
+ it "can detect a nose, eye, and face" do
41
+ findaface = Findaface.new
42
+ findaface.add_cascade(
43
+ {
44
+ cascade:'haarcascades/haarcascade_eye.xml',
45
+ fussyness: 8,
46
+ scale_factor: 1.05,
47
+ min_size: 100,
48
+ max_size: 512,
49
+ })
50
+ findaface.add_cascade({
51
+ cascade:'haarcascades/haarcascade_mcs_nose.xml',
52
+ fussyness: 8,
53
+ scale_factor: 1.044,
54
+ min_size: 100,
55
+ max_size: 512,
56
+ })
57
+ findaface.add_cascade(
58
+ {
59
+ cascade:'haarcascades/haarcascade_frontalface_alt2.xml',
60
+ fussyness: 8,
61
+ scale_factor: 1.05,
62
+ min_size: 100,
63
+ max_size: 512,
64
+ })
65
+ [eye, nose, face].each do |path|
66
+ findaface.has_face?(path).should be_true
67
+ end
68
+ end
69
+ end
54
70
  end
Binary file
Binary file
Binary file
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: findaface
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Nagi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-09 00:00:00.000000000 Z
11
+ date: 2014-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: posix-spawn
@@ -94,20 +94,6 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: pry-debugger
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: awesome_print
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -172,15 +158,12 @@ files:
172
158
  - lib/readme.txt
173
159
  - lib/softcascade/inria_caltech-17.01.2013.xml
174
160
  - lib/softcascade/soft-cascade-17.12.2012.xml
161
+ - report.md
175
162
  - spec/findaface_spec.rb
176
- - spec/test_photos/eye_nose_face/eye.jpg
177
- - spec/test_photos/eye_nose_face/face.jpg
178
- - spec/test_photos/eye_nose_face/nose.jpg
179
- - spec/test_photos/has_face/.gitkeep
180
- - spec/test_photos/has_face/face.jpg
181
- - spec/test_photos/no_face/.gitkeep
182
- - spec/test_photos/no_face/fruit.jpg
183
- - spec/test_photos/small_faces/beach.jpg
163
+ - spec/photos/eye.jpg
164
+ - spec/photos/face.jpg
165
+ - spec/photos/fruit.jpg
166
+ - spec/photos/nose.jpg
184
167
  homepage: ''
185
168
  licenses:
186
169
  - MIT
@@ -201,18 +184,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
201
184
  version: '0'
202
185
  requirements: []
203
186
  rubyforge_project:
204
- rubygems_version: 2.2.0
187
+ rubygems_version: 2.2.2
205
188
  signing_key:
206
189
  specification_version: 4
207
190
  summary: Finds a face in an image.
208
191
  test_files:
209
192
  - spec/findaface_spec.rb
210
- - spec/test_photos/eye_nose_face/eye.jpg
211
- - spec/test_photos/eye_nose_face/face.jpg
212
- - spec/test_photos/eye_nose_face/nose.jpg
213
- - spec/test_photos/has_face/.gitkeep
214
- - spec/test_photos/has_face/face.jpg
215
- - spec/test_photos/no_face/.gitkeep
216
- - spec/test_photos/no_face/fruit.jpg
217
- - spec/test_photos/small_faces/beach.jpg
193
+ - spec/photos/eye.jpg
194
+ - spec/photos/face.jpg
195
+ - spec/photos/fruit.jpg
196
+ - spec/photos/nose.jpg
218
197
  has_rdoc: