Skip to content

A rust crate to find a subimage within a larger image. MIT licensed

License

Notifications You must be signed in to change notification settings

nico-abram/find-subimage

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Find Subimage

github crates.io docs.rs build status

This crate provides basic functionality to find likely positions of a subimage within a larger image by calculating an image distance. It has a naive scalar implementation in rust, and a simd implementation that selects the best implementation based on cpu features at runtime in rust using the simdeez crate. It also provides an implementation which uses OpenCV's (A C++ library) matchTemplate function using the opencv-rust crate through an optional off-by-default feature. It can also optionally convert images to grayscale before applying the algorithms.

Here's a simple example showing how to use the API:

use find_subimage::{Image, SubImageFinderState};
// Make a dummy 128x128 black image with a red dot at (50, 0)
let (w, h) = (128, 128);
let mut rgb_image = vec![0u8; w * h * 3];
rgb_image[50 * 3] = 250;
// Make a dummy 32x32 black image
// with a red dot at (0, 0)
let (sub_w, sub_h) = (32, 32);
let mut rgb_subimage = vec![0u8; sub_w * sub_h * 3];
rgb_subimage[0] = 250;

let mut finder = SubImageFinderState::new();
// These are (x, y, distance) where x and y are the position within the larger image
// and distance is the distance value, where a smaller distance means a more precise match
let positions: &[(usize, usize, f32)] =
    finder.find_subimage_positions((&rgb_image, w, h), (&rgb_subimage, sub_w, sub_h), 3);
let max: Option<&(usize, usize, f32)> = positions
    .iter()
    .min_by(|(_, _, dist), (_, _, dist2)| dist.partial_cmp(dist2).unwrap());
println!("The subimage was found at position {:?}", &max);
assert_eq!(Some((50, 0)), max.map(|max| (max.0, max.1)));
// find_subimage_positions actually returns the results sorted by distance already,
// so we can skip finding the minimum
assert_eq!(Some((50, 0)), positions.get(0).map(|max| (max.0, max.1)));

Additional documentation can be found in the generated rustdoc docs hosted on docs.rs.

Here's an example of what can be done using this crate:

Our search image:

Ferris

Our subimage:

A crop of ferris' eyes

The best match:

Ferris again but with a red rectangle over their eyes

Licensing

The code in this repository is available under any of the following licenses, at your choice: MIT OR Apache-2.0 OR BSL-1.0 OR MPL-2.0 OR Zlib OR Unlicense

This crate optionally depends on opencv. You can find it's license here (3-clause BSD or Apache 2 depending on the version). The rust bindings are licensed as MIT.

It also optionally depends on simdeez which is licensed as MIT.

Running tests

I recommend running the tests in release mode.

About

A rust crate to find a subimage within a larger image. MIT licensed

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published