IceFloeTracker

Documentation for IceFloeTracker.jl package.

Functions

Base.isequalMethod
isequal(matchedpairs1::MatchedPairs, matchedpairs2::MatchedPairs)

Return true if matchedpairs1 and matchedpairs2 are equal, false otherwise.

source
IceFloeTracker._adjust_histogramMethod
_adjust_histogram(masked_view, nbins, rblocks, cblocks, clip)

Perform adaptive histogram equalization to a masked image. To be invoked within imsharpen.

Arguments

  • masked_view: input image in truecolor

See imsharpen for a description of the remaining arguments

source
IceFloeTracker._bin9todecMethod
_bin9todec(v)

Get decimal representation of a bit vector v with the leading bit at its leftmost posistion.

Example

julia> _bin9todec([0 0 0 0 0 0 0 0 0])    
0

julia> _bin9todec([1 1 1 1 1 1 1 1 1])    
511
source
IceFloeTracker._branch_filterFunction
_branch_filter(
img::AbstractArray{Bool},
func1::Function=branch_candidates_func,
func2::Function=connected_background_count,)

Filter img with _operator_lut using lut1 and lut2.

source
IceFloeTracker._operator_lutMethod
_operator_lut(I, img, nhood, lut1, lut2)

Look up the neighborhood nhood in lookup tables lut1 and lut2.

Handles cases when the center of nhood is on the edge of img using data in I.

source
IceFloeTracker.add_paddingMethod
add_padding(img, style)

Extrapolate the image img according to the style specifications type. Returns the extrapolated image.

Arguments

  • img: Image to be padded.
  • style: A supported type (such as Pad or Fill) representing the extrapolation style. See the relevant documentation for details.

See also remove_padding

source
IceFloeTracker.add_passtimes!Method
add_passtimes!(props, passtimes)

Add a column passtime to each DataFrame in props containing the time of the image in which the floes were captured.

Arguments

  • props: array of DataFrames containing floe properties.
  • passtimes: array of DateTime objects containing the time of the image in which the floes were captured.
source
IceFloeTracker.addfloemasks!Method
addfloearrays(props::DataFrame, floeimg::BitMatrix)

Add a column to props called floearray containing the cropped floe masks from floeimg.

source
IceFloeTracker.addlatlon!Method
addlatlon(pairedfloesdf::DataFrame, refimage::AbstractString)

Add columns latitude, longitude, and pixel coordinates x, y to pairedfloesdf.

Arguments

  • pairedfloesdf: dataframe containing floe tracking data.
  • refimage: path to reference image.
source
IceFloeTracker.appendrows!Method
appendrows!(df::MatchingProps, props::T, ratios, idx::Int64, dist::Float64) where {T<:DataFrameRow}

Append a row to df.props and df.ratios with the values of props and ratios respectively.

source
IceFloeTracker.apply_cloudmaskMethod
apply_cloudmask(ref_image, cloudmask)

Zero out pixels containing clouds where clouds and ice are not discernable. Arguments should be of the same size.

Arguments

  • ref_image: reference image, e.g. corrected reflectance false color image bands [7,2,1] or grayscale
  • cloudmask: binary cloudmask with clouds = 0, else = 1
source
IceFloeTracker.apply_landmaskMethod
apply_landmask(input_image, landmask_binary)

Zero out pixels in land and soft ice regions on truecolor image, return RGB image with zero for all three channels on land/soft ice.

Arguments

  • input_image: truecolor RGB image
  • landmask_binary: binary landmask with 1=land, 0=water/ice
source
IceFloeTracker.binarize_landmaskMethod
binarize_landmask(landmask_image)

Convert a 3-channel RGB land mask image to a 1-channel binary matrix; land = 0, water/ice = 1.

Arguments

  • landmask_image: RGB land mask image from fetchdata
source
IceFloeTracker.branchMethod
branch(img::AbstractArray{Bool})

Find branch points in skeletonized image img according to Definition 3 of [1].

[1] Arcelli, Carlo, and Gabriella Sanniti di Baja. "Skeletons of planar patterns." Machine Intelligence and Pattern Recognition. Vol. 19. North-Holland, 1996. 99-143.

source
IceFloeTracker.bridgeMethod
bridge(bw)

Set 0-valued pixels to 1 if they have two nonzero neighbors that are not connected. Note the following exceptions:

0 0 0 0 0 0 1 0 1 becomes 1 1 1 0 0 0 0 0 0

1 0 1 1 1 1 0 0 0 becomes 0 0 0 0 0 0 0 0 0

The same applies to all their corresponding rotations.

Examples

julia> bw = [0 0 0; 0 0 0; 1 0 1]
3×3 Matrix{Int64}:
 0  0  0
 0  0  0
 1  0  1

julia> bridge(bw)
3×3 BitMatrix:
 0  0  0
 0  0  0
 1  1  1

julia> bw = [1 0 0; 1 0 1; 0 0 1]
3×3 Matrix{Int64}:
 1  0  0
 1  0  1
 0  0  1

julia> bridge(bw)
3×3 BitMatrix:
 1  1  0
 1  1  1
 0  1  1

 julia> bw = [1 0 1; 0 0 0; 1 0 1]
3×3 Matrix{Int64}:
 1  0  1
 0  0  0
 1  0  1

julia> bridge(bw)
3×3 BitMatrix:
 1  1  1
 1  1  1
 1  1  1
source
IceFloeTracker.bwareamaxfiltFunction
bwareamaxfilt(bwimg::AbstractArray{Bool}, conn)

Filter the smaller (by area) connected components in bwimg keeping the (assumed unique) largest.

Uses 8-pixel connectivity by default (conn=8). Use conn=4 for 4-pixel connectivity.

source
IceFloeTracker.bwperimMethod
bwperim(bwimg)

Locate the pixels at the boundary of objects in an binary image bwimg using 8-pixel connectivity.

Arguments

  • bwimg: Binary (black/white – 1/0) image

Examples

julia> A = zeros(Bool, 13, 16); A[2:6, 2:6] .= 1; A[4:8, 7:10] .= 1; A[10:12,13:15] .= 1; A[10:12,3:6] .= 1;

julia> A
13×16 Matrix{Bool}:
 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 0  1  1  1  1  1  0  0  0  0  0  0  0  0  0  0
 0  1  1  1  1  1  0  0  0  0  0  0  0  0  0  0
 0  1  1  1  1  1  1  1  1  1  0  0  0  0  0  0
 0  1  1  1  1  1  1  1  1  1  0  0  0  0  0  0
 0  1  1  1  1  1  1  1  1  1  0  0  0  0  0  0
 0  0  0  0  0  0  1  1  1  1  0  0  0  0  0  0
 0  0  0  0  0  0  1  1  1  1  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 0  0  1  1  1  1  0  0  0  0  0  0  1  1  1  0
 0  0  1  1  1  1  0  0  0  0  0  0  1  1  1  0
 0  0  1  1  1  1  0  0  0  0  0  0  1  1  1  0
 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

 julia> bwperim(A)
13×16 Matrix{Bool}:
 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 0  1  1  1  1  1  0  0  0  0  0  0  0  0  0  0
 0  1  0  0  0  1  0  0  0  0  0  0  0  0  0  0
 0  1  0  0  0  0  1  1  1  1  0  0  0  0  0  0
 0  1  0  0  0  0  0  0  0  1  0  0  0  0  0  0
 0  1  1  1  1  1  0  0  0  1  0  0  0  0  0  0
 0  0  0  0  0  0  1  0  0  1  0  0  0  0  0  0
 0  0  0  0  0  0  1  1  1  1  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 0  0  1  1  1  1  0  0  0  0  0  0  1  1  1  0
 0  0  1  0  0  1  0  0  0  0  0  0  1  0  1  0
 0  0  1  1  1  1  0  0  0  0  0  0  1  1  1  0
 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
source
IceFloeTracker.bwtraceboundaryMethod
bwtraceboundary(image::Union{Matrix{Int64},Matrix{Float64},T};
                P0::Union{Tuple{Int,Int},CartesianIndex{2},Nothing}=nothing,
                closed::Bool=true) where T<:AbstractMatrix{Bool}

Trace the boundary of objects in image

Background pixels are represented as zero. The algorithm traces the boundary counterclockwise and an initial point P0 can be specified. If more than one boundary is detected and an initial point is provided, the boundary that contains this point is returned as a vector of CartesianIndex types. Otherwise an array of vectors is returned with all the detected boundaries in image.

Arguments

  • image: image, preferably binary with one single object, whose objects' boundaries are to be traced.
  • P0: initial point of a target boundary.
  • closed: if true (default) makes the inital point of a boundary equal to the last point.

Example

julia> A = zeros(Int, 13, 16); A[2:6, 2:6] .= 1; A[4:8, 7:10] .= 1; A[10:12,13:15] .= 1; A[10:12,3:6] .= 1;

julia> A
13×16 Matrix{Int64}:
 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 0  1  1  1  1  1  0  0  0  0  0  0  0  0  0  0
 0  1  1  1  1  1  0  0  0  0  0  0  0  0  0  0
 0  1  1  1  1  1  1  1  1  1  0  0  0  0  0  0
 0  1  1  1  1  1  1  1  1  1  0  0  0  0  0  0
 0  1  1  1  1  1  1  1  1  1  0  0  0  0  0  0
 0  0  0  0  0  0  1  1  1  1  0  0  0  0  0  0
 0  0  0  0  0  0  1  1  1  1  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 0  0  1  1  1  1  0  0  0  0  0  0  1  1  1  0
 0  0  1  1  1  1  0  0  0  0  0  0  1  1  1  0
 0  0  1  1  1  1  0  0  0  0  0  0  1  1  1  0
 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

julia> boundary = IceFloeTracker.bwtraceboundary(A);

julia> boundary[3]
9-element Vector{CartesianIndex}:
 CartesianIndex(10, 13)
 CartesianIndex(11, 13)
 CartesianIndex(12, 13)
 CartesianIndex(12, 14)
 CartesianIndex(12, 15)
 CartesianIndex(11, 15)
 CartesianIndex(10, 15)
 CartesianIndex(10, 14)
 CartesianIndex(10, 13)
source
IceFloeTracker.check_fnameFunction
check_fname(fname)

Checks fname does not exist in current directory; throws an assertion if this condition is false.

Arguments

  • fname: String object or Symbol to a reference to a String representing a path.
source
IceFloeTracker.compute_ratiosMethod
compute_ratios((props_day1, r), (props_day2,s))

Compute the ratios of the floe properties between the rth floe in props_day1 and the sth floe in props_day2. Return a tuple of the ratios.

Arguments

  • props_day1: floe properties for day 1
  • r: index of floe in props_day1
  • props_day2: floe properties for day 2
  • s: index of floe in props_day2
source
IceFloeTracker.compute_ratios_conditionsMethod
compute_ratios_conditions((props_day1, r), (props_day2, s), delta_time, t)

Compute the conditions for a match between the rth floe in props_day1 and the sth floe in props_day2. Return a tuple of the conditions.

Arguments

  • props_day1: floe properties for day 1
  • r: index of floe in props_day1
  • props_day2: floe properties for day 2
  • s: index of floe in props_day2
  • delta_time: time elapsed from image day 1 to image day 2
  • t: tuple of thresholds for elapsed time and distance. See pair_floes for details.
source
IceFloeTracker.convertcentroid!Method
convertcentroid!(propdf, latlondata, colstodrop)

Convert the centroid coordinates from row and column to latitude and longitude dropping unwanted columns specified in colstodrop for the output data structure. Addionally, add columns x and y with the pixel coordinates of the centroid.

source
IceFloeTracker.converttounits!Method
converttounits!(propdf, latlondata, colstodrop)

Convert the floe properties from pixels to kilometers and square kilometers where appropiate. Also drop the columns specified in colstodrop.

source
IceFloeTracker.create_cloudmaskMethod
create_cloudmask(falsecolor_image; prelim_threshold, band_7_threshold, band_2_threshold, ratio_lower, ratio_upper)

Convert a 3-channel false color reflectance image to a 1-channel binary matrix; clouds = 0, else = 1. Default thresholds are defined in the published Ice Floe Tracker article: Remote Sensing of the Environment 234 (2019) 111406.

Arguments

  • falsecolor_image: corrected reflectance false color image - bands [7,2,1]
  • prelim_threshold: threshold value used to identify clouds in band 7, N0f8(RGB intensity/255)
  • band_7_threshold: threshold value used to identify cloud-ice in band 7, N0f8(RGB intensity/255)
  • band_2_threshold: threshold value used to identify cloud-ice in band 2, N0f8(RGB intensity/255)
  • ratio_lower: threshold value used to set lower ratio of cloud-ice in bands 7 and 2
  • ratio_upper: threshold value used to set upper ratio of cloud-ice in bands 7 and 2
source
IceFloeTracker.create_landmaskMethod
create_landmask(landmask_image, struct_elem, fill_value_lower, fill_value_upper)

Convert a 3-channel RGB land mask image to a 1-channel binary matrix, including a buffer to extend the land over any soft ice regions; land = 0, water/ice = 1. Returns a named tuple with the dilated and non-dilated landmask.

Arguments

  • landmask_image: RGB land mask image from fetchdata
  • struct_elem: structuring element for dilation (optional)
  • fill_value_lower: fill holes having at least these many pixels (optional)
  • fill_value_upper: fill holes having at most these many pixels (optional)
source
IceFloeTracker.cropfloeMethod
cropfloe(floesimg, props, i)

Crops the floe delimited by the bounding box data in props at index i from the floe image floesimg.

source
IceFloeTracker.crosscorrMethod
r, lags = crosscorr(u::Vector{T},
                    v::Vector{T};
                    normalize::Bool=false,
                    padmode::Symbol=:longest)

Wrapper of DSP.xcorr with normalization (see https://docs.juliadsp.org/stable/convolutions/#DSP.xcorr)

Returns the pair (r, lags) with the cross correlation scores r and corresponding lags according to padmode.

Arguments

  • u,v: real vectors which could have unequal length.
  • normalize: return normalized correlation scores (false by default).
  • padmode: either :longest (default) or :none to control padding of shorter vector with zeros.

Examples

The example below builds two vectors, one a shifted version of the other, and computes various cross correlation scores.

julia> n = 1:5;

julia> x = 0.48.^n;

julia> y = circshift(x,3);

julia> r, lags = crosscorr(x,y,normalize=true);

julia> [r lags]
9×2 Matrix{Float64}:
0.369648    -4.0
0.947531    -3.0
0.495695    -2.0
0.3231      -1.0
0.332519     0.0
0.15019      1.0
0.052469     2.0
0.0241435    3.0
0.00941878   4.0

julia> r, lags = crosscorr(x,y,normalize=true,padmode=:none);

julia> [r lags]
9×2 Matrix{Float64}:
0.369648    1.0
0.947531    2.0
0.495695    3.0
0.3231      4.0
0.332519    5.0
0.15019     6.0
0.052469    7.0
0.0241435   8.0
0.00941878  9.0

This final example builds two vectors of different length and computes some cross correlation scores.

julia> n = 1:5; m = 1:3;

julia> x = 0.48.^n; y = 0.48.^m;

julia> r, lags = crosscorr(x,y,normalize=true);

julia> [r lags]
9×2 Matrix{Float64}:
0.0          -4.0
4.14728e-17  -3.0
0.178468     -2.0
0.457473     -1.0
0.994189      0.0
0.477211      1.0
0.229061      2.0
0.105402      3.0
0.0411191     4.0

julia> r, lags = crosscorr(x,y,normalize=true,padmode=:none);

julia> [r lags]
7×2 Matrix{Float64}:
0.178468   1.0
0.457473   2.0
0.994189   3.0
0.477211   4.0
0.229061   5.0
0.105402   6.0
0.0411191  7.0
source
IceFloeTracker.discriminate_ice_waterMethod
discriminate_ice_water(
falsecolor_image::Matrix{RGB{Float64}},
normalized_image::Matrix{Gray{Float64}},
landmask_bitmatrix::T,
cloudmask_bitmatrix::T,
floes_threshold::Float64=Float64(100 / 255),
mask_clouds_lower::Float64=Float64(17 / 255),
mask_clouds_upper::Float64=Float64(30 / 255),
kurt_thresh_lower::Real=2,
kurt_thresh_upper::Real=8,
skew_thresh::Real=4,
st_dev_thresh_lower::Float64=Float64(84 / 255),
st_dev_thresh_upper::Float64=Float64(98.9 / 255),
clouds_ratio_threshold::Float64=0.02,
differ_threshold::Float64=0.6,
nbins::Real=155

)

Generates an image with ice floes apparent after filtering and combining previously processed versions of falsecolor and truecolor images from the same region of interest. Returns an image ready for segmentation to isolate floes.

Note: This function mutates the landmask object to avoid unnecessary memory allocation. If you need the original landmask, make a copy before passing it to this function. Example: discriminate_ice_water(falsecolor_image, normalized_image, copy(landmask_bitmatrix), cloudmask_bitmatrix)

Arguments

  • falsecolor_image: input image in false color reflectance
  • normalized_image: normalized version of true color image
  • landmask_bitmatrix: landmask for region of interest
  • cloudmask_bitmatrix: cloudmask for region of interest
  • floes_threshold: heuristic applied to original false color image
  • mask_clouds_lower: lower heuristic applied to mask out clouds
  • mask_clouds_upper: upper heuristic applied to mask out clouds
  • kurt_thresh_lower: lower heuristic used to set pixel value threshold based on kurtosis in histogram
  • kurt_thresh_upper: upper heuristic used to set pixel value threshold based on kurtosis in histogram
  • skew_thresh: heuristic used to set pixel value threshold based on skewness in histogram
  • st_dev_thresh_lower: lower heuristic used to set pixel value threshold based on standard deviation in histogram
  • st_dev_thresh_upper: upper heuristic used to set pixel value threshold based on standard deviation in histogram
  • clouds2_threshold: heuristic used to set pixel value threshold based on ratio of clouds
  • differ_threshold: heuristic used to calculate proportional intensity in histogram
  • nbins: number of bins during histogram build
source
IceFloeTracker.find_ice_labelsMethod
find_ice_labels(falsecolor_image, landmask; band_7_threshold, band_2_threshold, band_1_threshold, band_7_relaxed_threshold, band_1_relaxed_threshold, possible_ice_threshold)

Locate the pixels of likely ice from false color reflectance image. Returns a binary mask with ice floes contrasted from background. Default thresholds are defined in the published Ice Floe Tracker article: Remote Sensing of the Environment 234 (2019) 111406.

Arguments

  • falsecolor_image: corrected reflectance false color image - bands [7,2,1]
  • landmask: bitmatrix landmask for region of interest
  • band_7_threshold: threshold value used to identify ice in band 7, N0f8(RGB intensity/255)
  • band_2_threshold: threshold value used to identify ice in band 2, N0f8(RGB intensity/255)
  • band_1_threshold: threshold value used to identify ice in band 2, N0f8(RGB intensity/255)
  • band_7_relaxed_threshold: threshold value used to identify ice in band 7 if not found on first pass, N0f8(RGB intensity/255)
  • band_1_relaxed_threshold: threshold value used to identify ice in band 1 if not found on first pass, N0f8(RGB intensity/255)
source
IceFloeTracker.find_reflectance_peaksMethod
find_reflectance_peaks(reflectance_channel, possible_ice_threshold;)

Find histogram peaks in single channels of a reflectance image and return the second greatest peak. If needed, edges can be returned as the first object from build_histogram. Similarly, peak values can be returned as the second object from findmaxima.

Arguments

  • reflectance_channel: either band 2 or band 1 of false-color reflectance image
  • possible_ice_threshold: threshold value used to identify ice if not found on first or second pass
source
IceFloeTracker.fixzeroindexing!Method
fixzeroindexing!(props::DataFrame, props_to_fix::Vector{T}) where T<:Union{Symbol,String}

Fix the zero-indexing of the props_to_fix columns in props by adding 1 to each element.

source
IceFloeTracker.from_toMethod

Get index in Moore neigborhood representing the direction from the from pixel coords to the to pixel coords (see definition of dir_delta below).

Clockwise Moore neighborhood.

dir_delta = [CartesianIndex(-1, 0), CartesianIndex(-1, 1), CartesianIndex(0, 1), CartesianIndex(1, 1), CartesianIndex(1, 0), CartesianIndex(1, -1), CartesianIndex(0, -1), CartesianIndex(-1,-1)]

source
IceFloeTracker.get_areasMethod
get_areas(labeled_arr::Array{T, 2})::Dict{T, Int} where T

Get the "areas" (count of pixels of a given label) of the connected components in labeled_arr.

Return a dictionary with the frequency distribution: label => countoflabel.

source
IceFloeTracker.getbestmatchdataMethod
getbestmatchdata(idx, r, props_day1, matching_floes)

Collect the data for the best match between the rth floe in props_day1 and the idxth floe in matching_floes. Return a tuple of the floe properties for day 1 and day 2 and the ratios.

source
IceFloeTracker.getfloemasksMethod
getfloemasks(props::DataFrame, floeimg::BitMatrix)

Return a vector of cropped floe masks from floeimg using the bounding box data in props.

source
IceFloeTracker.getidxmostminimumeverythingMethod
getidxmostminimumeverything(ratiosdf)

Return the index of the row in ratiosdf with the most minima across its columns. If there are multiple columns with the same minimum value, return the index of the first column with the minimum value. If ratiosdf is empty, return NaN.

source
IceFloeTracker.getsizecomparabilityMethod
getsizecomparability(s1, s2)

Check if the size of two floes s1 and s2 are comparable. The size is defined as the product of the floe dimensions.

Arguments

  • s1: size of floe 1
  • s2: size of floe 2
source
IceFloeTracker.gradMethod
dx, dy = grad(A::Matrix{<:Number})

Make gradient vector field for the set of points with coordinates in the rows of the matrix A with x-coordinates down column 1 and y-coordinates down column 2. Return a tuple with dx and dy in that order.

source
IceFloeTracker.gradMethod
dx, dy = grad(x::Vector{<:Number}, y::Vector{<:Number})

Make gradient vector field for the set of points with coordinates in vectors x and y. Return a tuple with dx and dy in that order.

source
IceFloeTracker.hbreakMethod
hbreak(img::AbstractArray{Bool})

Remove H-connected pixels in the binary image img. See also hbreak! for an inplace version of this function.

Examples

```jldoctest; setup = :(using IceFloeTracker)

julia> h1 = trues(3,3); h1[[1 3], 2] .= false; h1 3×3 BitMatrix: 1 0 1 1 1 1 1 0 1

julia> h2 = trues(3,3); h2[2, [1 3]] .= false; h2 3×3 BitMatrix: 1 1 1 0 1 0 1 1 1

julia> hbreak!(h1); h1 # modify h1 inplace 3×3 BitMatrix: 1 0 1 1 0 1 1 0 1

julia> hbreak(h2) 3×3 BitMatrix: 1 1 1 0 0 0 1 1 1

source
IceFloeTracker.imextendedminMethod
imextendedmin(img)

Mimics MATLAB's imextendedmin function that computes the extended-minima transform, which is the regional minima of the H-minima transform. Regional minima are connected components of pixels with a constant intensity value. This function returns a transformed bitmatrix.

Arguments

  • img: image object
  • h: suppress minima below this depth threshold
  • conn: neighborhood connectivity; in 2D 1 = 4-neighborhood and 2 = 8-neighborhood
source
IceFloeTracker.imsharpenFunction
imsharpen(truecolor_image, landmask_no_dilate, lambda, kappa, niters, nbins, rblocks, cblocks, clip, smoothing_param, intensity)

Sharpen truecolor_image.

Arguments

  • truecolor_image: input image in truecolor
  • landmask_no_dilate: landmask for region of interest
  • lambda: speed of diffusion (0–0.25)
  • kappa: conduction coefficient for diffusion (25–100)
  • niters: number of iterations of diffusion
  • nbins: number of bins during histogram equalization
  • rblocks: number of row blocks to divide input image during equalization
  • cblocks: number of column blocks to divide input image during equalization
  • clip: Thresholds for clipping histogram bins (0–1); values closer to one minimize contrast enhancement, values closer to zero maximize contrast enhancement
  • smoothing_param: pixel radius for gaussian blurring (1–10)
  • intensity: amount of sharpening to perform
source
IceFloeTracker.isfloegoodmatchMethod
isfloegoodmatch(conditions, mct, area_mismatch, corr)

Return true if the floes are a good match as per the set thresholds. Return false otherwise.

Arguments

  • conditions: tuple of booleans for evaluating the conditions
  • mct: tuple of thresholds for the match correlation test
  • area_mismatch and corr: values returned by match_corr
source
IceFloeTracker.kmeans_segmentationMethod
kmeans_segmentation(gray_image, ice_labels;)

Apply k-means segmentation to a gray image to isolate a cluster group representing sea ice. Returns a binary image with ice segmented from background.

Arguments

  • gray_image: output image from ice-water-discrimination.jl or gray ice floe leads image in segmentation_f.jl
  • ice_labels: vector if pixel coordinates output from find_ice_labels.jl
source
IceFloeTracker.loadimgMethod
loadimg(; dir::String, fname::String)

Load an image from dir with filename fname into a matrix of Float64 values. Returns the loaded image.

source
IceFloeTracker.make_hbreak_dictMethod
make_hbreak_dict()

Build dict with the two versions of an H-connected 3x3 neighboorhood.

h1 = [1 0 1 1 1 1 1 0 1]

h2 = [1 1 1 0 1 0 1 1 1]

source
IceFloeTracker.make_psi_sMethod
make_psi_s(XY::Matrix{<:Number};rangeout::Bool=true,
unwrap::Bool=true)

Alternate method of make_psi_s accepting input vectors x and y as a 2-column matrix [x y] in order to facillitate workflow (output from resample_boundary).

source
IceFloeTracker.make_psi_sMethod
make_psi_s(x::Vector{<:Number},
           y::Vector{<:Number};
           rangeout::Bool=true,
           unwrap::Bool=true)::Tuple{Vector{Float64}, Vector{Float64}}

Builds the ψ-s curve defined by vectors x and y.

Returns a tuple of vectors with the phases ψ in the first component and the traversed arclength in the second component.

Following the convention in [1], the wrapped ψ-s curve has values in [0, 2π) by default; use rangeout to control this behavior.

See also bwtraceboundary, resample_boundary

Arguments

  • x: Vector of x-coordinates
  • y: corresponding vector of y-coordinates
  • rangeout: true (default) for phase values in [0, 2π); false for phase values in (-π, π].
  • unwrap: set to true to get "unwrapped" phases (default).

Reference

[1] McConnell, Ross, et al. "psi-s correlation and dynamic time warping: two methods for tracking ice floes in SAR images." IEEE Transactions on Geoscience and Remote sensing 29.6 (1991): 1004-1012.

Example

The example below builds a cardioid and obtains its ψ-s curve.

julia> t = range(0,2pi,201);

julia> x = @. cos(t)*(1-cos(t));

julia> y = @. sin(t)*(1-cos(t));

julia> plot(x,y) # visualize the cardioid

julia> psi, s = make_psi_s(x,y);

julia> [s psi] # inspect psi-s data
200×2 Matrix{Float64}:
 0.00049344  0.0314159
 0.0019736   0.0733034
 0.00444011  0.11938
 0.00789238  0.166055
 0.0123296   0.212929
 0.0177505   0.259894
 0.024154    0.306907
 0.0315383   0.35395
 0.0399017   0.401012
 0.0492421   0.448087
 ⋮
 7.96772     9.02377
 7.97511     9.07083
 7.98151     9.11787
 7.98693     9.16488
 7.99137     9.21185
 7.99482     9.25872
 7.99729     9.3054
 7.99877     9.35147
 7.99926     9.39336

 julia> plot(s, psi) # inspect psi-s curve -- should be a straight line from (0, 0) to (8, 3π)
source
IceFloeTracker.makeemptydffromMethod
makeemptydffrom(df::DataFrame)

Return an object with an empty dataframe with the same column names as df and an empty dataframe with column names area, majoraxis, minoraxis, convex_area, area_mismatch, and corr for similarity ratios.

source
IceFloeTracker.makeemptyratiosdfMethod
makeemptyratiosdf()

Return an empty dataframe with column names area, majoraxis, minoraxis, convex_area, area_mismatch, and corr for similarity ratios.

source
IceFloeTracker.matchcorrMethod
matchcorr(
f1::T,
f2::T,
Δt::F,
mxrot::S=10,
psi::F=0.95,
sz::S=16,
comp::F=0.25,
mm::F=0.22
)
where {T<:AbstractArray{Bool,2},S<:Int64,F<:Float64}

Compute the mismatch mm and psi-s-correlation c for floes with masks f1 and f2.

The criteria for floes to be considered equivalent is as follows: - c greater than mm - _mm is less than mm

A pair of NaN is returned for cases for which one of their mask dimension is too small or their sizes are not comparable.

Arguments

  • f1: mask of floe 1
  • f2: mask of floe 2
  • Δt: time difference between floes
  • mxrot: maximum rotation (in degrees) allowed between floesn (default: 10)
  • psi: psi-s-correlation threshold (default: 0.95)
  • sz: size threshold (default: 16)
  • comp: size comparability threshold (default: 0.25)
  • mm: mismatch threshold (default: 0.22)
source
IceFloeTracker.mismatchFunction
mismatch(fixed::AbstractArray,
              moving::AbstractArray,
              mxshift::Tuple{Int64, Int64}=(10,10),
              mxrot::Float64=pi/4;
              kwargs...
              )

Estimate a rigid transformation (translation + rotation) that minimizes the 'mismatch' of aligning moving with fixed using the QuadDIRECT algorithm.

Returns a pair with the mismatch score mm and the associated registration angle rot.

Arguments

  • fixed,moving: images to align via a rigid transformation
  • mxshift: maximum allowed translation in units of array indices (default set to (10,10))
  • mxrot: maximum allowed rotation in radians (default set to π/4)
  • thresh: minimum sum-of-squared-intensity overlap between the images (default is 10% of the sum-of-squared-intensity of fixed)
  • kwargs: other arguments such as tol, ftol, and fvalue (see QuadDIRECT.analyze for details)

```

source
IceFloeTracker.normalize_imageMethod
normalize_image(image_sharpened, image_sharpened_gray, landmask, struct_elem;)

Adjusts sharpened land-masked image to highlight ice floe features.

Does reconstruction and landmasking to image_sharpened.

Arguments

  • image_sharpened: sharpened image (output of imsharpen)
  • image_sharpened_gray: grayscale, landmasked sharpened image (output of imsharpen_gray(image_sharpened))
  • landmask: landmask for region of interest
  • struct_elem: structuring element for dilation
source
IceFloeTracker.padnhoodMethod
padnhood(img, I, nhood)

Pad the matrix img[nhood] with zeros according to the position of I within the edgesimg.

Returns img[nhood] if I is not an edge index.

source
IceFloeTracker.pairfloesMethod
pairfloes(
segmented_imgs::Vector{BitMatrix},
props::Vector{DataFrame},
passtimes::Vector{DateTime},
latlonrefimage::AbstractString,
condition_thresholds,
mc_thresholds,

)

Pair floes in props[k] to floes in props[k+1] for k=1:length(props)-1.

The main steps of the algorithm are as follows:

  1. Crop floes from segmented_imgs using bounding box data in props. Floes in the edges are removed.
  2. For each floekr in props[k], compare to floek+1s in props[k+1] by computing similarity ratios, set of conditions, and drift distance dist. If the conditions are met, compute the area mismatch mm and psi-s correlation c for this pair of floes. Pair these two floes if mm and c satisfy the thresholds in mc_thresholds.
  3. If there are collisions (i.e. floe s in props[k+1] is paired to more than one floe in props[k]), then the floe in props[k] with the best match is paired to floe s in props[k+1].
  4. Drop paired floes from props[k] and props[k+1] and repeat steps 2 and 3 until there are no more floes to match in props[k].
  5. Repeat steps 2-4 for k=2:length(props)-1.

Arguments

  • segmented_imgs: array of images with segmented floes
  • props: array of dataframes containing floe properties
  • passtimes: array of DateTime objects containing the time of the image in which the floes were captured
  • latlonrefimage: path to geotiff reference image for getting latitude and longitude of floe centroids
  • condition_thresholds: 3-tuple of thresholds (each a named tuple) for deciding whether to match floe i from day k to floe j from day k+1
  • mc_thresholds: thresholds for area mismatch and psi-s shape correlation

Returns a dataframe containing the following columns:

  • ID: unique ID for each floe pairing.
  • passtime: time of the image in which the floes were captured.
  • area: area of the floe in sq. kilometers
  • convex_area: area of the convex hull of the floe in sq. kilometers
  • major_axis_length: length of the major axis of the floe in kilometers
  • minor_axis_length: length of the minor axis of the floe in kilometers
  • orientation: angle between the major axis and the x-axis in radians
  • perimeter: perimeter of the floe in kilometers
  • latitude: latitude of the floe centroid
  • longitude: longitude of the floe centroid
  • x: x-coordinate of the floe centroid
  • y: y-coordinate of the floe centroid
  • area_mismatch: area mismatch between the two floes in rowi and rowi+1 after registration
  • corr: psi-s shape correlation between the two floes in rowi and rowi+1
source
IceFloeTracker.regionpropsFunction
regionprops(label_img, ; properties, connectivity)

A wrapper of the regionprops function from the skimage python library.

See its full documentation at https://scikit-image.org/docs/stable/api/skimage.measure.html#skimage.measure.regionprops.

Arguments

  • label_img: Image with the labeled objects of interest
  • intensity_img: (Optional) Used for generating extra_properties, integer/float array from which (presumably) label_img was generated
  • extra_properties: (Optional) not yet implemented. It will be set to nothing

See also regionprops_table

Examples

julia> Random.seed!(123);

julia> bw_img = rand([0, 1], 5, 10)
5×10 Matrix{Int64}:
 1  0  1  0  0  0  0  0  0  1
 1  0  1  1  1  0  0  0  1  1
 1  1  0  1  1  0  1  0  0  1
 0  1  0  1  0  0  0  0  1  0
 1  0  0  0  0  1  0  1  0  1

 julia> label_img = Images.label_components(bw_img, trues(3,3))
 5×10 Matrix{Int64}:
  1  0  1  0  0  0  0  0  0  4
  1  0  1  1  1  0  0  0  4  4
  1  1  0  1  1  0  3  0  0  4
  0  1  0  1  0  0  0  0  4  0
  1  0  0  0  0  2  0  4  0  4

 julia> regions = regionprops(label_img, bw_img);

 julia> for region in regions
           println(region.area,"	", region.perimeter)
        end
13      11.621320343559642
1       0.0
1       0.0
7       4.621320343559642
source
IceFloeTracker.regionprops_tableFunction
regionprops_table(label_img, intensity_img; properties, connectivity, extra_properties)

A wrapper of the regionprops_table function from the skimage python library.

See its full documentation at https://scikit-image.org/docs/stable/api/skimage.measure.html#regionprops-table.

Arguments

  • label_img: Image with the labeled objects of interest
  • intensity_img: (Optional) Used for generating extra_properties, integer/float array from which (presumably) label_img was generated
  • properties: List (Vector or Tuple) of properties to be generated for each connected component in label_img
  • extra_properties: (Optional) not yet implemented. It will be set to nothing

Notes

  • Zero indexing has been corrected for the bbox and centroid properties
  • bbox data (max_col and max_row) are inclusive
  • centroid data are rounded to the nearest integer

See also regionprops

Examples

julia> using IceFloeTracker, Random

julia> Random.seed!(123);

julia> bw_img = rand([0, 1], 5, 10)
5×10 Matrix{Int64}:
 1  0  1  0  0  0  0  0  0  1
 1  0  1  1  1  0  0  0  1  1
 1  1  0  1  1  0  1  0  0  1
 0  1  0  1  0  0  0  0  1  0
 1  0  0  0  0  1  0  1  0  1

julia> label_img = IceFloeTracker.label_components(bw_img, trues(3,3))
5×10 Matrix{Int64}:
 1  0  1  0  0  0  0  0  0  4
 1  0  1  1  1  0  0  0  4  4
 1  1  0  1  1  0  3  0  0  4
 0  1  0  1  0  0  0  0  4  0
 1  0  0  0  0  2  0  4  0  4

julia> properties = ["area", "perimeter"]
2-element Vector{String}:
 "area"
 "perimeter"

 julia> IceFloeTracker.regionprops_table(label_img, bw_img, properties = properties)
 4×2 DataFrame
  Row │ area   perimeter 
      │ Int32  Float64   
 ─────┼──────────────────
    1 │    13   11.6213
    2 │     1    0.0
    3 │     1    0.0
    4 │     7    4.62132
source
IceFloeTracker.remove_paddingMethod
remove_padding(paddedimg, border_spec)

Removes padding from the boundary of padded image paddedimg according to the border specification border_spec type. Returns the cropped image.

Arguments

  • paddedimg: Pre-padded image.
  • border_spec: Type representing the style of padding (such as Pad or Fill) with which paddedimg is assumend to be pre-padded. Example: Pad((1,2), (3,4)) specifies 1 row on the top, 2 columns on the left, 3 rows on the bottom, and 4 columns on the right boundary.

See also add_padding

source
IceFloeTracker.renamecols!Method
renamecols!(props::DataFrame, oldnames::Vector{T}, newnames::Vector{T}) where T<:Union{Symbol,String}

Rename the oldnames columns in props to newnames.

source
IceFloeTracker.resample_boundaryFunction
resample_boundary(bd_points::Vector{<:CartesianIndex}, reduc_factor::Int64=2, bd::String="natural")

Get a uniform set of resampled boundary points from bd_points using cubic splines with specified boundary conditions

The resampled set of points is obtained using parametric interpolation of the points in bd_points. It is assumed that the separation between a pair of adjacent points is 1.

Arguments

  • bd_points: Sequetial set of boundary points for the object of interest
  • reduc_factor: Factor by which to reduce the number of points in bd_points (2 by default)

-bd: Boundary condition, either 'natural' (default) or 'periodic'

See also bwtraceboundary

Example

```jldoctest; setup = :(using IceFloeTracker) julia> A = zeros(Int, 13, 16); A[2:6, 2:6] .= 1; A[4:8, 7:10] .= 1; A[10:12,13:15] .= 1; A[10:12,3:6] .= 1; julia> A 13×16 Matrix{Int64}: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

julia> boundary = bwtraceboundary(A);

julia> boundary[3] 9-element Vector{CartesianIndex}: CartesianIndex(10, 13) CartesianIndex(11, 13) CartesianIndex(12, 13) CartesianIndex(12, 14) CartesianIndex(12, 15) CartesianIndex(11, 15) CartesianIndex(10, 15) CartesianIndex(10, 14) CartesianIndex(10, 13)

julia> resample_boundary(boundary[3]) 4×2 Matrix{Float64}: 10.0 13.0 12.0357 13.5859 10.5859 15.0357 10.0 13.0

source
IceFloeTracker.roundtoint!Method
roundtoint!(props::DataFrame, colnames::Vector{T}) where T<:Union{Symbol,String}

Round the colnames columns in props to Int.

source
IceFloeTracker.segmentation_AMethod
segmentation_A(segmented_ice_cloudmasked; min_opening_area)

Apply k-means segmentation to a gray image to isolate a cluster group representing sea ice. Returns an image segmented and processed as well as an intermediate files needed for downstream functions.

Arguments

  • segmented_ice_cloudmask: bitmatrix with open water/clouds = 0, ice = 1, output from segmented_ice_cloudmasking()
  • min_opening_area: minimum size of pixels to use during morphological opening
  • fill_range: range of values dictating the size of holes to fill
source
IceFloeTracker.segmentation_BFunction
segmentation_B(sharpened_image, cloudmask, segmented_a_ice_mask, struct_elem; fill_range, isolation_threshold, alpha_level, adjusted_ice_threshold)

Performs image processing and morphological filtering with intermediate files from normalization.jl and segmentation_A to further isolate ice floes, returning a mask of potential ice.

Arguments

  • sharpened_image: non-cloudmasked but sharpened image, output from normalization.jl
  • cloudmask: bitmatrix cloudmask for region of interest
  • segmented_a_ice_mask: binary cloudmasked ice mask from segmentation_a_direct.jl
  • struct_elem: structuring element for dilation
  • fill_range: range of values dictating the size of holes to fill
  • isolation_threshold: threshold used to isolated pixels from sharpened_image; between 0-1
  • alpha_level: alpha threshold used to adjust contrast
  • gamma_factor: amount of gamma adjustment
  • adjusted_ice_threshold: threshold used to set ice equal to one after gamma adjustment
source
IceFloeTracker.segmentation_FMethod
segmentation_F(
segmentation_B_not_ice_mask::Matrix{Gray{Float64}},
segmentation_B_ice_intersect::BitMatrix,
segmentation_B_watershed_intersect::BitMatrix,
ice_labels::Vector{Int64},
cloudmask::BitMatrix,
landmask::BitMatrix;
min_area_opening::Int64=20

)

Cleans up past segmentation images with morphological operations, and applies the results of prior watershed segmentation, returning the final cleaned image for tracking with ice floes segmented and isolated.

Arguments

  • segmentation_B_not_ice_mask: gray image output from segmentation_b.jl
  • segmentation_B_ice_intersect: binary mask output from segmentation_b.jl
  • segmentation_B_watershed_intersect: ice pixels, output from segmentation_b.jl
  • ice_labels: vector of pixel coordinates output from find_ice_labels.jl
  • cloudmask.jl: bitmatrix cloudmask for region of interest
  • landmask.jl: bitmatrix landmask for region of interest
  • min_area_opening: threshold used for area opening; pixel groups greater than threshold are retained
source
IceFloeTracker.segmented_ice_cloudmaskingMethod
segmented_ice_cloudmasking(gray_image, cloudmask, ice_labels;)

Apply cloudmask to a bitmatrix of segmented ice after kmeans clustering. Returns a bitmatrix with open water/clouds = 0, ice = 1).

Arguments

  • gray_image: output image from ice-water-discrimination.jl or gray ice floe leads image in segmentation_f.jl
  • cloudmask: bitmatrix cloudmask for region of interest
  • ice_labels: vector if pixel coordinates output from find_ice_labels.jl
source
IceFloeTracker.trackercond1Function
trackercond1(p1, p2, delta_time, t1=(dt = (30, 100, 1300), dist=(15, 30, 120)))

Return true if the floe at p1 and the floe at p2 are within a certain distance of each other and the displacement time is within a certain range. Return false otherwise.

Arguments

  • p1: coordinates of floe 1
  • p2: coordinates of floe 2
  • delta_time: time elapsed from image day 1 to image day 2
  • t: tuple of thresholds for elapsed time and distance
source
IceFloeTracker.trackercond2Function
trackercond2(area1, ratios, t2=(area=1200, arearatio=0.28, majaxisratio=0.10, minaxisratio=0.12, convex_area=0.14))

Set of conditions for "big" floes. Return true if the area of the floe is greater than t2.area and the similarity ratios are less than the corresponding thresholds in t2. Return false otherwise.

source
IceFloeTracker.trackercond3Function
trackercond3(area1, ratios, t3=(area=1200, arearatio=0.18, majaxisratio=0.07, minaxisratio=0.08, convex_area=0.09))

Set of conditions for "small" floes. Return true if the area of the floe is less than t3.area and the similarity ratios are less than the corresponding thresholds in t3. Return false otherwise

source
IceFloeTracker.update!Method
update!(match_total::MatchedPairs, matched_pairs::MatchedPairs)

Update match_total with the data from matched_pairs.

source
IceFloeTracker.watershed_ice_floesMethod
watershed_ice_floes(intermediate_segmentation_image;)

Performs image processing and watershed segmentation with intermediate files from segmentation_b.jl to further isolate ice floes, returning a binary segmentation mask indicating potential sparse boundaries of ice floes.

Arguments

-intermediate_segmentation_image: binary cloudmasked and landmasked intermediate file from segmentation B, either SegB.not_ice_bit or SegB.ice_intersect

source
IceFloeTracker.watershed_productMethod
watershed_product(watershed_B_ice_intersect, watershed_B_not_ice;)

Intersects the outputs of watershed segmentation on intermediate files from segmentation B, indicating potential sparse boundaries of ice floes.

Arguments

  • watershed_B_ice_intersect: binary segmentation mask from watershed_ice_floes
  • watershed_B_not_ice: binary segmentation mask from watershed_ice_floes
source
IceFloeTracker.@persistMacro
@persist img fname
@persist(img,fname)
@persist img
@persist(img)
@persist img fname ts
@persist(img, fname, ts)

Given a reference to an image object img, the macro persists (saves to a file) img to the current working directory using fname as filename. Returns img.

Arguments

  • img: Symbol expression representing an image object loaded in memory.
  • fname: Optional filename for the persisted image.
  • ts: Optional boolean to attach timestamp to fname.
source
IceFloeTracker.MatchedPairsType

Container for matched pairs of floes. props1 and props2 are dataframes with the same column names as the input dataframes. ratios is a dataframe with column names area, majoraxis, minoraxis, convex_area, area_mismatch, and corr for similarity ratios. dist is a vector of (pixel) distances between paired floes.

source
IceFloeTracker.MatchedPairsMethod
MatchedPairs(df)

Return an object of type MatchedPairs with an empty dataframe with the same column names as df, an empty dataframe with column names area, majoraxis, minoraxis, convex_area, area_mismatch, and corr for similarity ratios, and an empty vector for distances.

source

Index