///|
pub fn edge_map(
image : GrayImage,
low : Double,
high : Double,
) -> EdgeMapSummary {
let magnitude = gradient_magnitude(image)
let edges = hysteresis_edges(image, low~, high~)
let strengths : Array[Double] = []
for y in 0.. EdgeMapSummary {
let magnitude = gradient_magnitude(image)
let edges = image_to_mask(magnitude, threshold)
let strengths : Array[Double] = []
for y in 0.. Array[Component] {
label_components(summary.edges)
}
///|
pub fn edge_map_largest(summary : EdgeMapSummary) -> Component {
largest_component(summary.edges)
}
///|
pub fn edge_map_skeleton(summary : EdgeMapSummary) -> BinaryMask {
let result = summary.edges.clone()
let changed = true
let mut iteration = 0
while changed && iteration < 20 {
iteration += 1
let mut changed_now = false
for y in 1..<(result.height - 1) {
for x in 1..<(result.width - 1) {
if result.at(x, y) {
let neighbors = count_true_neighbors(result, x, y, 1)
if neighbors >= 6 {
result.set(x, y, false)
changed_now = true
}
}
}
}
if !changed_now {
break
}
}
result
}
///|
pub fn count_true_neighbors(
mask : BinaryMask,
x : Int,
y : Int,
radius : Int,
) -> Int {
let mut result = 0
let safe = radius.max(0)
for dy in -safe..<=safe {
for dx in -safe..<=safe {
if (dx != 0 || dy != 0) && mask.at(x + dx, y + dy) {
result += 1
}
}
}
result
}
///|
pub fn edge_map_thin(summary : EdgeMapSummary) -> EdgeMapSummary {
let skeleton = edge_map_skeleton(summary)
{ ..summary, edges: skeleton, count: skeleton.count() }
}
///|
pub fn edge_map_dilate(
summary : EdgeMapSummary,
radius : Int,
) -> EdgeMapSummary {
let edges = summary.edges.dilate(radius)
{ ..summary, edges, count: edges.count() }
}
///|
pub fn edge_map_close(summary : EdgeMapSummary, radius : Int) -> EdgeMapSummary {
let edges = summary.edges.closing(radius)
{ ..summary, edges, count: edges.count() }
}
///|
pub fn edge_map_strengths(
summary : EdgeMapSummary,
magnitude : GrayImage,
) -> Array[Double] {
let result : Array[Double] = []
for y in 0.. Double {
clamp_double(summary.density * summary.mean_strength, 0.0, 1.0)
}
///|
pub fn edge_map_report(summary : EdgeMapSummary) -> String {
let out = StringBuilder()
out.write_string("count=")
out.write_string(summary.count.to_string())
out.write_string("; density=")
out.write_string(summary.density.to_string())
out.write_string("; mean_strength=")
out.write_string(summary.mean_strength.to_string())
out.to_string()
}
///|
pub fn edge_points(summary : EdgeMapSummary) -> Array[EdgePoint] {
let result : Array[EdgePoint] = []
for y in 0.. Line {
fit_line(edge_points(summary).map(fn(edge) { edge.point }))
}
///|
pub fn edge_map_circle_fit(summary : EdgeMapSummary) -> Circle {
let points = edge_points(summary)
if points.length() < 3 {
{ center: Point::Point(x=0.0, y=0.0), radius: 0.0, rms_error: 0.0 }
} else {
let selected : Array[Point] = [
points[0].point,
points[1].point,
points[2].point,
]
detect_circle_from_points(selected)
}
}
///|
pub fn edge_map_overlay(
image : GrayImage,
summary : EdgeMapSummary,
value : Double,
) -> GrayImage {
let result = image.copy()
for y in 0..