class Mork::SheetOMR
Optical mark recognition of a response sheet that was: 1) generated with SheetPDF
, 2) printed on plain paper, 3) filled out by a responder, and 4) acquired as a image file.
The sheet is automatically registered upon object creation, after which it is possible to perform queries, as well as save a copy of the scanned image with various overlays superimposed, highlighting the expected correc choices, the actually marked ones, etc.
Public Class Methods
@param path [String] the required path/filename to the saved image
(.jpg, .jpeg, .png, or .pdf)
@param layout [String, Hash] the sheet description. Send a hash of
parameters or a string to specify the path/filename of a YAML file containing the parameters. See the README file for a full listing of the available parameters.
# File lib/mork/sheet_omr.rb, line 20 def initialize(path, layout=nil) grom = GridOMR.new layout @mim = Mimage.new path, grom end
Public Instance Methods
Sheet barcode as an integer
@return [Integer]
# File lib/mork/sheet_omr.rb, line 48 def barcode return if not_registered barcode_string.to_i(2) end
Sheet barcode as a binary-like string
@return [String] a string of 0s and 1s; the string is `barcode_bits`
bits long, with most significant bits to the left
# File lib/mork/sheet_omr.rb, line 57 def barcode_string return if not_registered @mim.barcode_bits.map do |b| b ? '1' : '0' end.join.reverse end
# File lib/mork/sheet_omr.rb, line 32 def low_contrast? @mim.low_contrast? end
True if the specified question/choice cell has been marked
@param question [Integer] the question number, zero-based @param choice [Integer] the choice number, zero-based @return [Boolean]
# File lib/mork/sheet_omr.rb, line 93 def marked?(question, choice) return if not_registered marked_choices[question].find {|x| x==choice} ? true : false end
The set of choice indices marked on the response sheet
@return [Array] an array of arrays of integers; each element contains
the (zero-based) list of marked choices for the corresponding question. For example, the following `marked_choices` array: `[[0], [], [3,4]]` indicates that the responder has marked the first choice for the first question, none for the second, and the fourth and fifth choices for the third question.
# File lib/mork/sheet_omr.rb, line 106 def marked_choices return if not_registered @mim.marked end
The set of choice indices marked on the response sheet. If more than one choice was marked for a question, the response is regarded as invalid and treated as if it had been left blank.
@return [Array] an array of integers; each element contains
the (zero-based) marked choice for the corresponding question.
# File lib/mork/sheet_omr.rb, line 117 def marked_choices_unique return if not_registered marked_choices.map do |c| c.length == 1 ? c.first : nil end end
The set of letters marked on the response sheet. At this time, only the latin sequence 'A, B, C…' is supported.
@return [Array] an array of arrays of 1-character strings; each element
contains the list of letters marked for the corresponding question.
# File lib/mork/sheet_omr.rb, line 129 def marked_letters return if not_registered marked_choices.map do |q| q.map { |cho| (65+cho).chr } end end
The set of letters marked on the response sheet. At this time, only the latin sequence 'A, B, C…' is supported. If more than one choice was marked for an item, the response is regarded as invalid and treated as if it had been left blank.
@return [Array] an array of 1-character strings
# File lib/mork/sheet_omr.rb, line 142 def marked_letters_unique return if not_registered marked_choices_unique.map do |c| c.nil?? '' : (65+c).chr end end
Apply an overlay on the image
@param what [Symbol] the overlay type, choose from `:outline`, `:check`,
`:highlight`
@param where [Array, Symbol] where to apply the overlay. Either an array
of arrays of (zero-based) indices to specify target cells, or one of the following symbols: `:marked`: all marked cells, among those specified by the `choices` argument during object creation (this is the default); `:all`: all cells in `choices`; `:max`: maximum number of cells allowed by the layout (can be larger than `:all`); `:barcode`: the dark barcode elements; `:cal` the calibration cells
# File lib/mork/sheet_omr.rb, line 161 def overlay(what, where=:marked) return if not_registered @mim.overlay what, where end
Saves a copy of the source image after registration; the output image will also contain any previously applied overlays.
@param fname [String] the path/filename of the target image, including
the extension (`.jpg`, `.png`)
# File lib/mork/sheet_omr.rb, line 171 def save(fname) return if not_registered @mim.save(fname, true) end
Saves a copy of the original image with overlays showing the crop areas used to localize the registration marks and the detected registration mark centers.
@param fname [String] the path/filename of the target image, including
the extension (`.jpg`, `.png`)
# File lib/mork/sheet_omr.rb, line 182 def save_registration(fname) @mim.save_registration fname end
Setting the choices/questions to analyze. If this function is not called, the maximum number of choices/questions allowed by the layout will be evaluated.
@param choices [Integer, Array] the questions/choices we want subsequent
scoring/overlaying to apply to. Normally, `choices` should be an array of integers, with each element indicating the number of available choices for the corresponding question (i.e. `choices.length` is the number of questions). As a shortcut, `choices` can also be a single integer value, indicating the number of questions; in such case, the maximum number of choices allowed by the layout will be considered.
@return [Boolean] True if the sheet is properly registered and ready to
be marked; false otherwise.
# File lib/mork/sheet_omr.rb, line 78 def set_choices(choices) return false unless valid? @mim.set_ch case choices when Integer; @mim.choxq[0...choices] when Array; choices else fail ArgumentError, 'Invalid choice set' end true end
Registration status for each of the four corners
@return [Hash] { tl: Symbol, tr: Symbol, br: Symbol, bl: Symbol } where
symbol is either `:ok` or `:edgy`, meaning that the centroid was found to be too close to the edge of the search area to be considered reliable
# File lib/mork/sheet_omr.rb, line 41 def status @mim.status end
True if sheet registration completed successfully
@return [Boolean]
# File lib/mork/sheet_omr.rb, line 28 def valid? @mim.valid? end