Excluded "nearest" algorithm for benchmarking of "resizer" crate.

This commit is contained in:
Kirill Kuzminykh
2022-04-22 19:44:38 +03:00
parent d5d46066f4
commit 33d51a36bf
6 changed files with 109 additions and 21 deletions
+69 -6
View File
@@ -11,6 +11,7 @@ about resizing with respect to color space._
[CHANGELOG](https://github.com/Cykooz/fast_image_resize/blob/main/CHANGELOG.md)
Supported pixel formats and available optimisations:
- `U8` - one `u8` component per pixel:
- native Rust-code without forced SIMD
- SSE4.1 (partial)
@@ -35,6 +36,7 @@ Supported pixel formats and available optimisations:
## Benchmarks
Environment:
- CPU: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
- RAM: DDR4 3000 MHz
- Ubuntu 20.04 (linux 5.13)
@@ -44,10 +46,12 @@ Environment:
- `rustflags = ["-C", "llvm-args=-x86-branches-within-32B-boundaries"]`
Other Rust libraries used to compare of resizing speed:
- image = "0.24.1" (<https://crates.io/crates/image>)
- resize = "0.7.2" (<https://crates.io/crates/resize>)
Resize algorithms:
- Nearest
- Convolution with Bilinear filter
- Convolution with CatmullRom filter
@@ -76,7 +80,8 @@ Pipeline:
`src_image => multiply by alpha => resize => divide by alpha => dst_image`
- Source image [nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
- Source image
[nasa-4928x3279-rgba.png](https://github.com/Cykooz/fast_image_resize/blob/main/data/nasa-4928x3279-rgba.png)
- Numbers in table is mean duration of image resizing in milliseconds.
| | Nearest | Bilinear | CatmullRom | Lanczos3 |
@@ -125,7 +130,7 @@ Pipeline:
## Examples
### Resize image
### Resize RGBA8 image
```rust
use std::io::BufWriter;
@@ -137,8 +142,7 @@ use image::{ColorType, GenericImageView};
use fast_image_resize as fr;
#[test]
fn resize_image_example() {
fn main() {
// Read source image from file
let img = ImageReader::open("./data/nasa-4928x3279.png")
.unwrap()
@@ -151,8 +155,7 @@ fn resize_image_example() {
height,
img.to_rgba8().into_raw(),
fr::PixelType::U8x4,
)
.unwrap();
).unwrap();
// Create MulDiv instance
let alpha_mul_div = fr::MulDiv::default();
@@ -196,6 +199,66 @@ fn resize_image_example() {
}
```
### Resize with cropping
```rust
use std::io::BufWriter;
use std::num::NonZeroU32;
use image::codecs::png::PngEncoder;
use image::io::Reader as ImageReader;
use image::{ColorType, GenericImageView};
use fast_image_resize as fr;
fn resize_image_with_cropping(
mut src_view: fr::ImageView,
dst_width: NonZeroU32,
dst_height: NonZeroU32
) -> fr::Image {
// Set cropping parameters
src_view.set_crop_box_to_fit_dst_size(dst_width, dst_height, None);
// Create container for data of destination image
let mut dst_image = fr::Image::new(
dst_width,
dst_height,
src_view.pixel_type(),
);
// Get mutable view of destination image data
let mut dst_view = dst_image.view_mut();
// Create Resizer instance and resize source image
// into buffer of destination image
let mut resizer = fr::Resizer::new(
fr::ResizeAlg::Convolution(fr::FilterType::Lanczos3)
);
resizer.resize(&src_view, &mut dst_view).unwrap();
dst_image
}
fn main() {
let img = ImageReader::open("./data/nasa-4928x3279.png")
.unwrap()
.decode()
.unwrap();
let width = NonZeroU32::new(img.width()).unwrap();
let height = NonZeroU32::new(img.height()).unwrap();
let src_image = fr::Image::from_vec_u8(
width,
height,
img.to_rgb8().into_raw(),
fr::PixelType::U8x3,
).unwrap();
resize_image_with_cropping(
src_image.view(),
NonZeroU32::new(1024).unwrap(),
NonZeroU32::new(768).unwrap(),
);
}
```
### Change CPU extensions used by resizer
```rust, ignore
+5 -3
View File
@@ -12,9 +12,11 @@ const fn p(r: u8, g: u8, b: u8, a: u8) -> u32 {
// Multiplies by alpha
fn get_src_image(width: NonZeroU32, height: NonZeroU32, pixel: u32) -> Image<'static> {
let buf_size = (width.get() * height.get()) as usize;
let buffer = vec![pixel; buf_size];
Image::from_vec_u32(width, height, buffer, PixelType::U8x4).unwrap()
let pixels_count = (width.get() * height.get()) as usize;
let buffer = (0..pixels_count)
.flat_map(|_| pixel.to_le_bytes())
.collect();
Image::from_vec_u8(width, height, buffer, PixelType::U8x4).unwrap()
}
#[cfg(target_arch = "x86_64")]
+5 -1
View File
@@ -41,7 +41,11 @@ pub fn bench_downscale_rgb(bench: &mut Bench) {
let mut dst = vec![RGB::new(0, 0, 0); (new_width.get() * new_height.get()) as usize];
bench.task(format!("resize - {}", alg_name), |task| {
let filter = match alg_name {
"Nearest" => resize::Type::Point,
"Nearest" => {
// resizer doesn't support "nearest" algorithm
task.iter(|| {});
return;
}
"Bilinear" => resize::Type::Triangle,
"CatmullRom" => resize::Type::Catrom,
"Lanczos3" => resize::Type::Lanczos3,
+5 -1
View File
@@ -42,7 +42,11 @@ pub fn bench_downscale_rgb16(bench: &mut Bench) {
vec![RGB::new(0u16, 0u16, 0u16); (new_width.get() * new_height.get()) as usize];
bench.task(format!("resize - {}", alg_name), |task| {
let filter = match alg_name {
"Nearest" => resize::Type::Point,
"Nearest" => {
// resizer doesn't support "nearest" algorithm
task.iter(|| {});
return;
}
"Bilinear" => resize::Type::Triangle,
"CatmullRom" => resize::Type::Catrom,
"Lanczos3" => resize::Type::Lanczos3,
+20 -9
View File
@@ -41,7 +41,11 @@ pub fn bench_downscale_rgba(bench: &mut Bench) {
let mut dst = vec![RGBA::new(0, 0, 0, 0); (new_width.get() * new_height.get()) as usize];
bench.task(format!("resize - {}", alg_name), |task| {
let filter = match alg_name {
"Nearest" => resize::Type::Point,
"Nearest" => {
// resizer doesn't support "nearest" algorithm
task.iter(|| {});
return;
}
"Bilinear" => resize::Type::Triangle,
"CatmullRom" => resize::Type::Catrom,
"Lanczos3" => resize::Type::Lanczos3,
@@ -104,14 +108,21 @@ pub fn bench_downscale_rgba(bench: &mut Bench) {
}
bench.task(format!("fir {} - {}", ext_name, alg_name), |task| {
task.iter(|| {
mul_div
.multiply_alpha(&src_view, &mut premultiplied_src_image.view_mut())
.unwrap();
fast_resizer
.resize(&premultiplied_src_image.view(), &mut dst_view)
.unwrap();
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
task.iter(|| match resize_alg {
ResizeAlg::Nearest => {
fast_resizer
.resize(&premultiplied_src_image.view(), &mut dst_view)
.unwrap();
}
_ => {
mul_div
.multiply_alpha(&src_view, &mut premultiplied_src_image.view_mut())
.unwrap();
fast_resizer
.resize(&premultiplied_src_image.view(), &mut dst_view)
.unwrap();
mul_div.divide_alpha_inplace(&mut dst_view).unwrap();
}
})
});
}
+5 -1
View File
@@ -42,7 +42,11 @@ pub fn bench_downscale_u8(bench: &mut Bench) {
let mut dst = vec![Gray(0u8); (new_width.get() * new_height.get()) as usize];
bench.task(format!("resize - {}", alg_name), |task| {
let filter = match alg_name {
"Nearest" => resize::Type::Point,
"Nearest" => {
// resizer doesn't support "nearest" algorithm
task.iter(|| {});
return;
}
"Bilinear" => resize::Type::Triangle,
"CatmullRom" => resize::Type::Catrom,
"Lanczos3" => resize::Type::Lanczos3,