percept 0.0.1 → 3.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 +5 -5
- data/.github/workflows/ruby.yml +34 -0
- data/.gitignore +3 -1
- data/.rspec +3 -0
- data/.rubocop.yml +110 -0
- data/.rubocop_todo.yml +383 -0
- data/.tool-versions +2 -0
- data/Gemfile +12 -1
- data/Gemfile.lock +138 -0
- data/Guardfile +10 -0
- data/README.md +20 -0
- data/Rakefile +18 -0
- data/bin/percept +8 -1
- data/lib/ext/rmagick_pixel.rb +19 -0
- data/lib/percept/checkbox_collection.rb +19 -0
- data/lib/percept/checkbox_detector.rb +19 -0
- data/lib/percept/checkbox_field.rb +24 -0
- data/lib/percept/color_utils.rb +17 -0
- data/lib/percept/config.rb +35 -0
- data/lib/percept/field.rb +74 -0
- data/lib/percept/field_collection.rb +29 -0
- data/lib/percept/field_detector.rb +56 -0
- data/lib/percept/image.rb +60 -0
- data/lib/percept/line.rb +116 -4
- data/lib/percept/line_collection.rb +88 -0
- data/lib/percept/line_detector.rb +102 -0
- data/lib/percept/line_filter.rb +95 -0
- data/lib/percept/pixel.rb +28 -0
- data/lib/percept/pixel_utils.rb +73 -0
- data/lib/percept/rmagick_image.rb +49 -0
- data/lib/percept/runner.rb +15 -96
- data/lib/percept/utils.rb +15 -0
- data/lib/percept/version.rb +3 -1
- data/lib/percept.rb +40 -1
- data/percept.gemspec +6 -7
- data/spec/fixtures/black_lines.png +0 -0
- data/spec/fixtures/bottom_line.png +0 -0
- data/spec/fixtures/bumpy_no_line.png +0 -0
- data/spec/fixtures/corners.png +0 -0
- data/spec/fixtures/divots.png +0 -0
- data/spec/fixtures/field_next_to_text.png +0 -0
- data/spec/fixtures/gray_cell_bottom.png +0 -0
- data/spec/fixtures/gray_image_section.png +0 -0
- data/spec/fixtures/grey_lines.png +0 -0
- data/spec/fixtures/high_line.png +0 -0
- data/spec/fixtures/large_checkbox.png +0 -0
- data/spec/fixtures/large_checkboxes.png +0 -0
- data/spec/fixtures/light_gray.png +0 -0
- data/spec/fixtures/low_line.png +0 -0
- data/spec/fixtures/low_lines.png +0 -0
- data/spec/fixtures/mid_lines.png +0 -0
- data/spec/fixtures/more_corners.png +0 -0
- data/spec/fixtures/more_text_on_line.png +0 -0
- data/spec/fixtures/nub_both_sides.png +0 -0
- data/spec/fixtures/nub_bottom_left.png +0 -0
- data/spec/fixtures/nub_top_right.png +0 -0
- data/spec/fixtures/nubs.png +0 -0
- data/spec/fixtures/slanted_left.png +0 -0
- data/spec/fixtures/slanted_right.png +0 -0
- data/spec/fixtures/small_checkbox.png +0 -0
- data/spec/fixtures/text_no_line.png +0 -0
- data/spec/fixtures/text_no_line_2.png +0 -0
- data/spec/fixtures/text_on_line.png +0 -0
- data/spec/fixtures/thick_line.png +0 -0
- data/spec/fixtures/thin_field.png +0 -0
- data/spec/percept/checkbox_field/height_spec.rb +15 -0
- data/spec/percept/checkbox_field/width_spec.rb +15 -0
- data/spec/percept/field/contains_spec.rb +50 -0
- data/spec/percept/field_detector/detect_field_spec.rb +90 -0
- data/spec/percept/field_detector/detect_fields_spec.rb +42 -0
- data/spec/percept/fields_collection/shovel_spec.rb +53 -0
- data/spec/percept/line/approxequals_spec.rb +60 -0
- data/spec/percept/line/initialize_spec.rb +29 -0
- data/spec/percept/line/length_spec.rb +22 -0
- data/spec/percept/line/merge_bang_spec.rb +58 -0
- data/spec/percept/line/pixels_spec.rb +15 -0
- data/spec/percept/line/split_spec.rb +28 -0
- data/spec/percept/line/to_s_spec.rb +13 -0
- data/spec/percept/line_collection/merge_line_spec.rb +50 -0
- data/spec/percept/line_collection/remove_unwanted_lines_bang_spec.rb +17 -0
- data/spec/percept/line_collection/split_spec.rb +20 -0
- data/spec/percept/line_collection/to_s_spec.rb +11 -0
- data/spec/percept/line_detector/detect_lines_spec.rb +93 -0
- data/spec/percept/line_detector/scaled_color_spec.rb +14 -0
- data/spec/percept/line_filter/filter_line_predicate_spec.rb +29 -0
- data/spec/percept/line_filter/left_bottom_corner_predicate_spec.rb +49 -0
- data/spec/percept/line_filter/left_top_corner_predicate_spec.rb +50 -0
- data/spec/percept/line_filter/right_bottom_corner_predicate_spec.rb +49 -0
- data/spec/percept/line_filter/right_top_corner_predicate_spec.rb +49 -0
- data/spec/percept/line_filter/table_bottom_predicate_spec.rb +48 -0
- data/spec/percept/line_filter/table_top_predicate_spec.rb +48 -0
- data/spec/percept/pixel/blackish_predicate_spec.rb +36 -0
- data/spec/percept/rmagick_image/interface_spec.rb +11 -0
- data/spec/percept/runner/color_fields_spec.rb +28 -0
- data/spec/percept/runner/color_lines_spec.rb +27 -0
- data/spec/shared_examples/image_interface_shared_examples.rb +162 -0
- data/spec/spec_helper.rb +52 -0
- data/tddium.yml +12 -0
- data/test_images/funky_image.png +0 -0
- data/test_images/interaction_test.png +0 -0
- data/test_images/jagged_lines.png +0 -0
- data/test_images/permission.png +0 -0
- data/test_images/rough.png +0 -0
- data/test_images/slanted.png +0 -0
- data/test_images/time_sheet.png +0 -0
- data/test_images/travel_reimbursement.png +0 -0
- data/test_images/warehouse_form.png +0 -0
- metadata +171 -34
- data/new_permission.png +0 -0
- data/permission.png +0 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
describe Percept::LineDetector, '#detect_lines' do
|
2
|
+
|
3
|
+
let(:line_detector) { Percept::LineDetector.new }
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
Percept.config.line_length = 30
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'returns a collection of lines with the appropriate coordinates' do
|
10
|
+
image = image_class.new(File.join(fixture_path, 'low_line.png'))
|
11
|
+
lines = line_detector.detect_lines(image)
|
12
|
+
expect(lines.size).to eq 1
|
13
|
+
line = lines.first
|
14
|
+
expect(line.length).to eq 32
|
15
|
+
expect(line.start_y).to eq 14
|
16
|
+
expect(line.end_y).to eq 15
|
17
|
+
expect(line.start_x).to eq 4
|
18
|
+
expect(line.end_x).to eq 36
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'detects lines with divots' do
|
22
|
+
image = image_class.new(File.join(fixture_path, 'divots.png'))
|
23
|
+
lines = line_detector.detect_lines(image)
|
24
|
+
expect(lines.size).to eq 1
|
25
|
+
line = lines.first
|
26
|
+
expect(line.length).to eq 32
|
27
|
+
expect(line.start_y).to eq 11
|
28
|
+
expect(line.end_y).to eq 14
|
29
|
+
expect(line.start_x).to eq 4
|
30
|
+
expect(line.end_x).to eq 36
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'detects lines with nubs' do
|
34
|
+
image = image_class.new(File.join(fixture_path, 'nubs.png'))
|
35
|
+
lines = line_detector.detect_lines(image)
|
36
|
+
expect(lines.size).to eq 1
|
37
|
+
line = lines.first
|
38
|
+
expect(line.length).to eq 32
|
39
|
+
expect(line.start_y).to eq 12
|
40
|
+
expect(line.end_y).to eq 14
|
41
|
+
expect(line.start_x).to eq 4
|
42
|
+
expect(line.end_x).to eq 36
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'detects lines that are sloped to the left' do
|
46
|
+
image = image_class.new(File.join(fixture_path, 'slanted_left.png'))
|
47
|
+
lines = line_detector.detect_lines(image)
|
48
|
+
expect(lines.size).to eq 1
|
49
|
+
line = lines.first
|
50
|
+
expect(line.length).to eq 91
|
51
|
+
expect(line.start_y).to eq 21
|
52
|
+
expect(line.end_y).to eq 23
|
53
|
+
expect(line.start_x).to eq 5
|
54
|
+
expect(line.end_x).to eq 96
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'detects lines that are sloped to the right' do
|
58
|
+
image = image_class.new(File.join(fixture_path, 'slanted_right.png'))
|
59
|
+
lines = line_detector.detect_lines(image)
|
60
|
+
expect(lines.size).to eq 1
|
61
|
+
line = lines.first
|
62
|
+
expect(line.length).to eq 91
|
63
|
+
expect(line.start_y).to eq 21
|
64
|
+
expect(line.end_y).to eq 23
|
65
|
+
expect(line.start_x).to eq 5
|
66
|
+
expect(line.end_x).to eq 96
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'detects lines in images with gray filler' do
|
70
|
+
image = image_class.new(File.join(fixture_path, 'gray_image_section.png'))
|
71
|
+
lines = line_detector.detect_lines(image)
|
72
|
+
expect(lines.size).to eq 2
|
73
|
+
line = lines.first
|
74
|
+
expect(line.length).to eq 180
|
75
|
+
expect(line.start_y).to eq 16
|
76
|
+
expect(line.end_y).to eq 19
|
77
|
+
expect(line.start_x).to eq 20
|
78
|
+
expect(line.end_x).to eq 200
|
79
|
+
line = lines.last
|
80
|
+
expect(line.length).to eq 180
|
81
|
+
expect(line.start_y).to eq 68
|
82
|
+
expect(line.end_y).to eq 72
|
83
|
+
expect(line.start_x).to eq 20
|
84
|
+
expect(line.end_x).to eq 200
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'it detects lines in a lighter gray image' do
|
88
|
+
image = image_class.new(File.join(fixture_path, 'light_gray.png'))
|
89
|
+
lines = line_detector.detect_lines(image)
|
90
|
+
expect(lines.size).to eq 1
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
describe Percept::LineDetector, '#scaled_color' do
|
2
|
+
|
3
|
+
let(:detector) { Percept::LineDetector.new }
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
Percept.config.color_tolerance = 150
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'multiplies the value by 256' do
|
10
|
+
expect(detector.scaled_color(1)).to eq 255
|
11
|
+
expect(detector.scaled_color(256)).to eq 65_535
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
describe Percept::LineFilter, '#filter_line?' do
|
2
|
+
|
3
|
+
let(:filter) { Percept::LineFilter.new }
|
4
|
+
|
5
|
+
context 'when a line is the tops of letters' do
|
6
|
+
it 'returns true' do
|
7
|
+
image = image_class.new(File.join(fixture_path, 'text_no_line.png'))
|
8
|
+
line = image.lines.first
|
9
|
+
expect(filter.filter_line?(line)).to be true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when a line is the bottom of a table cell' do
|
14
|
+
it 'returns false' do
|
15
|
+
image = image_class.new(File.join(fixture_path, 'gray_cell_bottom.png'))
|
16
|
+
line = image.lines.first
|
17
|
+
expect(filter.filter_line?(line)).to be false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when a line is too thick' do
|
22
|
+
it 'returns true' do
|
23
|
+
image = image_class.new(File.join(fixture_path, 'bumpy_no_line.png'))
|
24
|
+
line = image.lines.first
|
25
|
+
expect(filter.filter_line?(line)).to be true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
describe Percept::LineFilter, '#left_bottom_corner?' do
|
2
|
+
|
3
|
+
let(:corners_path) { File.join(fixture_path, 'corners.png') }
|
4
|
+
let(:image_1) { image_class.new(corners_path) }
|
5
|
+
let(:lines_1) { image_1.lines }
|
6
|
+
|
7
|
+
let(:more_corners_path) { File.join(fixture_path, 'more_corners.png') }
|
8
|
+
let(:image_2) { image_class.new(more_corners_path) }
|
9
|
+
let(:lines_2) { image_2.lines }
|
10
|
+
|
11
|
+
let(:filter) { Percept::LineFilter.new }
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
Percept.config.line_length = 30
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when the line is the left bottom corner of a box' do
|
18
|
+
it 'returns true' do
|
19
|
+
expect(filter.left_bottom_corner?(lines_1[5])).to eq true
|
20
|
+
expect(filter.left_bottom_corner?(lines_1[6])).to eq true
|
21
|
+
expect(filter.left_bottom_corner?(lines_1[8])).to eq true
|
22
|
+
|
23
|
+
expect(filter.left_bottom_corner?(lines_2[8])).to eq true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when the line is not the left bottom corner of a box' do
|
28
|
+
it 'returns false' do
|
29
|
+
expect(filter.left_bottom_corner?(lines_1[0])).to eq false
|
30
|
+
expect(filter.left_bottom_corner?(lines_1[1])).to eq false
|
31
|
+
expect(filter.left_bottom_corner?(lines_1[2])).to eq false
|
32
|
+
expect(filter.left_bottom_corner?(lines_1[3])).to eq false
|
33
|
+
expect(filter.left_bottom_corner?(lines_1[4])).to eq false
|
34
|
+
expect(filter.left_bottom_corner?(lines_1[7])).to eq false
|
35
|
+
expect(filter.left_bottom_corner?(lines_1[9])).to eq false
|
36
|
+
|
37
|
+
expect(filter.left_bottom_corner?(lines_2[0])).to eq false
|
38
|
+
expect(filter.left_bottom_corner?(lines_2[1])).to eq false
|
39
|
+
expect(filter.left_bottom_corner?(lines_2[2])).to eq false
|
40
|
+
expect(filter.left_bottom_corner?(lines_2[3])).to eq false
|
41
|
+
expect(filter.left_bottom_corner?(lines_2[4])).to eq false
|
42
|
+
expect(filter.left_bottom_corner?(lines_2[5])).to eq false
|
43
|
+
expect(filter.left_bottom_corner?(lines_2[6])).to eq false
|
44
|
+
expect(filter.left_bottom_corner?(lines_2[7])).to eq false
|
45
|
+
expect(filter.left_bottom_corner?(lines_2[9])).to eq false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
describe Percept::LineFilter, '#left_top_corner?' do
|
2
|
+
|
3
|
+
let(:corners_path) { File.join(fixture_path, 'corners.png') }
|
4
|
+
let(:image_1) { image_class.new(corners_path) }
|
5
|
+
let(:lines_1) { image_1.lines }
|
6
|
+
|
7
|
+
let(:more_corners_path) { File.join(fixture_path, 'more_corners.png') }
|
8
|
+
let(:image_2) { image_class.new(more_corners_path) }
|
9
|
+
let(:lines_2) { image_2.lines }
|
10
|
+
|
11
|
+
let(:filter) { Percept::LineFilter.new }
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
Percept.config.line_length = 30
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when the line is the left top corner of a box' do
|
18
|
+
it 'returns true' do
|
19
|
+
expect(lines_1.size).to eq 10
|
20
|
+
expect(filter.left_top_corner?(lines_1[2])).to eq true
|
21
|
+
expect(filter.left_top_corner?(lines_1[2])).to eq true
|
22
|
+
expect(filter.left_top_corner?(lines_1[3])).to eq true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when the line is not the left top corner of a box' do
|
27
|
+
it 'returns false' do
|
28
|
+
expect(filter.left_top_corner?(lines_1[0])).to eq false
|
29
|
+
expect(filter.left_top_corner?(lines_1[1])).to eq false
|
30
|
+
expect(filter.left_top_corner?(lines_1[4])).to eq false
|
31
|
+
expect(filter.left_top_corner?(lines_1[5])).to eq false
|
32
|
+
expect(filter.left_top_corner?(lines_1[6])).to eq false
|
33
|
+
expect(filter.left_top_corner?(lines_1[7])).to eq false
|
34
|
+
expect(filter.left_top_corner?(lines_1[8])).to eq false
|
35
|
+
expect(filter.left_top_corner?(lines_1[9])).to eq false
|
36
|
+
|
37
|
+
expect(filter.left_top_corner?(lines_2[0])).to eq false
|
38
|
+
expect(filter.left_top_corner?(lines_2[1])).to eq false
|
39
|
+
expect(filter.left_top_corner?(lines_2[2])).to eq false
|
40
|
+
expect(filter.left_top_corner?(lines_2[3])).to eq false
|
41
|
+
expect(filter.left_top_corner?(lines_2[4])).to eq false
|
42
|
+
expect(filter.left_top_corner?(lines_2[5])).to eq false
|
43
|
+
expect(filter.left_top_corner?(lines_2[6])).to eq false
|
44
|
+
expect(filter.left_top_corner?(lines_2[7])).to eq false
|
45
|
+
expect(filter.left_top_corner?(lines_2[8])).to eq false
|
46
|
+
expect(filter.left_top_corner?(lines_2[9])).to eq false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
describe Percept::LineFilter, '#right_bottom_corner?' do
|
2
|
+
|
3
|
+
let(:corners_path) { File.join(fixture_path, 'corners.png') }
|
4
|
+
let(:image_1) { image_class.new(corners_path) }
|
5
|
+
let(:lines_1) { image_1.lines }
|
6
|
+
|
7
|
+
let(:more_corners_path) { File.join(fixture_path, 'more_corners.png') }
|
8
|
+
let(:image_2) { image_class.new(more_corners_path) }
|
9
|
+
let(:lines_2) { image_2.lines }
|
10
|
+
|
11
|
+
let(:filter) { Percept::LineFilter.new }
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
Percept.config.line_length = 30
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when the line is the right bottom corner of a box' do
|
18
|
+
it 'returns true' do
|
19
|
+
expect(filter.right_bottom_corner?(lines_1[4])).to eq true
|
20
|
+
expect(filter.right_bottom_corner?(lines_1[6])).to eq true
|
21
|
+
expect(filter.right_bottom_corner?(lines_1[7])).to eq true
|
22
|
+
|
23
|
+
expect(filter.right_bottom_corner?(lines_2[9])).to eq true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when the line is not the right bottom corner of a box' do
|
28
|
+
it 'returns false' do
|
29
|
+
expect(filter.right_bottom_corner?(lines_1[0])).to eq false
|
30
|
+
expect(filter.right_bottom_corner?(lines_1[1])).to eq false
|
31
|
+
expect(filter.right_bottom_corner?(lines_1[2])).to eq false
|
32
|
+
expect(filter.right_bottom_corner?(lines_1[3])).to eq false
|
33
|
+
expect(filter.right_bottom_corner?(lines_1[5])).to eq false
|
34
|
+
expect(filter.right_bottom_corner?(lines_1[8])).to eq false
|
35
|
+
expect(filter.right_bottom_corner?(lines_1[9])).to eq false
|
36
|
+
|
37
|
+
expect(filter.right_bottom_corner?(lines_2[0])).to eq false
|
38
|
+
expect(filter.right_bottom_corner?(lines_2[1])).to eq false
|
39
|
+
expect(filter.right_bottom_corner?(lines_2[2])).to eq false
|
40
|
+
expect(filter.right_bottom_corner?(lines_2[3])).to eq false
|
41
|
+
expect(filter.right_bottom_corner?(lines_2[4])).to eq false
|
42
|
+
expect(filter.right_bottom_corner?(lines_2[5])).to eq false
|
43
|
+
expect(filter.right_bottom_corner?(lines_2[6])).to eq false
|
44
|
+
expect(filter.right_bottom_corner?(lines_2[7])).to eq false
|
45
|
+
expect(filter.right_bottom_corner?(lines_2[8])).to eq false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
describe Percept::LineFilter, '#right_top_corner?' do
|
2
|
+
|
3
|
+
let(:corners_path) { File.join(fixture_path, 'corners.png') }
|
4
|
+
let(:image_1) { image_class.new(corners_path) }
|
5
|
+
let(:lines_1) { image_1.lines }
|
6
|
+
|
7
|
+
let(:more_corners_path) { File.join(fixture_path, 'more_corners.png') }
|
8
|
+
let(:image_2) { image_class.new(more_corners_path) }
|
9
|
+
let(:lines_2) { image_2.lines }
|
10
|
+
|
11
|
+
let(:filter) { Percept::LineFilter.new }
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
Percept.config.line_length = 30
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when the line is the right top corner of a box' do
|
18
|
+
it 'returns true' do
|
19
|
+
expect(lines_1.size).to eq 10
|
20
|
+
expect(filter.right_top_corner?(lines_1[1])).to eq true
|
21
|
+
expect(filter.right_top_corner?(lines_1[3])).to eq true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when the line is not the right top corner of a box' do
|
26
|
+
it 'returns false' do
|
27
|
+
expect(filter.right_top_corner?(lines_1[0])).to eq false
|
28
|
+
expect(filter.right_top_corner?(lines_1[2])).to eq false
|
29
|
+
expect(filter.right_top_corner?(lines_1[4])).to eq false
|
30
|
+
expect(filter.right_top_corner?(lines_1[5])).to eq false
|
31
|
+
expect(filter.right_top_corner?(lines_1[6])).to eq false
|
32
|
+
expect(filter.right_top_corner?(lines_1[7])).to eq false
|
33
|
+
expect(filter.right_top_corner?(lines_1[8])).to eq false
|
34
|
+
expect(filter.right_top_corner?(lines_1[9])).to eq false
|
35
|
+
|
36
|
+
expect(filter.right_top_corner?(lines_2[0])).to eq false
|
37
|
+
expect(filter.right_top_corner?(lines_2[1])).to eq false
|
38
|
+
expect(filter.right_top_corner?(lines_2[2])).to eq false
|
39
|
+
expect(filter.right_top_corner?(lines_2[3])).to eq false
|
40
|
+
expect(filter.right_top_corner?(lines_2[4])).to eq false
|
41
|
+
expect(filter.right_top_corner?(lines_2[5])).to eq false
|
42
|
+
expect(filter.right_top_corner?(lines_2[6])).to eq false
|
43
|
+
expect(filter.right_top_corner?(lines_2[7])).to eq false
|
44
|
+
expect(filter.right_top_corner?(lines_2[8])).to eq false
|
45
|
+
expect(filter.right_top_corner?(lines_2[9])).to eq false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
describe Percept::LineFilter, '#table_bottom?' do
|
2
|
+
|
3
|
+
let(:corners_path) { File.join(fixture_path, 'corners.png') }
|
4
|
+
let(:image_1) { image_class.new(corners_path) }
|
5
|
+
let(:lines_1) { image_1.lines }
|
6
|
+
|
7
|
+
let(:more_corners_path) { File.join(fixture_path, 'more_corners.png') }
|
8
|
+
let(:image_2) { image_class.new(more_corners_path) }
|
9
|
+
let(:lines_2) { image_2.lines }
|
10
|
+
|
11
|
+
let(:filter) { Percept::LineFilter.new }
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
Percept.config.line_length = 30
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when the line has both left and right bottom corners' do
|
18
|
+
it 'returns true' do
|
19
|
+
expect(filter.table_bottom?(lines_1[6])).to eq true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when the line does not have left and right bottom corners' do
|
24
|
+
it 'returns false' do
|
25
|
+
expect(filter.table_bottom?(lines_1[0])).to eq false
|
26
|
+
expect(filter.table_bottom?(lines_1[1])).to eq false
|
27
|
+
expect(filter.table_bottom?(lines_1[2])).to eq false
|
28
|
+
expect(filter.table_bottom?(lines_1[3])).to eq false
|
29
|
+
expect(filter.table_bottom?(lines_1[4])).to eq false
|
30
|
+
expect(filter.table_bottom?(lines_1[5])).to eq false
|
31
|
+
expect(filter.table_bottom?(lines_1[7])).to eq false
|
32
|
+
expect(filter.table_bottom?(lines_1[8])).to eq false
|
33
|
+
expect(filter.table_bottom?(lines_1[9])).to eq false
|
34
|
+
|
35
|
+
expect(filter.table_bottom?(lines_2[0])).to eq false
|
36
|
+
expect(filter.table_bottom?(lines_2[1])).to eq false
|
37
|
+
expect(filter.table_bottom?(lines_2[2])).to eq false
|
38
|
+
expect(filter.table_bottom?(lines_2[3])).to eq false
|
39
|
+
expect(filter.table_bottom?(lines_2[4])).to eq false
|
40
|
+
expect(filter.table_bottom?(lines_2[5])).to eq false
|
41
|
+
expect(filter.table_bottom?(lines_2[6])).to eq false
|
42
|
+
expect(filter.table_bottom?(lines_2[7])).to eq false
|
43
|
+
expect(filter.table_bottom?(lines_2[8])).to eq false
|
44
|
+
expect(filter.table_bottom?(lines_2[9])).to eq false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
describe Percept::LineFilter, '#table_top?' do
|
2
|
+
|
3
|
+
let(:corners_path) { File.join(fixture_path, 'corners.png') }
|
4
|
+
let(:image_1) { image_class.new(corners_path) }
|
5
|
+
let(:lines_1) { image_1.lines }
|
6
|
+
|
7
|
+
let(:more_corners_path) { File.join(fixture_path, 'more_corners.png') }
|
8
|
+
let(:image_2) { image_class.new(more_corners_path) }
|
9
|
+
let(:lines_2) { image_2.lines }
|
10
|
+
|
11
|
+
let(:filter) { Percept::LineFilter.new }
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
Percept.config.line_length = 30
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when the line has both left and right top corners' do
|
18
|
+
it 'returns true' do
|
19
|
+
expect(filter.table_top?(lines_1[3])).to eq true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when the line does not have left and right top corners' do
|
24
|
+
it 'returns false' do
|
25
|
+
expect(filter.table_top?(lines_1[0])).to eq false
|
26
|
+
expect(filter.table_top?(lines_1[1])).to eq false
|
27
|
+
expect(filter.table_top?(lines_1[2])).to eq false
|
28
|
+
expect(filter.table_top?(lines_1[4])).to eq false
|
29
|
+
expect(filter.table_top?(lines_1[5])).to eq false
|
30
|
+
expect(filter.table_top?(lines_1[6])).to eq false
|
31
|
+
expect(filter.table_top?(lines_1[7])).to eq false
|
32
|
+
expect(filter.table_top?(lines_1[8])).to eq false
|
33
|
+
expect(filter.table_top?(lines_1[9])).to eq false
|
34
|
+
|
35
|
+
expect(filter.table_top?(lines_2[0])).to eq false
|
36
|
+
expect(filter.table_top?(lines_2[1])).to eq false
|
37
|
+
expect(filter.table_top?(lines_2[2])).to eq false
|
38
|
+
expect(filter.table_top?(lines_2[3])).to eq false
|
39
|
+
expect(filter.table_top?(lines_2[4])).to eq false
|
40
|
+
expect(filter.table_top?(lines_2[5])).to eq false
|
41
|
+
expect(filter.table_top?(lines_2[6])).to eq false
|
42
|
+
expect(filter.table_top?(lines_2[7])).to eq false
|
43
|
+
expect(filter.table_top?(lines_2[8])).to eq false
|
44
|
+
expect(filter.table_top?(lines_2[9])).to eq false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
describe Percept::Pixel, '#blackish?' do
|
2
|
+
|
3
|
+
let(:pixel) { Percept::Pixel.new({ red: 10, green: 10, blue: 10 }) }
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
Percept.config.color_tolerance = 150
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'if the given object has all colors below the tolerance' do
|
10
|
+
it 'returns true' do
|
11
|
+
expect(pixel.blackish?).to eq true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'if red is greater than the tolerance' do
|
16
|
+
it 'returns false' do
|
17
|
+
expect(pixel).to receive(:red).and_return(45_000)
|
18
|
+
expect(pixel.blackish?).to eq false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'if blue is greater than the tolerance' do
|
23
|
+
it 'returns false' do
|
24
|
+
expect(pixel).to receive(:blue).and_return(45_000)
|
25
|
+
expect(pixel.blackish?).to eq false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'if green is greater than the tolerance' do
|
30
|
+
it 'returns false' do
|
31
|
+
expect(pixel).to receive(:green).and_return(45_000)
|
32
|
+
expect(pixel.blackish?).to eq false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
describe Percept::Runner, '#color_fields' do
|
2
|
+
|
3
|
+
let(:image_path) { File.join(fixture_path, 'black_lines.png') }
|
4
|
+
let(:runner) { Percept::Runner.new }
|
5
|
+
let(:image) { image_class.new(image_path) }
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Percept.config.line_length = 30
|
9
|
+
Percept.config.min_field_height = 10
|
10
|
+
end
|
11
|
+
|
12
|
+
def red?(pixel)
|
13
|
+
pixel.red > 0 && pixel.blue == 0 && pixel.green == 0
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'colors a red box above the lines' do
|
17
|
+
black_pixels = image.pixels.select(&:blackish?)
|
18
|
+
runner.color_fields(image_path)
|
19
|
+
line = image.lines.first
|
20
|
+
field = Percept::FieldDetector.new.detect_field(line, image)
|
21
|
+
output_image = image_class.new(output_path)
|
22
|
+
output_black_pixels = output_image.pixels.select(&:blackish?)
|
23
|
+
expect(output_black_pixels.length).to eq black_pixels.length
|
24
|
+
output_red_pixels = output_image.pixels.select { |p| red?(p) }
|
25
|
+
expect(output_red_pixels.length).to eq field.pixels.length
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
describe Percept::Runner, '#color_lines' do
|
2
|
+
|
3
|
+
let(:image_path) { File.join(fixture_path, 'black_lines.png') }
|
4
|
+
let(:runner) { Percept::Runner.new }
|
5
|
+
let(:image) { image_class.new(image_path) }
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Percept.config.line_length = 30
|
9
|
+
Percept.config.color_tolerance = 150
|
10
|
+
end
|
11
|
+
|
12
|
+
def red?(pixel)
|
13
|
+
pixel.red > 0 && pixel.blue == 0 && pixel.green == 0
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'colors lines red that are greater than or equal to the line length' do
|
17
|
+
black_pixels = image.pixels.select(&:blackish?)
|
18
|
+
runner.color_lines(image_path)
|
19
|
+
output_image = image_class.new(output_path)
|
20
|
+
output_black_pixels = output_image.pixels.select(&:blackish?)
|
21
|
+
output_red_pixels = output_image.pixels.select { |p| red?(p) }
|
22
|
+
expect(output_red_pixels.length).to eq 77
|
23
|
+
expected_length = black_pixels.length - output_red_pixels.length
|
24
|
+
expect(output_black_pixels.length).to eq expected_length
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|