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

479 imbrighten #480

Merged
merged 9 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
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
1 change: 1 addition & 0 deletions src/IceFloeTracker.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ include("branch.jl")
include("special_strels.jl")
include("tilingutils.jl")
include("histogram_equalization.jl")
include("brighten.jl")


const sk_measure = PyNULL()
Expand Down
28 changes: 28 additions & 0 deletions src/brighten.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""
get_brighten_mask(equalized_gray_reconstructed_img, gamma_green)
# Arguments
- `equalized_gray_reconstructed_img`: The equalized gray reconstructed image (uint8 in Matlab).
- `gamma_green`: The gamma value for the green channel (also uint8).
# Returns
Difference equalized_gray_reconstructed_img - gamma_green clamped between 0 and 255.
"""
function get_brighten_mask(equalized_gray_reconstructed_img, gamma_green)
return to_uint8(equalized_gray_reconstructed_img - gamma_green)
end

"""
imbrighten(img, brighten_mask, bright_factor)
Brighten the image using a mask and a brightening factor.
# Arguments
- `img`: The input image.
- `brighten_mask`: A mask indicating the pixels to brighten.
- `bright_factor`: The factor by which to brighten the pixels.
# Returns
- The brightened image.
"""
function imbrighten(img, brighten_mask, bright_factor)
img = Float64.(img)
brighten_mask = brighten_mask .> 0
img[brighten_mask] .= img[brighten_mask] * bright_factor
return img = to_uint8(img)
end
54 changes: 27 additions & 27 deletions src/histogram_equalization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ function to_uint8(arr::AbstractMatrix{T}) where {T<:AbstractFloat}
return img
end

function to_uint8(arr::AbstractMatrix{T}) where {T<:Integer}
img = clamp.(arr, 0, 255)
return img
end

function anisotropic_diffusion_3D(I)
rgbchannels = get_rgb_channels(I)
Expand All @@ -13,10 +17,11 @@ function anisotropic_diffusion_3D(I)
end

return rgbchannels

end

function anisotropic_diffusion_2D(I::AbstractMatrix{T}; gradient_threshold::Union{T,Nothing}=nothing, niter::Int=1) where {T}
function anisotropic_diffusion_2D(
I::AbstractMatrix{T}; gradient_threshold::Union{T,Nothing}=nothing, niter::Int=1
) where {T}
if eltype(I) <: Int
I = Gray.(I ./ 255)
end
Expand All @@ -34,11 +39,13 @@ function anisotropic_diffusion_2D(I::AbstractMatrix{T}; gradient_threshold::Unio

for _ in 1:niter
# These are zero-indexed offset arrays
diff_img_north = padded_img[0:end-1, 1:end-1] .- padded_img[1:end, 1:end-1]
diff_img_east = padded_img[1:end-1, 1:end] .- padded_img[1:end-1, 0:end-1]
diff_img_nw = padded_img[0:end-2, 0:end-2] .- I
diff_img_ne = padded_img[0:end-2, 2:end] .- I
diff_img_sw = padded_img[2:end, 0:end-2] .- I
diff_img_north =
padded_img[0:(end - 1), 1:(end - 1)] .- padded_img[1:end, 1:(end - 1)]
diff_img_east =
padded_img[1:(end - 1), 1:end] .- padded_img[1:(end - 1), 0:(end - 1)]
diff_img_nw = padded_img[0:(end - 2), 0:(end - 2)] .- I
diff_img_ne = padded_img[0:(end - 2), 2:end] .- I
diff_img_sw = padded_img[2:end, 0:(end - 2)] .- I
diff_img_se = padded_img[2:end, 2:end] .- I

# Exponential conduction coefficients
Expand All @@ -49,7 +56,6 @@ function anisotropic_diffusion_2D(I::AbstractMatrix{T}; gradient_threshold::Unio
conduct_coeff_sw = exp.(-(abs.(diff_img_sw) ./ gradient_threshold) .^ 2)
conduct_coeff_se = exp.(-(abs.(diff_img_se) ./ gradient_threshold) .^ 2)


# Flux calculations
flux_north = conduct_coeff_north .* diff_img_north
flux_east = conduct_coeff_east .* diff_img_east
Expand All @@ -59,42 +65,40 @@ function anisotropic_diffusion_2D(I::AbstractMatrix{T}; gradient_threshold::Unio
flux_se = conduct_coeff_se .* diff_img_se

# Back to regular 1-indexed arrays
flux_north_diff = flux_north[1:end-1, :] .- flux_north[2:end, :]
flux_east_diff = flux_east[:, 2:end] .- flux_east[:, 1:end-1]
flux_north_diff = flux_north[1:(end - 1), :] .- flux_north[2:end, :]
flux_east_diff = flux_east[:, 2:end] .- flux_east[:, 1:(end - 1)]

# Discrete PDE solution
sum_ = (1 / (dd^2)) .* (flux_nw .+ flux_ne .+ flux_sw .+ flux_se)
I = I .+ diffusion_rate .* (flux_north_diff .- flux_north_diff .+ sum_)

end

return I
end


function imshow(img)
if typeof(img) <: BitMatrix
return Gray.(img)
end
Gray.(img ./ 255)
return Gray.(img ./ 255)
end



function adapthisteq(img::Matrix{T}, nbins=256, clip=0.01) where {T}
# Step 1: Normalize the image to [0, 1] based on its own min and max
image_min, image_max = minimum(img), maximum(img)
normalized_image = (img .- image_min) / (image_max - image_min)

# Step 2: Apply adaptive histogram equalization. equalize_adapthist handles the tiling to 1/8 of the image size (equivalent to 8x8 blocks in MATLAB)
equalized_image = sk_exposure.equalize_adapthist(
normalized_image,
normalized_image;
clip_limit=clip, # Equivalent to MATLAB's 'ClipLimit'
nbins=nbins # Number of histogram bins. 255 is used to match the default in MATLAB script
nbins=nbins, # Number of histogram bins. 255 is used to match the default in MATLAB script
)

# Step 3: Rescale the image back to the original range [image_min, image_max]
final_image = sk_exposure.rescale_intensity(equalized_image, in_range="image", out_range=(image_min, image_max))
final_image = sk_exposure.rescale_intensity(
equalized_image; in_range="image", out_range=(image_min, image_max)
)

# Convert back to the original data type if necessary
final_image = to_uint8(final_image)
Expand All @@ -120,10 +124,9 @@ function get_rgb_channels(img)
greenc = green.(img) * 255
bluec = blue.(img) * 255

return cat(redc, greenc, bluec, dims=3)
return cat(redc, greenc, bluec; dims=3)
end


function _process_image_tiles(
true_color_image,
clouds_red,
Expand Down Expand Up @@ -156,7 +159,6 @@ function _process_image_tiles(
return rgbchannels
end


"""
conditional_histeq(
true_color_image,
Expand Down Expand Up @@ -192,7 +194,7 @@ function conditional_histeq(
white_threshold::AbstractFloat=25.5,
white_fraction_threshold::AbstractFloat=0.4,
)
tiles = get_tiles(true_color_image, rblocks=rblocks, cblocks=cblocks)
tiles = get_tiles(true_color_image; rblocks=rblocks, cblocks=cblocks)
rgbchannels_equalized = _process_image_tiles(
true_color_image,
clouds_red,
Expand All @@ -203,7 +205,6 @@ function conditional_histeq(
)

return rgbchannels_equalized

end

"""
Expand All @@ -227,7 +228,6 @@ function conditional_histeq(
white_threshold::AbstractFloat=25.5,
white_fraction_threshold::AbstractFloat=0.4,
)

side_length = IceFloeTracker.get_optimal_tile_size(side_length, size(true_color_image))

tiles = IceFloeTracker.get_tiles(true_color_image, side_length)
Expand All @@ -242,16 +242,16 @@ function conditional_histeq(
)

return rgbchannels_equalized

end

function _get_false_color_cloudmasked(; false_color_image,
function _get_false_color_cloudmasked(;
false_color_image,
prelim_threshold=110.0,
band_7_threshold=200.0,
band_2_threshold=190.0,
)
mask_cloud_ice, clouds_view = IceFloeTracker._get_masks(
false_color_image,
false_color_image;
prelim_threshold=prelim_threshold,
band_7_threshold=band_7_threshold,
band_2_threshold=band_2_threshold,
Expand Down
22 changes: 22 additions & 0 deletions test/test-brighten.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using IceFloeTracker: get_brighten_mask, imbrighten

@testset "brighten tests" begin
@testset "get_brighten_mask" begin
img = rand(0:255, 5, 5)
bumped_img = img .+ 1
mask = get_brighten_mask(img, bumped_img)
@test all(mask .== 0)
end

@testset "imbrighten tests" begin
img = [1 2; 3 4]
brighten_mask = [1 0; 1 0]

test_cases = [(1.25, [1 2; 4 4]), (0.1, [0 2; 0 4]), (0.9, img)]

for (bright_factor, expected_result) in test_cases
result = imbrighten(img, brighten_mask, bright_factor)
@test result == expected_result
end
end
end
Loading