|
|
@ -14,6 +14,8 @@ extern crate test; |
|
|
|
pub mod hash;
|
|
|
|
pub mod cache;
|
|
|
|
|
|
|
|
use std::collections::{HashMap, LinkedList};
|
|
|
|
use std::boxed::Box;
|
|
|
|
use std::path::Path;
|
|
|
|
use std::ffi::CStr;
|
|
|
|
use cache::Cache;
|
|
|
@ -80,6 +82,51 @@ impl<'a> PIHash<'a> { |
|
|
|
&hash::HashType::PHash,
|
|
|
|
&self.cache)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_all_similar_images(&self, images: &[&Path]) -> Option<HashMap<&Path, &Path>> {
|
|
|
|
for image in images {
|
|
|
|
println!("Test Path -> {}", image.to_str().unwrap());
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_similar_images(&self,
|
|
|
|
base_image: &Path,
|
|
|
|
images: &'a [&Path])
|
|
|
|
-> Option<LinkedList<&Path>> {
|
|
|
|
//let similar_images = LinkedList::new();
|
|
|
|
let similar_images = images
|
|
|
|
.iter()
|
|
|
|
.filter(|image| self.are_similar_images(&base_image, &image, None))
|
|
|
|
.map(|&x| x)
|
|
|
|
.collect::<LinkedList<&Path>>();
|
|
|
|
Some(similar_images)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn are_similar_images(&self,
|
|
|
|
first: &Path,
|
|
|
|
second: &Path,
|
|
|
|
sensitivity: Option<u64>)
|
|
|
|
-> bool {
|
|
|
|
|
|
|
|
let threshold = match sensitivity {
|
|
|
|
Some(value) => value,
|
|
|
|
None => 4,
|
|
|
|
};
|
|
|
|
|
|
|
|
let first_pihash = self.get_phashes(first);
|
|
|
|
let second_pihash = self.get_phashes(second);
|
|
|
|
if hash::calculate_hamming_distance(first_pihash.ahash, second_pihash.ahash) <= threshold {
|
|
|
|
if hash::calculate_hamming_distance(first_pihash.dhash, second_pihash.dhash) <=
|
|
|
|
threshold {
|
|
|
|
if hash::calculate_hamming_distance(first_pihash.phash, second_pihash.phash) <=
|
|
|
|
threshold {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
@ -255,6 +302,38 @@ mod tests { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_confirm_get_similar_images() {
|
|
|
|
let lib = PIHash::new(Some(cache::DEFAULT_CACHE_DIR));
|
|
|
|
let sample_01_base_image = &Path::new("./test_images/sample_01_large.jpg");
|
|
|
|
let sample_01_images: [&Path; 2] = [&Path::new("./test_images/sample_01_medium.jpg"),
|
|
|
|
&Path::new("./test_images/sample_01_small.jpg")];
|
|
|
|
let sample_01_results = lib.get_similar_images(&sample_01_base_image, &sample_01_images)
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(sample_01_results.len(), 2);
|
|
|
|
|
|
|
|
let sample_02_base_image = &Path::new("./test_images/sample_02_large.jpg");
|
|
|
|
let sample_02_images: [&Path; 2] = [&Path::new("./test_images/sample_02_medium.jpg"),
|
|
|
|
&Path::new("./test_images/sample_02_small.jpg")];
|
|
|
|
let sample_02_results = lib.get_similar_images(&sample_02_base_image, &sample_02_images)
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(sample_02_results.len(), 2);
|
|
|
|
|
|
|
|
let sample_03_base_image = &Path::new("./test_images/sample_03_large.jpg");
|
|
|
|
let sample_03_images: [&Path; 2] = [&Path::new("./test_images/sample_03_medium.jpg"),
|
|
|
|
&Path::new("./test_images/sample_03_small.jpg")];
|
|
|
|
let sample_03_results = lib.get_similar_images(&sample_03_base_image, &sample_03_images)
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(sample_03_results.len(), 2);
|
|
|
|
|
|
|
|
let sample_04_base_image = &Path::new("./test_images/sample_04_large.jpg");
|
|
|
|
let sample_04_images: [&Path; 2] = [&Path::new("./test_images/sample_04_medium.jpg"),
|
|
|
|
&Path::new("./test_images/sample_04_small.jpg")];
|
|
|
|
let sample_04_results = lib.get_similar_images(&sample_04_base_image, &sample_04_images)
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(sample_04_results.len(), 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_confirm_ahash_results() {
|
|
|
|
// Prep_library
|
|
|
|