-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #500 from WilhelmusLab/493-get_new23-final
feat: regularize/final
- Loading branch information
Showing
12 changed files
with
16,424 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
using IceFloeTracker: unsharp_mask, to_uint8, hbreak, morph_fill | ||
|
||
# TODO: Add tests for regularize_fill_holes, regularize_sharpening, get_final | ||
|
||
""" | ||
regularize_fill_holes(img, local_maxima_mask, factor, segment_mask, L0mask) | ||
Regularize `img` by: | ||
1. increasing the maxima of `img` by a factor of `factor` | ||
2. filtering `img` at positions where either `segment_mask` or `L0mask` are true | ||
3. filling holes | ||
# Arguments | ||
- `img`: The morphological residue image. | ||
- `local_maxima_mask`: The local maxima mask. | ||
- `factor`: The factor to apply to the local maxima mask. | ||
- `segment_mask`: The segment mask -- intersection of bw1 and bw2 in first tiled workflow of `master.m`. | ||
- `L0mask`: zero-labeled pixels from watershed. | ||
""" | ||
function regularize_fill_holes(img, local_maxima_mask, segment_mask, L0mask, factor) | ||
new2 = to_uint8(img .+ local_maxima_mask .* factor) | ||
new2[segment_mask .|| L0mask] .= 0 | ||
return IceFloeTracker.MorphSE.fill_holes(new2) | ||
end | ||
|
||
""" | ||
regularize_sharpening(img, L0mask, radius, amount, local_maxima_mask, factor, segment_mask, se) | ||
Regularize `img` via sharpening, filtering, reconstruction, and maxima elevating. | ||
# Arguments | ||
- `img`: The input image. | ||
- `L0mask`: zero-labeled pixels from watershed. | ||
- `radius`: The radius of the unsharp mask. | ||
- `amount`: The amount of unsharp mask. | ||
- `local_maxima_mask`: The local maxima mask. | ||
- `factor`: The factor to apply to the local maxima mask. | ||
- `segment_mask`: The segment mask -- intersection of bw1 and bw2 in first tiled workflow of `master.m`. | ||
""" | ||
function regularize_sharpening( | ||
img, L0mask, local_maxima_mask, segment_mask, se, radius, amount, factor | ||
) | ||
new3 = unsharp_mask(img, radius, amount, 255) | ||
new3[L0mask] .= 0 | ||
new3 = IceFloeTracker.reconstruct(new3, se, "dilation", false) | ||
new3[segment_mask] .= 0 | ||
return to_uint8(new3 + local_maxima_mask .* factor) | ||
end | ||
|
||
function _regularize( | ||
morph_residue, local_maxima_mask, segment_mask, L0mask, se; factor, radius, amount | ||
) | ||
reg_fill_holes = regularize_fill_holes( | ||
morph_residue, local_maxima_mask, segment_mask, L0mask, factor[1] | ||
) | ||
reg_sharpened = regularize_sharpening( | ||
reg_fill_holes, | ||
L0mask, | ||
local_maxima_mask, | ||
segment_mask, | ||
se, | ||
radius, | ||
amount, | ||
factor[end], | ||
) | ||
return reg_sharpened | ||
end | ||
|
||
""" | ||
get_final(img, label, segment_mask, se_erosion, se_dilation) | ||
Final processing following the tiling workflow. | ||
# Arguments | ||
- `img`: The input image. | ||
- `label`: Mode of most common label in the find_ice_labels workflow. | ||
- `segment_mask`: The segment mask. | ||
- `se_erosion`: structuring element for erosion. | ||
- `se_dilation`: structuring element for dilation. | ||
- `apply_segment_mask=true`: Whether to filter `img` the segment mask. | ||
""" | ||
function get_final( | ||
# this function is used in preprocessing_tiling | ||
img, | ||
segment_mask, | ||
se_erosion, | ||
se_dilation, | ||
apply_segment_mask::Bool=true, | ||
) | ||
_img = hbreak(img) | ||
|
||
# slow for big images | ||
_img .= morph_fill(_img) | ||
|
||
# TODO: decide on criteria for applying segment mask | ||
apply_segment_mask && (_img[segment_mask] .= false) | ||
|
||
# tends to fill more than matlabs imfill | ||
_img .= IceFloeTracker.MorphSE.fill_holes(_img) | ||
|
||
# marker image | ||
_img .= branch(_img) | ||
|
||
#= opening to remove noise while preserving shape/size | ||
Note the different structuring elements for erosion and dilation =# | ||
mask = sk_morphology.erosion(_img, se_erosion) | ||
mask .= sk_morphology.dilation(mask, se_dilation) | ||
|
||
# Restore shape of floes based on the cleaned up `mask` | ||
final = IceFloeTracker.MorphSE.mreconstruct(IceFloeTracker.MorphSE.dilate, _img, mask) | ||
return final | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using IceFloeTracker: | ||
get_tiles, | ||
regularize_fill_holes, | ||
regularize_sharpening, | ||
_regularize, | ||
se_disk2, | ||
get_final | ||
using DelimitedFiles: readdlm | ||
|
||
se = collect(IceFloeTracker.MorphSE.strel_diamond((3, 3))) | ||
|
||
test_files_dir = joinpath(@__DIR__, "test_inputs/regularize") | ||
|
||
morph_residue = readdlm(joinpath(test_files_dir, "morph_residue.csv"), ',', Int) | ||
local_maxima_mask = readdlm(joinpath(test_files_dir, "local_maxima_mask.csv"), ',', Int) | ||
segment_mask = readdlm(joinpath(test_files_dir, "segment_mask.csv"), ',', Bool) | ||
L0mask = readdlm(joinpath(test_files_dir, "L0mask.csv"), ',', Bool) | ||
expected_regularized_holes_filled = readdlm( | ||
joinpath(test_files_dir, "reg_holes_filled_expected.csv"), ',', Int | ||
) | ||
expected_regularized_sharpened = readdlm( | ||
joinpath(test_files_dir, "reg_sharpened.csv"), ',', Int | ||
) | ||
|
||
get_final_input = readdlm(joinpath(test_files_dir, "get_final.csv"), ',', Bool) | ||
se_erosion = se | ||
se_dilation = se_disk2() | ||
get_final_expected = readdlm(joinpath(test_files_dir, "get_final_expected.csv"), ',', Bool) | ||
|
||
@testset "regularize/get_final" begin | ||
@testset "regularize_fill_holes/sharpening" begin | ||
reg_holes_filled = regularize_fill_holes( | ||
morph_residue, local_maxima_mask, segment_mask, L0mask, 0.3 | ||
) | ||
|
||
reg_sharpened = regularize_sharpening( | ||
reg_holes_filled, L0mask, local_maxima_mask, segment_mask, se, 10, 2, 0.5 | ||
) | ||
|
||
reg = _regularize( | ||
morph_residue, | ||
local_maxima_mask, | ||
segment_mask, | ||
L0mask, | ||
se; | ||
factor=(0.3, 0.5), | ||
radius=10, | ||
amount=2, | ||
) | ||
|
||
@test expected_regularized_holes_filled == reg_holes_filled | ||
@test expected_regularized_sharpened == reg_sharpened | ||
@test expected_regularized_sharpened == reg | ||
end | ||
|
||
@testset "get_final" begin | ||
get_final_output = get_final( | ||
get_final_input, segment_mask, se_erosion, se_dilation, true | ||
) | ||
|
||
@test get_final_output == get_final_expected | ||
end | ||
end |
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
2,030 changes: 2,030 additions & 0 deletions
2,030
test/test_inputs/regularize/get_final_expected.csv
Large diffs are not rendered by default.
Oops, something went wrong.
Oops, something went wrong.