Geometries
A common way of analyzing HCI data is to look at specific spatial extents, such as annuli. These geometries can be thought of as spatially filtering the input data.
For example, to create a geometry that is a concentric circle with radius r, we could filter a single frame like this
frame = ones(101, 101)
idxs = CartesianIndices(frame)
radius = 10
center = (51, 51)
# only include indices that are within circle
idxs_inside_circle = filter(idxs) do idx
translated = idx.I .- center
dist = sqrt(sum(abs2, translated))
return dist ≤ radius
endusing these filtered indices we can mask the data with something like
masked = zero(frame)
masked[idxs_inside_circle] = frames[idxs_inside_circle]more useful, though, is filtering the data. If we think of the frame as a sample of pixels unrolled into a vector, we can filter that vector and only use the pixels that are within the mask.
filtered = frame[idxs_inside_circle]This is very convenient for statistical algorithms wince we are filtering the data instead of just masking it, which greatly reduces the number of pixels. For example, the circle defined above only uses 4% of the data, so why waste time processing the rest?
Index
HCIToolbox.AnnulusViewHCIToolbox.MultiAnnulusViewBase.copyto!HCIToolbox.eachannulusHCIToolbox.inverseHCIToolbox.inverse!
API/Reference
HCIToolbox.AnnulusView — TypeAnnulusView(cube::AbstractArray{T,3};
inner=0, outer=first(size(parent))/2 + 0.5,
fill=0)Cut out an annulus with inner radius inner and outer radius outer. Values that fall outside of this region will be replaced with fill. This does not copy any data, it is merely a view into the data.
(::AnnulusView)(asview=false)Return the pixels that fall within the annulus as a matrix. This matrix is equivalent to unrolling each frame and then spatially filtering the pixels outside the annulus. If asview is true, the returned values will be a view of the parent array instead of a copy.
Examples
julia> ann = AnnulusView(ones(101, 101, 10); inner=5, outer=20);
julia> X = ann();
julia> size(X)
(1188, 10)HCIToolbox.MultiAnnulusView — TypeMultiAnnulusView(cube::AbstractArray{T,3} width, radii; fill=0)Create multiple annuli at each radius in radii with width width. Values that fall outside of these regions will be replaced with fill. This does not copy any data, it is merely a view into the data.
MultiAnnulusView(cube::AbstractArray{T,3}, width;
inner=0, outer=first(size(parent))/2 + 0.5,
fill=0)Create multiple annuli between inner and outer with width spacing. Values that fall outside of these regions will be replaced with fill. This does not copy any data, it is merely a view into the data.
(::MultiAnnulusView)(idx, asview=false)Return the idxth annulus as a matrix. This is equivalent to unrolling the frame and filtering out pixels outside of the idxth annulus. If asview is true, the returned values will be a view of the parent array instead of a copy.
Examples
julia> ann = MultiAnnulusView(ones(101, 101, 10), 5; inner=5, outer=30);
julia> X = ann(1);
julia> size(X)
(248, 10)
julia> X2 = ann(2);
julia> size(X2)
(404, 10)See also
HCIToolbox.eachannulus — Functioneachannulus(::MultiAnnulusView, asview=false)Create a generator for each annulus in the view. If asview is true, the annuli will be returned as a view into the parent array instead of a copy.
Examples
julia> ann = MultiAnnulusView(ones(101, 101, 10), 5; inner=5, outer=30);
julia> [size(X) for X in eachannulus(ann)]
5-element Vector{Tuple{Int64, Int64}}:
(248, 10)
(404, 10)
(560, 10)
(716, 10)
(880, 10)HCIToolbox.inverse — Functioninverse(::AnnulusView, mat::AbstractMatrix)Generate a cube similar to the view with the pixels from mat. mat should have the same size as the matrix output from AnnulusView
Examples
julia> ann = AnnulusView(ones(101, 101, 10); inner=5, outer=20);
julia> X = ann();
julia> out = inverse(ann, -X);
julia> out ≈ -ann
trueinverse(::MultiAnnulusView, idx, mat)
inverse(::MultiAnnulusView, mats...)Generate a cube similar to the view using the given pixel matrices. The pixels from mat will be put into the location of the idxth annulus. mat should have the same size as the output matrices generated by MultiAnnulusView. If multiple matrices are supplied, it is assumed each one corresponds to each annulus in the view.
Examples
Expand a single annulus-
julia> ann = MultiAnnulusView(ones(101, 101, 10), 5; inner=5, outer=30);
julia> X = ann(1);
julia> out = inverse(ann, 1, -X);
julia> sum(out) == -sum(X)
trueexpand many annuli-
julia> Xs = [-X for X in eachannulus(ann)];
julia> out = inverse(ann, Xs);
julia> out ≈ -ann
trueHCIToolbox.inverse! — Functioninverse!(::AnnulusView, out, mat)In-place version of inverse that fills out in-place.
inverse!(::MultiAnnulusView, out, idx, mat)
inverse!(::MultiAnnulusView, out, mats...)In-place version of inverse that fills out with annuli defined by the geometry of the view.
Base.copyto! — Functioncopyto!(::AnnulusView, mat::AbstractMatrix)Copy the pixels from mat into the pixels in the annulus. mat should have the same size as the matrix output from AnnulusView
Examples
julia> ann = AnnulusView(ones(101, 101, 10); inner=5, outer=20);
julia> X = ann();
julia> new_ann = copyto!(ann, -X);
julia> new_ann() ≈ -X
truecopyto!(::MultiAnnulusView, idx, mat)
copyto!(::MultiAnnulusView, mats...)Copy the pixels from mat into the pixels in the idxth annulus. mat should have the same size as the matrices generated by MultiAnnulusView. If multiple matrices are supplied, it is assumed each one corresponds to each annulus in the view.
Examples
Update a single annulus-
julia> ann = MultiAnnulusView(ones(101, 101, 10), 5; inner=5, outer=30);
julia> X = ann(1);
julia> new_ann = copyto!(ann, 1, -X);
julia> new_ann(1) ≈ -X
trueupdate each annulus-
julia> ann = MultiAnnulusView(ones(101, 101, 10), 5; inner=5, outer=30);
julia> Xs = [-X for X in eachannulus(ann)];
julia> new_ann = copyto!(copy(ann), Xs);
julia> new_ann ≈ -ann
true