Make an advertisement first, haha!!
My Sina Weibo: http://weibo.com/u/1645794700/home?wvr=5&c=spr_web_360_hao360_weibo_t001
CV Machine Vision 2013CV Machine Vision 2013CV Machine Vision 2013
start
Start the text!!!
Before I saw a http://topic.csdn.net/u/20120417/15/edbf86f8-cfec-45c3-93e1-67bd555c684a.html Web page, I thought it was quite interesting, the method seemed very simple, I wanted to use C + + To achieve it, but shelved for a long time, today suddenly interested in realizing the next. Give a free download Java source code address: http://download.csdn.net/detail/yjflinchong/4239243, pictures you can use their pictures ~ ~
The pictures in the following procedures can be found on their own.
Excerpt from the topic:
Google "Similar image search": You can use an image to search all images on the internet that resemble it.
To open the Google Image search page:
Click Use to upload a Angelababy original image:
When you click Search, Google will find a similar image, with the higher the image similarity.
What is the principle of this technology? How does a computer know that two pictures are similar?
According to Dr. Neal Krawetz's explanation, the key technology for similar image search is called "Perceptual hashing Algorithm" (Perceptualhash algorithm), which generates a "fingerprint" (fingerprint) string for each image. Then compare the fingerprints of the different pictures. The closer the result is, the more similar the picture is.
The following is one of the simplest Java implementations:
Preprocessing: Reading pictures
The first step is to reduce the size.
Reduce the image to 8x8 size, a total of 64 pixels. The role of this step is to remove the details of the picture, only the structure, shading and other basic information, discard the different sizes, proportions of the picture differences.
The second step is to simplify the color.
Converts the zoomed-in image to a level 64 grayscale. That is, all pixels have a total of 64 colors.
The third step is to calculate the average.
Calculates a grayscale average of all 64 pixels.
Fourth step, compare the grayscale of the pixel.
The grayscale of each pixel is compared to the average. Greater than or equal to the average, recorded as 1, less than the average, recorded as 0.
Fifth step, calculate the hash value.
By combining the results of the previous step, you make up a 64-bit integer, which is the fingerprint of the image. The order of the combinations is not important, just make sure all the pictures are in the same order.
After getting the fingerprint, you can compare different pictures and see how many of the 64 bits are not the same. In theory, this equates to the calculation of "Hamming distance" (hammingdistance). If the data bits are not more than 5, the two images are similar, and if they are greater than 10, they are two different pictures.
You can put a few pictures together, and also calculate their Hamming distance comparison, you can see whether the two pictures are similar.
The advantages of this algorithm are simple and fast, not affected by the size of the picture, the disadvantage is that the contents of the picture can not be changed. If you add a few words to the picture, it will not be recognized. So, it's best to use thumbnails to find out the original image.
In practical applications, more powerful phash algorithms and sift algorithms are often used to identify the deformation of images. As long as the degree of deformation does not exceed 25%, they can match the original image. Although these algorithms are more complex, the principle is the same as the simple algorithm above, that is, to first convert the image into a hash string, and then compare.
Use the OpenCV to open the image (seemingly no opencv, embarrassed)
Win32TestPure.cpp: Defines the entry point of the console application.
#include "stdafx.h"
#include <atlstr.h>//cstring, CEdit
#include "opencv2\opencv.hpp"
#include //----------------------------------------------------
using namespace Std;
using namespace CV;
Class Photofingerprint
{
Public
int Distance (string &str1,string &str2);
String HashValue (Mat &src); Main function function
void Insert (Mat &src,string &val);
void Find (Mat &src);
Private
Mat m_imgsrc;
Hash_map<string,string> M_hashmap;
};
String Photofingerprint::hashvalue (Mat &src)
{
String rst (64, ' + ');
Mat img;
if (Src.channels () ==3)
Cvtcolor (Src,img,cv_bgr2gray);
Else
Img=src.clone ();
The first step is to reduce the size.
/* Reduce the image to 8x8 size for a total of 64 pixels. The effect of this step is to remove the details of the picture,
Only the structure, shading and other basic information, discard different sizes, proportions brought about by the picture differences. */
Resize (img,img,size (8,8));//Size reduction
The second step is to simplify the color.
Converts the zoomed-in image to a level 64 grayscale. That is, all pixels have a total of 64 colors.
Uchar *pdata;
for (int i=0;i{
PData = img.ptr<uchar> (i);
for (int j=0;j{
PDATA[J]=PDATA[J]/4; 0~255--->0~63
}
}
The third step is to calculate the average.
Calculates a grayscale average of all 64 pixels.
int average = Mean (IMG). val[0];
Fourth step, compare the grayscale of the pixel.
The grayscale of each pixel is compared to the average. Greater than or equal to the average, recorded as 1, less than the average, recorded as 0.
Mat mask= (img>= (Uchar) average);//////
Fifth step, calculate the hash value.
/* Combining the results of the previous step, together, constitutes a 64-bit integer, which is the fingerprint of this image.
The order of the combinations is not important, just make sure all the pictures are in the same order.
*/
int index = 0;
for (int i=0;i<mask.rows;i++)
{
PData = mask.ptr<uchar> (i);
for (int j=0;j<mask.cols;j++)
{
if (pdata[j]==0)
rst[index++]= ' 0 ';
Else
rst[index++]= ' 1 ';
}
}
return rst;
}
void Photofingerprint::insert (Mat &src,string &val)
{
String strval = HashValue (src);
M_hashmap.insert (pair<string,string> (strval,val));
cout<< "Insert one value:" <<strVal<< "string:" <<val<<endl;
}
void Photofingerprint::find (Mat &src)
{
String Strval=hashvalue (SRC);
Hash_map<string,string>::iterator It=m_hashmap.find (Strval);
if (It==m_hashmap.end ())
{cout<< "No photo---------" <<STRVAL<<ENDL;}
Else
cout<< "Find one, Key:" <<it->first<< "Value:" <<it->second<<endl;
/* Return *it;*/
}
int Photofingerprint::D istance (String &str1,string &str2)
{
if ((Str1.size ()!=64) | | (Str2.size ()!=64))
return-1;
int difference = 0;
for (int i=0;i<64;i++)
{
if (Str1[i]!=str2[i])
difference++;
}
return difference;
}
int main (int argc, char* argv[])
{
Photofingerprint PFP;
Mat m1=imread ("Images\\example3.jpg", 0);
Mat m2=imread ("Images\\example4.jpg", 0);
Mat m3=imread ("Images\\example5.jpg", 0);
Mat m4=imread ("Images\\example6.jpg", 0);
Mat M5;
Resize (m3,m5,size (100,100));
String str1 = PfP. HashValue (M1);
String str2 = PfP. HashValue (m2);
String str3 = PfP. HashValue (m3);
String STR4 = PfP. HashValue (M4);
PfP. Insert (m1,string ("str1\0"));
PfP. Insert (m2,string ("str2\0"));
PfP. Insert (m3,string ("str3\0"));
PfP. Insert (m4,string ("str4\0"));
PfP. Find (M5);
Cout<<pfp. Distance (STR1,STR1) <<endl;
Cout<<pfp. Distance (STR1,STR2) <<endl;
Cout<<pfp. Distance (STR1,STR3) <<endl;
Cout<<pfp. Distance (STR1,STR4) <<endl;
return 0;
}
Well, this hash table makes sense only when enough images are added. This procedure gives a general model, the details are not carried out (Hash_map first use). I hope you will make some suggestions.
[Semi-original] fingerprint identification + Google image recognition technology OPENCV code