yearbook 0.1.0 → 0.2.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.
- data/VERSION +1 -1
- data/go.rb +4 -1
- data/lib/yearbook/att_hash.rb +15 -0
- data/lib/yearbook/classifier.rb +26 -0
- data/lib/yearbook/image.rb +66 -32
- data/spec/spec_helper.rb +4 -0
- data/spec/yearbook_spec.rb +57 -6
- data/yearbook.gemspec +4 -2
- metadata +5 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/go.rb
CHANGED
@@ -4,7 +4,10 @@ require 'yearbook'
|
|
4
4
|
include Yearbook
|
5
5
|
PIMGS = Dir.glob "#{File.expand_path '../spec/fixtures/images', '__FILE__'}/*.jpg"
|
6
6
|
|
7
|
+
=begin
|
7
8
|
img = Yearbook::Image.new(PIMGS.first)
|
8
9
|
img.write('test.jpg') do |i|
|
9
10
|
i.bw
|
10
|
-
|
11
|
+
i.resize_to_fit 200, 500
|
12
|
+
end
|
13
|
+
=end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
class AttHash < SimpleDelegator
|
3
|
+
def initialize
|
4
|
+
@hsh = {}
|
5
|
+
super(@hsh)
|
6
|
+
end
|
7
|
+
|
8
|
+
def method_missing(foo, *args, &blk)
|
9
|
+
if @hsh.respond_to?(foo)
|
10
|
+
@hsh.send(foo, *args, &blk)
|
11
|
+
else
|
12
|
+
@hsh[foo.to_sym] = args
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Yearbook
|
2
|
+
module Classifier
|
3
|
+
|
4
|
+
DATA_DIR = File.expand_path('../../../data/classifiers', __FILE__ )
|
5
|
+
DATA_FILES = {
|
6
|
+
faces: File.join(DATA_DIR, 'haarcascade_frontalface_default.xml')
|
7
|
+
|
8
|
+
}
|
9
|
+
|
10
|
+
|
11
|
+
# returns an array of detected objects
|
12
|
+
def self.detect_objects(cv_image, object_type)
|
13
|
+
detector = load_detector(object_type.to_sym)
|
14
|
+
|
15
|
+
detector.detect_objects(cv_image)
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def self.load_detector(object_type)
|
20
|
+
fname = DATA_FILES[object_type]
|
21
|
+
puts fname
|
22
|
+
OpenCV::CvHaarClassifierCascade::load( fname )
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
data/lib/yearbook/image.rb
CHANGED
@@ -1,62 +1,96 @@
|
|
1
1
|
require 'rmagick'
|
2
2
|
require 'hashie'
|
3
|
+
require_relative 'att_hash'
|
4
|
+
require_relative 'classifier'
|
3
5
|
|
4
6
|
|
5
7
|
|
6
|
-
require 'delegate'
|
7
|
-
class AttHash < SimpleDelegator
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
super(@hsh)
|
12
|
-
end
|
9
|
+
module Yearbook
|
10
|
+
class Image
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
@
|
17
|
-
|
18
|
-
@hsh[foo.to_sym] = args
|
12
|
+
attr_reader :filename
|
13
|
+
def initialize(fname)
|
14
|
+
@filename = fname
|
15
|
+
@objects = []
|
19
16
|
end
|
20
|
-
end
|
21
|
-
end
|
22
17
|
|
23
18
|
|
19
|
+
def detect_objects(obj_type)
|
20
|
+
@objects = Classifier.detect_objects(cv_object, obj_type).to_a
|
21
|
+
end
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
def initialize(fname)
|
29
|
-
@magick_image = read_magick_image(fname)
|
23
|
+
def detect_faces
|
24
|
+
detect_objects(:faces)
|
30
25
|
end
|
31
26
|
|
27
|
+
def detected_objects
|
28
|
+
@objects
|
29
|
+
end
|
32
30
|
|
33
|
-
def write(
|
31
|
+
def write(base_out_fname, &blk)
|
34
32
|
klass = self.class
|
35
|
-
image_out = image_object
|
36
33
|
|
37
|
-
if
|
38
|
-
|
39
|
-
|
34
|
+
if @objects.empty?
|
35
|
+
img_objects = Array(image_object)
|
36
|
+
else
|
37
|
+
img_objects = @objects.map{|o| constitute_from_cv(o, image_object)}
|
38
|
+
end
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
img_objects.each_with_index do |image_out, idx|
|
41
|
+
if block_given?
|
42
|
+
h = AttHash.new
|
43
|
+
yield h
|
44
|
+
|
45
|
+
# transform the image
|
46
|
+
image_out = h.inject(image_out) do |img, (foo, args)|
|
47
|
+
klass.send(foo, img, *args)
|
48
|
+
end
|
44
49
|
end
|
45
|
-
end
|
46
50
|
|
47
|
-
|
51
|
+
if idx == 0
|
52
|
+
out_fname = base_out_fname
|
53
|
+
else
|
54
|
+
out_fname = base_out_fname.sub(/\.(?=\w+$)/, "-#{idx}.")
|
55
|
+
end
|
56
|
+
|
57
|
+
klass.output(image_out, out_fname)
|
58
|
+
end
|
48
59
|
end
|
49
60
|
|
50
61
|
|
62
|
+
|
63
|
+
|
64
|
+
|
51
65
|
private
|
52
|
-
def read_magick_image(fname)
|
53
|
-
Magick::Image::read(fname).first
|
54
|
-
end
|
55
66
|
|
67
|
+
|
68
|
+
# defer loading until it is needed
|
56
69
|
def image_object
|
57
|
-
@magick_image
|
70
|
+
@magick_image ||= load_magick_image(@filename)
|
58
71
|
end
|
59
72
|
|
73
|
+
def cv_object
|
74
|
+
@cv_image ||= load_cv_image(@filename)
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
def constitute_from_cv(c, img)
|
80
|
+
pixels = img.dispatch(c.x, c.y, c.width, c.height, "RGB")
|
81
|
+
|
82
|
+
return Magick::Image.constitute(c.width, c.height, "RGB", pixels)
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def load_magick_image(fname)
|
87
|
+
Magick::Image::read(fname).first
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
def load_cv_image(fname)
|
92
|
+
IplImage::load(fname)
|
93
|
+
end
|
60
94
|
|
61
95
|
|
62
96
|
# Image manipulation methods at the class level
|
data/spec/spec_helper.rb
CHANGED
data/spec/yearbook_spec.rb
CHANGED
@@ -1,8 +1,59 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module Yearbook
|
4
|
+
describe Image do
|
5
|
+
|
6
|
+
context 'instance' do
|
7
|
+
before do
|
8
|
+
@fname = File.join(IMAGE_DIR, 'bush-george-w.jpg')
|
9
|
+
@image = Image.new(@fname)
|
10
|
+
@tempfile = Tempfile.new 'bush.jpg'
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
@tempfile.unlink
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
describe 'initialization' do
|
19
|
+
it 'should have :filename reader' do
|
20
|
+
expect(@image.filename).to eq @fname
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#detect_faces' do
|
25
|
+
it 'should return an Array' do
|
26
|
+
expect( @image.detect_faces ).to be_an Array
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#write' do
|
31
|
+
it 'should write to disk' do
|
32
|
+
@image.write(@tempfile.path)
|
33
|
+
expect(@tempfile.size > 10000).to be_true
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'after faces have been detected' do
|
37
|
+
before do
|
38
|
+
@image.detect_faces
|
39
|
+
end
|
8
40
|
|
41
|
+
it 'should write each object to disk' do
|
42
|
+
last_num = @image.detected_objects.count - 1
|
43
|
+
path = @tempfile.path
|
44
|
+
last_path = path.sub(/\.(?=\w+$)/, "-#{last_num}.")
|
45
|
+
|
46
|
+
@image.write(path)
|
47
|
+
expect(File.exists?(last_path)).to be_true
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
data/yearbook.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "yearbook"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["dannguyen"]
|
12
|
-
s.date = "2013-11-
|
12
|
+
s.date = "2013-11-06"
|
13
13
|
s.description = "Easy face-cropping"
|
14
14
|
s.email = "dansonguyen@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -32,6 +32,8 @@ Gem::Specification.new do |s|
|
|
32
32
|
"data/classifiers/shameem_haarcascade_eye.xml",
|
33
33
|
"go.rb",
|
34
34
|
"lib/yearbook.rb",
|
35
|
+
"lib/yearbook/att_hash.rb",
|
36
|
+
"lib/yearbook/classifier.rb",
|
35
37
|
"lib/yearbook/image.rb",
|
36
38
|
"spec/fixtures/images/bush-george-w.jpg",
|
37
39
|
"spec/fixtures/images/obama-barack.jpg",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yearbook
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
12
|
+
date: 2013-11-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rmagick
|
@@ -178,6 +178,8 @@ files:
|
|
178
178
|
- data/classifiers/shameem_haarcascade_eye.xml
|
179
179
|
- go.rb
|
180
180
|
- lib/yearbook.rb
|
181
|
+
- lib/yearbook/att_hash.rb
|
182
|
+
- lib/yearbook/classifier.rb
|
181
183
|
- lib/yearbook/image.rb
|
182
184
|
- spec/fixtures/images/bush-george-w.jpg
|
183
185
|
- spec/fixtures/images/obama-barack.jpg
|
@@ -203,7 +205,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
203
205
|
version: '0'
|
204
206
|
segments:
|
205
207
|
- 0
|
206
|
-
hash:
|
208
|
+
hash: -163145999741884676
|
207
209
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
208
210
|
none: false
|
209
211
|
requirements:
|