Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed select_region and colleagues. #13

Merged
merged 4 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions src/selection_tools.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ end


"""
select_region_view(src; new_size=size(src), center=ft_center_diff(size(src)).+1, pad_value=zero(eltype(src)))
select_region_view(src; new_size=size(src), center=ft_center_diff(size(src)).+1, dst_center=ft_center_diff(new_size), pad_value=zero(eltype(src)))

selects (extracts) a region of interest (ROI), defined by `new_size` and centered at `center` in the source image. Note that
the number of dimensions can be smaller in `new_size` and `center`, in which case the default values will be insterted
Expand All @@ -135,6 +135,7 @@ Arguments:
+ `src`. The source array to select from.
+ `new_size`. The size of the array view after the operation finished. By default the original size is assumed
+ `center`. Specifies the center of the new view in coordinates of the old view. By default an alignment of the Fourier-centers is assumed.
+ `dst_center`. Specifies the destination center of the new view to be mapped to the source center as given by `center`.
+ `pad_value`. Specifies the value which is inserted in case the ROI extends to outside the source area.

The returned results is a mutable view, which allows this method to also be used for writing into a ROI
Expand All @@ -156,11 +157,10 @@ julia> select_region_view(ones(3,3),new_size=(7,7),center=(1,3))
0.0 0.0 0.0 0.0 0.0 0.0 0.0
```
"""
function select_region_view(src::Array{T,N}; new_size=size(src), center=ft_center_diff(size(src)).+1, pad_value=zero(eltype(src))) where {T,N}
function select_region_view(src::Array{T,N}; new_size=size(src), center=ft_center_diff(size(src)).+1, dst_center=ft_center_diff(new_size).+1, pad_value=zero(eltype(src))) where {T,N}
new_size = Tuple(expand_size(new_size, size(src)))
center = Tuple(expand_size(center, ft_center_diff(size(src)).+1))
oldcenter = ft_center_diff(new_size).+1
MutablePaddedView(PaddedView(pad_value, src,new_size, oldcenter .- center.+1)) :: MutablePaddedView{T, N, NTuple{N,Base.OneTo{Int64}}, OffsetArrays.OffsetArray{T, N, Array{T, N}}}
MutablePaddedView(PaddedView(pad_value, src,new_size, dst_center .- center.+1)) :: MutablePaddedView{T, N, NTuple{N,Base.OneTo{Int64}}, OffsetArrays.OffsetArray{T, N, Array{T, N}}}
end

"""
Expand All @@ -171,8 +171,10 @@ integer center position of the destination aligning with the position in the sou
"""
function get_src_dst_range(src_size, dst_size, new_size, src_center, dst_ctr=dst_size .÷2 .+1)
ROI_center = (new_size.÷2 .+1)
src_start = src_center .- ROI_center .+1 # start of the first pixel to copy (without clipping)
src_end = src_start .+ new_size .- 1 # the last pixel to copy
# start of the first pixel to copy (without clipping):
src_start = src_center .- ROI_center .+1
# the last pixel to copy:
src_end = src_start .+ new_size .- 1
src_start_clip = max.(1, src_start)
src_end_clip = min.(src_end, src_size)
if any(src_start_clip .> src_size) || any(src_end_clip .< 1)
Expand All @@ -187,7 +189,8 @@ function get_src_dst_range(src_size, dst_size, new_size, src_center, dst_ctr=dst
dst_end_clip = min.(dst_end, dst_size)
dst_start_clip = max.(1, dst_start)
if any(dst_start_clip .> dst_size) || any(dst_end_clip .< 1)
return (1:0), (1:0) # returns an empty range for all coordinates
# returns an empty range for all coordinates
return (1:0), (1:0)
end

extra_dst_start = max.(0, dst_start_clip .- dst_start)
Expand Down Expand Up @@ -252,7 +255,10 @@ end


"""
select_region!(src, dst=nothing; new_size=size(src), center=size(src).÷2 .+1, dst_center=nothing, pad_value=zero(eltype(mat), operator!=assign_to!))
select_region!(src, dst=nothing;
new_size=ntuple((d)->typemax(Int)÷2,Val(length(size(src)))),
center=size(src).÷2 .+1, dst_center=nothing,
pad_value=zero(eltype(mat), operator!=assign_to!))

selects (extracts, pads, shifts) a region of interest (ROI), defined by `new_size` and centered with the destination center aligned at
the position `center` in the source image. Note that the number of dimensions in `new_size`, `center` and `dst_center` can be smaller ,
Expand All @@ -266,7 +272,8 @@ If `nothing` is provided for `dst`, a new array of size `new_size` is created.
Arguments:
+ `src`. The source array to select from.
+ `dst`. The destination array to write into, if provided. By default `dst=nothing` a new array is created. The `dst`array (or new array) is returned.
+ `new_size`. The size of the array view after the operation finished. By default the original size is assumed
+ `new_size`. The size of the array view after the operation finished. By default a maximally large destination size is chosen, which means that any overlap is copied.
If you specify `new_size`, be aware that the `center` and `dst_center` specifications below really have to refer to centers to be copied!
+ `center`. Specifies the center of the new view in coordinates of the old view. By default an alignment of the Fourier-center (right center) is assumed.
+ `dst_center`. defines the center coordinate in the destination array which should align with the above source center. If nothing is provided, the right center pixel of the `dst` array or new array is used.
+ `pad_value`. specifies the value which is inserted in case the ROI extends to outside the source area. This is only used, if no `dst` array is provided.
Expand Down Expand Up @@ -311,9 +318,9 @@ julia> dst=select_region(a,new_size=(10,10), dst_center=(1,1)) # pad a with zero
0.0 0.0 0.0 0.0 0.0 0.0 2.0 2.0 2.0 2.0
```
"""
function select_region!(src, dst; new_size=size(dst),
function select_region!(src, dst; new_size=ntuple((d)->typemax(Int)÷2,Val(length(size(src)))),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why typemax?
You can also use nothing to handle that.
Also instead of using length(size(src)) better do src::AbstractArray{T, N} and use the parametric type N.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to avoid branches in the code. First had a "nothing" version but this would anyway then branch to the same expression.
typemax is needed as the index-calculation which is used explicitely considers a finite copy-size. If the user specifies center=-100, dst_center=-100 it should still work. For copy operations such as in select_region!() the code still insists on the centers, if the new_size is specifies, but it should allow for maximal src and dst overlap, in case the user does not specify new_size.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... the use of length was fixed now.

center=size(src).÷2 .+1, dst_center=size(dst).÷ 2 .+1, operator! =assign_to!)
new_size = Tuple(expand_size(new_size, size(dst)))
new_size = Tuple(expand_size(new_size, size(dst)))
center = Tuple(expand_size(center, size(src).÷2 .+1))
dst_center = Tuple(expand_size(dst_center, size(dst).÷ 2 .+1))

Expand Down Expand Up @@ -412,7 +419,9 @@ function select_region(src::AbstractArray{T,N}; M=nothing,
fill!(arr_n, pad_value)
end
end
select_region!(src,dst;new_size=new_size, center=center, dst_center=dst_center)
# new_size is intentionally not specified which forces the method to adapt for maximal overlay
# of source and destination.
select_region!(src, dst; center=center, dst_center=dst_center)
return dst
end

2 changes: 2 additions & 0 deletions test/selection_tools.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@
@test all(select_region(a, new_size=nz, center=(-100,100), pad_value=10) .== 10) # only pad values
function f(a,b) a.+=1 end # user-defined function
@test all(select_region!(2 .*a, a, operator! = f) .== 2) # let the operator add one to destination
@test select_region(collect(1:10), new_size=(5,), center=(1,), dst_center=(1,)) == collect(1:5)
@test select_region_view(collect(1:10), new_size=(5,), center=(1,), dst_center=(1,)) == collect(1:5)
end

@testset "Test Magnificiation" begin
Expand Down