Class: Qrio::SamplingGrid
- Inherits:
-
Object
- Object
- Qrio::SamplingGrid
- Defined in:
- lib/qrio/sampling_grid.rb
Instance Attribute Summary collapse
-
#angles ⇒ Object
readonly
Returns the value of attribute angles.
-
#block_height ⇒ Object
readonly
Returns the value of attribute block_height.
-
#block_width ⇒ Object
readonly
Returns the value of attribute block_width.
-
#bottom_left ⇒ Object
readonly
Returns the value of attribute bottom_left.
-
#bounds ⇒ Object
readonly
Returns the value of attribute bounds.
-
#finder_patterns ⇒ Object
readonly
Returns the value of attribute finder_patterns.
-
#matrix ⇒ Object
readonly
Returns the value of attribute matrix.
-
#orientation ⇒ Object
readonly
Returns the value of attribute orientation.
-
#origin_corner ⇒ Object
readonly
Returns the value of attribute origin_corner.
-
#provisional_version ⇒ Object
readonly
Returns the value of attribute provisional_version.
-
#top_right ⇒ Object
readonly
Returns the value of attribute top_right.
Instance Method Summary collapse
- #build_finder_pattern_neighbors ⇒ Object
-
#detect_orientation ⇒ Object
which way is the QR rotated? 0) normal - shared finder patterns in top left 1) - shared finder patterns in top right 2) - shared finder patterns in bottom right 3) - shared finder patterns in bottom left.
- #extracted_pixels ⇒ Object
- #find_origin_corner(normalized = false) ⇒ Object
-
#initialize(matrix, finder_patterns) ⇒ SamplingGrid
constructor
A new instance of SamplingGrid.
- #logical_height ⇒ Object
- #logical_width ⇒ Object
- #non_origin_finder_patterns ⇒ Object
- #normalize ⇒ Object
- #rotate ⇒ Object
- #set_block_dimensions(*finder_patterns) ⇒ Object
- #set_bounds ⇒ Object
- #translate(x, y) ⇒ Object
Constructor Details
#initialize(matrix, finder_patterns) ⇒ SamplingGrid
Returns a new instance of SamplingGrid.
8 9 10 11 12 13 14 15 |
# File 'lib/qrio/sampling_grid.rb', line 8 def initialize(matrix, finder_patterns) @matrix = matrix @finder_patterns = finder_patterns @angles = [] find_origin_corner detect_orientation end |
Instance Attribute Details
#angles ⇒ Object (readonly)
Returns the value of attribute angles.
3 4 5 |
# File 'lib/qrio/sampling_grid.rb', line 3 def angles @angles end |
#block_height ⇒ Object (readonly)
Returns the value of attribute block_height.
3 4 5 |
# File 'lib/qrio/sampling_grid.rb', line 3 def block_height @block_height end |
#block_width ⇒ Object (readonly)
Returns the value of attribute block_width.
3 4 5 |
# File 'lib/qrio/sampling_grid.rb', line 3 def block_width @block_width end |
#bottom_left ⇒ Object (readonly)
Returns the value of attribute bottom_left.
3 4 5 |
# File 'lib/qrio/sampling_grid.rb', line 3 def bottom_left @bottom_left end |
#bounds ⇒ Object (readonly)
Returns the value of attribute bounds.
3 4 5 |
# File 'lib/qrio/sampling_grid.rb', line 3 def bounds @bounds end |
#finder_patterns ⇒ Object (readonly)
Returns the value of attribute finder_patterns.
3 4 5 |
# File 'lib/qrio/sampling_grid.rb', line 3 def finder_patterns @finder_patterns end |
#matrix ⇒ Object (readonly)
Returns the value of attribute matrix.
3 4 5 |
# File 'lib/qrio/sampling_grid.rb', line 3 def matrix @matrix end |
#orientation ⇒ Object (readonly)
Returns the value of attribute orientation.
3 4 5 |
# File 'lib/qrio/sampling_grid.rb', line 3 def orientation @orientation end |
#origin_corner ⇒ Object (readonly)
Returns the value of attribute origin_corner.
3 4 5 |
# File 'lib/qrio/sampling_grid.rb', line 3 def origin_corner @origin_corner end |
#provisional_version ⇒ Object (readonly)
Returns the value of attribute provisional_version.
3 4 5 |
# File 'lib/qrio/sampling_grid.rb', line 3 def provisional_version @provisional_version end |
#top_right ⇒ Object (readonly)
Returns the value of attribute top_right.
3 4 5 |
# File 'lib/qrio/sampling_grid.rb', line 3 def top_right @top_right end |
Instance Method Details
#build_finder_pattern_neighbors ⇒ Object
77 78 79 80 81 82 83 84 |
# File 'lib/qrio/sampling_grid.rb', line 77 def build_finder_pattern_neighbors @finder_patterns.each do |source| @finder_patterns.each do |destination| next if source.center == destination.center @angles << Neighbor.new(source, destination) end end end |
#detect_orientation ⇒ Object
which way is the QR rotated?
0) normal - shared finder patterns in top left
1) - shared finder patterns in top right
2) - shared finder patterns in bottom right
3) - shared finder patterns in bottom left
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/qrio/sampling_grid.rb', line 48 def detect_orientation # TODO : handle multiple possible matches other_corners = non_origin_finder_patterns dc = other_corners.map(&:distance).inject(0){|s,d| s + d } / 2.0 threshold = dc / 2.0 other_corners = other_corners.map(&:destination) set_block_dimensions(@origin_corner, *other_corners) @provisional_version = ((dc / @block_width).round - 10) / 4 xs = other_corners.map{|fp| fp.center.first } ys = other_corners.map{|fp| fp.center.last } above = ys.select{|y| y < (@origin_corner.center.last - threshold) } left = xs.select{|x| x < (@origin_corner.center.first - threshold) } @orientation = if above.any? left.any? ? 2 : 3 else left.any? ? 1 : 0 end end |
#extracted_pixels ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/qrio/sampling_grid.rb', line 128 def extracted_pixels start_x = @origin_corner.center.first - (@block_width * 3.0) start_y = @origin_corner.center.last - (@block_height * 3.0) dest_x = @bottom_left.center.first - (@block_width * 3.0) dest_y = @top_right.center.last - (@block_height * 3.0) # TODO : take bottom right alignment pattern into consideration dy = (dest_y - start_y) / logical_width dx = (dest_x - start_x) / logical_height logical_height.round.times do |row_index| row_start_x = start_x + row_index * dx row_start_y = start_y + (row_index * @block_height) logical_width.round.times do |col_index| x = row_start_x + (col_index * @block_width) y = row_start_y + (col_index * dy) yield x.round, y.round end end end |
#find_origin_corner(normalized = false) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/qrio/sampling_grid.rb', line 17 def find_origin_corner(normalized=false) build_finder_pattern_neighbors shared_corners = @finder_patterns.select do |fp| fp.neighbors.select(&:right_angle?).count > 1 end # TODO : handle multiple possible matches if @origin_corner = shared_corners.first if normalized # we have correct orientation, identify fp positions @top_right = non_origin_finder_patterns.map(&:destination).detect{|fp| fp.center.last < @matrix.height / 2.0 } @bottom_left = non_origin_finder_patterns.map(&:destination).detect{|fp| fp.center.first < @matrix.width / 2.0 } else set_bounds end end end |
#logical_height ⇒ Object
95 96 97 |
# File 'lib/qrio/sampling_grid.rb', line 95 def logical_height @matrix.height / @block_height end |
#logical_width ⇒ Object
91 92 93 |
# File 'lib/qrio/sampling_grid.rb', line 91 def logical_width @matrix.width / @block_width end |
#non_origin_finder_patterns ⇒ Object
73 74 75 |
# File 'lib/qrio/sampling_grid.rb', line 73 def non_origin_finder_patterns @origin_corner.neighbors.select(&:right_angle?)[0,2] end |
#normalize ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/qrio/sampling_grid.rb', line 99 def normalize @matrix = @matrix.extract(*@bounds.to_point_size) translate(*@bounds.top_left) if @orientation > 0 (4 - @orientation).times do rotate end end find_origin_corner(true) end |
#rotate ⇒ Object
123 124 125 126 |
# File 'lib/qrio/sampling_grid.rb', line 123 def rotate @matrix = @matrix.rotate @finder_patterns.map!{|f| f.rotate(@bounds.width, @bounds.height) } end |
#set_block_dimensions(*finder_patterns) ⇒ Object
86 87 88 89 |
# File 'lib/qrio/sampling_grid.rb', line 86 def set_block_dimensions(*finder_patterns) @block_width = finder_patterns.inject(0){|s,f| s + f.width } / 21.0 @block_height = finder_patterns.inject(0){|s,f| s + f.height } / 21.0 end |
#set_bounds ⇒ Object
36 37 38 39 40 41 |
# File 'lib/qrio/sampling_grid.rb', line 36 def set_bounds @bounds = @origin_corner.dup @bounds.neighbors.select(&:right_angle?).each do |n| @bounds = @bounds.union(n.destination) end end |
#translate(x, y) ⇒ Object
112 113 114 115 116 117 118 119 120 121 |
# File 'lib/qrio/sampling_grid.rb', line 112 def translate(x, y) @angles = [] other_corners = non_origin_finder_patterns.map(&:destination) @origin_corner = @origin_corner.translate(x, y) translated = [@origin_corner] translated += other_corners.map{|c| c.translate(x, y) } @finder_patterns = translated end |