Face detection library for the Rust programming language

Overview

Rustface


SeetaFace detection library for the Rust programming language

Bt Example Example of demo program output

crates.io docs.rs Linux build License

About

SeetaFace Detection is an implementation of Funnel-Structured cascade, which is designed for real-time multi-view face detection. FuSt aims at a good trade-off between accuracy and speed by using a coarse-to-fine structure. It consists of multiple view-specific fast LAB cascade classifiers at early stages, followed by coarse Multilayer Perceptron (MLP) cascades at later stages. The final stage is one unified fine MLP cascade, processing all proposed windows in a centralized style.

Read more...

Performance

You can run the criterion benchmarks using cargo bench.

Using nightly Rust

The nightly branch contains a slightly (~20%) faster version of rustface. This speedup is made possible by using explicit SIMD intrinsics. If you want to use this branch, you need an older nightly toolchain.

rustup toolchain install nightly-2018-01-15
rustup default nightly-2018-01-15

Regarding the performance of the nightly branch: crude manual benchmarking showed that this nightly Rust version of SeetaFace is slightly faster than the original C++ version. In this particular test the Rust version has been 4% faster on average than its C++ counterpart. When using multiple threads and enabling LTO (link-time optimization), Rust performance is a tad better (I observe a 8% boost):

Multi-threaded (Rayon threads set to 2)
LTO enabled

* Rustface *
samples (ms): 787,789,795,795,787,785,791,799,795,788
mean (ms): 791.1
stddev (ms): 4.39

Usage example

extern crate rustface;

use rustface::{Detector, FaceInfo, ImageData};

fn main() {
    let mut detector = rustface::create_detector("/path/to/model").unwrap();
    detector.set_min_face_size(20);
    detector.set_score_thresh(2.0);
    detector.set_pyramid_scale_factor(0.8);
    detector.set_slide_window_step(4, 4);
    
    let mut image = ImageData::new(bytes, width, height);
    for face in detector.detect(&mut image).into_iter() {
        // print confidence score and coordinates
        println!("found face: {:?}", face);
    }
}

How to build

The project is a library crate and also contains a runnable example for demonstration purposes.

Then just use the standard Cargo build command:

cargo build --release

Run demo

Code for the demo is located in examples/image_demo.rs file. It performs face detection for a given image and saves the result into a file in the working directory.

The simplest way to run the demo is to use the bin/test.sh script:

./bin/test.sh <path-to-image>

Please note that this library makes use of Rayon framework to parallelize some computations. By default, Rayon spawns the same number of threads as the number of CPUs (logicals cores) available. Instead of making things faster, the penalty of switching between so many threads may severely hurt the performance, so it's strongly advised to keep the number of threads small by manually setting RAYON_NUM_THREADS environment variable.

# empirically found to be the sweet spot for the number of threads
export RAYON_NUM_THREADS=2
cargo run --release --example image_demo model/seeta_fd_frontal_v1.0.bin <path-to-image>

Note that Rayon can be disabled entirely at compile time by providing the --no-default-features flag.

TODO

  • Use stable SIMD intrinsics when available
  • Benchmark benefit of parallelisation. Compiler improvements may have reduced the relative benefit of parallel processing, especially when running on smaller images. Simplify where possible.
  • Parallelize remaining CPU intensive loops
  • Tests (it would make sense to start with an integration test for Detector::detect, based on the results retrieved from the original library)

Authors

  • Andrei Tomashpolskiy @atomashpolskiy

    Original developer and maintainer

  • Jurriaan BW @jjhbw

    Contributor and chief maintainer

  • Ashley @expenses

    Contributor. Added the switch from OpenCV to Image.

This library is based on the following works:

  • Face detection method described in the paper: "Funnel-structured cascade for multi-view face detection with alignment awareness, Shuzhe Wu, Meina Kan, Zhenliang He, Shiguang Shan, Xilin Chen. In Neurocomputing (under review)"

  • original C++ implementation

License

Original SeetaFace Detection is released under the BSD 2-Clause license. This project is a derivative work and uses the same license as the original.

Comments
  • Error detect image

    Error detect image

    I'm testing using the example, but I get an error, this is the code, what am I doing wrong?

    fn detect_faces(path: &String) {
        let image: DynamicImage = match image::open(path) {
            Ok(image) => image,
            Err(message) => {
                println!("Failed to read image: {}", message);
                std::process::exit(1)
            }
        };
    
        let img_luma = &image.to_luma8();
        let (width, height) = img_luma.dimensions();
    
        let mut detector =
            rustface::create_detector("./files/model/seeta_fd_frontal_v1.0.bin").unwrap();
        detector.set_min_face_size(20);
        detector.set_score_thresh(2.0);
        detector.set_pyramid_scale_factor(0.8);
        detector.set_slide_window_step(4, 4);
    
        let mut image_data = ImageData::new(&img_luma, width, height);
    
        let faces = detector.detect(&mut image_data);
    
        //println!("faces {:?}", faces); //<- This generate error 
    
        println!("Found {} faces in", faces.len()); //<- This generate error 
    
    } 
    

    Call function

     detect_faces("./files/images/scientists.jpg");
    

    Error

    thread '<unnamed>' panicked at 'attempt to subtract with overflow', /home/benjamin/.cargo/registry/src/github.com-1ecc6299db9ec823/rustface-0.1.6/src/math/mod.rs:48:27
    stack backtrace:
       0:     0x55562010ddf0 - std::backtrace_rs::backtrace::libunwind::trace::h72c2fb8038f1bbee
                                   at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/../../backtrace/src/backtrace/libunwind.rs:96
       1:     0x55562010ddf0 - std::backtrace_rs::backtrace::trace_unsynchronized::h1e3b084883f1e78c
                                   at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/../../backtrace/src/backtrace/mod.rs:66
       2:     0x55562010ddf0 - std::sys_common::backtrace::_print_fmt::h3bf6a7ebf7f0394a
                                   at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/sys_common/backtrace.rs:79
       3:     0x55562010ddf0 - <std::sys_common::backtrace::_print::DisplayBacktrace as 
    
    ....
    

    Note Update the example code

    opened by benjamingb 6
  • Moving to stable rustc 1.28

    Moving to stable rustc 1.28

    Hi Andrei,

    Following up on #8 , I made a little bit of progress.

    Bad news: the faster crate is still unstable. While it would have been very useful, having to stay on nightly is a bit of a dealbreaker for me. If I want SIMD, I'm afraid it needs to be explicit for now.

    First I wanted to investigate whether explicit SIMD is still worth it with all the compiler improvements that were introduced since rustc 1.25 nightly (latest version on which the rustface master branch works, according to Travis).

    To get a quick-and-dirty answer to this question, I did the following:

    • I cut out all code that was incompatible with rustc 1.28.0 stable (that is: mostly reverting to your portable implementations of the vector math, and removing their counterparts that used explicit SIMD). See the only_stable_features branch.
    • I spun up a n1-standard-4 (4 vCPUs, 15 GB memory) in GCP.
    • I built the binaries of the image_demo example for master using rustc 1.25 nightly, and for my only_stable_features branch using rustc 1.28 stable.
    • I simply compared the runtime of these binaries from the command line, also testing the impact of the number of available Rayon threads. Note that this includes the execution time of importing the model and test image.

    This yielded the following results:

    | Command | Mean [ms] | Min…Max [ms] | | :----------------------------------------------------------- | ------------: | ------------: | | RAYON_NUM_THREADS=1 ./image_demo_master_nightly_1.25.0 model/seeta_fd_frontal_v1.0.bin assets/test/scientists.jpg | 1238.2 ± 85.0 | 1136.6…1374.6 | | RAYON_NUM_THREADS=1 ./image_demo_stable_1.28.0 model/seeta_fd_frontal_v1.0.bin assets/test/scientists.jpg | 1440.8 ± 81.5 | 1322.2…1581.9 | | RAYON_NUM_THREADS=2 ./image_demo_master_nightly_1.25.0 model/seeta_fd_frontal_v1.0.bin assets/test/scientists.jpg | 1242.0 ± 34.2 | 1198.7…1344.9 | | RAYON_NUM_THREADS=2 ./image_demo_stable_1.28.0 model/seeta_fd_frontal_v1.0.bin assets/test/scientists.jpg | 1301.2 ± 15.4 | 1273.5…1323.7 | | RAYON_NUM_THREADS=3 ./image_demo_master_nightly_1.25.0 model/seeta_fd_frontal_v1.0.bin assets/test/scientists.jpg | 1278.0 ± 16.4 | 1246.8…1311.2 | | RAYON_NUM_THREADS=3 ./image_demo_stable_1.28.0 model/seeta_fd_frontal_v1.0.bin assets/test/scientists.jpg | 1328.4 ± 13.4 | 1309.0…1354.5 |

    In words, that means: 'RAYON_NUM_THREADS=1 ./image_demo_master_nightly_1.25.0' ran 1.00x faster than 'RAYON_NUM_THREADS=2 ./image_demo_master_nightly_1.25.0' 1.03x faster than 'RAYON_NUM_THREADS=3 ./image_demo_master_nightly_1.25.0' 1.05x faster than 'RAYON_NUM_THREADS=2 ./image_demo_stable_1.28.0' 1.07x faster than 'RAYON_NUM_THREADS=3 ./image_demo_stable_1.28.0' 1.16x faster than 'RAYON_NUM_THREADS=1 ./image_demo_stable_1.28.0'

    I guess this means master is still about ~20% faster than the 1.28 version without explicit SIMD, as could be expected. Adding more Rayon threads to 1.28 seems to compensate the difference a little bit.

    As a side investigation, I also checked whether recent improvements in autovectorization may have obsoleted the need for some of your unsafe portable vector math functions. As expected, your functions are still the fastest:

    The square function:

    square

    The abs function: abs

    Exact code used for all the above benchmarks can be found in the README of only_stable_features.

    Merging only_stable_features would offer a quick-and-dirty way to become compatible with stable rust, but at the cost of a performance hit. For my use case, the perf hit is fine, but you may not like it for the main lib.

    As mentioned in https://github.com/atomashpolskiy/rustface/issues/7#issuecomment-399665596, the new stable SIMD intrinsics may help, depending on how complete they are. I can give refactoring a try when I find the time.

    Let me know what you think.

    opened by jjhbw 5
  • Cannot install rustface even when using nightly Rust

    Cannot install rustface even when using nightly Rust

    Hi,

    I am using the nightly build of Rust:

    rustup 1.11.0 (e751ff9f8 2018-02-13)
    rustc 1.28.0-nightly (f28c7aef7 2018-06-19)
    cargo 1.28.0-nightly (e2348c2db 2018-06-07)
    

    but when I try to install rustface, I get this error:

    232 | #[target_feature = "+tbm"]
        | ^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    error: #[target_feature] attribute must be of the form #[target_feature(..)]
       --> /Users/Radu.Cioienaru/.cargo/registry/src/github.com-1ecc6299db9ec823/stdsimd-0.0.3/src/x86/tbm.rs:244:1
        |
    244 | #[target_feature = "+tbm"]
        | ^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    error: #[target_feature] attribute must be of the form #[target_feature(..)]
       --> /Users/Radu.Cioienaru/.cargo/registry/src/github.com-1ecc6299db9ec823/stdsimd-0.0.3/src/x86/tbm.rs:255:1
        |
    255 | #[target_feature = "+tbm"]
        | ^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    error: aborting due to 750 previous errors
    
    error: Could not compile `stdsimd`.
    warning: build failed, waiting for other jobs to finish...
    error: failed to compile `rustface v0.1.0`, intermediate artifacts can be found at `/var/folders/pz/45htc8zn6_sbd3411btr4pq40000gp/T/cargo-installGrNVuk
    
    opened by rococtz 5
  • Attempt to subtract with overflow error

    Attempt to subtract with overflow error

    Hey, I'm getting a Attempt to subtract with overflow error on some images.

    One such file is attached below.

    Code:

    
    const MODEL_SEETA_FD_FRONTAL: &'static [u8] = include_bytes!("./seeta_fd_frontal_v1.0.bin");
    
    
    fn face_detector() -> Box<rustface::Detector> {
        let model = rustface::read_model(MODEL_SEETA_FD_FRONTAL.to_vec()).unwrap();
        rustface::create_detector_with_model(model)
    }
    
    pub fn face_detect<P>(
        path: P
    ) -> Result<Option<image::DynamicImage>, failure::Error>
        where P: AsRef<std::path::Path>
    {
        use image::Pixel;
    
        let path = path.as_ref();
    
        let mut detector = face_detector();
    
        // Load the image.
        let mut image: image::DynamicImage = image::open(path)?;
    
        //        let rgb = image.clone().to_rgb();
        let gray = image.to_luma();
        let (width, height) = gray.dimensions();
        let mut grey_image = rustface::ImageData::new(gray.as_ptr(), width, height);
        let mut faces = detector.detect(&mut grey_image);
    
        dbg!(("Detected faces in image", &path, &faces,));
    
        if faces.len() == 1 {
            let info = faces.get(0).unwrap();
            let grid = &info.bbox();
            // Detected exactly one face!
            let face_image = image.crop(
                grid.x() as u32,
                grid.y() as u32,
                grid.width() as u32,
                grid.height() as u32,
            );
    
            Ok(Some(image))
        } else {
            Ok(None)
        }
    }
    

    Backtrace:

    thread '<unnamed>' panicked at 'attempt to subtract with overflow', /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rustface-0.1.2/src/math/mod.rs:56:31
    stack backtrace:
       0: backtrace::backtrace::libunwind::trace
                 at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88
       1: backtrace::backtrace::trace_unsynchronized
                 at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/mod.rs:66
       2: std::sys_common::backtrace::_print
                 at src/libstd/sys_common/backtrace.rs:47
       3: std::sys_common::backtrace::print
                 at src/libstd/sys_common/backtrace.rs:36
       4: std::panicking::default_hook::{{closure}}
                 at src/libstd/panicking.rs:198
       5: std::panicking::default_hook
                 at src/libstd/panicking.rs:212
       6: std::panicking::rust_panic_with_hook
                 at src/libstd/panicking.rs:475
       7: std::panicking::continue_panic_fmt
                 at src/libstd/panicking.rs:382
       8: rust_begin_unwind
                 at src/libstd/panicking.rs:309
       9: core::panicking::panic_fmt
                 at src/libcore/panicking.rs:85
      10: core::panicking::panic
                 at src/libcore/panicking.rs:49
      11: rustface::math::vector_sub
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rustface-0.1.2/src/math/mod.rs:56
      12: rustface::feat::surf_mlp_featmap::SurfMlpFeatureMap::compute_grad_y::{{closure}}
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rustface-0.1.2/src/feat/surf_mlp_featmap.rs:153
      13: <rayon::iter::for_each::ForEachConsumer<F> as rayon::iter::plumbing::Folder<T>>::consume_iter::{{closure}}
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.1.0/src/iter/for_each.rs:55
      14: core::iter::traits::iterator::Iterator::fold::{{closure}}
                 at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libcore/iter/traits/iterator.rs:1685
      15: core::iter::traits::iterator::Iterator::try_fold
                 at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libcore/iter/traits/iterator.rs:1573
      16: core::iter::traits::iterator::Iterator::fold
                 at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libcore/iter/traits/iterator.rs:1685
      17: <rayon::iter::for_each::ForEachConsumer<F> as rayon::iter::plumbing::Folder<T>>::consume_iter
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.1.0/src/iter/for_each.rs:55
      18: rayon::iter::plumbing::Producer::fold_with
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.1.0/src/iter/plumbing/mod.rs:110
      19: rayon::iter::plumbing::bridge_producer_consumer::helper
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.1.0/src/iter/plumbing/mod.rs:438
      20: rayon::iter::plumbing::bridge_producer_consumer::helper::{{closure}}
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.1.0/src/iter/plumbing/mod.rs:427
      21: rayon_core::join::join_context::{{closure}}::{{closure}}
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/join/mod.rs:127
      22: <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute::{{closure}}
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/job.rs:115
      23: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
                 at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libstd/panic.rs:309
      24: std::panicking::try::do_call
                 at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libstd/panicking.rs:294
      25: __rust_maybe_catch_panic
                 at src/libpanic_unwind/lib.rs:85
      26: std::panicking::try
                 at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libstd/panicking.rs:273
      27: std::panic::catch_unwind
                 at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libstd/panic.rs:388
      28: rayon_core::unwind::halt_unwinding
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/unwind.rs:17
      29: <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/job.rs:115
      30: rayon_core::job::JobRef::execute
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/job.rs:59
      31: rayon_core::registry::WorkerThread::execute
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/registry.rs:734
      32: rayon_core::registry::WorkerThread::wait_until_cold
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/registry.rs:718
      33: rayon_core::registry::WorkerThread::wait_until
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/registry.rs:692
      34: rayon_core::registry::main_loop
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/registry.rs:812
      35: rayon_core::registry::ThreadBuilder::run
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/registry.rs:58
      36: <rayon_core::registry::DefaultSpawn as rayon_core::registry::ThreadSpawn>::spawn::{{closure}}
                 at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/registry.rs:103
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    test detect::detect_faces ... FAILED
    

    twitch_preview_1

    opened by theduke 4
  • SIMD State and feature flag

    SIMD State and feature flag

    Hi! This library looks awesome. I'm a little confused. Does the stable version include SIMD? I'd like to use this with wasm, which does not support SIMD yet. Is it only in the nightly branch, or is there a way to deactivate it?

    question 
    opened by johannesvollmer 3
  • Use slices for image data

    Use slices for image data

    • Makes extend_from_slice manage img_buf's capacity, which avoids reallocations
    • safe copy_u8_to_i32 generates the same assembly for the inner loop
    • ImageData can actually have a correct lifetime
    opened by kornelski 3
  • Add feature to make use of rayon optional

    Add feature to make use of rayon optional

    Wow this is really great work. I am super impressed with your library.

    I want to use it in a project I am working on but I need to insure it doesn't use more than one core. I know its an odd use case :) .

    I know I could set an ENV var to limit rayon to just one core, but that is really inconvenient. Here is a patch to allow a user to disable rayon if they want. I have enabled rayon as one of the default features since I would think more people would want it enabled.

    opened by lex148 3
  • error: Could not compile `regex`. when trying to run test.sh

    error: Could not compile `regex`. when trying to run test.sh

    rustc --version rustc 1.25.0-nightly (3f92e8d89 2018-01-14)

    $./bin/test.sh /home/johnh/gits/rustfacegitmaster/rustface/examples/ ./bin/test.sh: 4: ./bin/test.sh: [[: not found ./bin/test.sh: 10: ./bin/test.sh: [[: not found Using as the working directory Compiling regex v1.0.4 error[E0433]: failed to resolve. Could not find arch in std --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:3:10 | 3 | use std::arch::x86_64::*; | ^^^^ Could not find arch in std

    error[E0433]: failed to resolve. Could not find arch in std --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:3:10 | 3 | use std::arch::x86_64::*; | ^^^^ Could not find arch in std

    error: cannot find macro is_x86_feature_detected! in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:11:12 | 11 | if is_x86_feature_detected!("avx2") { | ^^^^^^^^^^^^^^^^^^^^^^^

    error: cannot find macro is_x86_feature_detected! in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:23:12 | 23 | if is_x86_feature_detected!("ssse3") { | ^^^^^^^^^^^^^^^^^^^^^^^

    error[E0412]: cannot find type __m256i in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:60:13 | 60 | vector: __m256i, | ^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_set1_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:67:25 | 67 | u8x32 { vector: _mm256_set1_epi8(n as i8) } | ^^^^^^^^^^^^^^^^ not found in this scope

    error[E0412]: cannot find type __m256i in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:78:55 | 78 | let p = slice.as_ptr() as *const u8 as *const __m256i; | ^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_loadu_si256 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:79:25 | 79 | u8x32 { vector: _mm256_loadu_si256(p) } | ^^^^^^^^^^^^^^^^^^ not found in this scope

    error[E0412]: cannot find type __m256i in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:91:55 | 91 | let p = slice.as_ptr() as *const u8 as *const __m256i; | ^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_load_si256 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:92:25 | 92 | u8x32 { vector: _mm256_load_si256(p) } | ^^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_shuffle_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:111:29 | 111 | u8x32 { vector: _mm256_shuffle_epi8(self.vector, indices.vector) } | ^^^^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_cmpeq_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:119:25 | 119 | let boolv = _mm256_cmpeq_epi8(self.vector, other.vector); | ^^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_set1_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:120:24 | 120 | let ones = _mm256_set1_epi8(0xFF as u8 as i8); | ^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_andnot_si256 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:121:29 | 121 | u8x32 { vector: _mm256_andnot_si256(boolv, ones) } | ^^^^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_and_si256 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:129:29 | 129 | u8x32 { vector: _mm256_and_si256(self.vector, other.vector) } | ^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_movemask_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:137:13 | 137 | _mm256_movemask_epi8(self.vector) as u32 | ^^^^^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_permute2x128_si256 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:151:21 | 151 | let v = _mm256_permute2x128_si256(other.vector, self.vector, 0x21); | ^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_alignr_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:152:21 | 152 | let v = _mm256_alignr_epi8(self.vector, v, 14); | ^^^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_permute2x128_si256 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:167:21 | 167 | let v = _mm256_permute2x128_si256(other.vector, self.vector, 0x21); | ^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_alignr_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:168:21 | 168 | let v = _mm256_alignr_epi8(self.vector, v, 15); | ^^^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm256_srli_epi16 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:177:29 | 177 | u8x32 { vector: _mm256_srli_epi16(self.vector, 4) } | ^^^^^^^^^^^^^^^^^ not found in this scope

    error[E0412]: cannot find type __m128i in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:81:13 | 81 | vector: __m128i, | ^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm_set1_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:88:25 | 88 | u8x16 { vector: _mm_set1_epi8(n as i8) } | ^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm_loadu_si128 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:99:17 | 99 | let v = _mm_loadu_si128(slice.as_ptr() as *const u8 as *const __m128i); | ^^^^^^^^^^^^^^^ not found in this scope

    error[E0412]: cannot find type __m128i in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:99:71 | 99 | let v = _mm_loadu_si128(slice.as_ptr() as *const u8 as *const __m128i); | ^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm_load_si128 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:112:17 | 112 | let v = _mm_load_si128(slice.as_ptr() as *const u8 as *const __m128i); | ^^^^^^^^^^^^^^ not found in this scope

    error[E0412]: cannot find type __m128i in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:112:70 | 112 | let v = _mm_load_si128(slice.as_ptr() as *const u8 as *const __m128i); | ^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm_shuffle_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:132:29 | 132 | u8x16 { vector: _mm_shuffle_epi8(self.vector, indices.vector) } | ^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm_cmpeq_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:140:25 | 140 | let boolv = _mm_cmpeq_epi8(self.vector, other.vector); | ^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm_set1_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:141:24 | 141 | let ones = _mm_set1_epi8(0xFF as u8 as i8); | ^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm_andnot_si128 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:142:29 | 142 | u8x16 { vector: _mm_andnot_si128(boolv, ones) } | ^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm_and_si128 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:150:29 | 150 | u8x16 { vector: _mm_and_si128(self.vector, other.vector) } | ^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm_movemask_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:158:13 | 158 | _mm_movemask_epi8(self.vector) as u32 | ^^^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm_alignr_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:166:29 | 166 | u8x16 { vector: _mm_alignr_epi8(self.vector, other.vector, 14) } | ^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm_alignr_epi8 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:174:29 | 174 | u8x16 { vector: _mm_alignr_epi8(self.vector, other.vector, 15) } | ^^^^^^^^^^^^^^^ not found in this scope

    error[E0425]: cannot find function _mm_srli_epi16 in this scope --> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:182:29 | 182 | u8x16 { vector: _mm_srli_epi16(self.vector, 4) } | ^^^^^^^^^^^^^^ not found in this scope

    OS: Ubuntu 18.10 cosmic
    Kernel: x86_64 Linux 4.18.0-13-generic Uptime: 1h 9m Packages: 2393 Shell: bash 4.4.19 Resolution: 1920x1200 DE: LXDE WM: OpenBox CPU: Intel Xeon W-2125 @ 8x 4.5GHz [36.0°C] GPU: Quadro P4000 RAM: 2811MiB / 31821MiB

    opened by danindiana 3
  • Make some internals public to allow creating a model from buffer

    Make some internals public to allow creating a model from buffer

    This opens up some more parts of the API, to allow creation of a model from an in memory buffer instead of a file.

    For example:

    use rustface::{Detector, FuStDetector};
    use rustface::model::ModelReader;
    
    fn custom_make_detector(buf: Vec<u8>) -> Box<Detector> {
        let model = ModelReader::new(buf).read()?;
        Box::new(FuStDetector::new(model))
    }
    
    opened by kaedroho 3
  • Make it possible to run ./test.sh from bin folder

    Make it possible to run ./test.sh from bin folder

    If someone like me goes to bin folder and runs "./test.sh ../assets/test/scientists.jpg", file_not_found error will occur. Fixed RUSTFACE_HOME detection when script runs from other places.

    opened by sashao 2
  • Webassembly - Assertion panics

    Webassembly - Assertion panics

    When compiling to webassembly ( --target wasm32-wasi ) detection always results in an assertion failure.

    thread 'main' panicked at 'assertion failed: `(left == right)`
      left: `826165`,
     right: `743000`', cargo/registry/src/github.com-1ecc6299db9ec823/rustface-0.1.6/src/common/image_pyramid.rs:32:9
    
    opened by theduke 2
  • Re-evaluate parallelization (Rayon)

    Re-evaluate parallelization (Rayon)

    Seems lik the --no-default-features flag (which disables Rayon multiprocessing) actually leads to a serious speedup of detect(), from ~1000 ms to ~700 ms on the scientists.jpg image. Likely due to shaving off threading overhead. This is on a noisy dual core 2018 MBP, so YMMV.

    I think larger images may benefit more from parallel processing, let's test that first. We may need to re-evaluate whether we want parallel processing on by default.

    performance 
    opened by jjhbw 0
  • Off by one?

    Off by one?

    I'm wondering why this code has (feature_id - 1):

    https://github.com/atomashpolskiy/rustface/blob/807ae56ff6e818d90908835d45db15cc12f12d8d/src/classifier/surf_mlp_classifier.rs#L212-L216

    shouldn't it advance the pointer by the size of the same feature vector that has been copied, not the next one?

    opened by kornelski 0
  • Parallelize CPU intensive loops

    Parallelize CPU intensive loops

    The original version uses OpenMP for parallelization, in 6 places in total. So far I've been able to use Rayon to modify the corresponding code in the Rust version, in 2 places:

    (1)
    MLPLayer::Compute (src/classifier/mlp.cpp:39)
    classifier::surf_mlp_classifier::Layer::compute (src/classifier/surf_mlp_classifier.rs:153)
    
    (2)
    SURFFeatureMap::ComputeGradY (src/feat/surf_feature_map.cpp:197)
    feat::surf_mlp_featmap::SurfMlpFeatureMap::compute_grad_y (src/feat/surf_mlp_featmap.rs:137)
    

    Here are the remaining places:

    (3)
    SURFFeatureMap::ComputeGradX (src/feat/surf_feature_map.cpp:178)
    feat::surf_mlp_featmap::SurfMlpFeatureMap::compute_grad_x (src/feat/surf_mlp_featmap.rs:116)
    
    (4)
    LABFeatureMap::ComputeRectSum (src/feat/lab_feature_map.cpp:145)
    feat::lab_boosted_featmap::LabBoostedFeatureMap::compute_rect_sum (feat/lab_boosted_featmap.rs:183)
    
    (5)
    LABFeatureMap::ComputeFeatureMap (src/feat/lab_feature_map.cpp:173)
    feat::lab_boosted_featmap::LabBoostedFeatureMap::compute_feature_map (feat/lab_boosted_featmap.rs:215)
    
    (6)
    fd::ResizeImage (include/util/image_pyramid.h:44)
    common::resize_image (common/image_pyramid.rs:175)
    
    enhancement performance 
    opened by atomashpolskiy 0
Releases(v0.1.6)
  • v0.1.6(Nov 2, 2020)

  • v0.1.5(Oct 28, 2020)

  • v0.1.4(Oct 1, 2020)

    • Made Rayon an optional dependency using a feature flag. It is enabled by default. Parallel processing can now be disabled by providing the --no-default-features flag at build time.
    Source code(tar.gz)
    Source code(zip)
Owner
Andrei Tomashpolskiy
Andrei Tomashpolskiy
A programming language where comments are the first-class citizen and ASCII art flowcharts are the controls!

regretti ?? A programming language where comments are the first-class citizen and ASCII art flowcharts are the controls! Made for Lang Jam (jam0001) t

Mufeed VH 15 Dec 27, 2022
a cute language with a bunch emoji🐶

nylang a cute language with a bunch emoji documentation WIKI usage dependancies rust ( cargo ) install & uninstall install chmod +x scripts/install.sh

jumango pussu 13 Jul 4, 2022
A Rust library for calculating perceptual hash values of images

img_hash Now builds on stable Rust! (But needs nightly to bench.) A library for getting perceptual hash values of images. Thanks to Dr. Neal Krawetz f

Austin Bonander 264 Dec 9, 2022
A simple steganography library written in rust

steganography A stable steganography library written in rust Crates.io Usage Add the following to the Cargo.toml in your project: [dependencies] stega

Teodor Voinea 79 Dec 9, 2022
A Simple-to-use, cross-platform Rust Webcam Capture Library

Cross Platform Rust Library for powerful Webcam Capture and Virtual Webcams

null 246 Jan 8, 2023
😱 Dead fast thumbnail library for browser and NodeJs! Built with Rust 🦀 and WebAssembly 🕸

thumbo-core ?? Dead fast thumbnail library for browser and NodeJs Built with Rust ?? & WebAssembly ?? ?? About thumbo-core is a thubnail library for b

Victor Aremu 12 Dec 2, 2022
Rust library for fast image resizing with using of SIMD instructions.

fast_image_resize Rust library for fast image resizing with using of SIMD instructions. CHANGELOG Supported pixel formats and available optimisations:

Kirill Kuzminykh 115 Jan 5, 2023
PNG decoding and encoding library in pure Rust

PNG Decoder/Encoder PNG decoder/encoder in pure Rust. It contains all features required to handle the entirety of the PngSuite by Willem van Schack. p

image-rs 247 Dec 25, 2022
An advanced image processing library for Rust.

ImageProc Maintainers: @chyh1990 Note: this project is under active depvelopment, API may change! imageproc is a advanced image proccessing library fo

Chen Yuheng 97 Oct 18, 2022
Rust library to get image size and format without loading/decoding

imageinfo-rs Rust library to get image size and format without loading/decoding. The imageinfo don't get image format by file ext name, but infer by f

xiaozhuai, Weihang Ding 47 Dec 30, 2022
Image operation rust library

Image operation rust library

LongYinan 166 Dec 20, 2022
Antialiased 2D vector drawing library in Rust for Android, Web, Desktop

nonaquad Vector anti-aliased graphics renderer for Android, WASM, Desktop in Rust, using miniquad. This library started as a port of NanoVG for miniqu

Nokola 33 Nov 14, 2022
Antialiased 2D vector drawing library written in Rust

femtovg Join the femtovg Discord channel Work in progress! Antialiased 2D vector drawing library written in Rust.

Tomasz Sterna 0 Aug 24, 2021
2D polyline/shape library for offsetting, combining, etc.

This project is a continuation of the C++ CavalierContours library rewritten in Rust with the goal of building out more functionality, better

Jedidiah Buck McCready 59 Jan 6, 2023
resvg is an SVG rendering library.

resvg can be used as a Rust library, a C library and as a CLI application to render SVG files based on a static SVG Full 1.1 subset.

Evgeniy Reizner 1.8k Dec 30, 2022
A linear algebra and mathematics library for computer graphics.

cgmath-rs A linear algebra and mathematics library for computer graphics. The library provides: vectors: Vector2, Vector3, Vector4 square matrices: Ma

rustgd 998 Jan 2, 2023
ePaperify: Framebuffer/image pre-processing library for e-Paper displays

ePaperify: Framebuffer/image pre-processing library for e-Paper displays

Jackson Ming Hu 5 Mar 15, 2022
Screen-capturer: A cross-platform screenshots library for MacOS、Windows、Linux(X11).

Screen-capturer: A cross-platform screenshots library for MacOS、Windows、Linux(X11).

nashaofu 49 Dec 12, 2022
Encoding and decoding images in Rust

Image Maintainers: @HeroicKatora, @fintelia How to contribute An Image Processing Library This crate provides basic image processing functions and met

image-rs 3.5k Jan 9, 2023