sqed 0.1.2 → 0.1.3
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 +4 -4
- data/lib/sqed.rb +1 -1
- data/lib/sqed/boundary_finder.rb +34 -6
- data/lib/sqed/boundary_finder/color_line_finder.rb +41 -41
- data/lib/sqed/version.rb +1 -1
- data/lib/sqed_config.rb +17 -10
- data/spec/lib/sqed/boundaries_spec.rb +1 -1
- data/spec/lib/sqed/boundary_finder/color_line_finder_spec.rb +50 -6
- data/spec/lib/sqed/boundary_finder_spec.rb +66 -62
- data/spec/lib/sqed_spec.rb +1 -1
- data/spec/support/files/stage_images/frost_stage_medium.jpg +0 -0
- data/spec/support/files/stage_images/frost_stage_thumb.jpg +0 -0
- data/spec/support/image_helpers.rb +11 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4fc79ffe69e04fb549335328b4cb1e1288cbcf37
|
4
|
+
data.tar.gz: 89e513debbd76b425584416cfb8a32f1e8932aa2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c7b1fc8db47d2efff2fce8767c2c6d7e219f184f23142a55875436c67cd4c07b3503f2ee731467ce62cc47db21ebbd73c62780e365da81f873a6260855c38b8
|
7
|
+
data.tar.gz: 648bf20fed24fb28e8aa003e71c04e0606ba82d748f9fc3b814add434235de283b5f734fea7e26df04e5b39a32cc6139cf20270d01427ac966530e7d536ffe19
|
data/lib/sqed.rb
CHANGED
data/lib/sqed/boundary_finder.rb
CHANGED
@@ -25,6 +25,31 @@ class Sqed::BoundaryFinder
|
|
25
25
|
@boundaries ||= Sqed::Boundaries.new(@layout)
|
26
26
|
end
|
27
27
|
|
28
|
+
|
29
|
+
# return [Integer, nil]
|
30
|
+
# sample more with small images, less with large images
|
31
|
+
# we want to return larger numbers (= faster sampling)
|
32
|
+
#
|
33
|
+
#
|
34
|
+
def self.get_subdivision_size(image_width)
|
35
|
+
case image_width
|
36
|
+
when nil
|
37
|
+
nil
|
38
|
+
when 0..140
|
39
|
+
6
|
40
|
+
when 141..640
|
41
|
+
12
|
42
|
+
when 641..1000
|
43
|
+
16
|
44
|
+
when 1001..3000
|
45
|
+
60
|
46
|
+
when 3001..6400
|
47
|
+
80
|
48
|
+
else
|
49
|
+
140
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
28
53
|
# @return
|
29
54
|
# the column (x position) in the middle of the single green vertical line dividing the stage
|
30
55
|
#
|
@@ -43,16 +68,19 @@ class Sqed::BoundaryFinder
|
|
43
68
|
# @param scan
|
44
69
|
# (:rows|:columns), :rows finds vertical borders, :columns finds horizontal borders
|
45
70
|
#
|
46
|
-
def self.color_boundary_finder(image: image, sample_subdivision_size:
|
71
|
+
def self.color_boundary_finder(image: image, sample_subdivision_size: nil, sample_cutoff_factor: nil, scan: :rows, boundary_color: :green)
|
72
|
+
image_width = image.send(scan)
|
73
|
+
sample_subdivision_size = get_subdivision_size(image_width) if sample_subdivision_size.nil?
|
74
|
+
samples_to_take = (image_width / sample_subdivision_size).to_i - 1
|
75
|
+
|
47
76
|
border_hits = {}
|
48
|
-
samples_to_take = (image.send(scan) / sample_subdivision_size).to_i - 1
|
49
77
|
|
50
78
|
(0..samples_to_take).each do |s|
|
51
79
|
# Create a sample image a single pixel tall
|
52
80
|
if scan == :rows
|
53
|
-
j = image.crop(0, s * sample_subdivision_size, image.columns, 1)
|
81
|
+
j = image.crop(0, s * sample_subdivision_size, image.columns, 1, true)
|
54
82
|
elsif scan == :columns
|
55
|
-
j = image.crop(s * sample_subdivision_size, 0, 1, image.rows)
|
83
|
+
j = image.crop(s * sample_subdivision_size, 0, 1, image.rows, true)
|
56
84
|
else
|
57
85
|
raise
|
58
86
|
end
|
@@ -101,8 +129,8 @@ class Sqed::BoundaryFinder
|
|
101
129
|
(pixel.red < black_threshold) && (pixel.blue < black_threshold) && (pixel.green < black_threshold)
|
102
130
|
end
|
103
131
|
|
104
|
-
#
|
105
|
-
#
|
132
|
+
# return [Array]
|
133
|
+
# the median position of all (pixel) positions that have a count greater than the cutoff
|
106
134
|
def self.frequency_stats(frequency_hash, sample_cutoff = 0)
|
107
135
|
return nil if sample_cutoff.nil? || sample_cutoff < 1
|
108
136
|
hit_ranges = []
|
@@ -21,69 +21,69 @@ class Sqed::BoundaryFinder::ColorLineFinder < Sqed::BoundaryFinder
|
|
21
21
|
return if t.nil?
|
22
22
|
boundaries.set(0, [0, 0, t[0], img.rows]) # left section of image
|
23
23
|
boundaries.set(1, [t[2], 0, img.columns - t[2], img.rows]) # right section of image
|
24
|
-
boundaries.complete = true
|
25
24
|
|
26
25
|
when :horizontal_split
|
27
26
|
t = Sqed::BoundaryFinder.color_boundary_finder(image: img, scan: :columns, boundary_color: @boundary_color) # set to detect horizontal division, (green line)
|
28
27
|
return if t.nil?
|
29
28
|
boundaries.set(0, [0, 0, img.columns, t[0]]) # upper section of image
|
30
29
|
boundaries.set(1, [0, t[2], img.columns, img.rows - t[2]]) # lower section of image
|
31
|
-
boundaries.complete = true
|
32
|
-
# boundaries.coordinates[2] = [0, 0, img.columns, t[1]] # upper section of image
|
33
|
-
# boundaries.coordinates[3] = [0, t[1], img.columns, img.rows - t[1]] # lower section of image
|
34
30
|
|
35
31
|
when :right_t # only 3 zones expected, with horizontal division in right-side of vertical division
|
36
|
-
|
37
|
-
|
32
|
+
vertical = self.class.new(image: @img, layout: :vertical_split, boundary_color: @boundary_color ).boundaries
|
33
|
+
irt = img.crop(*vertical.for(1), true)
|
34
|
+
right = self.class.new(image: irt, layout: :horizontal_split, boundary_color: @boundary_color ).boundaries
|
35
|
+
|
36
|
+
boundaries.set(0, vertical.for(0))
|
37
|
+
boundaries.set(1, [ vertical.x_for(1), 0, right.width_for(0), right.height_for(0) ] )
|
38
|
+
boundaries.set(2, [ vertical.x_for(1), right.y_for(1), right.width_for(1), right.height_for(1)] )
|
38
39
|
|
39
|
-
|
40
|
-
|
40
|
+
when :vertical_offset_cross # 4 zones expected, with (varying) horizontal division in left- and right- sides of vertical division
|
41
|
+
vertical = self.class.new(image: @img, layout: :vertical_split, boundary_color: @boundary_color ).boundaries
|
42
|
+
|
43
|
+
ilt = img.crop(*vertical.for(0), true)
|
44
|
+
irt = img.crop(*vertical.for(1), true)
|
41
45
|
|
42
|
-
|
46
|
+
left = self.class.new(image: ilt, layout: :horizontal_split, boundary_color: @boundary_color ).boundaries
|
47
|
+
right = self.class.new(image: irt, layout: :horizontal_split, boundary_color: @boundary_color ).boundaries
|
43
48
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
boundaries.set(1, [t[2], 0, img.columns - t[2], rt[0]]) # upper section of image
|
49
|
-
boundaries.set(2, [t[2], rt[2], img.columns - t[2], img.rows - rt[2]]) # lower section of image
|
50
|
-
boundaries.complete = true
|
51
|
-
# will return 1, 2, or 3
|
49
|
+
boundaries.set(0, [0, 0, left.width_for(0), left.height_for(0) ])
|
50
|
+
boundaries.set(1, [vertical.x_for(1), 0, right.width_for(0), right.height_for(0) ])
|
51
|
+
boundaries.set(2, [vertical.x_for(1), right.y_for(1), right.width_for(1), right.height_for(1) ])
|
52
|
+
boundaries.set(3, [0, left.y_for(1), left.width_for(1), left.height_for(1) ])
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
54
|
+
# No specs for this yet
|
55
|
+
when :horizontal_offset_cross
|
56
|
+
horizontal = self.class.new(image: @img, layout: :horizontal_split, boundary_color: @boundary_color ).boundaries
|
56
57
|
|
57
|
-
|
58
|
-
|
58
|
+
itop = img.crop(*horizontal.for(0), true)
|
59
|
+
ibottom = img.crop(*horizontal.for(1), true)
|
59
60
|
|
60
|
-
|
61
|
-
|
61
|
+
top = self.class.new(image: ilt, layout: :vertical_split, boundary_color: @boundary_color ).boundaries
|
62
|
+
bottom = self.class.new(image: irt, layout: :vertical_split, boundary_color: @boundary_color ).boundaries
|
62
63
|
|
63
|
-
|
64
|
+
boundaries.set(0, [0, 0, top.width_for(0), top.height_for(0) ])
|
65
|
+
boundaries.set(1, [top.x_for(1), 0, top.width_for(1), top.height_for(1) ])
|
66
|
+
boundaries.set(2, [bottom.x_for(1), horizontal.y_for(1), bottom.width_for(1), bottom.height_for(1) ])
|
67
|
+
boundaries.set(3, [0, horizontal.y_for(1), bottom.width_for(0), bottom.height_for(0) ])
|
64
68
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
+
when :cross # 4 zones, with perfectly intersected horizontal and vertical division
|
70
|
+
v = self.class.new(image: @img, layout: :vertical_split, boundary_color: @boundary_color ).boundaries
|
71
|
+
h = self.class.new(image: @img, layout: :horizontal_split, boundary_color: @boundary_color ).boundaries
|
72
|
+
|
73
|
+
return if v.nil? || h.nil?
|
69
74
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
75
|
+
boundaries.set(0, [0,0, v.width_for(0), h.height_for(0) ])
|
76
|
+
boundaries.set(1, [ v.x_for(1), 0, v.width_for(1), h.height_for(0) ])
|
77
|
+
boundaries.set(2, [ v.x_for(1), h.y_for(1), v.width_for(1), h.height_for(1) ])
|
78
|
+
boundaries.set(3, [0, h.y_for(1), v.width_for(0), h.height_for(1) ])
|
74
79
|
|
75
|
-
|
76
|
-
boundaries.set(2, [t[2], rt[2], img.columns - t[2], img.rows - rt[2]]) # lower section of image
|
77
|
-
# will return 1, 2, 3, or 4 //// does not handle staggered vertical boundary case
|
78
|
-
|
79
|
-
boundaries.complete = true if boundaries.populated?
|
80
|
+
else # no @layout provided !?
|
80
81
|
|
81
|
-
else
|
82
82
|
boundaries.set(0, [0, 0, img.columns, img.rows]) # totality of image as default
|
83
|
-
# TODO: boundaries.complete status here?
|
84
|
-
return # return original image boundary if no method implemented
|
85
83
|
end
|
86
84
|
|
85
|
+
boundaries.complete = true if boundaries.populated?
|
86
|
+
|
87
87
|
end
|
88
88
|
|
89
89
|
|
data/lib/sqed/version.rb
CHANGED
data/lib/sqed_config.rb
CHANGED
@@ -19,25 +19,31 @@ module SqedConfig
|
|
19
19
|
# Layouts refer to the arrangement of the divided stage.
|
20
20
|
# Windows are enumerated from the top left, moving around the border
|
21
21
|
# in a clockwise position. For example:
|
22
|
+
#
|
22
23
|
# 0 | 1
|
23
|
-
# ----|---- :equal_cross
|
24
|
+
# ----|---- :equal_cross (always perfectly divided through the center)
|
24
25
|
# 3 | 2
|
25
26
|
#
|
26
|
-
# | 1
|
27
|
-
# 0 |---- :right_t
|
28
|
-
# | 2
|
29
27
|
#
|
30
|
-
#
|
28
|
+
# 0 | 1
|
29
|
+
# ----|---- :cross (height of [0, 1], [2,3] same, width of [0,1], [2,3] same, otherwise variable (i.e. height(0) != height(3))
|
30
|
+
# |
|
31
|
+
# 3 | 2
|
32
|
+
#
|
31
33
|
# 0 | 1
|
32
34
|
# |
|
33
|
-
# --------- :
|
35
|
+
# --------- :horizontal_offset_cross // NOT CURRENTLY IMPLEMENTED
|
34
36
|
# 3 | 2
|
35
37
|
#
|
38
|
+
#
|
36
39
|
# 0 | 1
|
37
40
|
# |____
|
38
|
-
# ----| :
|
41
|
+
# ----| :vertical_offset_cross // matches current code !!
|
39
42
|
# 3 | 2
|
40
43
|
#
|
44
|
+
# | 1
|
45
|
+
# 0 |---- :right_t
|
46
|
+
# | 2
|
41
47
|
# 0
|
42
48
|
# -------- :horizontal_split
|
43
49
|
# 1
|
@@ -53,9 +59,10 @@ module SqedConfig
|
|
53
59
|
|
54
60
|
# Hash values are used to stub out
|
55
61
|
# the Sqed::Boundaries instance.
|
62
|
+
# TODO: deprecate for simpler breakdown (cross, split, t)
|
56
63
|
LAYOUTS = {
|
57
64
|
cross: [0,1,2,3],
|
58
|
-
|
65
|
+
vertical_offset_cross: [0,1,2,3],
|
59
66
|
horizontal_split: [0,1],
|
60
67
|
vertical_split: [0,1],
|
61
68
|
right_t: [0,1,2],
|
@@ -91,9 +98,9 @@ module SqedConfig
|
|
91
98
|
layout: :right_t,
|
92
99
|
metadata_map: {0 => :annotated_specimen, 1 => :identifier, 2 =>:image_registration }
|
93
100
|
},
|
94
|
-
|
101
|
+
vertical_offset_cross: {
|
95
102
|
boundary_finder: Sqed::BoundaryFinder::ColorLineFinder,
|
96
|
-
layout: :
|
103
|
+
layout: :vertical_offset_cross,
|
97
104
|
metadata_map: {0 => :curator_metadata, 1 => :identifier, 2 => :image_registration, 3 => :specimen }
|
98
105
|
# metadata_map: {0 => :annotated_specimen, 1 => :identifier, 2 =>:image_registration }
|
99
106
|
},
|
@@ -33,7 +33,7 @@ describe Sqed::Boundaries do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
context '#offset' do
|
36
|
-
let(:s) { Sqed.new(image: ImageHelpers.crossy_green_line_specimen, pattern: :
|
36
|
+
let(:s) { Sqed.new(image: ImageHelpers.crossy_green_line_specimen, pattern: :vertical_offset_cross) }
|
37
37
|
let(:offset_boundaries) {
|
38
38
|
s.crop_image
|
39
39
|
s.boundaries.offset(s.stage_boundary)
|
@@ -10,12 +10,12 @@ describe Sqed::BoundaryFinder::ColorLineFinder do
|
|
10
10
|
|
11
11
|
let(:e) { Sqed::BoundaryFinder::ColorLineFinder.new(image: d, layout: :right_t) }
|
12
12
|
let(:f) { e.boundaries }
|
13
|
-
let(:g) { Sqed::BoundaryFinder::ColorLineFinder.new(image: d, layout: :
|
13
|
+
let(:g) { Sqed::BoundaryFinder::ColorLineFinder.new(image: d, layout: :vertical_offset_cross)}
|
14
14
|
let(:h) { g.boundaries }
|
15
15
|
let(:gv) { Sqed::BoundaryFinder::ColorLineFinder.new(image: d, layout: :vertical_split) }
|
16
16
|
let(:hv) { gv.boundaries }
|
17
17
|
|
18
|
-
let(:ah) { ImageHelpers.
|
18
|
+
let(:ah) { ImageHelpers.vertical_offset_cross_red }
|
19
19
|
let(:bh) { Sqed::BoundaryFinder::StageFinder.new(image: ah) }
|
20
20
|
let(:ch) { bh.boundaries }
|
21
21
|
let(:dh) { ah.crop(*ch.for(0), true) }
|
@@ -26,7 +26,7 @@ describe Sqed::BoundaryFinder::ColorLineFinder do
|
|
26
26
|
let(:bbs) { Sqed::BoundaryFinder::StageFinder.new(image: ibs) }
|
27
27
|
let(:cbs) { bbs.boundaries }
|
28
28
|
let(:dbs) { ibs.crop(*cbs.for(0), true) }
|
29
|
-
let(:gbs) { Sqed::BoundaryFinder::ColorLineFinder.new(image: dbs, layout: :
|
29
|
+
let(:gbs) { Sqed::BoundaryFinder::ColorLineFinder.new(image: dbs, layout: :vertical_offset_cross) }
|
30
30
|
let(:hbs) { gbs.boundaries }
|
31
31
|
|
32
32
|
specify 'initial image columns are as expected for :image above' do
|
@@ -51,7 +51,7 @@ describe Sqed::BoundaryFinder::ColorLineFinder do
|
|
51
51
|
|
52
52
|
specify "CrossGreenLinesSpecimen using right_t layout should yield 3 rectangular boundaries" do
|
53
53
|
# use the f object for right_t
|
54
|
-
f.each do |i, coord|
|
54
|
+
f.each do |i, coord|
|
55
55
|
q = d.crop(*coord, true)
|
56
56
|
q.write("tmp/q0#{i}.jpg")
|
57
57
|
end
|
@@ -75,7 +75,7 @@ describe Sqed::BoundaryFinder::ColorLineFinder do
|
|
75
75
|
expect(f.height_for(2)).to be_within(pct*964).of(964)
|
76
76
|
end
|
77
77
|
|
78
|
-
specify "CrossGreenLinesSpecimen using
|
78
|
+
specify "CrossGreenLinesSpecimen using vertical_offset_cross layout should yield 4 rectangular boundaries" do
|
79
79
|
h.each do |i, coord|
|
80
80
|
q = d.crop(*coord, true)
|
81
81
|
q.write("tmp/q1#{i}.jpg")
|
@@ -124,7 +124,7 @@ describe Sqed::BoundaryFinder::ColorLineFinder do
|
|
124
124
|
expect(hv.height_for(1)).to be_within(0.02*1990).of(1990)
|
125
125
|
end
|
126
126
|
|
127
|
-
specify "
|
127
|
+
specify "boundary_vertical_offset_cross_red using horizontal_split layout should yield 2 rectangular boundaries" do
|
128
128
|
hh.each do |k, v|
|
129
129
|
q = dh.crop(*v, true)
|
130
130
|
q.write("tmp/q3#{k}.jpg")
|
@@ -164,4 +164,48 @@ describe Sqed::BoundaryFinder::ColorLineFinder do
|
|
164
164
|
expect(hbs.height_for(3)).to be_within(0.02*1677).of(1677)
|
165
165
|
end
|
166
166
|
|
167
|
+
context 'thumbnail processing finds reasonable boundaries' do
|
168
|
+
|
169
|
+
let(:thumb) { ImageHelpers.frost_stage_thumb }
|
170
|
+
let(:finder) { Sqed::BoundaryFinder::ColorLineFinder.new(image: thumb, layout: :cross)}
|
171
|
+
let(:finder_boundaries) { finder.boundaries }
|
172
|
+
|
173
|
+
let(:pct) { 0.08 }
|
174
|
+
|
175
|
+
before {
|
176
|
+
finder.boundaries.each do |i, coord|
|
177
|
+
# q = thumb.crop(*coord, true)
|
178
|
+
# q.write("tmp/thumb#{i}.jpg")
|
179
|
+
end
|
180
|
+
}
|
181
|
+
|
182
|
+
specify "for section 0" do
|
183
|
+
expect(finder_boundaries.x_for(0)).to be_within(pct*thumb.columns).of(0)
|
184
|
+
expect(finder_boundaries.y_for(0)).to be_within(pct*0).of(0)
|
185
|
+
expect(finder_boundaries.width_for(0)).to be_within(pct*66).of(66)
|
186
|
+
expect(finder_boundaries.height_for(0)).to be_within(pct*13).of(13)
|
187
|
+
end
|
188
|
+
|
189
|
+
specify 'for section 1' do
|
190
|
+
expect(finder_boundaries.x_for(1)).to be_within(pct*69).of(69)
|
191
|
+
expect(finder_boundaries.y_for(1)).to be_within(pct*0).of(0)
|
192
|
+
expect(finder_boundaries.width_for(1)).to be_within(pct*32).of(32)
|
193
|
+
expect(finder_boundaries.height_for(1)).to be_within(pct*14).of(14)
|
194
|
+
end
|
195
|
+
|
196
|
+
specify 'for section 2' do
|
197
|
+
expect(finder_boundaries.x_for(2)).to be_within(pct*69).of(69)
|
198
|
+
expect(finder_boundaries.y_for(2)).to be_within(pct*17).of(17)
|
199
|
+
expect(finder_boundaries.width_for(2)).to be_within(pct*32).of(32)
|
200
|
+
expect(finder_boundaries.height_for(2)).to be_within(pct*59).of(59)
|
201
|
+
end
|
202
|
+
|
203
|
+
specify 'for section 3' do
|
204
|
+
expect(finder_boundaries.x_for(3)).to be_within(0).of(0)
|
205
|
+
expect(finder_boundaries.y_for(3)).to be_within(pct*17).of(17)
|
206
|
+
expect(finder_boundaries.width_for(3)).to be_within(pct*65).of(65)
|
207
|
+
expect(finder_boundaries.height_for(3)).to be_within(pct*59).of(59)
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
167
211
|
end
|
@@ -7,7 +7,7 @@ describe Sqed::BoundaryFinder do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
context 'when initiated with an image' do
|
10
|
-
let(:b) {Sqed::BoundaryFinder.new(image: ImageHelpers.standard_cross_green, layout: :
|
10
|
+
let(:b) {Sqed::BoundaryFinder.new(image: ImageHelpers.standard_cross_green, layout: :vertical_offset_cross)}
|
11
11
|
|
12
12
|
context 'attributes' do
|
13
13
|
specify '#img' do
|
@@ -20,75 +20,79 @@ describe Sqed::BoundaryFinder do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
context '.color_boundary_finder(image: image
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
23
|
+
context '.color_boundary_finder(image: image)' do
|
24
|
+
context 'with sample_subdivision_size: 10' do
|
25
|
+
specify 'finds the vertical dividing line in a standard cross, with border still present' do
|
26
|
+
center = Sqed::BoundaryFinder.color_boundary_finder(image: ImageHelpers.standard_cross_green, sample_subdivision_size: 10 )[1]
|
27
|
+
expect(center).to be > 492
|
28
|
+
expect(center).to be < 504
|
29
|
+
end
|
30
|
+
|
31
|
+
specify 'finds the vertical dividing line in a right t green cross, with border still present' do
|
32
|
+
center = Sqed::BoundaryFinder.color_boundary_finder(image: ImageHelpers.right_t_green, sample_subdivision_size: 10)[1]
|
33
|
+
expect(center).to be > 695
|
34
|
+
expect(center).to be < 705
|
35
|
+
end
|
34
36
|
end
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
context 'with sample_subdivision_size auto set' do
|
39
|
+
specify 'finds the vertical dividing line in a standard cross, with border still present, when more precise' do
|
40
|
+
center = Sqed::BoundaryFinder.color_boundary_finder(image: ImageHelpers.standard_cross_green, sample_cutoff_factor: 0.7)[1]
|
41
|
+
expect(center).to be > 492
|
42
|
+
expect(center).to be < 504
|
43
|
+
end
|
41
44
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
specify 'finds the vertical dividing line a real image, with border still present' do
|
46
|
+
center = Sqed::BoundaryFinder.color_boundary_finder(image: ImageHelpers.crossy_green_line_specimen)[1]
|
47
|
+
expect(center).to be > 2452
|
48
|
+
expect(center).to be < 2495
|
49
|
+
end
|
47
50
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
specify 'finds the vertical dividing line a real image, with border still present, with 10x fewer subsamples' do
|
52
|
+
center = Sqed::BoundaryFinder.color_boundary_finder(image: ImageHelpers.crossy_green_line_specimen, sample_subdivision_size: 100 )[1]
|
53
|
+
expect(center).to be > 2452
|
54
|
+
expect(center).to be < 2495
|
55
|
+
end
|
53
56
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
specify 'finds the vertical dividing line a real image, with border still present, with 50x fewer subsamples' do
|
58
|
+
center = Sqed::BoundaryFinder.color_boundary_finder(image: ImageHelpers.crossy_green_line_specimen, sample_subdivision_size: 500 )[1]
|
59
|
+
expect(center).to be > 2452
|
60
|
+
expect(center).to be < 2495
|
61
|
+
end
|
59
62
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
63
|
+
specify 'FAILS to find the vertical dividing line a real image, with border still present, with 200x fewer subsamples' do
|
64
|
+
center = Sqed::BoundaryFinder.color_boundary_finder(image: ImageHelpers.crossy_green_line_specimen, sample_subdivision_size: 2000 )
|
65
|
+
expect(center).to be nil
|
66
|
+
end
|
64
67
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
68
|
+
specify 'finds the vertical dividing line another real image, with border still present' do
|
69
|
+
center = Sqed::BoundaryFinder.color_boundary_finder(image: ImageHelpers.greenline_image)[1]
|
70
|
+
expect(center).to be > 2445
|
71
|
+
expect(center).to be < 2495
|
72
|
+
end
|
70
73
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
74
|
+
specify 'finds the vertical dividing line another real image, with border still present, and 20x fewer subsamples' do
|
75
|
+
center = Sqed::BoundaryFinder.color_boundary_finder(image: ImageHelpers.greenline_image, sample_subdivision_size: 200)[1]
|
76
|
+
expect(center).to be > 2445
|
77
|
+
expect(center).to be < 2495
|
78
|
+
end
|
76
79
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
80
|
+
specify 'finds the vertical dividing line another real image, with border still present, and 50x fewer subsamples' do
|
81
|
+
center = Sqed::BoundaryFinder.color_boundary_finder(image: ImageHelpers.greenline_image, sample_subdivision_size: 500)[1]
|
82
|
+
expect(center).to be > 2445
|
83
|
+
expect(center).to be < 2495
|
84
|
+
end
|
82
85
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
86
|
+
specify 'FAILS to find the vertical dividing line in a standard cross, with border still present, when even more precise' do
|
87
|
+
center = Sqed::BoundaryFinder.color_boundary_finder(image: ImageHelpers.standard_cross_green, sample_cutoff_factor: 1)
|
88
|
+
expect(center).to be nil
|
89
|
+
end
|
87
90
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
91
|
+
specify 'finds the horizontal dividing line another real image, with border still present' do
|
92
|
+
center = Sqed::BoundaryFinder.color_boundary_finder(image: ImageHelpers.greenline_image, scan: :columns)[1]
|
93
|
+
expect(center).to be > 1282
|
94
|
+
expect(center).to be < 1332
|
95
|
+
end
|
92
96
|
end
|
93
97
|
|
94
98
|
end
|
@@ -107,7 +111,7 @@ describe Sqed::BoundaryFinder do
|
|
107
111
|
|
108
112
|
context 'offset boundaries from crossy_black_line_specimen image ' do
|
109
113
|
before(:all) {
|
110
|
-
@s = Sqed.new(image: ImageHelpers.crossy_black_line_specimen, pattern: :
|
114
|
+
@s = Sqed.new(image: ImageHelpers.crossy_black_line_specimen, pattern: :vertical_offset_cross, boundary_color: :black)
|
111
115
|
@s.crop_image
|
112
116
|
@offset_boundaries = @s.boundaries.offset(@s.stage_boundary)
|
113
117
|
true
|
@@ -136,7 +140,7 @@ describe Sqed::BoundaryFinder do
|
|
136
140
|
|
137
141
|
context 'offset boundaries from black_green_line_specimen image ' do
|
138
142
|
before(:all) {
|
139
|
-
@s = Sqed.new(image: ImageHelpers.black_stage_green_line_specimen, pattern: :
|
143
|
+
@s = Sqed.new(image: ImageHelpers.black_stage_green_line_specimen, pattern: :vertical_offset_cross)
|
140
144
|
@s.crop_image
|
141
145
|
@offset_boundaries = @s.boundaries.offset(@s.stage_boundary)
|
142
146
|
true
|
@@ -164,7 +168,7 @@ describe Sqed::BoundaryFinder do
|
|
164
168
|
|
165
169
|
context 'offset boundaries from original red_line image ' do
|
166
170
|
before(:all) {
|
167
|
-
@s = Sqed.new(image: ImageHelpers.
|
171
|
+
@s = Sqed.new(image: ImageHelpers.vertical_offset_cross_red, pattern: :right_t, boundary_color: :red)
|
168
172
|
@s.crop_image
|
169
173
|
@offset_boundaries = @s.boundaries.offset(@s.stage_boundary)
|
170
174
|
}
|
data/spec/lib/sqed_spec.rb
CHANGED
@@ -69,7 +69,7 @@ describe Sqed do
|
|
69
69
|
|
70
70
|
context 'all together' do
|
71
71
|
let(:image) { ImageHelpers.frost_stage }
|
72
|
-
let(:pattern) { :
|
72
|
+
let(:pattern) { :vertical_offset_cross }
|
73
73
|
let(:s) { Sqed.new(image: image, pattern: pattern) }
|
74
74
|
|
75
75
|
specify '#boundaries returns a Sqed::Boundaries instance' do
|
Binary file
|
Binary file
|
@@ -23,6 +23,16 @@ module ImageHelpers
|
|
23
23
|
get_image 'stage_images/frost_stage.jpg'
|
24
24
|
end
|
25
25
|
|
26
|
+
def frost_stage_thumb
|
27
|
+
get_image 'stage_images/frost_stage_thumb.jpg'
|
28
|
+
end
|
29
|
+
|
30
|
+
def frost_stage_medimum
|
31
|
+
get_image 'stage_images/frost_stage_medimum.jpg'
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
|
26
36
|
def crossy_green_line_specimen
|
27
37
|
get_image 'stage_images/CrossyGreenLinesSpecimen.jpg'
|
28
38
|
end
|
@@ -35,7 +45,7 @@ module ImageHelpers
|
|
35
45
|
get_image 'stage_images/black_stage_green_line_specimen.jpg'
|
36
46
|
end
|
37
47
|
|
38
|
-
def
|
48
|
+
def vertical_offset_cross_red
|
39
49
|
get_image 'stage_images/boundary_offset_cross_red.jpg'
|
40
50
|
end
|
41
51
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sqed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Yoder
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-06-
|
12
|
+
date: 2015-06-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -194,6 +194,8 @@ files:
|
|
194
194
|
- spec/support/files/stage_images/boundary_offset_cross_red.jpg
|
195
195
|
- spec/support/files/stage_images/boundary_right_t_green.jpg
|
196
196
|
- spec/support/files/stage_images/frost_stage.jpg
|
197
|
+
- spec/support/files/stage_images/frost_stage_medium.jpg
|
198
|
+
- spec/support/files/stage_images/frost_stage_thumb.jpg
|
197
199
|
- spec/support/files/stage_images/greenlineimage.jpg
|
198
200
|
- spec/support/files/test0.jpg
|
199
201
|
- spec/support/files/test1.jpg
|
@@ -258,6 +260,8 @@ test_files:
|
|
258
260
|
- spec/support/files/stage_images/boundary_offset_cross_red.jpg
|
259
261
|
- spec/support/files/stage_images/boundary_right_t_green.jpg
|
260
262
|
- spec/support/files/stage_images/frost_stage.jpg
|
263
|
+
- spec/support/files/stage_images/frost_stage_medium.jpg
|
264
|
+
- spec/support/files/stage_images/frost_stage_thumb.jpg
|
261
265
|
- spec/support/files/stage_images/greenlineimage.jpg
|
262
266
|
- spec/support/files/test0.jpg
|
263
267
|
- spec/support/files/test1.jpg
|