ruby_marks 0.1.5 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Document Example](https://raw.github.com/andrerpbts/ruby_marks/master/assets/sheet_demo2.png)](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
|
+
[![Document Example](https://raw.github.com/andrerpbts/ruby_marks/master/assets/sheet_demo2_group_coords.png)](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
|
+
[![Document Example](https://raw.github.com/andrerpbts/ruby_marks/master/assets/threshold_examples.png)](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
|
+
[![Document Example](https://raw.github.com/andrerpbts/ruby_marks/master/assets/sheet_demo2_edge.png)](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
|
+
[![Flagged Document Example](https://raw.github.com/andrerpbts/ruby_marks/master/assets/sheet_demo2_flagged.png)](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
|
-
[![Flagged Document Example](https://raw.github.com/andrerpbts/ruby_marks/master/assets/sheet_demo2_flagged.png)](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
|