ruby_marks 0.1.5 → 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/README.md +168 -139
- data/lib/ruby_marks/config.rb +14 -35
- data/lib/ruby_marks/group.rb +43 -13
- data/lib/ruby_marks/image_utils.rb +109 -1
- data/lib/ruby_marks/mark.rb +42 -0
- data/lib/ruby_marks/recognizer.rb +304 -315
- data/lib/ruby_marks/scan_area.rb +11 -0
- data/lib/ruby_marks/version.rb +1 -1
- data/lib/ruby_marks.rb +28 -19
- data/test/ruby_marks/image_utils_test.rb +17 -1
- data/test/ruby_marks/recognizer_test.rb +51 -55
- metadata +10 -10
- data/lib/ruby_marks/clock_mark.rb +0 -65
- data/test/ruby_marks/clock_mark_test.rb +0 -44
- data/test/ruby_marks/group_test.rb +0 -26
data/README.md
CHANGED
@@ -65,13 +65,20 @@ require 'ruby_marks'
|
|
65
65
|
How it Works
|
66
66
|
------------
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
Using a template document, you should especify the expected area where each group is. By applying an edge detect algorithm
|
69
|
+
it will discover where the groups are, and will check if they are near the expected position.
|
70
|
+
After the groups being found, the gem will perform a scan in each group in order to recognize their marks.
|
71
|
+
In the end, returns a hash with each correspondent mark found in the group.
|
71
72
|
|
72
|
-
The gem will not perform deskew in your documents. If the document have skew, then you should apply your own
|
73
|
+
The gem will not perform deskew in your documents. If the document have a huge skew, then you should apply your own
|
73
74
|
deskew method on the file before.
|
74
75
|
|
76
|
+
```
|
77
|
+
NOTE:
|
78
|
+
We changed the way it recognizes the marks. It's not based on clocks anymore. If you are updating the gem
|
79
|
+
from 0.1.4 version, you should refactor your code to eliminate the clocks parameters and adjust
|
80
|
+
some new configurations.
|
81
|
+
```
|
75
82
|
|
76
83
|
Usage
|
77
84
|
-----
|
@@ -83,105 +90,136 @@ That said, lets describe it's basic structure. The example will assume a directo
|
|
83
90
|
|
84
91
|
[](https://github.com/andrerpbts/ruby_marks/blob/master/assets/sheet_demo2.png)
|
85
92
|
|
86
|
-
|
93
|
+
|
94
|
+
First, we will need to get the pixels coordinates, using one document as template, of the areas
|
95
|
+
where the expected groups are. This image can explain where to pick each position:
|
96
|
+
|
97
|
+
[](https://github.com/andrerpbts/ruby_marks/blob/master/assets/sheet_demo2_group_coords.png)
|
98
|
+
|
99
|
+
|
100
|
+
The threshold level should be adjusted too, in order to don't get a too bright or too polluted marks. See:
|
101
|
+
|
102
|
+
[](https://github.com/andrerpbts/ruby_marks/blob/master/assets/threshold_examples.png)
|
103
|
+
|
104
|
+
|
105
|
+
Then, we write a basic code to scan it and print result on console (each option available are described bellow):
|
87
106
|
|
88
107
|
```ruby
|
108
|
+
# Instantiate the Recognizer
|
89
109
|
recognizer = RubyMarks::Recognizer.new
|
90
|
-
recognizer.configure do |config|
|
91
110
|
|
92
|
-
|
93
|
-
|
94
|
-
config.
|
111
|
+
# Configuring the document aspects
|
112
|
+
recognizer.configure do |config|
|
113
|
+
config.threshold_level = 90
|
114
|
+
config.default_expected_lines = 5
|
95
115
|
|
96
|
-
config.define_group :
|
97
|
-
group.
|
98
|
-
group.x_distance_from_clock = 89
|
116
|
+
config.define_group :first do |group|
|
117
|
+
group.expected_coordinates = {x1: 34, y1: 6, x2: 160, y2: 134}
|
99
118
|
end
|
100
119
|
|
101
|
-
config.define_group :
|
102
|
-
group.
|
103
|
-
group.x_distance_from_clock = 315
|
120
|
+
config.define_group :second do |group|
|
121
|
+
group.expected_coordinates = {x1: 258, y1: 6, x2: 388, y2: 134}
|
104
122
|
end
|
105
123
|
|
106
|
-
config.define_group :
|
107
|
-
group.
|
108
|
-
group.x_distance_from_clock = 542
|
124
|
+
config.define_group :third do |group|
|
125
|
+
group.expected_coordinates = {x1: 486, y1: 6, x2: 614, y2: 134}
|
109
126
|
end
|
110
127
|
|
111
|
-
config.define_group :
|
112
|
-
group.
|
113
|
-
group.x_distance_from_clock = 769
|
128
|
+
config.define_group :fourth do |group|
|
129
|
+
group.expected_coordinates = {x1: 714, y1: 6, x2: 844, y2: 134}
|
114
130
|
end
|
115
131
|
|
116
|
-
config.define_group :
|
117
|
-
group.
|
118
|
-
group.x_distance_from_clock = 996
|
132
|
+
config.define_group :fifth do |group|
|
133
|
+
group.expected_coordinates = {x1: 942, y1: 6, x2: 1068, y2: 134}
|
119
134
|
end
|
120
135
|
end
|
136
|
+
```
|
137
|
+
|
138
|
+
|
139
|
+
Then we need to adjust the edge level to make sure the groups are being highlighted enough to being recognized.
|
140
|
+
You can see the image after the edge algorithm is applied if you write the file after submit it to Recognizer. Like this:
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
recognizer.file = 'example.png'
|
144
|
+
file = @recognizer.file
|
145
|
+
filename = "temp_image.png"
|
146
|
+
file.write(filename)
|
147
|
+
```
|
148
|
+
|
149
|
+
The result image should be like this one (note that all the groups are separated from the rest of the document these white blocks):
|
150
|
+
|
151
|
+
[](https://github.com/andrerpbts/ruby_marks/blob/master/assets/sheet_demo2_edge.png)
|
152
|
+
|
153
|
+
|
154
|
+
There's a method you can call to will help you to identify how the document is being recognized. This method return the image
|
155
|
+
with the showing where is the expected groups coordinates are, where are the actual groups coordinates, and where the marks
|
156
|
+
is being recognized in each group.
|
121
157
|
|
158
|
+
Example:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
flagged_document = recognizer.flag_all_marks
|
162
|
+
flagged_document.write(temp_filename)
|
163
|
+
```
|
164
|
+
|
165
|
+
Will return the image below with recognized clock marks in green, the clock_marks_scan_x line in blue and
|
166
|
+
each mark position in a red cross:
|
167
|
+
|
168
|
+
[](https://github.com/andrerpbts/ruby_marks/blob/master/assets/sheet_demo2_flagged.png)
|
169
|
+
|
170
|
+
|
171
|
+
With all this configured, we can submit our images to a scan:
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
# Read all documents in directory thats in a png format
|
122
175
|
Dir["./*.png"].each do |file|
|
123
176
|
recognizer.file = file
|
124
177
|
puts recognizer.scan
|
125
178
|
end
|
126
179
|
```
|
127
180
|
|
128
|
-
|
181
|
+
And, this should puts each scan in a hash, like this:
|
129
182
|
|
130
183
|
```
|
131
184
|
{
|
132
|
-
:
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
185
|
+
first: {
|
186
|
+
1 => ['A'],
|
187
|
+
2 => ['C'],
|
188
|
+
3 => ['B'],
|
189
|
+
4 => ['B'],
|
190
|
+
5 => ['D']
|
138
191
|
},
|
139
|
-
:
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
192
|
+
second: {
|
193
|
+
1 => ['E'],
|
194
|
+
2 => ['A'],
|
195
|
+
3 => ['B'],
|
196
|
+
4 => ['A'],
|
197
|
+
5 => ['B']
|
145
198
|
},
|
146
|
-
:
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
199
|
+
three: {
|
200
|
+
1 => ['B'],
|
201
|
+
2 => ['B'],
|
202
|
+
3 => ['D'],
|
203
|
+
4 => ['B'],
|
204
|
+
5 => ['B']
|
152
205
|
},
|
153
|
-
:
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
206
|
+
four: {
|
207
|
+
1 => ['B'],
|
208
|
+
2 => ['E'],
|
209
|
+
3 => ['A'],
|
210
|
+
4 => ['C'],
|
211
|
+
5 => ['D']
|
159
212
|
},
|
160
|
-
:
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
213
|
+
five: {
|
214
|
+
1 => ['B'],
|
215
|
+
2 => ['A'],
|
216
|
+
3 => ['A'],
|
217
|
+
4 => ['C'],
|
218
|
+
5 => ['D']
|
166
219
|
}
|
167
220
|
}
|
168
221
|
```
|
169
222
|
|
170
|
-
There's a method you can call to will help you to configure the positions. This method return the image
|
171
|
-
with the markups of encountered clock marks, where the marks is being recognized and where the clock_marks_scan_x
|
172
|
-
config is making the column search.
|
173
|
-
|
174
|
-
Example:
|
175
|
-
|
176
|
-
```ruby
|
177
|
-
flagged_document = recognizer.flag_all_marks
|
178
|
-
flagged_document.write(temp_filename)
|
179
|
-
```
|
180
|
-
|
181
|
-
Will return the image below with recognized clock marks in green, the clock_marks_scan_x line in blue and
|
182
|
-
each mark position in a red cross:
|
183
|
-
|
184
|
-
[](https://github.com/andrerpbts/ruby_marks/blob/master/assets/sheet_demo2_flagged.png)
|
185
223
|
|
186
224
|
|
187
225
|
General Configuration Options
|
@@ -190,66 +228,38 @@ General Configuration Options
|
|
190
228
|
As you may see, it's necessary configure some document aspects to make this work properly. So, lets describe
|
191
229
|
each general configuration option available:
|
192
230
|
|
193
|
-
###
|
194
|
-
|
195
|
-
```ruby
|
196
|
-
# Applies the given percentual in the image in order to get it back with only black and white pixels.
|
197
|
-
# Low percentuals will result in a bright image, as High percentuals will result in a more darken image.
|
198
|
-
# The default value is 60
|
199
|
-
|
200
|
-
config.threshold_level = 60
|
201
|
-
```
|
202
|
-
|
203
|
-
### Distance in axis X from margin to scan the clock marks
|
231
|
+
### Edge level
|
204
232
|
|
205
233
|
```ruby
|
206
|
-
#
|
207
|
-
#
|
208
|
-
|
209
|
-
# a X pixel column that cross all the clocks.
|
210
|
-
# The default value is 62 but only for tests purposes. You SHOULD calculate this value and set
|
211
|
-
# a new one.
|
212
|
-
|
213
|
-
config.clock_marks_scan_x = 62
|
234
|
+
# The size of the edge to apply in the edge detect algorithm.
|
235
|
+
# The default value is 4, but is very important you verify the algorithm result and adjust it to work.
|
236
|
+
config.edge_level = 4
|
214
237
|
```
|
215
238
|
|
216
|
-
###
|
217
|
-
|
218
|
-
```ruby
|
219
|
-
# Defines the expected width and height of clock marks (in pixels). With the tolerance, if the first
|
220
|
-
# recognized clock exceeds or stricts those values, it will be ignored...
|
221
|
-
# The default values is 26 to width and 12 to height. Since the clock marks can be different, you SHOULD
|
222
|
-
# calculate those sizes for your documents.
|
223
|
-
|
224
|
-
config.clock_width = 26
|
225
|
-
config.clock_height = 12
|
226
|
-
```
|
227
|
-
|
228
|
-
### Tolerance on the size of clock mark
|
239
|
+
### Threshold level
|
229
240
|
|
230
241
|
```ruby
|
231
|
-
#
|
232
|
-
#
|
233
|
-
# The default value is
|
242
|
+
# Applies the given percentual in the image in order to get it back with only black and white pixels.
|
243
|
+
# Low percentuals will result in a bright image, as High percentuals will result in a more darken image.
|
244
|
+
# The default value is 60, but is very important you verify the algorithm result and adjust it to work.
|
234
245
|
|
235
|
-
config.
|
246
|
+
config.threshold_level = 60
|
236
247
|
```
|
237
248
|
|
238
|
-
### Expected
|
249
|
+
### Expected lines
|
239
250
|
|
240
251
|
```ruby
|
241
|
-
#
|
242
|
-
#
|
243
|
-
#
|
244
|
-
# The default value is 0
|
252
|
+
# The scan will raise the incorrect group watcher if one or more group don't have the expected number of lines
|
253
|
+
# Here, this configuration becomes valid to all groups.
|
254
|
+
# The default value is 20, but is very
|
245
255
|
|
246
|
-
config.
|
256
|
+
config.default_expected_lines = 20
|
247
257
|
```
|
248
258
|
|
249
259
|
### Default mark sizes
|
250
260
|
|
251
261
|
```ruby
|
252
|
-
# Defines the expected width and height of the marks (in pixels). With the tolerance, if the
|
262
|
+
# Defines the expected width and height of the marks (in pixels). With the tolerance, if the recognized
|
253
263
|
# mark exceeds or stricts those values, it will be ignored.
|
254
264
|
# The default values is 20 to width and 20 to height. Since the marks can be different, you SHOULD
|
255
265
|
# calculate those sizes for your documents.
|
@@ -258,6 +268,17 @@ config.default_mark_width = 20
|
|
258
268
|
config.default_mark_height = 20
|
259
269
|
```
|
260
270
|
|
271
|
+
### Default mark sizes tolerances
|
272
|
+
|
273
|
+
```ruby
|
274
|
+
# Defines the tolerance in width and height of the marks (in pixels). With the the mark size, if the recognized
|
275
|
+
# mark exceeds or stricts those values, it will be ignored.
|
276
|
+
# The default values is 4 for both width and height.
|
277
|
+
|
278
|
+
config.default_mark_width_tolerance = 4
|
279
|
+
config.default_mark_height_tolerance = 4
|
280
|
+
```
|
281
|
+
|
261
282
|
### Intensity percentual
|
262
283
|
|
263
284
|
```ruby
|
@@ -285,13 +306,22 @@ config.default_marks_options = %w{A B C D E}
|
|
285
306
|
|
286
307
|
```ruby
|
287
308
|
# Defines the distance (in pixel) between the middle of a mark and the middle of the next mark in the same group.
|
288
|
-
#
|
289
|
-
# After it, each mark option in the group will be checked based in this distance.
|
309
|
+
# This option is used to try suppose not found marks.
|
290
310
|
# The default value is 25
|
291
311
|
|
292
312
|
config.default_distance_between_marks = 25
|
293
313
|
```
|
294
314
|
|
315
|
+
### Adjust bnconsistent bubbles
|
316
|
+
|
317
|
+
```ruby
|
318
|
+
# If true, it will perform an analysis in each group in order to see if there's more or less than expected bubbles,
|
319
|
+
# an will try to remove or add these inconsistent marks.
|
320
|
+
# The default value is true
|
321
|
+
|
322
|
+
config.adjust_inconsistent_bubbles = true
|
323
|
+
```
|
324
|
+
|
295
325
|
|
296
326
|
Group Configuration Options
|
297
327
|
---------------------------
|
@@ -299,6 +329,14 @@ Group Configuration Options
|
|
299
329
|
The General Configuration Options is more generic for the entire document. So, you can have some particularities
|
300
330
|
when defining a group. So:
|
301
331
|
|
332
|
+
### Expected coordinates
|
333
|
+
|
334
|
+
```ruby
|
335
|
+
# This configuration defines the area coordinate where the group is expected to be.
|
336
|
+
|
337
|
+
group.expected_coordinates = {x1: 145, y1: 780, x2: 270, y2: 1290}
|
338
|
+
```
|
339
|
+
|
302
340
|
### Mark sizes
|
303
341
|
|
304
342
|
```ruby
|
@@ -316,15 +354,6 @@ group.mark_height = RubyMarks.default_mark_height
|
|
316
354
|
group.marks_options = RubyMarks.default_marks_options
|
317
355
|
```
|
318
356
|
|
319
|
-
### Distance in axis X from clock
|
320
|
-
|
321
|
-
```ruby
|
322
|
-
# Defines the distance from the right corner of the clock mark to the middle of the first mark in the group
|
323
|
-
# It don't have a default value, you MUST set this value for each group in your document
|
324
|
-
|
325
|
-
group.x_distance_from_clock = 89
|
326
|
-
```
|
327
|
-
|
328
357
|
### Distance Between Marks
|
329
358
|
|
330
359
|
```ruby
|
@@ -333,26 +362,25 @@ group.x_distance_from_clock = 89
|
|
333
362
|
group.distance_between_marks = RubyMarks.default_distance_between_marks
|
334
363
|
```
|
335
364
|
|
336
|
-
###
|
365
|
+
### Expected lines
|
337
366
|
|
338
367
|
```ruby
|
339
|
-
#
|
340
|
-
# should be returned in the result of the scan.
|
368
|
+
# It overwrites the default_expected_lines values for the group you configure it.
|
341
369
|
|
342
|
-
group.
|
370
|
+
group.expected_lines = @recognizer.config.default_expected_lines
|
343
371
|
```
|
344
372
|
|
345
373
|
|
346
374
|
Watchers
|
347
375
|
--------
|
348
376
|
|
349
|
-
Sometimes, due some image flaws, the scan can't recognize some
|
377
|
+
Sometimes, due some image flaws, the scan can't recognize some group, or a mark, or even recognize
|
350
378
|
more than one mark in a clock row in the same group when it is not expected. Then, you can place some
|
351
|
-
watchers, that will perform some custom code made by yourself in those cases
|
352
|
-
|
353
|
-
call the scan method again inside the watcher, you should make sure that you
|
354
|
-
to avoid a endless loop. You always can check how many times the watcher
|
355
|
-
`recognizer.raised_watchers[:watcher_name]` hash.
|
379
|
+
watchers, that will perform some custom code made by yourself in those cases, such applies a deskew
|
380
|
+
in image and re-run the scan, for example.
|
381
|
+
But, be advised, if you call the scan method again inside the watcher, you should make sure that you
|
382
|
+
have a way to leave the watcher to avoid a endless loop. You always can check how many times the watcher
|
383
|
+
got raised by checking in `recognizer.raised_watchers[:watcher_name]` hash.
|
356
384
|
|
357
385
|
|
358
386
|
### Scan Mark Watcher
|
@@ -390,14 +418,15 @@ recognizer.add_watcher :scan_multiple_marked_watcher do |recognizer, result|
|
|
390
418
|
end
|
391
419
|
```
|
392
420
|
|
393
|
-
###
|
421
|
+
### Incorrect Group Watcher
|
394
422
|
|
395
423
|
```ruby
|
396
|
-
# Will execute your custom code if didn't
|
397
|
-
#
|
398
|
-
# It returns the recognizer object
|
424
|
+
# Will execute your custom code if didn't a group isn't found, or it have a line count different than expected,
|
425
|
+
# or in one or more lines the options marks found are different of the specified in marks options.
|
426
|
+
# It returns the recognizer object, a boolean value to incorrect expected lines count, and a boolean value
|
427
|
+
# to incorrect bubble line found, and a boolean value to bubbles adjusted or not.
|
399
428
|
|
400
|
-
recognizer.add_watcher :clock_mark_difference_watcher do |recognizer|
|
429
|
+
recognizer.add_watcher :clock_mark_difference_watcher do |recognizer, incorrect_expected_lines, incorrect_bubble_line_found, bubbles_adjusted|
|
401
430
|
# place your custom code
|
402
431
|
end
|
403
432
|
```
|
data/lib/ruby_marks/config.rb
CHANGED
@@ -3,58 +3,37 @@ module RubyMarks
|
|
3
3
|
|
4
4
|
class Config
|
5
5
|
|
6
|
-
attr_accessor :
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
6
|
+
attr_accessor :intensity_percentual, :edge_level, :default_marks_options, :threshold_level,
|
7
|
+
:default_mark_width, :default_mark_height,
|
8
|
+
:default_mark_width_tolerance, :default_mark_height_tolerance,
|
9
|
+
:default_distance_between_marks, :adjust_inconsistent_bubbles,
|
10
|
+
:default_expected_lines
|
11
|
+
|
10
12
|
|
11
13
|
def initialize(recognizer)
|
12
14
|
@recognizer = recognizer
|
13
15
|
@threshold_level = RubyMarks.threshold_level
|
16
|
+
@edge_level = RubyMarks.edge_level
|
14
17
|
|
15
|
-
@
|
16
|
-
@recognition_colors = RubyMarks.recognition_colors
|
18
|
+
@adjust_inconsistent_bubbles = RubyMarks.adjust_inconsistent_bubbles
|
17
19
|
|
18
|
-
@
|
19
|
-
@clock_marks_scan_x = RubyMarks.clock_marks_scan_x
|
20
|
-
@clock_width = RubyMarks.clock_width
|
21
|
-
@clock_height = RubyMarks.clock_height
|
22
|
-
@clock_mark_size_tolerance = RubyMarks.clock_mark_size_tolerance
|
20
|
+
@intensity_percentual = RubyMarks.intensity_percentual
|
23
21
|
|
24
22
|
@default_mark_width = RubyMarks.default_mark_width
|
25
23
|
@default_mark_height = RubyMarks.default_mark_height
|
24
|
+
|
25
|
+
@default_mark_width_tolerance = RubyMarks.default_mark_width_tolerance
|
26
|
+
@default_mark_height_tolerance = RubyMarks.default_mark_height_tolerance
|
27
|
+
|
26
28
|
@default_marks_options = RubyMarks.default_marks_options
|
27
29
|
@default_distance_between_marks = RubyMarks.default_distance_between_marks
|
30
|
+
@default_expected_lines = RubyMarks.default_expected_lines
|
28
31
|
end
|
29
32
|
|
30
33
|
def calculated_threshold_level
|
31
34
|
Magick::QuantumRange * (@threshold_level.to_f / 100)
|
32
35
|
end
|
33
36
|
|
34
|
-
def clock_width_with_down_tolerance
|
35
|
-
@clock_width - @clock_mark_size_tolerance
|
36
|
-
end
|
37
|
-
|
38
|
-
def clock_width_with_up_tolerance
|
39
|
-
@clock_width + @clock_mark_size_tolerance
|
40
|
-
end
|
41
|
-
|
42
|
-
def clock_height_with_down_tolerance
|
43
|
-
@clock_height - @clock_mark_size_tolerance
|
44
|
-
end
|
45
|
-
|
46
|
-
def clock_height_with_up_tolerance
|
47
|
-
@clock_height + @clock_mark_size_tolerance
|
48
|
-
end
|
49
|
-
|
50
|
-
def clock_width_tolerance_range
|
51
|
-
clock_width_with_down_tolerance..clock_width_with_up_tolerance
|
52
|
-
end
|
53
|
-
|
54
|
-
def clock_height_tolerance_range
|
55
|
-
clock_height_with_down_tolerance..clock_height_with_up_tolerance
|
56
|
-
end
|
57
|
-
|
58
37
|
def define_group(group_label, &block)
|
59
38
|
group = RubyMarks::Group.new(group_label, @recognizer, &block)
|
60
39
|
@recognizer.add_group(group)
|
data/lib/ruby_marks/group.rb
CHANGED
@@ -2,33 +2,63 @@
|
|
2
2
|
module RubyMarks
|
3
3
|
|
4
4
|
class Group
|
5
|
-
attr_reader :label, :recognizer
|
5
|
+
attr_reader :label, :recognizer
|
6
|
+
attr_accessor :mark_width, :mark_height, :marks_options, :coordinates, :expected_coordinates,
|
7
|
+
:mark_width_tolerance, :mark_height_tolerance, :marks, :distance_between_marks
|
6
8
|
|
7
|
-
attr_accessor :mark_width, :mark_height, :marks_options, :x_distance_from_clock,
|
8
|
-
:distance_between_marks
|
9
9
|
|
10
10
|
def initialize(label, recognizer)
|
11
11
|
@label = label
|
12
12
|
@recognizer = recognizer
|
13
|
-
|
13
|
+
|
14
|
+
@mark_width = @recognizer.config.default_mark_width
|
14
15
|
@mark_height = @recognizer.config.default_mark_height
|
16
|
+
|
17
|
+
@mark_width_tolerance = @recognizer.config.default_mark_width_tolerance
|
18
|
+
@mark_height_tolerance = @recognizer.config.default_mark_height_tolerance
|
19
|
+
|
15
20
|
@marks_options = @recognizer.config.default_marks_options
|
16
21
|
@distance_between_marks = @recognizer.config.default_distance_between_marks
|
17
|
-
|
18
|
-
@
|
22
|
+
|
23
|
+
@expected_lines = @recognizer.config.default_expected_lines
|
24
|
+
@expected_coordinates = {}
|
19
25
|
yield self if block_given?
|
20
26
|
end
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
@
|
28
|
+
|
29
|
+
def incorrect_expected_lines
|
30
|
+
@expected_lines != marks.count
|
31
|
+
end
|
32
|
+
|
33
|
+
def mark_width_with_down_tolerance
|
34
|
+
@mark_width - @mark_width_tolerance
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def mark_width_with_up_tolerance
|
39
|
+
@mark_width + @mark_width_tolerance
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def mark_height_with_down_tolerance
|
44
|
+
@mark_height - @mark_height_tolerance
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def mark_height_with_up_tolerance
|
49
|
+
@mark_height + @mark_height_tolerance
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def mark_width_tolerance_range
|
54
|
+
mark_width_with_down_tolerance..mark_width_with_up_tolerance
|
25
55
|
end
|
26
56
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
57
|
+
|
58
|
+
def mark_height_tolerance_range
|
59
|
+
mark_height_with_down_tolerance..mark_height_with_up_tolerance
|
31
60
|
end
|
61
|
+
|
32
62
|
end
|
33
63
|
|
34
64
|
end
|