Skip to content

Commit

Permalink
Merge pull request #13 from bionanoimaging/fix_select_region
Browse files Browse the repository at this point in the history
fixed select_region and colleagues.
  • Loading branch information
RainerHeintzmann authored Dec 21, 2023
2 parents 980f967 + 4fbe45e commit 041d090
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 13 deletions.
38 changes: 25 additions & 13 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_size2 .+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::AbstractArray{T, N}, dst=nothing;
center=size(src).÷2 .+1, dst_center=nothing,
new_size=2 .*(1 .+ abs.(dst_center.-(size(src).÷ 2 .+ 1))) .+ size(src),
pad_value=zero(eltype(mat), operator!=assign_to!)) where {T,N}
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,9 @@ 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!
If `new_size` is not specified, a size to fully encompass the (potentially displaced) source array is automatically chosen.
+ `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 +319,11 @@ 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),
center=size(src)2 .+1, dst_center=size(dst) 2 .+1, operator! =assign_to!)
new_size = Tuple(expand_size(new_size, size(dst)))
function select_region!(src::AbstractArray{T, N}, dst;
center=size(src)2 .+1, dst_center=size(dst) 2 .+1,
new_size=2 .*(1 .+ abs.(dst_center.-(size(src) 2 .+ 1))) .+ size(src),
operator! =assign_to!) where {T,N}
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 +422,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

10 changes: 10 additions & 0 deletions test/selection_tools.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@
@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)
a = ones(10,10)
select_region!(2 .*a, a, dst_center=(10,10));
@test all(a[5:end,5:end] .== 2) # check the overwritten part
@test all(a[1:4,1:4] .== 1) # check part of the non-overwritten part
a = ones(10,10)
b = 4*ones(70,70)
select_region!(b, a, dst_center=(-20,20));
@test all(a .== 4) # check the automatic selection of a large enough new_size
end

@testset "Test Magnificiation" begin
Expand Down

0 comments on commit 041d090

Please sign in to comment.