diff --git a/docs/src/buffering.md b/docs/src/buffering.md index 4b97ff3..eb3a8fc 100644 --- a/docs/src/buffering.md +++ b/docs/src/buffering.md @@ -9,15 +9,20 @@ apply!(buffer, tfm, item) However, for some transformations, a different buffer is needed. [`Sequence`](@ref), for example, needs to reuse all intermediate results. That is why the buffer creation can be customized: -- [`makebuffer`](@ref)`(tfm, item)` creates a buffer `buf` that can be used in an `apply!` call: `apply!(buf, tfm, item)`. +- [`DataAugmentation.makebuffer`](@ref)`(tfm, item)` creates a buffer `buf` that can be used in an `apply!` call: `apply!(buf, tfm, item)`. --- -Managing the buffers manually quickly becomes tedious. For convenience, this library implements [`Buffered`](@ref), a transformation wrapper that will use a buffer internally. `btfm = Buffered(tfm)` will create a buffer the first time it is `apply`ed and then use it by internally calling `apply!`. +Managing the buffers manually quickly becomes tedious. For convenience, this library implements [`DataAugmentation.Buffered`](@ref), a transformation wrapper that will use a buffer internally. `btfm = Buffered(tfm)` will create a buffer the first time it is `apply`ed and then use it by internally calling `apply!`. ```julia buffered = Buffered(tfm) buffer = apply(tfm, item) # uses apply! internally ``` -Since `Buffered` only stores one buffer, you may run into problems when using it in a multi-threading context where different threads invalidate the buffer before it can be used. In that case, you can use [`BufferedThreadsafe`](@ref), a version of `Buffered` that keeps a separate buffer for every thread. \ No newline at end of file +Since `Buffered` only stores one buffer, you may run into problems when using it in a multi-threading context where different threads invalidate the buffer before it can be used. In that case, you can use [`DataAugmentation.BufferedThreadsafe`](@ref), a version of `Buffered` that keeps a separate buffer for every thread. + +```@docs +DataAugmentation.Buffered +DataAugmentation.BufferedThreadsafe +``` diff --git a/docs/src/index.md b/docs/src/index.md index 4f7ee44..3d855f9 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -21,7 +21,7 @@ The above example is simple, but there are more requirements of data augmentatio A transformation is stochastic (as opposed to deterministic) if it produces different outputs based on some random state. This randomness can become a problem when applying an transformation to an aligned pair of input and target. If we have an image and a corresponding segmentation mask, using different scaling factors results in misalignment of the two; the segmentation no longer matches up with the image pixels. -To handle this, the random state is explicitly passed to the transformations, rendering them deterministic. A generator for the random state can be defined with [`getrandstate`](@ref)`(tfm)` and passed to `apply` with the `randstate` keyword argument. +To handle this, the random state is explicitly passed to the transformations, rendering them deterministic. A generator for the random state can be defined with [`DataAugmentation.getrandstate`](@ref)`(tfm)` and passed to `apply` with the `randstate` keyword argument. ### Composition diff --git a/docs/src/iteminterface.md b/docs/src/iteminterface.md index cae9027..da809b7 100644 --- a/docs/src/iteminterface.md +++ b/docs/src/iteminterface.md @@ -20,8 +20,8 @@ struct MyItem <: Item end ``` -The only function that is expected to be implemented is [`itemdata`](@ref), which simply returns the wrapped data. If, as above, you simply call the field holding the data `data`, you do not need to implement it. The same goes for the [`setdata`](@ref) helper. +The only function that is expected to be implemented is [`itemdata`](@ref), which simply returns the wrapped data. If, as above, you simply call the field holding the data `data`, you do not need to implement it. The same goes for the [`DataAugmentation.setdata`](@ref) helper. For some items, it also makes sense to implement the following: -- [`showitem!`](@ref)`(img, item::I)` creates a visual representation of an item on top of `img`. \ No newline at end of file +- [`DataAugmentation.showitem!`](@ref)`(img, item::I)` creates a visual representation of an item on top of `img`. diff --git a/docs/src/preprocessing.md b/docs/src/preprocessing.md index 7456584..406f6bf 100644 --- a/docs/src/preprocessing.md +++ b/docs/src/preprocessing.md @@ -2,7 +2,7 @@ This library also implements some general transformations useful for getting data ready to be put into a model. -- [`ToEltype`](@ref)`(T)` converts the element type of any [`AbstractArrayItem`](@ref) to `T`. +- [`ToEltype`](@ref)`(T)` converts the element type of any [`DataAugmentation.AbstractArrayItem`](@ref) to `T`. - [`ImageToTensor`](@ref) converts an image to an `ArrayItem` with another dimension for the color channels - [`Normalize`](@ref) normalizes image tensors - [`OneHot`](@ref) to one-hot encode multi-class masks ([`MaskMulti`](@ref)s) diff --git a/docs/src/projective/intro.md b/docs/src/projective/intro.md index 6d29a27..f96e4e0 100644 --- a/docs/src/projective/intro.md +++ b/docs/src/projective/intro.md @@ -30,8 +30,8 @@ By default, the bounds of a projected item will be chosen so they still encase a ## Projective transformations interface -The abstract type [`ProjectiveTransform`](@ref) represents a projective transformation. -A `ProjectiveTransform` needs to implement [`getprojection`](@ref)`(tfm, bounds; randstate)` that should return a `Transformation` from [CoordinateTransformations.jl](https://github.com/JuliaGeometry/CoordinateTransformations.jl). +The abstract type [`DataAugmentation.ProjectiveTransform`](@ref) represents a projective transformation. +A `ProjectiveTransform` needs to implement [`DataAugmentation.getprojection`](@ref)`(tfm, bounds; randstate)` that should return a `Transformation` from [CoordinateTransformations.jl](https://github.com/JuliaGeometry/CoordinateTransformations.jl). To add support for projective transformations to an item `I`, you need to implement diff --git a/docs/src/ref.md b/docs/src/ref.md index f9c4a21..d2911a7 100644 --- a/docs/src/ref.md +++ b/docs/src/ref.md @@ -12,4 +12,47 @@ Crop Rotate itemdata showitems + +DataAugmentation.AbstractArrayItem +DataAugmentation.AbstractItem +DataAugmentation.ArrayItem +DataAugmentation.Categorify +DataAugmentation.ComposedProjectiveTransform +DataAugmentation.FillMissing +DataAugmentation.Identity +DataAugmentation.Item +DataAugmentation.ItemWrapper +DataAugmentation.MapElem +DataAugmentation.Normalize +DataAugmentation.NormalizeRow +DataAugmentation.OneHot +DataAugmentation.PinOrigin +DataAugmentation.ProjectiveTransform +DataAugmentation.ResizePadDivisible +DataAugmentation.ScaleFixed +DataAugmentation.Sequence +DataAugmentation.ToEltype +DataAugmentation.Transform +DataAugmentation.Zoom +DataAugmentation.apply +DataAugmentation.apply! +DataAugmentation.boundsof +DataAugmentation.centered +DataAugmentation.compose +DataAugmentation.getbounds +DataAugmentation.getprojection +DataAugmentation.getrandstate +DataAugmentation.makebuffer +DataAugmentation.offsetcropbounds +DataAugmentation.project +DataAugmentation.project! +DataAugmentation.projectionbounds +DataAugmentation.setdata +DataAugmentation.showitem! +DataAugmentation.testapply +DataAugmentation.testapply! +DataAugmentation.testitem +DataAugmentation.testprojective +DataAugmentation.threepointwarpaffine +DataAugmentation.transformbounds ``` diff --git a/docs/src/tfminterface.md b/docs/src/tfminterface.md index 0a8dfc8..c787be4 100644 --- a/docs/src/tfminterface.md +++ b/docs/src/tfminterface.md @@ -17,7 +17,7 @@ A transformation is a type that subtypes [`Transform`](@ref). The only *required You may additionally also implement: -- [`getrandstate`](@ref)`(tfm)` for *stochastic* transformations +- [`DataAugmentation.getrandstate`](@ref)`(tfm)` for *stochastic* transformations Generates random state to be used inside `apply`. Calling `apply(tfm, item)` is equivalent to `apply(tfm, item; randstate = getrandstate(tfm))`. It defaults to `nothing`, so we need not implement it for deterministic transformations. @@ -27,7 +27,7 @@ You may additionally also implement: Buffered version of `apply` that mutates `bufitem`. If not implemented, falls back to regular `apply`. -- [`compose`](@ref)`(tfm1, tfm2)` for custom *composition* with other transformations +- [`DataAugmentation.compose`](@ref)`(tfm1, tfm2)` for custom *composition* with other transformations Composes transformations. By default, returns a [`Sequence`](@ref) transformation that applies the transformations one after the other. @@ -43,7 +43,7 @@ struct MapElem <: Transform end ``` -The `apply` implementation dispatches on [`AbstractArrayItem`](@ref), an abstract item type for items that wrap arrays. Note that the `randstate` keyword argument needs to be given even for implementations of deterministic transformations. We also make use of the [`setdata`](@ref) helper to update the item data. +The `apply` implementation dispatches on [`DataAugmentation.AbstractArrayItem`](@ref), an abstract item type for items that wrap arrays. Note that the `randstate` keyword argument needs to be given even for implementations of deterministic transformations. We also make use of the [`DataAugmentation.setdata`](@ref) helper to update the item data. ```julia function apply(tfm::MapElem, item::AbstractArrayItem; randstate = nothing) diff --git a/docs/src/transformations.md b/docs/src/transformations.md index be60330..449776d 100644 --- a/docs/src/transformations.md +++ b/docs/src/transformations.md @@ -71,3 +71,7 @@ tfm = Maybe(FlipX()) titems = [apply(tfm, item) for _ in 1:8] showgrid(titems; ncol = 4, npad = 16) ``` + +```@docs +DataAugmentation.ImageToTensor +``` diff --git a/src/base.jl b/src/base.jl index 5961ee8..7762240 100644 --- a/src/base.jl +++ b/src/base.jl @@ -110,10 +110,11 @@ compose(::Identity, ::Identity) = Identity() compose(tfm::Transform, ::Identity) = tfm compose(::Identity, tfm::Transform) = tfm -# Lastly, [`setdata`](@ref) provides a convenient way to create a copy -# of an item, replacing only the wrapped data. This relies on the -# wrapped data field being named `data`, though. - +""" +Provides a convenient way to create a copy +of an item, replacing only the wrapped data. This relies on the +wrapped data field being named `data`, though. +""" function setdata(item::Item, data) item = Setfield.@set item.data = data return item diff --git a/src/buffered.jl b/src/buffered.jl index a9b1fdd..3f2f023 100644 --- a/src/buffered.jl +++ b/src/buffered.jl @@ -41,6 +41,9 @@ end # ## Buffered transforms +""" +Buffer to store transform results +""" mutable struct Buffered{T<:Transform} <: Transform tfm::T buffers::Dict @@ -73,6 +76,9 @@ function apply!(buf, buffered::Buffered, items::T; randstate = getrandstate(buff end +""" +Buffer to store transform results (threadsafe) +""" struct BufferedThreadsafe <: Transform buffereds::Vector{Buffered} function BufferedThreadsafe(tfm; n = Threads.nthreads()) diff --git a/src/projective/affine.jl b/src/projective/affine.jl index 861116b..3205d41 100644 --- a/src/projective/affine.jl +++ b/src/projective/affine.jl @@ -108,6 +108,9 @@ end Zoom(scales::NTuple{2, T} = (1., 1.2)) where T = Zoom(Uniform(scales[1], scales[2])) +""" +Return random state of the transform +""" getrandstate(tfm::Zoom) = rand(tfm.dist) function getprojection(tfm::Zoom, bounds::Bounds{N}; randstate = getrandstate(tfm)) where N diff --git a/src/projective/base.jl b/src/projective/base.jl index dc54fe1..43415a7 100644 --- a/src/projective/base.jl +++ b/src/projective/base.jl @@ -2,7 +2,6 @@ abstract type ProjectiveTransform <: Transform Abstract supertype for projective transformations. See -[Projective transformations](../docs/projective/interface.md). """ abstract type ProjectiveTransform <: Transform end diff --git a/src/projective/warp.jl b/src/projective/warp.jl index 01731e7..a954f76 100644 --- a/src/projective/warp.jl +++ b/src/projective/warp.jl @@ -32,7 +32,7 @@ end """ threepointwarpaffine(srcps, dstps) -Calculate an affine [`CoordinateTransformations.LinearMap`](@ref) +Calculate an affine `CoordinateTransformations.LinearMap` from 3 source points to 3 destination points. Adapted from [CoordinateTransformations.jl#30](https://github.com/JuliaGeometry/CoordinateTransformations.jl/issues/30#issuecomment-610337378).