Add mhash

This commit is contained in:
simon987 2019-12-28 09:46:59 -05:00
parent ff1deac6f1
commit 356c8e4c64
4 changed files with 85 additions and 9 deletions

View File

@ -63,6 +63,17 @@ static void BM_ahash(benchmark::State &state) {
free(buf);
}
static void BM_mhash(benchmark::State &state) {
size_t size;
void *buf = load_test_file(&size);
for (auto _ : state) {
mhash_mem(buf, tmp, size, state.range());
}
free(buf);
}
static void BM_multi(benchmark::State &state) {
size_t size;
void *buf = load_test_file(&size);
@ -83,6 +94,7 @@ BENCHMARK(BM_phash)->ArgName("size")->Arg(8);
BENCHMARK(BM_whash)->ArgName("size")->Arg(8);
BENCHMARK(BM_dhash)->ArgName("size")->Arg(8);
BENCHMARK(BM_ahash)->ArgName("size")->Arg(8);
BENCHMARK(BM_mhash)->ArgName("size")->Arg(8);
BENCHMARK(BM_multi)->ArgName("size")->Arg(8);

View File

@ -31,6 +31,17 @@ double median(double *arr, size_t len) {
}
}
__always_inline
double median(uchar *arr, size_t len) {
std::sort(arr, arr + len);
if (len % 2 == 0) {
return (double)(arr[(len / 2) - 1] + arr[len / 2]) / 2;
} else {
return arr[(len + 1 / 2)];
}
}
void hash_to_hex_string(const uchar *h, char *out, int hash_size) {
int hash_len = hash_size * hash_size / 4;
@ -121,6 +132,42 @@ int ahash_mem(void *buf, uchar *out, size_t buf_len, int hash_size) {
return FASTIMAGEHASH_OK;
}
int mhash_file(const char *filepath, uchar *out, int hash_size) {
size_t size;
void *buf = load_file_in_mem(filepath, &size);
if (buf == nullptr) {
return FASTIMAGEHASH_READ_ERR;
}
int ret = mhash_mem(buf, out, size, hash_size);
free(buf);
return ret;
}
int mhash_mem(void *buf, uchar *out, size_t buf_len, int hash_size) {
Mat im;
try {
im = imdecode(Mat(1, buf_len, CV_8UC1, buf), IMREAD_GRAYSCALE);
resize(im, im, Size(hash_size, hash_size), 0, 0, INTER_AREA);
} catch (Exception &e) {
return FASTIMAGEHASH_DECODE_ERR;
}
uchar *pixel = im.ptr(0);
const int endPixel = im.cols * im.rows;
uchar sorted[im.cols * im.rows];
memcpy(sorted, pixel, endPixel);
double med = median(sorted, endPixel);
for (int i = 0; i < endPixel; i++) {
set_bit_at(out, i, pixel[i] > med);
}
return FASTIMAGEHASH_OK;
}
int dhash_file(const char *filepath, uchar *out, int hash_size) {
size_t size;
void *buf = load_file_in_mem(filepath, &size);
@ -298,12 +345,13 @@ int phash_mem(void *buf, uchar *out, size_t buf_len, const int hash_size, int hi
multi_hash_t *multi_hash_create(int hash_size) {
auto multi_hash = (multi_hash_t *) malloc(sizeof(multi_hash_t));
auto data = (uchar *) malloc((hash_size + 1) * 4);
auto data = (uchar *) malloc((hash_size + 1) * 5);
multi_hash->ahash = data;
multi_hash->phash = data + (hash_size + 1);
multi_hash->dhash = data + (hash_size + 1) * 2;
multi_hash->whash = data + (hash_size + 1) * 3;
multi_hash->mhash = data + (hash_size + 1) * 4;
return multi_hash;
}
@ -336,7 +384,7 @@ int multi_hash_mem(void *buf, multi_hash_t *out, size_t buf_len,
return FASTIMAGEHASH_DECODE_ERR;
}
Mat ahash_im;
Mat ahash_im; // Also used for mhash!
Mat dhash_im;
Mat phash_im;
Mat whash_im;
@ -383,8 +431,15 @@ int multi_hash_mem(void *buf, multi_hash_t *out, size_t buf_len,
uchar *pixel = ahash_im.ptr(0);
int endPixel = ahash_im.cols * ahash_im.rows;
// mhash
uchar mhash_sorted [ahash_im.cols * ahash_im.rows];
mempcpy(mhash_sorted, pixel, endPixel);
double m_median = median(mhash_sorted, endPixel);
for (int i = 0; i < endPixel; i++) {
set_bit_at(out->ahash, i, pixel[i] > avg);
set_bit_at(out->mhash, i, pixel[i] > m_median);
}
//dhash

View File

@ -13,6 +13,7 @@ typedef struct multi_hash {
uchar *phash;
uchar *dhash;
uchar *whash;
uchar *mhash;
} multi_hash_t;
#ifdef __cplusplus
@ -31,12 +32,10 @@ void hash_to_hex_string_reversed(const uchar *h, char *out, int hash_size);
void hash_to_hex_string(const uchar *h, char *out, int hash_size);
/**
*
* @param buf
* @param buf_len
* @param hash_size
*/
int mhash_mem(void *buf, uchar *out, size_t buf_len, int hash_size);
int mhash_file(const char *filepath, uchar *out, int hash_size);
int ahash_mem(void *buf, uchar *out, size_t buf_len, int hash_size);
int ahash_file(const char *filepath, uchar *out, int hash_size);

View File

@ -14,7 +14,7 @@ int main(int argc, char *argv[]) {
return 0;
}
int do_phash = 0, do_ahash = 0, do_whash = 0, do_dhash = 0;
int do_phash = 0, do_ahash = 0, do_whash = 0, do_dhash = 0, do_mhash = 0;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--phash") == 0) {
@ -25,6 +25,8 @@ int main(int argc, char *argv[]) {
do_whash = 1;
} else if (strcmp(argv[i], "--dhash") == 0) {
do_dhash = 1;
} else if (strcmp(argv[i], "--mhash") == 0) {
do_mhash = 1;
} else {
uchar hash[9];
@ -54,6 +56,12 @@ int main(int argc, char *argv[]) {
printf("%s\tw:%s\n", argv[i], hashstr);
}
}
if (do_mhash) {
if (mhash_file(argv[i], hash, 8) == 0) {
hash_to_hex_string_reversed(hash, hashstr, 8);
printf("%s\tm:%s\n", argv[i], hashstr);
}
}
multi_hash_t *m = multi_hash_create(8);
multi_hash_file(argv[i], m, 8, 4, 0);
@ -66,6 +74,8 @@ int main(int argc, char *argv[]) {
printf("%s\tmd:%s\n", argv[i], hashstr);
hash_to_hex_string_reversed(m->whash, hashstr, 8);
printf("%s\tmw:%s\n", argv[i], hashstr);
hash_to_hex_string_reversed(m->mhash, hashstr, 8);
printf("%s\tmm:%s\n", argv[i], hashstr);
multi_hash_destroy(m);
}