use crate::common::{RegParams, load_test_image};
use leptonica::PixelDepth;
use leptonica::io::ImageFormat;
use leptonica::morph::{
bottom_hat_gray, close_gray, dilate_gray, erode_gray, gray_morph_sequence, h_dome, open_gray,
top_hat_gray,
};
const WSIZE: u32 = 7;
const HSIZE: u32 = 7;
#[test]
fn graymorph1_reg() {
let mut rp = RegParams::new("graymorph1");
let pixs = load_test_image("aneurisms8.jpg").expect("load aneurisms8.jpg");
assert_eq!(
pixs.depth(),
PixelDepth::Bit8,
"Test image should be 8-bpp grayscale"
);
eprintln!(" Testing gray dilation vs sequence");
let pix1 = dilate_gray(&pixs, WSIZE, HSIZE).expect("dilate_gray");
rp.write_pix_and_check(&pix1, ImageFormat::Png)
.expect("check: dilate_gray");
let seq = format!("D{}.{}", WSIZE, HSIZE);
let pix2 = gray_morph_sequence(&pixs, &seq).expect("gray_morph_sequence D");
let same = pix1.equals(&pix2);
rp.compare_values(1.0, if same { 1.0 } else { 0.0 }, 0.0);
if !same {
eprintln!(
" DIFFER: dilate_gray vs gray_morph_sequence(\"{}\")",
seq
);
}
eprintln!(" Testing gray erosion vs sequence");
let pix1 = erode_gray(&pixs, WSIZE, HSIZE).expect("erode_gray");
rp.write_pix_and_check(&pix1, ImageFormat::Png)
.expect("check: erode_gray");
let seq = format!("E{}.{}", WSIZE, HSIZE);
let pix2 = gray_morph_sequence(&pixs, &seq).expect("gray_morph_sequence E");
let same = pix1.equals(&pix2);
rp.compare_values(1.0, if same { 1.0 } else { 0.0 }, 0.0);
if !same {
eprintln!(" DIFFER: erode_gray vs gray_morph_sequence(\"{}\")", seq);
}
eprintln!(" Testing gray opening vs sequence");
let pix1 = open_gray(&pixs, WSIZE, HSIZE).expect("open_gray");
rp.write_pix_and_check(&pix1, ImageFormat::Png)
.expect("check: open_gray");
let seq = format!("O{}.{}", WSIZE, HSIZE);
let pix2 = gray_morph_sequence(&pixs, &seq).expect("gray_morph_sequence O");
let same = pix1.equals(&pix2);
rp.compare_values(1.0, if same { 1.0 } else { 0.0 }, 0.0);
if !same {
eprintln!(" DIFFER: open_gray vs gray_morph_sequence(\"{}\")", seq);
}
eprintln!(" Testing gray closing vs sequence");
let pix1 = close_gray(&pixs, WSIZE, HSIZE).expect("close_gray");
rp.write_pix_and_check(&pix1, ImageFormat::Png)
.expect("check: close_gray");
let seq = format!("C{}.{}", WSIZE, HSIZE);
let pix2 = gray_morph_sequence(&pixs, &seq).expect("gray_morph_sequence C");
let same = pix1.equals(&pix2);
rp.compare_values(1.0, if same { 1.0 } else { 0.0 }, 0.0);
if !same {
eprintln!(" DIFFER: close_gray vs gray_morph_sequence(\"{}\")", seq);
}
eprintln!(" Testing white tophat vs sequence");
let pix1 = top_hat_gray(&pixs, WSIZE, HSIZE).expect("top_hat_gray");
rp.write_pix_and_check(&pix1, ImageFormat::Png)
.expect("check: top_hat_gray");
let seq = format!("Tw{}.{}", WSIZE, HSIZE);
let pix2 = gray_morph_sequence(&pixs, &seq).expect("gray_morph_sequence Tw");
let same = pix1.equals(&pix2);
rp.compare_values(1.0, if same { 1.0 } else { 0.0 }, 0.0);
if !same {
eprintln!(
" DIFFER: top_hat_gray vs gray_morph_sequence(\"{}\")",
seq
);
}
eprintln!(" Testing black tophat vs sequence");
let pix1 = bottom_hat_gray(&pixs, WSIZE, HSIZE).expect("bottom_hat_gray");
rp.write_pix_and_check(&pix1, ImageFormat::Png)
.expect("check: bottom_hat_gray");
let seq = format!("Tb{}.{}", WSIZE, HSIZE);
let pix2 = gray_morph_sequence(&pixs, &seq).expect("gray_morph_sequence Tb");
let same = pix1.equals(&pix2);
rp.compare_values(1.0, if same { 1.0 } else { 0.0 }, 0.0);
if !same {
eprintln!(
" DIFFER: bottom_hat_gray vs gray_morph_sequence(\"{}\")",
seq
);
}
eprintln!(" Testing erode/dilate duality");
let pix1 = dilate_gray(&pixs, WSIZE, HSIZE).expect("dilate_gray");
let pix2 = pixs.invert();
let pix3 = erode_gray(&pix2, WSIZE, HSIZE).expect("erode_gray on inverted");
let pix3_inv = pix3.invert();
let same = pix1.equals(&pix3_inv);
rp.compare_values(1.0, if same { 1.0 } else { 0.0 }, 0.0);
if !same {
eprintln!(" DIFFER: dilate != invert(erode(invert))");
}
eprintln!(" Testing open/close duality");
let pix1 = open_gray(&pixs, WSIZE, HSIZE).expect("open_gray");
let pix2 = pixs.invert();
let pix3 = close_gray(&pix2, WSIZE, HSIZE).expect("close_gray on inverted");
let pix3_inv = pix3.invert();
let same = pix1.equals(&pix3_inv);
rp.compare_values(1.0, if same { 1.0 } else { 0.0 }, 0.0);
if !same {
eprintln!(" DIFFER: open != invert(close(invert))");
}
eprintln!(" Testing tophat duality");
let pix1 = top_hat_gray(&pixs, WSIZE, HSIZE).expect("top_hat white");
let pix2 = pixs.invert();
let pix3 = bottom_hat_gray(&pix2, WSIZE, HSIZE).expect("bottom_hat on inverted");
let same = pix1.equals(&pix3);
rp.compare_values(1.0, if same { 1.0 } else { 0.0 }, 0.0);
if !same {
eprintln!(" DIFFER: white_tophat(pixs) != black_tophat(invert(pixs))");
}
eprintln!(" Testing tophat duality via sequence");
let pix1 = gray_morph_sequence(&pixs, "Tw9.5").expect("Tw9.5");
let pix2 = pixs.invert();
let pix3 = gray_morph_sequence(&pix2, "Tb9.5").expect("Tb9.5");
let same = pix1.equals(&pix3);
rp.compare_values(1.0, if same { 1.0 } else { 0.0 }, 0.0);
if !same {
eprintln!(" DIFFER: Tw9.5 != Tb9.5(inverted)");
}
eprintln!(" Testing large sel sequences");
let pix1 = gray_morph_sequence(&pixs, "C9.9 + C19.19 + C29.29 + C39.39 + C49.49")
.expect("close sequence");
assert_eq!(pix1.depth(), PixelDepth::Bit8);
rp.write_pix_and_check(&pix1, ImageFormat::Png)
.expect("check: large close sequence");
let pix1 = gray_morph_sequence(&pixs, "O9.9 + O19.19 + O29.29 + O39.39 + O49.49")
.expect("open sequence");
assert_eq!(pix1.depth(), PixelDepth::Bit8);
rp.write_pix_and_check(&pix1, ImageFormat::Png)
.expect("check: large open sequence");
eprintln!(" Testing closing + white tophat");
let pix_closed = close_gray(&pixs, 9, 9).expect("close_gray 9x9");
let pix_tophat = top_hat_gray(&pix_closed, 9, 9).expect("tophat on closed");
let pix_seq = gray_morph_sequence(&pixs, "C9.9 + Tw9.9").expect("C9.9+Tw9.9");
let same = pix_tophat.equals(&pix_seq);
rp.compare_values(1.0, if same { 1.0 } else { 0.0 }, 0.0);
if !same {
eprintln!(" DIFFER: close+tophat vs sequence C9.9+Tw9.9");
}
let pix_closed = close_gray(&pixs, 29, 29).expect("close_gray 29x29");
let pix_tophat = top_hat_gray(&pix_closed, 29, 29).expect("tophat on closed 29");
let pix_seq = gray_morph_sequence(&pixs, "C29.29 + Tw29.29").expect("C29.29+Tw29.29");
let same = pix_tophat.equals(&pix_seq);
rp.compare_values(1.0, if same { 1.0 } else { 0.0 }, 0.0);
if !same {
eprintln!(" DIFFER: close+tophat vs sequence C29.29+Tw29.29");
}
eprintln!(" Testing h_dome");
let pix_hdome = h_dome(&pixs, 100, 4).expect("h_dome");
assert_eq!(pix_hdome.depth(), PixelDepth::Bit8);
rp.write_pix_and_check(&pix_hdome, ImageFormat::Png)
.expect("check: h_dome");
eprintln!();
assert!(rp.cleanup(), "graymorph1 regression test failed");
}
#[test]
#[ignore = "not yet implemented: pixMaxDynamicRange / pixInitAccumulate / Pixacc not available"]
fn graymorph1_reg_contrast_enhancement() {
}
#[test]
#[ignore = "not yet implemented: pixRemoveColormap / pixConvertRGBToGray / pixGammaTRC not available"]
fn graymorph1_reg_feynman_stamp() {
}