findaface 0.0.6 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: