Realization of image search based on perceptual hashing algorithm

Source: Internet
Author: User
Tags scalar

Inadvertently saw a blog, is to imitate Google search image, the link is as follows:

Google Map-Similar image search principle-Java implementation

Think quite fun, bloggers use Java implementation, so I used OPENCV implementation of the next.

According to the blog post, it says that the key technology of Google image search is "perceptual compression algorithm" (perceptual hash algorithm), which is to generate a "fingerprint" (fingerprint) string for each image, and then compare the fingerprints of different images. The closer the result is, the more similar the picture is. See here I suddenly come to the interest to realize their own!

Next, we briefly describe the following perceptual hashing algorithms: Lab Shaoyi brother has summed up quite well, so I took part:

Mean hash based on low frequency

A picture is a two-dimensional signal that contains the components of different frequencies. As shown, the areas with small luminance changes are low-frequency components, which describe a wide range of information. Areas with sharp variations in brightness (such as the edges of objects) are high-frequency components that describe specific details. Or the high frequency can provide detailed picture information, and the low frequency can provide a framework.

And a big, detailed picture has very high frequency, and the small picture lacks the image detail, therefore all is the low frequency. So our usual next sampling, that is, the process of narrowing the picture, is actually the process of loss of high-frequency information. Such as:

These things, we can learn in the DSP class.

The mean hash algorithm mainly uses the low frequency information of the picture, and its working process is as follows:

(1) Size reduction: The quickest way to remove high frequencies and details is to shrink the image and reduce the image to 8x8, a total of 64 pixels. Don't keep the aspect ratio, just turn it into a 8*8 square. This allows you to compare images of any size, and discard the differences in the images of different sizes and proportions.

(2) Simplify color: Convert small images of 8*8 into grayscale images.

(3) Calculate average: Calculates the gray average of all 64 pixels.

(4) Compare the grayscale of pixels: compare the grayscale of each pixel to the average. Greater than or equal to the average, recorded as 1, less than the average, recorded as 0.

(5) Calculate the hash value: The previous step of the comparison results, grouped together, constitutes a 64-bit integer, this is the image of the fingerprint. The order of the combinations is not important, just make sure all the pictures are in the same order. (I set it from left to right, from top to bottom, with binary).

The calculation of a picture of the hash fingerprint is so simple, the computed hash fingerprint relative than the original picture has lost too much information, so that we all doubt that such a fingerprint is really able to recognize the similar image. However, the result of course is no doubt, the beauty of mathematics and programming beauty of the combination!

If the picture zooms in or out, or changes the aspect ratio, the resulting value does not change. Increasing or decreasing the brightness or contrast, or changing the color, does not affect the hash value too much. This method is the greatest advantage of being a picture: fast computing speed!

Because, as we can see, a picture is compressed, turned into a grayscale image, only a hash fingerprint, the process is not a large amount of computation, and these fingerprints are equivalent to the image characteristics.

Comparing the similarity of two images, the hash fingerprint of the two images is calculated first, that is, 64 bits 0 or 1 values, and then the number of different bits (Hamming distance) is calculated. If this value is 0, then the two pictures are very similar, if the Hamming distance is less than 5, it is somewhat different, but relatively similar, if the Hamming distance greater than 10 indicates a completely different picture.

In fact, I wrote the time, found that the Hamming distance of less than 5 is too harsh, hamming distance close to 20 of the two pictures of the similarity is still very high.

Actually see here, you can according to this idea yourself to achieve the following, do not look at the following code, has always felt that this is a good way to learn, look at the blog to expand their thinking, to achieve their own.

Next, the code implementation:

First introduce the Getimagefinger function, that is, generate the image of the fingerprint, the code is as follows:

//Search for image fingerprints//Parameters: Input image img, image's fingerprint arrayvoidGetimagefinger (Iplimage * img,Char*status) {intAvrpixel=0;intI,j; Cvscalar scalar; for(i =0;i<8; i++) { for(j =0;j<8; j + +) {scalar = cvget2d (img,i,j); Avrpixel + = scalar.val[0]; }} Avrpixel = Avrpixel/ -;intK =0; for(i =0;i<8; i++) { for(j =0;j<8; j + +) {if(CVGET2D (img,i,j). val[0] > Avrpixel) {status[k++] =1; }Else{status[k++] =0; }        }    }}

The code can be understood based on the principle above.

Next is the function to calculate the Hamming distance:

// 计算汉明距离// 参数: 两幅图的指纹数组// 输出: 汉明距离int calHammDist(char * src_img,char * dst_img){    int0;    for(int i=  0;i<MAX_PIXEL_NUMBER;i++)    {        if (src_img[i] != dst_img[i])        {            dist ++;        }    }    return dist;}

Search for image matching process code:

    //Read all images in a local directory to search for matches    intShow_number =0; for(inti =0;i<7; i++) {sprintf(FilePath,"F://image//%d.jpg", i);        dst_img = Cvloadimage (FilePath); resz_dst_img = Cvcreateimage (Cvsize (8,8), ipl_depth_8u,3); Cvresize (Dst_img,resz_dst_img,1); com_dst_img = Cvcreateimage (Cvsize (8,8), ipl_depth_8u,1);        Cvcvtcolor (Resz_dst_img,com_dst_img,cv_rgb2gray);        Getimagefinger (COM_DST_IMG,STATUS_DST); dis = calhammdist (STATUS_SRC,STATUS_DST);cout<<"Dis:"<<dis<<endl;if(dis< -) {showimgindex[show_number++] = i; }    }

The For loop i is less than 7 because I only put 7 pictures, I can modify the specific.

The effect is as follows:

This is my local 7 photos to search

The first left for the input picture, the second Zhang and the third is to match out the similarity degree higher picture, the second is actually the original picture, only changed the size size, according to the following command line to print out the Hamming distance, the first and the second Hamming distance is 0, the first and the third Hamming distance is 10, The similarity is still relatively high.


Here is not put out all the code, it is not difficult to achieve, you can try it yourself.

Implementation of image search based on perceptual hashing algorithm

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.