///|
pub fn blank_fixture(width : Int, height : Int, value : Double) -> GrayImage {
GrayImage::GrayImage(width~, height~, fill=value)
}
///|
pub fn rectangle_fixture(
width : Int,
height : Int,
left : Int,
top : Int,
right : Int,
bottom : Int,
background : Double,
foreground : Double,
) -> GrayImage {
let image = blank_fixture(width, height, background)
for y in top.max(0)..<(bottom + 1).min(height) {
for x in left.max(0)..<(right + 1).min(width) {
image.set(x, y, foreground)
}
}
image
}
///|
pub fn bracket_fixture() -> GrayImage {
let image = rectangle_fixture(160, 96, 32, 18, 126, 76, 0.05, 0.82)
for y in 30..<64 {
for x in 56..<104 {
image.set(x, y, 0.05)
}
}
for y in 18..<77 {
image.set(32, y, 1.0)
image.set(126, y, 1.0)
}
image
}
///|
pub fn slot_fixture(
width : Int,
height : Int,
center : Point,
slot_width : Double,
slot_height : Double,
) -> GrayImage {
let image = blank_fixture(width, height, 0.08)
let left = (center.x - slot_width / 2.0).floor().to_int()
let right = (center.x + slot_width / 2.0).ceil().to_int()
let top = (center.y - slot_height / 2.0).floor().to_int()
let bottom = (center.y + slot_height / 2.0).ceil().to_int()
for y in top.max(0)..<(bottom + 1).min(height) {
for x in left.max(0)..<(right + 1).min(width) {
image.set(x, y, 0.9)
}
}
image
}
///|
pub fn circle_fixture(
width : Int,
height : Int,
center : Point,
radius : Double,
background : Double,
foreground : Double,
) -> GrayImage {
let image = blank_fixture(width, height, background)
let radius_squared = radius * radius
for y in 0.. GrayImage {
let image = blank_fixture(width, height, 0.05)
let inner_squared = inner_radius * inner_radius
let outer_squared = outer_radius * outer_radius
for y in 0..= inner_squared && squared <= outer_squared {
image.set(x, y, 0.9)
}
}
}
image
}
///|
pub fn diagonal_edge_fixture(
width : Int,
height : Int,
slope : Double,
intercept : Double,
) -> GrayImage {
let image = blank_fixture(width, height, 0.05)
for y in 0..= boundary {
image.set(x, y, 0.9)
}
}
}
image
}
///|
pub fn noisy_fixture(
image : GrayImage,
amplitude : Double,
seed : Int,
) -> GrayImage {
let result = image.copy()
let mut state = seed.abs() + 1
for i in 0.. GrayImage {
let image = blank_fixture(width, height, 0.05)
let inverse = AffineTransform::rotation(-angle)
for y in 0.. GrayImage {
let image = blank_fixture(width, height, 0.0)
let safe_cell = cell.max(1)
for y in 0.. GrayImage {
let image = blank_fixture(width, height, 0.0)
for y in 0.. GrayImage {
let image = blank_fixture(192, 128, 0.04)
let first = circle_fixture(
192,
128,
Point::Point(x=48.0, y=64.0),
24.0,
0.04,
0.92,
)
let second = rectangle_fixture(192, 128, 108, 36, 164, 92, 0.04, 0.78)
for y in 0.. 0.5 || second.at(x, y) > 0.5 {
image.set(x, y, first.at(x, y).max(second.at(x, y)))
}
}
}
image
}
///|
pub fn profile_fixture(
length : Int,
first_edge : Int,
second_edge : Int,
low : Double,
high : Double,
) -> Array[ProfileSample] {
let result : Array[ProfileSample] = []
let safe_length = length.max(2)
for i in 0.. Array[Point] {
let result : Array[Point] = []
for y in 0.. Measurement {
let pixels = gauge_width(image, start, finish)
let scale = calibration_from_reference(pixels, nominal)
analyze_gap(
"fixture-width",
pixels,
scale,
Tolerance::Tolerance(nominal~, lower=nominal * 0.99, upper=nominal * 1.01),
)
}
///|
pub fn fixture_checksum_suite() -> Array[Double] {
[
image_checksum(bracket_fixture()),
image_checksum(
circle_fixture(64, 64, Point::Point(x=32.0, y=32.0), 16.0, 0.0, 1.0),
),
image_checksum(
ring_fixture(64, 64, Point::Point(x=32.0, y=32.0), 12.0, 20.0),
),
image_checksum(diagonal_edge_fixture(64, 64, 1.0, -10.0)),
]
}
///|
pub fn make_benchmark_image(width : Int, height : Int) -> GrayImage {
noisy_fixture(multi_part_fixture(), 0.015, width + height)
}