previous time introduced similar image search principle one (Ahash) http://blog.csdn.net/lu597203933/article/details/45101859 , it is the simplest one based on content retrieval; The enhanced version-aware hashing algorithm is described here (perceptual hash, Phash) . It is mainly using thumbnails to search the original image and to achieve a better point of effect .
Theoretical part:
The theoretical part mainly consists of the following steps:
<1> Image Scaling - Zoom the image to 32*32 size
<2> Grayscale - the 32*32 the size of the image is grayscale
<3> Discrete cosine transform (DCT) -to 32*32 size image for DCT
<4> calculate mean value - with 32*32 size picture Front 8*8 size picture processing and calculating this - the mean value of a pixel
<4> Get 8*8 of the image phash-8*8 is greater than the mean value in the pixel value of the 1 indicates that the use of less than 0 said, this will get a - bit binary code as the image's Phash values.
<5> Calculate two images Ahash the Hamming distance of the value, the smaller the distance, indicates that the two images are more similar, the larger the distance, the greater the distance between the two images.
This avoids the effects of gamma correction or color histogram adjustment.
More detailed theories can be see:
1 : http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html
2 : http://blog.csdn.net/luoweifu/article/details/8220992 include Java Code Implementation
below I give my own C + + Code implementation:
<1> grayscale and zooming of images
Mat img = imread ("e:\\algorithmzack\\imagesearch\\image\\person.jpg", 1); if (!img.data) {cout << "the image is not Exist "<< Endl;return 0;} int size = +; Picture scaled after size resize (IMG, img, size (size,size)); Zoom to 32*32cvtcolor (IMG, IMG, color_bgr2gray); Grayscale
<2>DCT Transformations
/* Function: Get DCT coefficient n: Matrix size quotient: coefficient quotientt: coefficient transpose */void coefficient (const int &n, double **quotient, double **quotientt {Double SQR = 1.0/sqrt (n+0.0); for (int i = 0; i < n; i++) {quotient[0][i] = sqr;quotientt[i][0] = SQR;} for (int i = 1, i < n; i++) {for (int j = 0; J < N; j + +) {Quotient[i][j] = sqrt (2.0/n) *cos (i* (j+0.5) *pi/n); obtained by formula Quotientt[j][i] = Quotient[i][j];}}} /* Function: Two matrices multiplied by A and B: source input matrix Result: output matrix */void matrixmultiply (double **a, double **b, int n, double **result) {Double t = 0;for (int i = 0; I < n; i++) {for (int j = 0; J < N; j + +) {t = 0;for (int k = 0; k < n; k++) T + = a[i][k]*b[k][j]; RESULT[I][J] = t;}}} void DCT (mat_<uchar> image, const int &n, double **imatrix) {for (int i = 0; i < n; i++) {for (int j = 0; J < N J + +) {Imatrix[i][j] = (double) image (I,J);}} Allocate space for coefficients double **quotient = new Double*[n];d ouble **quotientt = new Double*[n];d ouble **tmp = new Double*[n];for (int i = 0; I < n; i++) {Quotient[i] = new Double[n];quotientt[i] = new Double[n];Tmp[i] = new Double[n];} Calculate coefficient matrix coefficient (n, quotient, Quotientt), matrixmultiply (quotient, Imatrix, N, TMP); Results from the formula result matrixmultiply (TMP, QUOTIENTT, N, Imatrix); for (int i = 0; i < n; i++) {delete []tmp[i];d elete []quotient[i];d E lete []quotientt[i];} delete []tmp;delete []quotient;delete []quotientt;}
<3> calculate mean value
Calculates the average gray level of the 8*8 image float Calcaverage (double **imatrix, const int &size) {Float sum = 0;for (int i = 0; i < size; i++) {fo R (Int j = 0; J < size; J + +) {sum + = Imatrix[i][j];}} Return sum/(size*size);}
<4> Calculate Hamming distance
/* Calculates the grayscale image of the hash value image:8*8 Size: Image size 8*8phash: Holds 64-bit hash value Averagepix: Average value of grayscale */void fingerprint (double **imatrix, const int &size, bitset
Full Source code:
#include <iostream> #include <bitset> #include <string> #include <iomanip> #include <cmath > #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> #include <opencv2\ Core\core.hpp>using namespace std;using namespace CV; #define PI 3.1415926#define hashlength 64/* function: Get DCT coefficient n: Matrix size quotient: coefficient quotientt: coefficient transpose */void coefficient (const int &n, double **quotient, double **quotientt) { Double Sqr = 1.0/sqrt (n+0.0); for (int i = 0; i < n; i++) {quotient[0][i] = sqr;quotientt[i][0] = SQR;} for (int i = 1, i < n; i++) {for (int j = 0; J < N; j + +) {Quotient[i][j] = sqrt (2.0/n) *cos (i* (j+0.5) *pi/n); obtained by formula Quotientt[j][i] = Quotient[i][j];}}} /* Function: Two matrices multiplied by A and B: source input matrix Result: output matrix */void matrixmultiply (double **a, double **b, int n, double **result) {Double t = 0;for (int i = 0; I < n; i++) {for (int j = 0; J < N; j + +) {t = 0;for (int k = 0; k < n; k++) T + = a[i][k]*b[k][j]; RESULT[I][J] = t;}}} void DCT (mat_<uchar> image, const int &n, double **imatrix) {for (int i = 0; i < n; i++) {for (int j = 0; J < N; j + +) {Imatrix[i][j] = (double) image (I,J); }}//allocate space for coefficients double **quotient = new Double*[n];d ouble **quotientt = new Double*[n];d ouble **tmp = new Double*[n];for (int i = 0; I < n; i++) {Quotient[i] = new Double[n];quotientt[i] = new Double[n]; Tmp[i] = new Double[n];} Calculate coefficient matrix coefficient (n, quotient, Quotientt), matrixmultiply (quotient, Imatrix, N, TMP); Results from the formula result matrixmultiply (TMP, QUOTIENTT, N, Imatrix); for (int i = 0; i < n; i++) {delete []tmp[i];d elete []quotient[i];d E lete []quotientt[i];} delete []tmp;delete []quotient;delete []quotientt;} Calculates the average gray level of the 8*8 image float Calcaverage (double **imatrix, const int &size) {Float sum = 0;for (int i = 0; i < size; i++) {fo R (Int j = 0; J < size; J + +) {sum + = Imatrix[i][j];}} Return sum/(size*size);} /* Calculates the grayscale image of the hash value image:8*8 Size: Image size 8*8phash: Holds 64-bit hash value Averagepix: Average value of grayscale */void fingerprint (double **imatrix, const int &size, bitset
The test picture is:
The result is:
where " i-j ", I Representative Personi , J Representative Personi with the Person the Hamming distance. and by the results visible Phash for the rotation of the picture is certainly powerless.
Description: The complete project document waits for several regular image retrieval method to write and then uploads, please concern!
Reference documents:
1 : http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html English Original information
2 : http://blog.csdn.net/luoweifu/article/details/8220992 include Java Code Implementation
Similarity Image Search Principle II (phash-c++ implementation)