Browse Source

Fixed some formatting issues

Looking to do micro-benchmarks with the critereon library
develop
Drew Short 9 years ago
parent
commit
0b28ddeb4c
  1. 1
      Cargo.toml
  2. 4
      src/hash/ahash.rs
  3. 4
      src/hash/dhash.rs
  4. 18
      src/hash/mod.rs
  5. 25
      src/hash/phash.rs
  6. 37
      src/lib.rs
  7. 14
      src/main.rs

1
Cargo.toml

@ -28,3 +28,4 @@ num = "0.1.32"
docopt = "0.6.80"
flate2 = "0.2.13"
sha1 = "0.1.1"
criterion-stats = "0.1.0"

4
src/hash/ahash.rs

@ -60,8 +60,8 @@ impl<'a> PerceptualHash for AHash<'a> {
}
// println!("Hash for {} is {}", prepared_image.orig_path, hash);
hash
},
None => 0u64
}
None => 0u64,
}
}
}

4
src/hash/dhash.rs

@ -61,8 +61,8 @@ impl<'a> PerceptualHash for DHash<'a> {
}
hash
},
None => 0u64
}
None => 0u64,
}
}
}

18
src/hash/mod.rs

@ -59,9 +59,12 @@ pub struct PerceptualHashes<'a> {
impl<'a> PerceptualHashes<'a> {
pub fn similar(&self, other: &'a PerceptualHashes<'a>) -> bool {
if self.orig_path != other.orig_path &&
calculate_hamming_distance(self.ahash, other.ahash) <= HAMMING_DISTANCE_SIMILARITY_LIMIT &&
calculate_hamming_distance(self.dhash, other.dhash) <= HAMMING_DISTANCE_SIMILARITY_LIMIT &&
calculate_hamming_distance(self.phash, other.phash) <= HAMMING_DISTANCE_SIMILARITY_LIMIT {
calculate_hamming_distance(self.ahash, other.ahash) <=
HAMMING_DISTANCE_SIMILARITY_LIMIT &&
calculate_hamming_distance(self.dhash, other.dhash) <=
HAMMING_DISTANCE_SIMILARITY_LIMIT &&
calculate_hamming_distance(self.phash, other.phash) <=
HAMMING_DISTANCE_SIMILARITY_LIMIT {
true
} else {
false
@ -155,13 +158,13 @@ pub fn prepare_image<'a>(path: &'a Path,
Ok(_) => {}
Err(e) => println!("Unable to store image in cache. {}", e),
};
},
}
None => {}
};
processed_image
}
}
},
}
None => process_image(&image_path, size),
}
}
@ -169,15 +172,14 @@ pub fn prepare_image<'a>(path: &'a Path,
/**
* Turn the image into something we can work with
*/
fn process_image<'a>(image_path: &'a str,
size: u32) -> PreparedImage<'a> {
fn process_image<'a>(image_path: &'a str, size: u32) -> PreparedImage<'a> {
// Otherwise let's do that work now and store it.
// println!("Path: {}", image_path);
let image = match image::open(Path::new(image_path)) {
Ok(image) => {
let small_image = image.resize_exact(size, size, FilterType::Lanczos3);
Some(small_image.to_luma())
},
}
Err(e) => {
println!("Error Processing Image [{}]: {} ", image_path, e);
None

25
src/hash/phash.rs

@ -44,20 +44,24 @@ impl<'a> PerceptualHash for PHash<'a> {
// Atleast compared to opening and processing the images
let data_matrix: Vec<Vec<f64>> = match *cache {
Some(ref c) => {
match c.get_matrix_from_cache(&Path::new(self.prepared_image.orig_path), width as u32) {
match c.get_matrix_from_cache(&Path::new(self.prepared_image.orig_path),
width as u32) {
Some(matrix) => matrix,
None => {
let matrix = create_data_matrix(width, height, &image);
// Store this DFT in the cache
match c.put_matrix_in_cache(&Path::new(self.prepared_image.orig_path), width as u32, &matrix) {
match c.put_matrix_in_cache(&Path::new(self.prepared_image
.orig_path),
width as u32,
&matrix) {
Ok(_) => {}
Err(e) => println!("Unable to store matrix in cache. {}", e),
};
matrix
}
}
},
None => create_data_matrix(width, height, &image)
}
None => create_data_matrix(width, height, &image),
};
// Only need the top left quadrant
@ -92,13 +96,16 @@ impl<'a> PerceptualHash for PHash<'a> {
}
// println!("Hash for {} is {}", prepared_image.orig_path, hash);
hash
},
None => 0u64
}
None => 0u64,
}
}
}
fn create_data_matrix(width: usize, height: usize, image: &super::image::ImageBuffer<super::image::Luma<u8>, Vec<u8>>) -> Vec<Vec<f64>> {
fn create_data_matrix(width: usize,
height: usize,
image: &super::image::ImageBuffer<super::image::Luma<u8>, Vec<u8>>)
-> Vec<Vec<f64>> {
let mut data_matrix: Vec<Vec<f64>> = Vec::new();
// Preparing the results
for x in 0..width {
@ -106,9 +113,7 @@ fn create_data_matrix(width: usize, height: usize, image: &super::image::ImageBu
for y in 0..height {
let pos_x = x as u32;
let pos_y = y as u32;
data_matrix[x]
.push(image
.get_pixel(pos_x, pos_y)
data_matrix[x].push(image.get_pixel(pos_x, pos_y)
.channels()[0] as f64);
}
}

37
src/lib.rs

@ -20,17 +20,21 @@ use cache::Cache;
#[repr(C)]
pub struct PIHash<'a> {
cache: Option<Cache<'a>>
cache: Option<Cache<'a>>,
}
impl<'a> PIHash<'a> {
/**
* Create a new pihash library, and initialize a cache of a path is passed. If none is passed then no cache is initialized or used with the library
* Create a new pihash library, and initialize a cache of a path is passed.
* If none is passed then no cache is initialized or used with the library
*/
pub fn new(cache_path: Option<&'a str>) -> PIHash<'a> {
match cache_path {
Some(path) => {
let cache = Cache { cache_dir: path, use_cache: true};
let cache = Cache {
cache_dir: path,
use_cache: true,
};
match cache.init() {
Ok(_) => PIHash { cache: Some(cache) },
Err(e) => {
@ -38,12 +42,16 @@ impl<'a> PIHash<'a> {
PIHash { cache: None }
}
}
},
}
None => PIHash { cache: None },
}
}
pub fn get_perceptual_hash(&self, path: &Path, precision: &hash::Precision, hash_type: &hash::HashType) -> u64 {
pub fn get_perceptual_hash(&self,
path: &Path,
precision: &hash::Precision,
hash_type: &hash::HashType)
-> u64 {
hash::get_perceptual_hash(&path, &precision, &hash_type, &self.cache)
}
@ -221,9 +229,7 @@ mod tests {
let mut hashes: [u64; 3] = [0; 3];
for index in 0..image_paths.len() {
let image_path = image_paths[index];
let calculated_hash = lib.get_perceptual_hash(&image_path,
&hash_precision,
&hash_type);
let calculated_hash = lib.get_perceptual_hash(&image_path, &hash_precision, &hash_type);
println!("Image hashes for [{}] expected: [{}] actual: [{}]",
image_path.to_str().unwrap(),
image_hashes[index],
@ -238,7 +244,8 @@ mod tests {
continue;
} else {
let distance = hash::calculate_hamming_distance(hashes[index], hashes[index2]);
println!("Hashes [{}] and [{}] have a hamming distance of [{}] of a max allowed distance of [{}]",
println!("Hashes [{}] and [{}] have a hamming distance of [{}] of a max \
allowed distance of [{}]",
hashes[index],
hashes[index2],
distance,
@ -448,11 +455,15 @@ mod tests {
// Setup the caches to make sure we're good to properly bench
// All phashes so that the matricies are pulled from cache as well
lib.get_perceptual_hash(&Path::new("./test_images/sample_01_large.jpg"),&hash::Precision::Medium, &hash::HashType::PHash);
lib.get_perceptual_hash(&Path::new("./test_images/sample_01_large.jpg"),
&hash::Precision::Medium,
&hash::HashType::PHash);
bench.iter(|| {
// Sample_01 Bench
lib.get_perceptual_hash(&Path::new("./test_images/sample_01_large.jpg"), &hash::Precision::Medium, &hash::HashType::PHash);
lib.get_perceptual_hash(&Path::new("./test_images/sample_01_large.jpg"),
&hash::Precision::Medium,
&hash::HashType::PHash);
})
}
@ -464,7 +475,9 @@ mod tests {
bench.iter(|| {
// Sample_01 Bench
lib.get_perceptual_hash(&Path::new("./test_images/sample_01_large.jpg"), &hash::Precision::Medium, &hash::HashType::PHash);
lib.get_perceptual_hash(&Path::new("./test_images/sample_01_large.jpg"),
&hash::Precision::Medium,
&hash::HashType::PHash);
})
}
}

14
src/main.rs

@ -63,7 +63,8 @@ fn main() {
let mut comparison_hashes: Vec<pihash::hash::PerceptualHashes> = Vec::new();
for index in 0..args.arg_comparison.len() {
comparison_hashes.push(get_requested_perceptual_hashes(&lib, &Path::new(&args.arg_comparison[index]), &args));
comparison_hashes.push(get_requested_perceptual_hashes(&lib,
&Path::new(&args.arg_comparison[index]), &args));
}
let mut similar_images: Vec<&str> = Vec::new();
@ -102,7 +103,10 @@ fn flags_get_all_perceptual_hashes(args: &Args) -> bool {
(!args.flag_ahash && !args.flag_dhash && !args.flag_phash)
}
fn get_requested_perceptual_hashes<'a>(lib: &pihash::PIHash, image_path: &'a Path, args: &Args) -> pihash::hash::PerceptualHashes<'a> {
fn get_requested_perceptual_hashes<'a>(lib: &pihash::PIHash,
image_path: &'a Path,
args: &Args)
-> pihash::hash::PerceptualHashes<'a> {
let ahash = if args.flag_ahash || flags_get_all_perceptual_hashes(&args) {
lib.get_ahash(&image_path)
} else {
@ -121,8 +125,10 @@ fn get_requested_perceptual_hashes<'a>(lib: &pihash::PIHash, image_path: &'a Pat
0u64
};
pihash::hash::PerceptualHashes {orig_path: image_path.to_str().unwrap(),
pihash::hash::PerceptualHashes {
orig_path: image_path.to_str().unwrap(),
ahash: ahash,
dhash: dhash,
phash: phash}
phash: phash,
}
}
Loading…
Cancel
Save