1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use self::private::*;
use mat::CMat;
use *;
extern "C" {
fn cv_hash_compute(phash: *const CHash, mat: *const CMat, result: *mut CMat);
fn cv_hash_compare(phash: *const CHash, lhs: *const CMat, rhs: *mut CMat) -> f64;
fn cv_average_hash_new() -> *mut CHash;
fn cv_average_hash_drop(phash: *mut CHash);
fn cv_block_mean_hash_new() -> *mut CHash;
fn cv_block_mean_hash_drop(phash: *mut CHash);
fn cv_color_moment_hash_new() -> *mut CHash;
fn cv_color_moment_hash_drop(phash: *mut CHash);
fn cv_marr_hildreth_hash_new() -> *mut CHash;
fn cv_marr_hildreth_hash_drop(phash: *mut CHash);
fn cv_phash_new() -> *mut CHash;
fn cv_phash_drop(phash: *mut CHash);
fn cv_radial_variance_hash_new() -> *mut CHash;
fn cv_radial_variance_hash_drop(phash: *mut CHash);
}
mod private {
#[allow(missing_copy_implementations, missing_debug_implementations)]
pub enum CHash {}
pub trait HashImpl {
fn get_value(&self) -> *const CHash;
}
}
#[allow(missing_docs)]
pub trait HashImplInterface: HashImpl {}
pub trait Hash {
fn compute(&self, mat: &Mat) -> Mat;
fn compare(&self, lhs: &Mat, rhs: &Mat) -> f64;
}
impl<T: HashImplInterface> Hash for T {
fn compute(&self, mat: &Mat) -> Mat {
let result = CMat::new();
let value = self.get_value();
unsafe { cv_hash_compute(value, mat.inner, result) };
Mat::from_raw(result)
}
fn compare(&self, lhs: &Mat, rhs: &Mat) -> f64 {
let value = self.get_value();
unsafe { cv_hash_compare(value, lhs.inner, rhs.inner) }
}
}
macro_rules! impl_hash {
($x:ident, $ctor:ident, $drop:ident, $description:expr) => {
#[doc=$description]
#[derive(Debug)]
pub struct $x {
value: *const CHash,
}
impl $x {
pub fn new() -> Self {
let value = unsafe { $ctor() };
Self { value }
}
}
impl Drop for $x {
fn drop(&mut self) {
unsafe {
$drop(self.value as *mut _);
}
}
}
impl HashImpl for $x {
fn get_value(&self) -> *const CHash {
self.value
}
}
impl HashImplInterface for $x {}
unsafe impl Send for $x {}
unsafe impl Sync for $x {}
};
}
impl_hash!(
AverageHash,
cv_average_hash_new,
cv_average_hash_drop,
"Computes average hash value of the input image"
);
impl_hash!(
BlockMeanHash,
cv_block_mean_hash_new,
cv_block_mean_hash_drop,
"Image hash based on block mean"
);
impl_hash!(
ColorMomentHash,
cv_color_moment_hash_new,
cv_color_moment_hash_drop,
"Image hash based on color moments"
);
impl_hash!(
MarrHildrethHash,
cv_marr_hildreth_hash_new,
cv_marr_hildreth_hash_drop,
"Marr-Hildreth Operator Based Hash, slowest but more discriminative."
);
impl_hash!(
PHash,
cv_phash_new,
cv_phash_drop,
"Slower than AverageHash, but tolerant of minor modifications"
);
impl_hash!(
RadialVarianceHash,
cv_radial_variance_hash_new,
cv_radial_variance_hash_drop,
"Image hash based on Radon transform"
);