Browse Source

Changed the exectable to print phash info for a single file, or print the similar images to the first when passed more than one image

develop
Drew Short 8 years ago
parent
commit
36cbc8d64d
  1. 15
      src/hash/mod.rs
  2. 2
      src/lib.rs
  3. 105
      src/main.rs

15
src/hash/mod.rs

@ -33,6 +33,8 @@ const FLOAT_PRECISION_MIN_4: f64 = f64::MIN / 10000_f64;
// Can round to 5 significant factors of precision
const FLOAT_PRECISION_MAX_5: f64 = f64::MAX / 100000_f64;
const FLOAT_PRECISION_MIN_5: f64 = f64::MIN / 100000_f64;
// Hamming Distance Similarity Limit //
const HAMMING_DISTANCE_SIMILARITY_LIMIT: u64 = 5u64;
// Structs/Enums //
@ -55,6 +57,19 @@ pub struct PerceptualHashes<'a> {
pub phash: u64,
}
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 {
true
} else {
false
}
}
}
/**
* All the supported precision types
*

2
src/lib.rs

@ -6,7 +6,7 @@
extern crate libc;
extern crate rustc_serialize;
mod hash;
pub mod hash;
mod cache;
use std::path::Path;

105
src/main.rs

@ -16,9 +16,12 @@ const VERSION: &'static str = env!("CARGO_PKG_VERSION");
// The usage description
const USAGE: &'static str = "
Perceptual Image Hashing (pihash)
Calculate the perceptual hash values for an input or compare the
input file to a set of other images and return a list of the similar
images.
Usage:
pihash [options] <path>...
pihash [options] <path> [<comparison>...]
pihash (--help | --version)
Options:
@ -35,7 +38,8 @@ struct Args {
flag_ahash: bool,
flag_dhash: bool,
flag_phash: bool,
arg_path: Vec<String>,
arg_path: String,
arg_comparison: Vec<String>,
}
fn main() {
@ -53,43 +57,72 @@ fn main() {
pihash::init();
// println!("{:?}", args);
if args.arg_comparison.len() > 0 {
let base_image_path = Path::new(&args.arg_path);
let base_hash = get_requested_perceptual_hashes(&base_image_path, &args);
// All flags set or, no flags set
if (args.flag_ahash && args.flag_dhash && args.flag_phash) ||
(!args.flag_ahash && !args.flag_dhash && !args.flag_phash) {
for path in args.arg_path {
let image_path = Path::new(&path);
let hashes = pihash::get_phashes(&image_path);
let hash_result = format!(r#"
file: {}
ahash: {}
dhash: {}
phash: {}
"#,
hashes.orig_path,
hashes.ahash,
hashes.dhash,
hashes.phash);
println!("{}", hash_result);
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(&Path::new(&args.arg_comparison[index]), &args));
}
// Otherwise process only specific hashes
} else {
for path in args.arg_path {
println!("file: {}", path);
let image_path = Path::new(&path);
if args.flag_ahash {
let ahash = pihash::get_ahash(&image_path);
println!("ahash: {}", ahash);
}
if args.flag_dhash {
let dhash = pihash::get_dhash(&image_path);
println!("dhash: {}", dhash);
}
if args.flag_phash {
let phash = pihash::get_phash(&image_path);
println!("phash: {}", phash);
let mut similar_images: Vec<&str> = Vec::new();
for comparison_hash in comparison_hashes {
if base_hash.similar(&comparison_hash) {
similar_images.push(&comparison_hash.orig_path);
}
println!("");
}
println!("Base Image:");
println!("{}", base_image_path.to_str().unwrap());
println!("Similar Images:");
for similar_image in similar_images {
println!("{}", similar_image);
}
} else {
let image_path = Path::new(&args.arg_path);
let hashes = get_requested_perceptual_hashes(&image_path, &args);
let hash_result = format!(r#"
file: {}
ahash: {}
dhash: {}
phash: {}
"#,
hashes.orig_path,
hashes.ahash,
hashes.dhash,
hashes.phash);
println!("{}", hash_result);
}
}
fn flags_get_all_perceptual_hashes(args: &Args) -> bool {
(args.flag_ahash && args.flag_dhash && args.flag_phash) ||
(!args.flag_ahash && !args.flag_dhash && !args.flag_phash)
}
fn get_requested_perceptual_hashes<'a>(image_path: &'a Path, args: &Args) -> pihash::hash::PerceptualHashes<'a> {
let ahash = if args.flag_ahash || flags_get_all_perceptual_hashes(&args) {
pihash::get_ahash(&image_path)
} else {
0u64
};
let dhash = if args.flag_dhash || flags_get_all_perceptual_hashes(&args) {
pihash::get_ahash(&image_path)
} else {
0u64
};
let phash = if args.flag_phash || flags_get_all_perceptual_hashes(&args) {
pihash::get_ahash(&image_path)
} else {
0u64
};
pihash::hash::PerceptualHashes {orig_path: image_path.to_str().unwrap(),
ahash: ahash,
dhash: dhash,
phash: phash}
}
Loading…
Cancel
Save