NaN-aware `imresize`

Is there an easy way hack ImageTransforms.imresize to not propagate NaN values?

julia> using ImageTransformations

julia> im = Float32[
       1 2 3 4
       5 6 7 8
       9 10 11 12
       13 14 15 NaN
     ]
4×4 Matrix{Float32}:
  1.0   2.0   3.0    4.0
  5.0   6.0   7.0    8.0
  9.0  10.0  11.0   12.0
 13.0  14.0  15.0  NaN

julia> imresize(im, (2, 2))
2×2 Matrix{Float32}:
  3.5    5.5
 11.5  NaN

In result the lower right corner should be mean(11, 12, 15).

1 Like

Perhaps you can clarify if you need a solution with ImageTransforms.jl specifically. There are various other packages that can achieve this.

No need to use ImageTransforms.jl.

One possible solution is to use the Aggregate transform from GeoStats.jl:

Aggregate(domain, var₁ => agg₁, var₂ => agg₂, ..., varₙ => aggₙ)
  Aggregate([g₁, g₂, ..., gₙ], var₁ => agg₁, var₂ => agg₂, ..., varₙ => aggₙ)

  Aggregate variables var₁, var₂, ..., varₙ over geospatial domain using aggregation functions agg₁, agg₂, ..., aggₙ. Alternatively, aggregate variables over geometries g₁,
  g₂, ..., gₙ. Default aggregation function is mean for continuous variables and first otherwise.

  Examples
  ≡≡≡≡≡≡≡≡

  Aggregate(domain, 1 => last, 2 => maximum)
  Aggregate(domain, :a => first, :b => minimum)
  Aggregate(domain, "a" => last, "b" => maximum)
  Aggregate(geoms, "a" => last, "b" => maximum)

Pass your own aggregation function aggfun to ignore NaN values:

img = GeoIO.load("foo.jpg")

grid = CartesianGrid(M, N)

img |> Aggregate(grid, "color" => aggfun)

Of course this solution is mostly useful if you are already taking advantage of the full stack we are building for geospatial data science. Others can suggest simpler solutions with smaller packages.

In case you want to learn more: Geospatial Data Science with Julia