Skip to content

Commit

Permalink
Merge branch 'master' into feature/filter-parallel
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/filter/mod.rs
#	src/filter/sharpen.rs
#	src/gradients.rs
#	src/seam_carving.rs
  • Loading branch information
sunsided committed May 19, 2024
2 parents 7286863 + 092c3f1 commit dd4d1c3
Show file tree
Hide file tree
Showing 13 changed files with 634 additions and 726 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "imageproc"
version = "0.25.0"
version = "0.26.0"
authors = ["theotherphil"]
# note: when changed, also update `msrv` in `.github/workflows/check.yml`
rust-version = "1.70.0"
Expand Down
110 changes: 52 additions & 58 deletions examples/gradients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,37 @@
//!
//! `cargo run --example gradients ./examples/empire-state-building.jpg ./tmp`
use image::{open, GrayImage, Luma};
use image::{open, GrayImage};
#[cfg(not(feature = "rayon"))]
use imageproc::filter::filter_clamped;
#[cfg(feature = "rayon")]
use imageproc::filter::filter_clamped_parallel as filter_clamped;
use imageproc::{
definitions::Image,
gradients::{
horizontal_prewitt, horizontal_scharr, horizontal_sobel, vertical_prewitt, vertical_scharr,
vertical_sobel,
},
map::map_pixels,
kernel::{self, Kernel},
map::map_subpixels,
};
use std::{env, fs, path::Path};

fn compute_gradients<F>(
fn save_gradients(
input: &GrayImage,
gradient_func: F,
horizontal_kernel: Kernel<i32>,
vertical_kernel: Kernel<i32>,
output_dir: &Path,
file_name: &str,
name: &str,
scale: i16,
) where
F: Fn(&GrayImage) -> Image<Luma<i16>>,
{
let gradient = gradient_func(input);
let gradient = map_pixels(&gradient, |_, _, p| Luma([(p[0].abs() / scale) as u8]));
gradient.save(&output_dir.join(file_name)).unwrap();
) {
let horizontal_gradients = filter_clamped(input, horizontal_kernel);
let vertical_gradients = filter_clamped(input, vertical_kernel);

let horizontal_scaled = map_subpixels(&horizontal_gradients, |p: i16| (p.abs() / scale) as u8);
let vertical_scaled = map_subpixels(&vertical_gradients, |p: i16| (p.abs() / scale) as u8);

horizontal_scaled
.save(&output_dir.join(format!("{name}_horizontal.png")))
.unwrap();
vertical_scaled
.save(&output_dir.join(format!("{name}_vertical.png")))
.unwrap();
}

fn main() {
Expand Down Expand Up @@ -57,46 +65,32 @@ fn main() {
let gray_path = output_dir.join("grey.png");
input_image.save(&gray_path).unwrap();

compute_gradients(
&input_image,
horizontal_scharr,
output_dir,
"horizontal_scharr.png",
32,
);
compute_gradients(
&input_image,
vertical_scharr,
output_dir,
"vertical_scharr.png",
32,
);
compute_gradients(
&input_image,
horizontal_sobel,
output_dir,
"horizontal_sobel.png",
8,
);
compute_gradients(
&input_image,
vertical_sobel,
output_dir,
"vertical_sobel.png",
8,
);
compute_gradients(
&input_image,
horizontal_prewitt,
output_dir,
"horizontal_prewitt.png",
6,
);
compute_gradients(
&input_image,
vertical_prewitt,
output_dir,
"vertical_prewitt.png",
6,
);
for (name, horizontal, vertical, scale) in [
(
"sobel",
kernel::SOBEL_HORIZONTAL_3X3,
kernel::SOBEL_VERTICAL_3X3,
32,
),
(
"scharr",
kernel::SCHARR_HORIZONTAL_3X3,
kernel::SCHARR_VERTICAL_3X3,
8,
),
(
"prewitt",
kernel::PREWITT_HORIZONTAL_3X3,
kernel::PREWITT_VERTICAL_3X3,
6,
),
(
"roberts",
kernel::ROBERTS_HORIZONTAL_2X2,
kernel::ROBERTS_VERTICAL_2X2,
4,
),
] {
save_gradients(&input_image, horizontal, vertical, output_dir, name, scale);
}
}
16 changes: 11 additions & 5 deletions examples/seam_carving.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use image::{open, GrayImage, Luma, Pixel};
use imageproc::definitions::Clamp;
use imageproc::gradients::sobel_gradient_map;
use imageproc::gradients::gradients;
use imageproc::kernel;
use imageproc::map::map_colors;
use imageproc::seam_carving::*;
use std::env;
Expand Down Expand Up @@ -59,10 +60,15 @@ fn main() {
annotated.save(&annotated_path).unwrap();

// Draw the seams on the gradient magnitude image.
let gradients = sobel_gradient_map(&input_image, |p| {
let mean = (p[0] + p[1] + p[2]) / 3;
Luma([mean as u32])
});
let gradients = gradients(
&input_image,
kernel::SOBEL_HORIZONTAL_3X3,
kernel::SOBEL_VERTICAL_3X3,
|p| {
let mean = (p[0] + p[1] + p[2]) / 3;
Luma([mean as u32])
},
);
let clamped_gradients: GrayImage = map_colors(&gradients, |p| Luma([Clamp::clamp(p[0])]));
let annotated_gradients = draw_vertical_seams(&clamped_gradients, &seams);
let gradients_path = output_dir.join("gradients.png");
Expand Down
8 changes: 4 additions & 4 deletions src/edges.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Functions for detecting edges in images.
use crate::definitions::{HasBlack, HasWhite};
use crate::filter::gaussian_blur_f32;
use crate::gradients::{horizontal_sobel, vertical_sobel};
use crate::filter::{filter_clamped, gaussian_blur_f32};
use crate::kernel::{self};
use image::{GenericImageView, GrayImage, ImageBuffer, Luma};
use std::f32;

Expand Down Expand Up @@ -35,8 +35,8 @@ pub fn canny(image: &GrayImage, low_threshold: f32, high_threshold: f32) -> Gray
let blurred = gaussian_blur_f32(image, SIGMA);

// 2. Intensity of gradients.
let gx = horizontal_sobel(&blurred);
let gy = vertical_sobel(&blurred);
let gx = filter_clamped(&blurred, kernel::SOBEL_HORIZONTAL_3X3);
let gy = filter_clamped(&blurred, kernel::SOBEL_VERTICAL_3X3);
let g: Vec<f32> = gx
.iter()
.zip(gy.iter())
Expand Down
Loading

0 comments on commit dd4d1c3

Please sign in to comment.