1 : How could I accelerate the speed of the img_hash module(click me) from 1.5x~500x(roughly) from my last post(click me).
2 : A new image hash algorithms which works quite well under rotation attack.
Accelerate the speed of img_hash
We only need one line to gain this huge performance gain, no more, no less.cv::ocl::setUseOpenCL(false);
What I do is close the optimization of openCL(I would not discuss why this speed things up dramatically on my laptop, if you are interesting about it, I would open another topic to discuss this phenomenon). Let us measure the performance after the change. Codes located at here(click me).
Following comparison do not list the results of PHash about Average hash, PHash and Color hash algorithms, because I cannot find these algorithms in PHash library.
Computation time |
Comparison time |
Computation of img_hash with and without opencl |
As the results show, computation time of img_hash outperform PHash after I switch off opencl support(on you computer, switch it on may help you gain better performance) on my laptop(y410p). Whatever, the comparison performance do not change much with or without opencl support.
Benchmark of Color Moment Hash
In this section, I would like to introduce an image hash algorithm which works quite well under rotation attack and provide a much better test results than my last post(click me). This algorithm is introduced by this paper(click me), the class ColorMomentHash of img_hash module implement this algorithm.
My last post only use one image--lena.png to do the experiment under different attack, in this post I will use the data set from phash to do the test(use miscellaneous data set(click me) as original image, apply different attack on it). These 3D bar charts are generated by Qt data visualization, I do not upload it to github yet because the codes are quite messy, if you need the source codes, please send the request to my email(thamngapwei@gmail.com), I would send you a copy of the codes, but do not expect I would refine the codes any time soon.
The name of the images are quite long, it do not looks good when I draw it on chart, so I rename them to shorter form(001~023). Following are the mapping of those images. You can download the mapping of new name and old name from mega(click me).
Threshold of the tests of color moment hash is 8, if the L2-Norm of two hash greater than 8, we treat it as fail, and draw it with red bars.
The name of the images are quite long, it do not looks good when I draw it on chart, so I rename them to shorter form(001~023). Following are the mapping of those images. You can download the mapping of new name and old name from mega(click me).
Threshold of the tests of color moment hash is 8, if the L2-Norm of two hash greater than 8, we treat it as fail, and draw it with red bars.
Contrast attack
Param is the gamma value of gamma correction.
Resize attack
Resize attack on color moment hash Param is the aspect ratio of horizontal and vertical site. |
Gaussion noise attack
Gaussian noise attack on color moment hash |
Param is the standard deviation of gaussion.
Salt and pepper noise attack
Salt and pepper noise attack on color moment hash |
Param is the threshold of pepper and salt.
Rotation attack
Param is the angle of rotation.
|
Gaussian blur attack
Gaussian blur attack on color moment hash |
Param is the standard deviation of 3x3 gaussian filter.
Jpeg compression attack
Param is the quality factor of jpeg compression, 100 means no compress.
Watermark attack
Param is the strength of watermark, 1.0 means the mark is 100% opaque. Image 017 and image 023 perform very poor because they are gray scale image.
From these experiment data, we can say color moment hash perform very well under various attack except gaussion noise, salt and pepper noise and contrast attack.
Overall results of different algorithms
Apparently, there are too many data to show for all of the algorithms, to make things more intuitive, I create the charts to help you measure the performance of these algorithms under different attacks.Their threshold are same as the last post(click me).
PHash algorithm performance |
Marr Hildreth algorithm performance |
Radial hash algorithm performance |
BMH zero algorithm performance |
BMH one algorithm performance |
Color moment algorithm performance |
These are the results of all of the algorithms, from the Overall results chart, it is easy to see that every algorithms have their pros and cons, you need to pick the one suit for your database. If speed is crucial, then average hash maybe is your best choices, because it is the fastest algorithms compare with other and perform very well under different attacks except of rotation and salt and pepper noise.If you need rotation resistance, color moment hash is you only choice because other algorithms suck on rotation attack. You can find the codes of these test cases from here(click me).
Compare with PHash library
As this post show, img_hash module possess five advantages over the PHash library(click me).
1 : Processing speed of this module outperform PHash.
2 : This module adopt the same license as opencv(click me), which means you can do anything with it as you like without charging.
3 : The codes are much more modern, easier to use, img_hash free you from memory management chores once and for all. A modern, good c++ library should not force their users take care the resources by themselves.
4 : Api of img_hash are consistent, much easier to use than PHash library. Do not believe it? Let us see some examples.
As you can see, img_hash not only faster, this module also provide you cleaner, more concise way to write your codes, you never need to remember different ways to find out your hash and how to compare them anymore, because the api of img_hash are consistent.
5 : This module only depend on opencv_core and opencv_imgproc, that means you should be able to compile it at ease on every major platform without scratching your heads.
Case 1a : Compute Radial Hash by PHash library
Digest digests_0, digests_1; digest_0.coeffs = 0; digest_1.coeffs = 1; ph_image_digest(img_0, 1.0, 1.0, digest_0); ph_image_digest(img_1, 1.0, 1.0, digest_1); double pcc = 0; ph_crosscorr(digest_0, digest_1, pcc, 0.9); //do something, remember to free your memory :( free(digest_0.coeffs); free(digest_1.coeffs);
Case 1b : Compare Radial Hash by img_hash
auto algo = RadialVarianceHash::create(); cv::Mat hash_0, hash_1; algo->compute(img_0, hash_0); algo->compute(img_1, hash_1); double const value = algo->compare(hash_0, hash_1); //do something //you do not need to free anything by yourself
Case 2a : Compute Marr Hash by PHash library
int N = 0; uint8_t *hash_0 = ph_mh_imagehash(img_0, N); uint8_t *hash_1 = ph_mh_imagehash(img_1, N); double const value = ph_hammingdistance2(hash_0 , 72, hash_1, 72); //do something, remember to free your memory :( free(hash_0); free(hash_1);
Case 2b : Compare Marr Hash by img_hash
auto algo = MarrHildrethHash::create(); cv::Mat hash_0, hash_1; algo->compute(img_0, hash_0); algo->compute(img_1, hash_1); double const value = algo->compare(hash_0, hash_1); //do something //you do not need to free anything by yourself
Case 3a : Compute Block mean Hash by PHash library
BinHash *hash_0 = 0; BinHash *hash_1 = 0; ph_bmb_imagehash(imgs_0, 1, &hash_0); ph_bmb_imagehash(imgs_1, 1, &hash_1); double const value = ph_hammingdistance2(hash_0->hash, hash_0->bytelength, hash_1->hash, hash_1->bytelength); //do something, remember to free your memory :( ph_bmb_free(hash_0); ph_bmb_free(hash_1);
Case 3b : Compare Block mean Hash by img_hash
auto algo = BlockMeanHash::create(0); cv::Mat hash_0, hash_1; algo->compute(img_0, hash_0); algo->compute(img_1, hash_1); double const value = algo->compare(hash_0, hash_1); //do something //you do not need to free anything by yourself
As you can see, img_hash not only faster, this module also provide you cleaner, more concise way to write your codes, you never need to remember different ways to find out your hash and how to compare them anymore, because the api of img_hash are consistent.
5 : This module only depend on opencv_core and opencv_imgproc, that means you should be able to compile it at ease on every major platform without scratching your heads.