ruby_marks 0.1.4 → 0.1.5
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.
@@ -15,7 +15,10 @@ module RubyMarks
|
|
15
15
|
|
16
16
|
return false if !self.recognizer.config.clock_width_tolerance_range.include?(self.width) ||
|
17
17
|
!self.recognizer.config.clock_height_tolerance_range.include?(self.height)
|
18
|
-
|
18
|
+
|
19
|
+
|
20
|
+
self.recognizer.export_file_to_str if self.recognizer.file_str.nil?
|
21
|
+
|
19
22
|
x_pos = coordinates[:x1]..coordinates[:x2]
|
20
23
|
y_pos = coordinates[:y1]..coordinates[:y2]
|
21
24
|
|
@@ -23,9 +26,9 @@ module RubyMarks
|
|
23
26
|
|
24
27
|
y_pos.each do |y|
|
25
28
|
x_pos.each do |x|
|
26
|
-
|
27
|
-
color =
|
28
|
-
|
29
|
+
|
30
|
+
color = self.recognizer.file_str[y][x]
|
31
|
+
|
29
32
|
colors << color
|
30
33
|
end
|
31
34
|
end
|
@@ -3,7 +3,7 @@ module RubyMarks
|
|
3
3
|
|
4
4
|
class Recognizer
|
5
5
|
|
6
|
-
attr_reader :file, :raised_watchers, :groups, :watchers
|
6
|
+
attr_reader :file, :raised_watchers, :groups, :watchers, :file_str
|
7
7
|
|
8
8
|
attr_accessor :current_position, :clock_marks, :config
|
9
9
|
|
@@ -16,8 +16,9 @@ module RubyMarks
|
|
16
16
|
def file=(file)
|
17
17
|
self.reset_document
|
18
18
|
@file = nil
|
19
|
+
@file_str = nil
|
19
20
|
@file = Magick::Image.read(file).first
|
20
|
-
@file = @file.threshold(@config.calculated_threshold_level)
|
21
|
+
@file = @file.threshold(@config.calculated_threshold_level)
|
21
22
|
end
|
22
23
|
|
23
24
|
def reset_document
|
@@ -64,6 +65,8 @@ module RubyMarks
|
|
64
65
|
|
65
66
|
def marked?(expected_width, expected_height)
|
66
67
|
raise IOError, "There's a invalid or missing file" if @file.nil?
|
68
|
+
|
69
|
+
self.export_file_to_str if self.file_str.nil?
|
67
70
|
|
68
71
|
if self.current_position
|
69
72
|
|
@@ -72,11 +75,10 @@ module RubyMarks
|
|
72
75
|
|
73
76
|
neighborhood_y.each do |current_y|
|
74
77
|
neighborhood_x.each do |current_x|
|
78
|
+
position = self.file_str[current_y][current_x]
|
79
|
+
|
80
|
+
if position == "."
|
75
81
|
|
76
|
-
color = @file.pixel_color(current_x, current_y)
|
77
|
-
color = RubyMarks::ImageUtils.to_hex(color.red, color.green, color.blue)
|
78
|
-
|
79
|
-
if @config.recognition_colors.include?(color)
|
80
82
|
stack = flood_scan(current_x, current_y)
|
81
83
|
|
82
84
|
x_elements = []
|
@@ -125,6 +127,7 @@ module RubyMarks
|
|
125
127
|
if (current_width >= expected_width - 4 && current_width <= expected_width + 4) &&
|
126
128
|
(current_height >= expected_height - 4 && current_height <= expected_height + 4)
|
127
129
|
|
130
|
+
|
128
131
|
colors = []
|
129
132
|
|
130
133
|
x_pos = x1..x2
|
@@ -132,9 +135,7 @@ module RubyMarks
|
|
132
135
|
|
133
136
|
y_pos.each do |y|
|
134
137
|
x_pos.each do |x|
|
135
|
-
color =
|
136
|
-
color = RubyMarks::ImageUtils.to_hex(color.red, color.green, color.blue)
|
137
|
-
color = @config.recognition_colors.include?(color) ? "." : " "
|
138
|
+
color = self.file_str[y][x]
|
138
139
|
colors << color
|
139
140
|
end
|
140
141
|
end
|
@@ -158,6 +159,8 @@ module RubyMarks
|
|
158
159
|
def scan
|
159
160
|
raise IOError, "There's a invalid or missing file" if @file.nil?
|
160
161
|
|
162
|
+
self.export_file_to_str if self.file_str.nil?
|
163
|
+
|
161
164
|
unmarked_group_found = false
|
162
165
|
multiple_marked_found = false
|
163
166
|
|
@@ -211,6 +214,8 @@ module RubyMarks
|
|
211
214
|
def flag_all_marks
|
212
215
|
|
213
216
|
raise IOError, "There's a invalid or missing file" if @file.nil?
|
217
|
+
|
218
|
+
self.export_file_to_str if self.file_str.nil?
|
214
219
|
|
215
220
|
file = @file.dup
|
216
221
|
|
@@ -252,6 +257,8 @@ module RubyMarks
|
|
252
257
|
|
253
258
|
raise IOError, "There's a invalid or missing file" if @file.nil?
|
254
259
|
|
260
|
+
self.export_file_to_str if self.file_str.nil?
|
261
|
+
|
255
262
|
@clock_marks = []
|
256
263
|
x = @config.clock_marks_scan_x
|
257
264
|
total_width = @file && @file.page.width || 0
|
@@ -261,12 +268,11 @@ module RubyMarks
|
|
261
268
|
current_y = 0
|
262
269
|
loop do
|
263
270
|
|
264
|
-
break if current_y
|
271
|
+
break if current_y >= total_height
|
265
272
|
|
266
|
-
|
267
|
-
color = RubyMarks::ImageUtils.to_hex(color.red, color.green, color.blue)
|
273
|
+
position = @file_str[current_y][x]
|
268
274
|
|
269
|
-
if
|
275
|
+
if position == "."
|
270
276
|
stack = flood_scan(x, current_y)
|
271
277
|
|
272
278
|
x_elements = []
|
@@ -343,20 +349,23 @@ module RubyMarks
|
|
343
349
|
end
|
344
350
|
|
345
351
|
def flood_scan(x, y)
|
352
|
+
|
346
353
|
result_mask = Hash.new { |hash, key| hash[key] = [] }
|
347
354
|
result_mask.tap do |result_mask|
|
348
355
|
process_queue = Hash.new { |hash, key| hash[key] = [] }
|
349
356
|
process_line = true
|
350
357
|
|
351
358
|
loop do
|
359
|
+
|
360
|
+
break if y > self.file_str.size - 1
|
352
361
|
reset_process = false
|
353
362
|
|
354
363
|
if process_line
|
355
364
|
current_x = x.to_i
|
356
365
|
loop do
|
357
|
-
|
358
|
-
|
359
|
-
break if
|
366
|
+
position = self.file_str[y][current_x]
|
367
|
+
|
368
|
+
break if position != "." || current_x - 1 <= 0
|
360
369
|
process_queue[y] << current_x unless process_queue[y].include?(current_x) || result_mask[y].include?(current_x)
|
361
370
|
result_mask[y] << current_x unless result_mask[y].include?(current_x)
|
362
371
|
current_x = current_x - 1
|
@@ -364,10 +373,9 @@ module RubyMarks
|
|
364
373
|
|
365
374
|
current_x = x.to_i
|
366
375
|
loop do
|
367
|
-
|
368
|
-
color = RubyMarks::ImageUtils.to_hex(color.red, color.green, color.blue)
|
376
|
+
position = self.file_str[y][current_x]
|
369
377
|
|
370
|
-
break if
|
378
|
+
break if position != "." || current_x + 1 >= self.file.page.width
|
371
379
|
process_queue[y] << current_x unless process_queue[y].include?(current_x) || result_mask[y].include?(current_x)
|
372
380
|
result_mask[y] << current_x unless result_mask[y].include?(current_x)
|
373
381
|
current_x = current_x + 1
|
@@ -377,13 +385,19 @@ module RubyMarks
|
|
377
385
|
process_queue[y] = process_queue[y].sort
|
378
386
|
end
|
379
387
|
|
388
|
+
if process_queue[y].size > 50
|
389
|
+
process_queue = Hash.new { |hash, key| hash[key] = [] }
|
390
|
+
y = y + 1
|
391
|
+
next
|
392
|
+
end
|
393
|
+
|
380
394
|
process_line = true
|
381
395
|
|
382
396
|
process_queue[y].each do |element|
|
383
397
|
if y - 1 >= 0
|
384
|
-
|
385
|
-
|
386
|
-
if
|
398
|
+
position = self.file_str[y-1][element]
|
399
|
+
|
400
|
+
if position == "." && !result_mask[y-1].include?(element)
|
387
401
|
x = element
|
388
402
|
y = y - 1
|
389
403
|
reset_process = true
|
@@ -396,9 +410,9 @@ module RubyMarks
|
|
396
410
|
|
397
411
|
process_queue[y].each do |element|
|
398
412
|
if y + 1 <= self.file.page.height
|
399
|
-
|
400
|
-
|
401
|
-
if
|
413
|
+
position = self.file_str[y+1][element]
|
414
|
+
|
415
|
+
if position == "." && !result_mask[y+1].include?(element)
|
402
416
|
x = element
|
403
417
|
y = y + 1
|
404
418
|
reset_process = true
|
@@ -423,6 +437,14 @@ module RubyMarks
|
|
423
437
|
end
|
424
438
|
end
|
425
439
|
|
440
|
+
def export_file_to_str
|
441
|
+
@file_str = @file.export_pixels_to_str
|
442
|
+
@file_str = @file_str.gsub!(Regexp.new('\xFF\xFF\xFF', nil, 'n'), " ,")
|
443
|
+
@file_str = @file_str.gsub!(Regexp.new('\x00\x00\x00', nil, 'n'), ".,")
|
444
|
+
@file_str = @file_str.split(',')
|
445
|
+
@file_str = @file_str.each_slice(@file.page.width).to_a
|
446
|
+
end
|
447
|
+
|
426
448
|
private
|
427
449
|
def add_mark(file)
|
428
450
|
dr = Magick::Draw.new
|
@@ -440,8 +462,6 @@ module RubyMarks
|
|
440
462
|
dr.draw(file)
|
441
463
|
end
|
442
464
|
|
443
|
-
|
444
|
-
|
445
465
|
end
|
446
466
|
|
447
467
|
end
|
data/lib/ruby_marks/version.rb
CHANGED
@@ -8,7 +8,7 @@ class RubyMarks::ClockMarkTest < Test::Unit::TestCase
|
|
8
8
|
@recognizer.file = @file
|
9
9
|
@positions = {}
|
10
10
|
@positions[:first_clock_position] = {x1: 49, x2: 74, y1: 790, y2: 801}
|
11
|
-
@positions[:not_a_clock] = {x1: 62, x2:63, y1: 859, y2: 860}
|
11
|
+
@positions[:not_a_clock] = {x1: 62, x2: 63, y1: 859, y2: 860}
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_should_obtain_the_clock_mark_width
|
@@ -75,12 +75,12 @@ class RubyMarks::RecognizerTest < Test::Unit::TestCase
|
|
75
75
|
|
76
76
|
def test_should_return_a_file_with_a_position_flagged
|
77
77
|
@recognizer.current_position = @positions[:invalid_clock]
|
78
|
-
|
79
|
-
assert_equal Magick::Image,
|
78
|
+
flagged_document = @recognizer.flag_position
|
79
|
+
assert_equal Magick::Image, flagged_document.class
|
80
80
|
|
81
81
|
# temp_filename = "temp_sheet_demo1.png"
|
82
82
|
# File.delete(temp_filename) if File.exist?(temp_filename)
|
83
|
-
#
|
83
|
+
# flagged_document.write(temp_filename)
|
84
84
|
end
|
85
85
|
|
86
86
|
def test_should_recognize_marked_position
|