Class: Curver

Inherits:
Object
  • Object
show all
Defined in:
lib/curver.rb

Defined Under Namespace

Classes: ChannelCurve, IndexReader, MultiChannelCurve

Constant Summary collapse

CHANNELS =
[:rgb, :r, :g, :b]

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(acv_file_path) ⇒ Curver

Returns a new instance of Curver.



26
27
28
29
30
# File 'lib/curver.rb', line 26

def initialize(acv_file_path)
  raise "No file at this path" unless File.exist?(acv_file_path)
  self.class.set_default_values
  @acv_file_path = acv_file_path
end

Class Attribute Details

.max_valueObject

Returns the value of attribute max_value.



55
56
57
# File 'lib/curver.rb', line 55

def max_value
  @max_value
end

.polynom_degreeObject

Returns the value of attribute polynom_degree.



55
56
57
# File 'lib/curver.rb', line 55

def polynom_degree
  @polynom_degree
end

.polynom_precisionObject

Returns the value of attribute polynom_precision.



55
56
57
# File 'lib/curver.rb', line 55

def polynom_precision
  @polynom_precision
end

.range_sizeObject

Returns the value of attribute range_size.



55
56
57
# File 'lib/curver.rb', line 55

def range_size
  @range_size
end

Instance Attribute Details

#acv_file_pathObject (readonly)

Returns the value of attribute acv_file_path.



7
8
9
# File 'lib/curver.rb', line 7

def acv_file_path
  @acv_file_path
end

Class Method Details

.compute_polynom(points, range) ⇒ Object



76
77
78
79
# File 'lib/curver.rb', line 76

def compute_polynom points, range
  values = spline_values(points, range)
  polynom(range, values)
end

.multi_channel_curve(ary) ⇒ Object



69
70
71
72
73
74
# File 'lib/curver.rb', line 69

def multi_channel_curve ary
  ir = IndexReader.new(2)
  channels_points = CHANNELS.map { |k| sanitize_points read_array!(ary, ir) }
  channels_curves = channels_points.map{ |points| ChannelCurve.new(points) }
  MultiChannelCurve.new(*channels_curves)
end

.polynom(x, y) ⇒ Object



94
95
96
97
98
99
# File 'lib/curver.rb', line 94

def polynom x, y
  x_data = x.map { |xi| (0..polynom_degree).map { |pow| (xi**pow).to_f } }
  mx = Matrix[*x_data]
  my = Matrix.column_vector(y)
  ((mx.t * mx).inv * mx.t * my).transpose.to_a[0].map{|e| truncate(e, polynom_precision) }
end

.range(coords) ⇒ Object



110
111
112
113
# File 'lib/curver.rb', line 110

def range coords
  min_value, max_value = coords.first.first, coords.last.first
  (min_value..max_value).step((max_value - min_value)/range_size).to_a
end

.read_array!(array, index_reader) ⇒ Object



86
87
88
89
90
91
92
# File 'lib/curver.rb', line 86

def read_array! array, index_reader
  ary = array.drop(index_reader.position)
  raise 'Wrong index reader position' if ary.empty?
  points_count = (ary.first * 2)
  index_reader.position += points_count + 1
  ary[1..points_count]
end

.read_curves(file_path) ⇒ Object



64
65
66
67
# File 'lib/curver.rb', line 64

def read_curves file_path
  ary = File.read(file_path, encode: 'binary').unpack('S>*')
  multi_channel_curve(ary)
end

.sanitize_points(array) ⇒ Object



81
82
83
84
# File 'lib/curver.rb', line 81

def sanitize_points array
  ary = (array.length / 2).times.map{|i| [array[2*i+1], array[2*i]]}
  ary.map{ |dot| dot.map{ |v| v / max_value.to_f } }
end

.set_default_valuesObject



57
58
59
60
61
62
# File 'lib/curver.rb', line 57

def set_default_values
  self.polynom_degree    ||= 6
  self.max_value         ||= 255
  self.range_size        ||= 255  
  self.polynom_precision ||= 3    
end

.spline_values(coords, range) ⇒ Object



105
106
107
108
# File 'lib/curver.rb', line 105

def spline_values(coords, range)
  spline = Spliner::Spliner.new coords.map(&:first), coords.map(&:last)
  spline[range]
end

.truncate(i, length) ⇒ Object



101
102
103
# File 'lib/curver.rb', line 101

def truncate i, length
  (i * (10 ** length)).to_i.to_f / (10 ** length)
end

Instance Method Details

#curvesObject



32
33
34
# File 'lib/curver.rb', line 32

def curves
  @curves ||= self.class.read_curves(acv_file_path)
end

#export_image(original_path, export_base_name) ⇒ Object



43
44
45
# File 'lib/curver.rb', line 43

def export_image(original_path, export_base_name)
  self.class.export_image(curves, original_path, export_base_name)
end

#polynomsObject



36
37
38
39
40
41
# File 'lib/curver.rb', line 36

def polynoms
  CHANNELS.reduce({}) do |h, channel|
    h[channel] = curves[channel].polynom
    h
  end
end

#puts_polynomsObject



47
48
49
50
51
# File 'lib/curver.rb', line 47

def puts_polynoms
  puts "Polynoms (x^0 -> x^n) ---"
  puts polynoms
  puts "---"
end