# Image pooling

**URL:** <https://discourse.julialang.org/t/image-pooling/5280>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 8, 2017, 1:31pm UTC](https://discourse.julialang.org/t/image-pooling/5280 "2017-08-08T13:31:13Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [August 8, 2017, 1:31pm UTC](https://discourse.julialang.org/t/image-pooling/5280/1 "2017-08-08T13:31:13Z")

</div>

Is there a package that implements image pooling?

In more detail: I have a big image and need to downsize it. Say my image is of size 1000x1000 and I want to bring it down to 100x100. What I want to do is tile it with 10x10 blocks and replace each block by its median or mean, maximum… This operation is called pooling I think.  
More generally I would like to be able to replace each 10x10 block by say a 4x4 block with respect to some function “f : 10x10 → 4x4”  
Is there a package that implements these kinds of operations?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [August 8, 2017, 1:58pm UTC](https://discourse.julialang.org/t/image-pooling/5280/2 "2017-08-08T13:58:12Z")

</div>

You can low-pass filter the image using [Images.jl/README.md at master · JuliaImages/Images.jl · GitHub](https://github.com/JuliaImages/Images.jl/blob/master/README.md)  
And then subsample it manually.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [August 8, 2017, 2:20pm UTC](https://discourse.julialang.org/t/image-pooling/5280/3 "2017-08-08T14:20:16Z")

</div>

Related to the question, you may try `Images.resize` as discussed in this thread:

[https://github.com/JuliaImages/Images.jl/issues/69](https://github.com/JuliaImages/Images.jl/issues/69)

Code optimization is still under development though.

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [August 8, 2017, 3:03pm UTC](https://discourse.julialang.org/t/image-pooling/5280/4 "2017-08-08T15:03:06Z")

</div>

That has bad performance (also not exactly equivalent, but that does probably not matter in practice). For example applying naively the 10x10 median filter and then subsampling does 100 times more work then necessary.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [August 8, 2017, 3:20pm UTC](https://discourse.julialang.org/t/image-pooling/5280/5 "2017-08-08T15:20:13Z")

</div>

The package [GitHub - JuliaArrays/TiledIteration.jl: Julia package to facilitate writing mulithreaded, multidimensional, cache-efficient code](https://github.com/JuliaArrays/TiledIteration.jl) probably provides the functionality you want, at least low level support for it, e.g.,

```julia
julia> using TiledIteration

julia> A = rand(1000,1000); # our big array

julia> asmall = map(TileIterator(indices(A), (100,100))) do tileinds
                    median(A[tileinds...])
                end;

julia> Asmall = reshape(asmall,10,10);

julia> Asmall[1,1] == median(A[1:100,1:100])
true

julia> Asmall[end,end] == median(A[901:end,901:end])
true

julia> size(Asmall)
(10, 10)

```

I have not verified that this actually does exactly what you want, maybe the final array must be permuted somehow.

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [August 8, 2017, 3:46pm UTC](https://discourse.julialang.org/t/image-pooling/5280/6 "2017-08-08T15:46:51Z")

</div>

Looks promising, I will check it out, thanks!

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [August 9, 2017, 1:02pm UTC](https://discourse.julialang.org/t/image-pooling/5280/7 "2017-08-09T13:02:57Z")

</div>

Try `restrict`, which (should have) good performance while also antialiasing. You can call `resize` for the final (less-than-a-factor-of-2) resizing.

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [March 5, 2021, 2:03pm UTC](https://discourse.julialang.org/t/image-pooling/5280/8 "2021-03-05T14:03:57Z")

</div>

Hello,  
probably this known, but when you apply `restrict`, what happens if my input matrix has NaN values, I did tried for my case, and I see that more empty regions appear, I suppose that the ouput within each cell is NaN if there is at least one during the computation. It would be feasible to say that if there is NaNs but at least one real value or more, then operate on those and give out a real value and not a NaN?

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [March 5, 2021, 5:24pm UTC](https://discourse.julialang.org/t/image-pooling/5280/9 "2021-03-05T17:24:44Z")

</div>

I think you are looking for what [gdaladdo](https://gdal.org/programs/gdaladdo.html) does. Likely possible to achieve with ArchGDAL.

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [March 5, 2021, 5:37pm UTC](https://discourse.julialang.org/t/image-pooling/5280/10 "2021-03-05T17:37:05Z")

</div>

> [@joa-quim](#):
>
> ArchGDAL

indeed, it seems likely, let’s hope ArchGDAL has a single and simple function like `restrict`. 🤞

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [March 5, 2021, 6:00pm UTC](https://discourse.julialang.org/t/image-pooling/5280/11 "2021-03-05T18:00:27Z")

</div>

It probably wouldn’t be hard to modify `restrict` to do that, though it would very likely have a performance impact so it would be best to keep the current implementation intact. One possibility would be to pass a function as an argument that would tally the local neighborhood. E.g., the current algorithm might accept

```julia
directweight(val, w) = val, w

```

and your version

```julia
nanweight(val, w) = isnan(val) ? (zero(val), zero(w)) : (val, w)

```

Then you pass `directweight` or `nanweight` as the first argument of `restrict` depending on which behavior you want.

A PR would be gratefully accepted!
