Module: Gsplat::Ops::Relocation

Defined in:
lib/gsplat/ops/relocation.rb

Overview

Closed-form opacity and scale update from 3DGS-MCMC equation 9.

Constant Summary collapse

DEFAULT_N_MAX =

Default maximum split ratio represented by binomial_table.

51

Class Method Summary collapse

Class Method Details

.binomial_table(n_max: DEFAULT_N_MAX, dtype: Numo::SFloat) ⇒ Numo::NArray

Builds the binomial coefficient lookup used by relocation.

Parameters:

  • n_max (Integer) (defaults to: DEFAULT_N_MAX)

    maximum split ratio, inclusive

  • dtype (Class) (defaults to: Numo::SFloat)

    Numo floating-point class

Returns:

  • (Numo::NArray)

    [n_max,n_max]

Raises:

  • (ArgumentError)


18
19
20
21
22
23
24
25
26
# File 'lib/gsplat/ops/relocation.rb', line 18

def binomial_table(n_max: DEFAULT_N_MAX, dtype: Numo::SFloat)
  raise ArgumentError, "n_max must be a positive integer" unless n_max.is_a?(Integer) && n_max.positive?

  output = dtype.zeros(n_max, n_max)
  n_max.times do |n_value|
    (n_value + 1).times { |k_value| output[n_value, k_value] = binomial(n_value, k_value) }
  end
  output
end

.compute(opacities, scales, ratios, binoms: binomial_table(dtype: opacities.class)) ⇒ Array<Numo::NArray>

Recalculates activated opacities and scales for a requested split ratio.

Parameters:

  • opacities (Numo::NArray)

    [N], activated values in [0,1]

  • scales (Numo::NArray)

    [N,3], activated positive scales

  • ratios (Numo::NArray)

    [N], clamped to 1..n_max

  • binoms (Numo::NArray) (defaults to: binomial_table(dtype: opacities.class))

    [n_max,n_max]

Returns:

  • (Array<Numo::NArray>)

    new opacities and scales



35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/gsplat/ops/relocation.rb', line 35

def compute(opacities, scales, ratios, binoms: binomial_table(dtype: opacities.class))
  validate_inputs!(opacities, scales, ratios, binoms)
  output_opacities = opacities.class.zeros(opacities.shape[0])
  output_scales = scales.class.zeros(*scales.shape)
  opacities.shape[0].times do |index|
    ratio = ratios[index].to_i.clamp(1, binoms.shape[0])
    opacity = opacities[index].to_f
    new_opacity = 1.0 - ((1.0 - opacity)**(1.0 / ratio))
    coefficient = opacity / denominator(new_opacity, ratio, binoms)
    output_opacities[index] = new_opacity
    output_scales[index, true] = scales[index, true] * coefficient
  end
  [output_opacities, output_scales]
end