image_compare/
colorization.rs1use image::{DynamicImage, GrayImage, ImageBuffer, Luma, Rgb, RgbImage, Rgba, RgbaImage};
2
3pub type GraySimilarityImage = ImageBuffer<Luma<f32>, Vec<f32>>;
5pub type RGBSimilarityImage = ImageBuffer<Rgb<f32>, Vec<f32>>;
7pub type RGBASimilarityImage = ImageBuffer<Rgba<f32>, Vec<f32>>;
9
10#[derive(Debug)]
11#[allow(clippy::upper_case_acronyms)]
12pub enum SimilarityImage {
13 Gray(GraySimilarityImage),
14 RGB(RGBSimilarityImage),
15 RGBA(RGBASimilarityImage),
16}
17
18impl From<GraySimilarityImage> for SimilarityImage {
19 fn from(value: GraySimilarityImage) -> Self {
20 SimilarityImage::Gray(value)
21 }
22}
23impl From<RGBASimilarityImage> for SimilarityImage {
24 fn from(value: RGBASimilarityImage) -> Self {
25 SimilarityImage::RGBA(value)
26 }
27}
28impl From<RGBSimilarityImage> for SimilarityImage {
29 fn from(value: RGBSimilarityImage) -> Self {
30 SimilarityImage::RGB(value)
31 }
32}
33
34fn gray_map(img: &GraySimilarityImage) -> DynamicImage {
35 let mut img_gray = GrayImage::new(img.width(), img.height());
36 for row in 0..img.height() {
37 for col in 0..img.width() {
38 let new_val = img.get_pixel(col, row)[0].clamp(0., 1.) * 255.;
39 img_gray.put_pixel(col, row, Luma([new_val as u8]));
40 }
41 }
42 img_gray.into()
43}
44
45fn to_color_map(img: &RGBSimilarityImage) -> DynamicImage {
46 let mut img_rgb = RgbImage::new(img.width(), img.height());
47 for row in 0..img.height() {
48 for col in 0..img.width() {
49 let pixel = img.get_pixel(col, row);
50 let mut new_pixel = [0u8; 3];
51 for channel in 0..3 {
52 new_pixel[channel] = (pixel[channel].clamp(0., 1.) * 255.) as u8;
53 }
54 img_rgb.put_pixel(col, row, Rgb(new_pixel));
55 }
56 }
57 img_rgb.into()
58}
59
60fn to_color_map_rgba(img: &RGBASimilarityImage) -> DynamicImage {
61 let mut img_rgba = RgbaImage::new(img.width(), img.height());
62 for row in 0..img.height() {
63 for col in 0..img.width() {
64 let pixel = img.get_pixel(col, row);
65 let mut new_pixel = [0u8; 4];
66 for channel in 0..4 {
67 new_pixel[channel] = (pixel[channel].clamp(0., 1.) * 255.) as u8;
68 }
69 img_rgba.put_pixel(col, row, Rgba(new_pixel));
70 }
71 }
72 img_rgba.into()
73}
74
75impl SimilarityImage {
76 pub fn to_color_map(&self) -> DynamicImage {
77 match self {
78 SimilarityImage::Gray(gray) => gray_map(gray),
79 SimilarityImage::RGB(rgb) => to_color_map(rgb),
80 SimilarityImage::RGBA(rgba) => to_color_map_rgba(rgba),
81 }
82 }
83}
84
85#[derive(Debug)]
86pub struct Similarity {
88 pub image: SimilarityImage,
94 pub score: f64,
96}