# Custom image loader in Julia using MLUtils.jl

**URL:** https://discourse.julialang.org/t/custom-image-loader-in-julia-using-mlutils-jl/96318
**Category:** New to Julia
**Created:** [March 19, 2023, 8:33pm UTC](https://discourse.julialang.org/t/custom-image-loader-in-julia-using-mlutils-jl/96318 "2023-03-19T20:33:14Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![ATR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/atr/32/46739_2.png) [@ATR](https://discourse.julialang.org/u/ATR)
#### Post date: [March 19, 2023, 8:33pm UTC](https://discourse.julialang.org/t/custom-image-loader-in-julia-using-mlutils-jl/96318/1 "2023-03-19T20:33:14Z")

</div>

I am new to Julia and feel a little bit confused about how to implement custom image loader, first I have generated 10 sample images and saved it in the temp folder, then I have defined “ImageFolder” but really got stuck in understanding how to use numobs and getobs since documentation is not very comprehensible for me this is what I got:

```julia
using FileIO, ImageIO, ImageCore, MLUtils

struct ImageFolder
    files::Vector{String}
    function ImageFolder(dir::String)
        return new(readdir(dir; join = true))
    end
end

MLUtils.numobs(data::ImageFolder) = data.files
MLUtils.getobs(data::ImageFolder, idx::AbstractVector{<:Integer} = rand(3, 4, length(idx)))

dir = tempname()
mkpath(dir)

@info "Writing random images to $(dir)"

for i in 1:10
    save(joinpath(dir, "$i.jpeg"), colorview(RGB, rand(3, 10, 10)))
end

```

would appreciate any help, thank you in advance…

Tried to implement numobs and getobs so that MLUtils.getobs(data::ImageFolder, idx::AbstractVector{\<:Integer}) should return an Array{Float32,4} of dimension d1xd2xd3xn where d1, d2 are the dimensions of the images and n is equal to length(idx).

---

<div class="post-metadata">

### Author: ![jeremiedb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeremiedb/32/29150_2.png) [@jeremiedb](https://discourse.julialang.org/u/jeremiedb)
#### Post date: [March 20, 2023, 4:01pm UTC](https://discourse.julialang.org/t/custom-image-loader-in-julia-using-mlutils-jl/96318/2 "2023-03-20T16:01:02Z")

</div>

For usage of a custom DataLoader with images saved on disk, the transfer learning tutorial provides an example: [model-zoo/tutorials/transfer\_learning at master · FluxML/model-zoo · GitHub](https://github.com/FluxML/model-zoo/tree/master/tutorials/transfer_learning)

---

<div class="post-metadata">

### Author: ![ATR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/atr/32/46739_2.png) [@ATR](https://discourse.julialang.org/u/ATR)
#### Post date: [March 20, 2023, 8:59pm UTC](https://discourse.julialang.org/t/custom-image-loader-in-julia-using-mlutils-jl/96318/3 "2023-03-20T20:59:35Z")

</div>

Thank you for the answer, nevertheless I would like to use numobs and getobs but could not find any comprehensive tutorials, will see if I can come up with something

---

<div class="post-metadata">

### Author: ![jeremiedb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeremiedb/32/29150_2.png) [@jeremiedb](https://discourse.julialang.org/u/jeremiedb)
#### Post date: [March 20, 2023, 9:10pm UTC](https://discourse.julialang.org/t/custom-image-loader-in-julia-using-mlutils-jl/96318/4 "2023-03-20T21:10:15Z")

</div>

What’s the issue with the above referenced `length` and `getindex` approach?  
These are aligned with the MLUtils DataLoader extension methodology and provides performance as good as it gets AFAIK.

---

<div class="post-metadata">

### Author: ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)
#### Post date: [March 20, 2023, 9:11pm UTC](https://discourse.julialang.org/t/custom-image-loader-in-julia-using-mlutils-jl/96318/5 "2023-03-20T21:11:08Z")

</div>

Note that the docs for `getobs` says:

> `getobs` should only be implemented for types where there is a difference between `getobs` and `Base.getindex` (such as multi-dimensional arrays).

Same story for `numobs`. So the usage above is correct. You are of course free to override it instead, but you’ll miss out on the nice `[...]` indexing syntax and other features Julia provides for types with `getindex`/`length` defined.

---

<div class="post-metadata">

### Author: ![ATR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/atr/32/46739_2.png) [@ATR](https://discourse.julialang.org/u/ATR)
#### Post date: [March 21, 2023, 7:01pm UTC](https://discourse.julialang.org/t/custom-image-loader-in-julia-using-mlutils-jl/96318/6 "2023-03-21T19:01:34Z")

</div>

Hi all, yes I am aware of the getobs usage only where is a difference, the thing is for me it is required to use getobs and numobs, but anyway I will try to implement the code with both, thanks for the input:)

---

<div class="post-metadata">

### Author: ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)
#### Post date: [March 24, 2023, 3:11pm UTC](https://discourse.julialang.org/t/custom-image-loader-in-julia-using-mlutils-jl/96318/7 "2023-03-24T15:11:11Z")

</div>

If you implement `getobs` and `numobs` like you would implement `getindex` and `length`, then you’re likely 90% of the way there. If you feel like the docs are missing some important detail on either, feel free to file an issue or PR.

---

<div class="post-metadata">

### Author: ![holylorenzo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/holylorenzo/32/34169_2.png) [@holylorenzo](https://discourse.julialang.org/u/holylorenzo)
#### Post date: [March 24, 2023, 4:25pm UTC](https://discourse.julialang.org/t/custom-image-loader-in-julia-using-mlutils-jl/96318/8 "2023-03-24T16:25:34Z")

</div>

Hi ATR, given a list of files, you can also use `mapobs` to turn those into a data container of images:

```julia
using MLUtils, FileIO

files = [file for file in readdir(DIR; recursive=true) if endswith(file, ".jpeg")]
images = MLUtils.mapobs(FileIO.load, files)

```

Then you can get individual images like this:

```julia
MLUtils.getobs(images, 1)

```

One more note: where you’re creating some test images, you’re creating arrays with size `(3, 10, 10)` like one would have in Python to represent a 2D image. In Julia however, images are usually represented as 2-dimensional arrays with an element type like `RGB` that includes a complete pixel value (e.g. 3 colors).

To convert such a 2D image to a 3D array with the color channels expanded, you can use `Images.channelview`:

```julia
using Images
imagetensors = MLUtils.mapobs(Images.channelview, images)
getobs(imagetensors, 1)

```
