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
end
using 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.AnnulusView
HCIToolbox.MultiAnnulusView
Base.copyto!
HCIToolbox.eachannulus
HCIToolbox.inverse
HCIToolbox.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 idx
th annulus as a matrix. This is equivalent to unrolling the frame and filtering out pixels outside of the idx
th 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
true
inverse(::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 idx
th 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)
true
expand many annuli-
julia> Xs = [-X for X in eachannulus(ann)];
julia> out = inverse(ann, Xs);
julia> out ≈ -ann
true
HCIToolbox.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
true
copyto!(::MultiAnnulusView, idx, mat)
copyto!(::MultiAnnulusView, mats...)
Copy the pixels from mat
into the pixels in the idx
th 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
true
update 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