///|
pub fn integral_image(image : GrayImage) -> GrayImage {
let result = GrayImage(width=image.width, height=image.height)
for y in 0.. Double {
let right = integral.at(bounds.max_x, bounds.max_y)
let left = integral.at(bounds.min_x - 1, bounds.max_y)
let top = integral.at(bounds.max_x, bounds.min_y - 1)
let corner = integral.at(bounds.min_x - 1, bounds.min_y - 1)
right - left - top + corner
}
///|
pub fn local_mean_image(image : GrayImage, radius : Int) -> GrayImage {
let integral = integral_image(image)
let result = GrayImage(width=image.width, height=image.height)
let safe = radius.max(0)
for y in 0.. GrayImage {
let squared = GrayImage(width=image.width, height=image.height)
for i in 0.. Double {
let histogram_value = histogram(image, bins)
let total = image.pixels.length()
if total == 0 {
0.0
} else {
let mut result = 0.0
for bin in histogram_value.bins {
if bin > 0 {
let probability = Double::from_int(bin) / Double::from_int(total)
result -= probability * @math.ln(probability)
}
}
result
}
}
///|
pub fn percentile_threshold(image : GrayImage, q : Double) -> Double {
percentile_value(image.pixels, q)
}
///|
pub fn adaptive_threshold(
image : GrayImage,
radius : Int,
offset : Double,
) -> BinaryMask {
let local_mean = local_mean_image(image, radius)
let result = BinaryMask(width=image.width, height=image.height)
for y in 0..= local_mean.at(x, y) - offset)
}
}
result
}
///|
pub fn local_contrast_normalized(image : GrayImage, radius : Int) -> GrayImage {
let mean = local_mean_image(image, radius)
let variance = local_variance_image(image, radius)
let result = GrayImage(width=image.width, height=image.height)
for y in 0.. Array[StatsSummary] {
let result : Array[StatsSummary] = []
for y in 0.. Array[StatsSummary] {
let result : Array[StatsSummary] = []
for x in 0.. Double {
let bounds = image_minmax(image)
bounds.max - bounds.min
}
///|
pub fn image_median(image : GrayImage) -> Double {
median_value(image.pixels)
}
///|
pub fn image_mad(image : GrayImage) -> Double {
mean_absolute_deviation(image.pixels)
}
///|
pub fn image_signal_to_noise(image : GrayImage, background : Double) -> Double {
let signal = (image_mean(image) - background).abs()
let noise = texture_noise(image)
if noise <= 0.0000001 {
signal
} else {
signal / noise
}
}
///|
pub fn image_range_report(image : GrayImage) -> String {
let bounds = image_minmax(image)
"min=" +
bounds.min.to_string() +
"; max=" +
bounds.max.to_string() +
"; range=" +
(bounds.max - bounds.min).to_string()
}