Method: Informers::Utils.interpolate_data

Defined in:
lib/informers/utils/math.rb

.interpolate_data(input, in_shape, out_shape, mode = "bilinear", align_corners = false) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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/informers/utils/math.rb', line 3

def self.interpolate_data(input, in_shape, out_shape, mode = "bilinear", align_corners = false)
  in_channels, in_height, in_width = in_shape
  out_height, out_width = out_shape

  # TODO use mode and align_corners

  # Output image dimensions
  x_scale = out_width / in_width.to_f
  y_scale = out_height / in_height.to_f

  # Output image
  out_img = Array.new(out_height * out_width * in_channels)

  # Pre-calculate strides
  in_stride = in_height * in_width
  out_stride = out_height * out_width

  out_height.times do |i|
    out_width.times do |j|
      # Calculate output offset
      out_offset = i * out_width + j

      # Calculate input pixel coordinates
      x = (j + 0.5) / x_scale - 0.5
      y = (i + 0.5) / y_scale - 0.5

      # Calculate the four nearest input pixels
      # We also check if the input pixel coordinates are within the image bounds
      x1 = x.floor
      y1 = y.floor
      x2 = [x1 + 1, in_width - 1].min
      y2 = [y1 + 1, in_height - 1].min

      x1 = [x1, 0].max
      y1 = [y1, 0].max

      # Calculate the fractional distances between the input pixel and the four nearest pixels
      s = x - x1
      t = y - y1

      # Perform bilinear interpolation
      w1 = (1 - s) * (1 - t)
      w2 = s * (1 - t)
      w3 = (1 - s) * t
      w4 = s * t

      # Calculate the four nearest input pixel indices
      y_stride = y1 * in_width
      x_stride = y2 * in_width
      idx1 = y_stride + x1
      idx2 = y_stride + x2
      idx3 = x_stride + x1
      idx4 = x_stride + x2

      in_channels.times do |k|
        # Calculate channel offset
        c_offset = k * in_stride

        out_img[k * out_stride + out_offset] =
          w1 * input[c_offset + idx1] +
          w2 * input[c_offset + idx2] +
          w3 * input[c_offset + idx3] +
          w4 * input[c_offset + idx4]
      end
    end
  end

  out_img
end