Class: ImageSvd::Channel
- Inherits:
-
Object
- Object
- ImageSvd::Channel
- Defined in:
- lib/image_svd/image_matrix.rb
Overview
This class is responsible for manipulating matricies that correspond to the color channels in images, which includes performing Singular Value Decomposition on a matrix
Instance Attribute Summary collapse
-
#m ⇒ Object
Returns the value of attribute m.
-
#n ⇒ Object
Returns the value of attribute n.
-
#num_singular_values ⇒ Object
readonly
Returns the value of attribute num_singular_values.
-
#sigma_vTs ⇒ Object
Returns the value of attribute sigma_vTs.
-
#us ⇒ Object
Returns the value of attribute us.
Class Method Summary collapse
-
.apply_h(hash, num_singular_values) ⇒ Object
can initialize with the result of #to_h.
Instance Method Summary collapse
-
#decompose(m_A = nil) ⇒ Object
The most time consuming method Launches the decomposition and saves the two lists of vectors needed to reconstruct the image rubocop:disable MethodLength.
-
#initialize(matrix, num_singular_values) ⇒ Channel
constructor
A new instance of Channel.
-
#reconstruct_matrix(num_singular_values = nil) ⇒ Object
rubocop:enable MethodLength.
-
#to_h ⇒ Object
returns all the information necessary to serialize this channel.
Constructor Details
#initialize(matrix, num_singular_values) ⇒ Channel
Returns a new instance of Channel.
16 17 18 19 20 |
# File 'lib/image_svd/image_matrix.rb', line 16 def initialize(matrix, num_singular_values) fail 'Channel initialized without a matrix' unless matrix.is_a? Matrix @matrix = matrix @num_singular_values = num_singular_values end |
Instance Attribute Details
#m ⇒ Object
Returns the value of attribute m.
13 14 15 |
# File 'lib/image_svd/image_matrix.rb', line 13 def m @m end |
#n ⇒ Object
Returns the value of attribute n.
13 14 15 |
# File 'lib/image_svd/image_matrix.rb', line 13 def n @n end |
#num_singular_values ⇒ Object (readonly)
Returns the value of attribute num_singular_values.
14 15 16 |
# File 'lib/image_svd/image_matrix.rb', line 14 def num_singular_values @num_singular_values end |
#sigma_vTs ⇒ Object
Returns the value of attribute sigma_vTs.
13 14 15 |
# File 'lib/image_svd/image_matrix.rb', line 13 def sigma_vTs @sigma_vTs end |
#us ⇒ Object
Returns the value of attribute us.
13 14 15 |
# File 'lib/image_svd/image_matrix.rb', line 13 def us @us end |
Class Method Details
.apply_h(hash, num_singular_values) ⇒ Object
can initialize with the result of #to_h
70 71 72 73 74 75 76 77 78 |
# File 'lib/image_svd/image_matrix.rb', line 70 def self.apply_h(hash, num_singular_values) c = new(Matrix[], num_singular_values) c.sigma_vTs = hash['sigma_vTs'] .map { |arr| Vector[*arr.flatten].covector } c.us = hash['us'].map { |arr| Vector[*arr.flatten] } c.m = hash['m'] c.n = hash['n'] c end |
Instance Method Details
#decompose(m_A = nil) ⇒ Object
The most time consuming method Launches the decomposition and saves the two lists of vectors needed to reconstruct the image rubocop:disable MethodLength
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/image_svd/image_matrix.rb', line 26 def decompose(m_A = nil) m_A ||= @matrix m_AT = m_A.transpose @m, @n = m_A.to_a.length, m_A.to_a.first.length m_ATA = m_AT * m_A # linear regression from several images over 200px wide eta = (0 < (t = (0.0003541 * (@m * @n) - 10.541)) ? t : 0) puts "Searching for eigenvalues... Estimated Time: #{eta.floor} seconds" dcmp = Matrix::EigenvalueDecomposition.new(m_ATA) evs = dcmp.eigenvalues # eigenvectors are already normalized and in same order as eigenvalues sorted_eigenvectors = dcmp.eigenvectors.each_with_index .sort_by { |_v, i| -evs[i] } .map { |v, _idx| v } both = (0...@num_singular_values).map do |idx| u = sorted_eigenvectors[idx] sigma_vT = (m_A * u).covector [u, sigma_vT] end @sigma_vTs = both.map { |p| p.last } @us = both.map { |p| p.first } self end |
#reconstruct_matrix(num_singular_values = nil) ⇒ Object
rubocop:enable MethodLength
51 52 53 54 55 56 57 |
# File 'lib/image_svd/image_matrix.rb', line 51 def reconstruct_matrix(num_singular_values = nil) num_singular_values ||= @num_singular_values zero_matrix = Matrix[*Array.new(@n) { Array.new(@m) { 0 } }] (0...num_singular_values).reduce(zero_matrix) do |acc, idx| acc + (@us[idx] * @sigma_vTs[idx]) end.transpose end |
#to_h ⇒ Object
returns all the information necessary to serialize this channel
60 61 62 63 64 65 66 67 |
# File 'lib/image_svd/image_matrix.rb', line 60 def to_h { 'sigma_vTs' => @sigma_vTs.map(&:to_a), 'us' => @us.map(&:to_a), 'm' => @m, 'n' => @n } end |