Python + Opencv recognizes two similar images,

Source: Internet
Author: User

Python + Opencv recognizes two similar images,

After reading articles related to image recognition in python on the internet, I really feel that python is too powerful. So I will summarize these articles and build my own knowledge system.
Of course, as a branch of computer science, the topic of image recognition cannot be clearly explained in a few simple words in this article. Therefore, this article only serves as a popular approach to basic algorithms.
I saw a blog about this, but he used the Image in PIL to implement it, and it was quite troublesome. Therefore, the Opencv library was used for a simpler implementation.
Background
To identify two similar images, let's talk about the process from the perspective of sensibility? First, we will differentiate the two types of photos, for example, landscape photos or character photos. In the landscape, is the desert or the ocean? In the figure, are both Chinese faces or melon faces ...... Haha ......).

From the machine's point of view, this is also the case. First, the image features are recognized and then compared.

Obviously, in the absence of trained computers (that is, building models), it is difficult for computers to distinguish what is the ocean and what is the desert. However, computers can easily recognize the pixel value of an image.

Therefore, color features are most commonly used in image recognition. (Other common features include texture features, shape features, and spatial relationship features)

It is divided

Histogram
Color Set
Color moment
Aggregation Vector
Correlation Diagram

Histogram Calculation
Here we will briefly describe it with a histogram.

First, I want to borrow a picture of my love butterfly,

The two images are similar to each other.
In Python, use the calcHist () method in opencv to obtain the histogram data. The returned result is a list. Use matplotlib to draw the histogram data of the two graphs.
As follows:


Yes, we can obviously find that the histograms of the two images are coincident. Therefore, the Histogram can be used to determine whether two images are similar, and the coincidence degree of the Histogram can be calculated.
The calculation method is as follows:

Gi and si respectively refer to the I point of the two curves.

The final calculation result is the degree of similarity.

However, this method has an obvious weakness, that is, it looks at the global distribution of colors, and cannot describe the local distribution of colors and the location of colors.

That is to say, if an image is mainly blue, the content is a blue sky, and the content of another image is also blue, but the content is the girl wearing a blue dress, this algorithm may also consider the two images as similar.

One way to alleviate this weakness is to use the crop method of the Image to divide the Image equally, and then calculate the similarity of the Image separately.

Distance between image fingerprint and Hamming
Before introducing the following methods for determining similarity, add some concepts. The first is the image fingerprint.

Like a human fingerprint, an image fingerprint is a symbolic identity. In simple terms, an image fingerprint is a set of binary numbers obtained after calculation based on a certain hash algorithm.

Here, we can introduce the concept of Hamming distance.

If a group of binary data is 101 and the other group is 111, it is clear that the second DATA 0 in the first group can be changed to 111 in the second group, therefore, the Hamming distance between the two groups of data is 1.

To put it simply, the Hamming distance is the number of steps required to convert a set of binary data into another set of data. Obviously, this value can measure the difference between the two images. The smaller the Hamming distance, the higher the similarity. The Hamming distance is 0, indicating that the two images are identical.

For details about how to calculate the Hamming distance, see the following three hash algorithms.

Average Hash (aHash)
This algorithm is implemented based on comparing each pixel and average value of grayscale images.

General steps:

1. Scale the image. Generally, the image size is 8x8 and the image size is 64 pixels.
2. Convert to grayscale
3. Calculate the average value: calculate the average value of all the pixels in the image after grayscale processing. Use the mean () in numpy to calculate the average value.
4. Compare the pixel gray value: traverse each pixel of the grayscale image. If the value is greater than the average value, the value is 1; otherwise, the value is 0.
5. obtain the information fingerprint: 64 bits are combined, and the order is consistent at will.
Finally, compare the fingerprints of the two images to obtain the Hamming distance.

Perception hash algorithm (pHash)
The average hash algorithm is too strict and not accurate enough. It is more suitable for searching for thumbnails. To obtain more accurate results, you can select the perception hash algorithm, which uses DCT (discrete cosine transformation) to reduce the frequency

General steps:

Reduced image size: 32*32 is a good size, which facilitates DCT computing.
Convert to grayscale
Calculate DCT: the dct () method provided in Opencv is used. Note that the input image must be of the 32-bit floating point type. Therefore, the float32 in numpy is used for conversion.
Reduced DCT: after DCT calculation, the matrix is 32*32, and the 8*8 in the upper left corner is retained. These represent the lowest frequency of the image.
Calculate the average value: calculate the average value of all pixels after reduced DCT.
Further reduce DCT: If the value is greater than the average value, the record is 1; otherwise, the record is 0.
Obtain the information fingerprint: 64 Information digits are combined, and the order is consistent at will.
Finally, compare the fingerprints of the two images to obtain the Hamming distance.

DHash Algorithm
Compared with pHash, dHash provides a much faster speed. Compared with aHash, dHash achieves better performance under almost the same efficiency. It is implemented based on gradient.

Steps:

Scale down the image to 9*8 so that it has 72 pixels
Convert to grayscale
Calculate the difference value: the dHash algorithm operates between neighboring pixels, so there are eight different differences between nine pixels in each line. A total of eight rows produce 64 Difference values.
Fingerprint acquisition: If the left pixel is brighter than the right pixel, the record is 1; otherwise, it is 0.
Finally, compare the fingerprints of the two images to obtain the Hamming distance.

The entire code is implemented as follows:

#-*-Coding: UTF-8-*-# feimengjuan # Use python to implement multiple methods for Image Recognition import cv2 import numpy as np from matplotlib import pyplot as plt # The simplest implementation of comparison using gray-scale histograms as similarity def classify_gray_hist (image1, image2, size = (256,256): # Calculate the histogram first # several parameters must be enclosed in square brackets # Calculate the histogram directly using a grayscale image here, so the first channel is used, # You can also obtain the histogram of multiple channels after Channel Separation # Use bins as 16 image1 = cv2.resize (image1, size) image2 = cv2.resize (image2, size) hist1 = cv2.calcHist ([image1], [0], None ,[ 256], [0.0, 255.0]) hist2 = cv2.calcHist ([image2], [0], None, [256], [0.0, 255.0]) # Compare the histogram plt. plot (range (256), hist1, 'R') plt. plot (range (256), hist2, 'B') plt. show () # Calculate the coincidence degree of the histogram degree = 0 for I in range (len (hist1): if hist1 [I]! = Hist2 [I]: degree = degree + (1-abs (hist1 [I]-hist2 [I])/max (hist1 [I], hist2 [I]) else: degree = degree + 1 degree = degree/len (hist1) return degree # calculate the similarity def calculate (image1, image2) of a single-channel histogram ): hist1 = cv2.calcHist ([image1], [0], None, [256], [0.0, 255.0]) hist2 = cv2.calcHist ([image2], [0], None, [256], [0.0, 255.0]) # Calculate the coincidence degree of the histogram. degree = 0 for I in range (len (hist1): if hist1 [I]! = Hist2 [I]: degree = degree + (1-abs (hist1 [I]-hist2 [I])/max (hist1 [I], hist2 [I]) else: degree = degree + 1 degree = degree/len (hist1) return degree # calculate similarity def classify_hist_with_split (image1, image2, size = (256,256) by obtaining the histogram of each channel )): # After the image is resize, it is separated into three channels, and then the similarity value image1 = cv2.resize (image1, size) image2 = cv2.resize (image2, size) of each channel is calculated) sub_image1 = cv2.split (image1) sub_image2 = cv2.split (image2) sub_data = 0 for im1, im2 in zip (sub_image1, sub_image2): sub_data + = calculate (im1, im2) sub_data = sub_data/3 return sub_data # calculate def classify_aHash (image1, sub_image2, image2): image1 = cv2.resize (image1, (8, 8) image2 = cv2.resize (image2, (8, 8) gray1 = equals (image1, cv2.COLOR _ BGR2GRAY) gray2 = cv2.cvtColor (image2, cv2.COLOR _ BGR2GRAY) hash1 = getHash (gray1) hash2 = getHash (gray2) return Hamming_distance (has H1, hash2) def classify_pHash (image1, image2): image1 = cv2.resize (image1, (32,32) image2 = cv2.resize (image2, (32,32) gray1 = cv2.cvtColor (image1, cv2.COLOR _ BGR2GRAY) gray2 = cv2.cvtColor (image2, cv2.COLOR _ BGR2GRAY) # convert the grayscale image into a floating point, and then perform dct transformation dct1 = cv2.dct (np. float32 (gray1) dct2 = cv2.dct (np. float32 (gray2) #8x8 in the upper left corner, these represent the minimum image frequency # this operation is equivalent to the mask Operation implemented by using opencv in c ++ # mask operation in python, you can directly retrieve a part of the image matrix dct1_roi = Dct1 [,] dct2_roi = dct2 [,] hash1 = getHash (dct1_roi) hash2 = getHash (dct2_roi) return Hamming_distance (hash1, hash2) # enter a grayscale image, returns hash def getHash (image): avreage = np. mean (image) hash = [] for I in range (image. shape [0]): for j in range (image. shape [1]): if image [I, j]> avreage: hash. append (1) else: hash. append (0) return hash # Calculate the Hamming distance def Hamming_distance (hash1, hash2): num = 0 for index in Range (len (hash1): if hash1 [index]! = Hash2 [index]: num + = 1 return num if _ name _ = '_ main _': img1 = cv2.imread('10.jpg ') cv2.imshow ('img1 ', img1) img2 = cv2.imread('11.jpg ') cv2.imshow ('img2', img2) degree = average (img1, img2) # degree = average (img1, img2) # degree = classify_aHash (img1, img2) # degree = classify_pHash (img1, img2) print degree cv2.waitKey (0)

The above is all the content of this article. I hope it will help you learn python programming.

Related Article

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.