相似图片搜索——感知哈希算法

注:原文地址:感知哈希算法
感知哈希算法

感知哈希算法(PHA)是哈希算法的一类,主要用来做相似图片的搜索工作。

算法原理

为图片生成一个指纹(字符串格式), 两张图片的指纹越相似, 说明两张图片就越相似。

算法步骤

1.缩小尺寸:将图片缩小到8*8的尺寸,总共64个像素。
2.简化色彩:将缩小后的图片,转为64级灰度,也就是说,所有的像素点共只有64种颜色。
3.计算DCT(离散余弦变换):DCT是把图片分解频率聚集和梯状形,虽然JPEG使用8*8的
DCT变换,在这里使用32*32的DCT变换。
4.缩小DCT:虽然DCT的结果是32*32大小的矩阵,但我们只要保留左上角的8*8的矩阵,这
部分呈现了图片中的最低频率。
5.计算平均值:计算所有64个值得平均值。
6.进一步减少DCT:根据8*8的DCT矩阵,设置0或1的64位hash值,大于DCT均值的设为“1”
小于DCT均值的设为“0”。
7.计算哈希值:将64bit设置成64位的长整型,组合的次序并不重要,只要保证所有图片都
采用同样次序就行了。将32*32的DCT转换成32*32的图像。

算法的优点

无论你改变图片的高宽、亮度甚至颜色,都不会改变哈希值。

参考代码

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include 
#include 
#include 
using namespace std;
using namespace cv;
string PHA(Mat &src)
{
    Mat img, dst;
    string ans(64, 0);
    double Hash[64];
    double mid = 0.0;
    double eps = 1e-9;
    int k = 0;
    //1.缩小尺寸
    resize(src, src, Size(8, 8));
    //2.简化色彩
    if (src.channels() == 3)
    {
        cvtColor(src, src, CV_BGR2GRAY);
        img = Mat_<double>(src);
    }
    else
    {
        img = Mat_<double>(src);
    }
    //3.计算DCT
    dct(img, dst);
    //4.缩小DCT  
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            Hash[k++] = dst.at<double>(i, j);
            mid += Hash[k - 1];
        }
    }
    //5.计算平均值
    mid = mid / 64;
    //6.计算哈希值
    for (int i = 0; i < 64; i++)
    {
        if (Hash[i] - mid>eps) ans[i] = '1';
        else ans[i] = '0';
    }
    return ans;
}

//计算汉明距离
int dis(string s1, string s2)
{
    int ans = 0;
    for (int i = 0; i < 64; i++)
    if (s1[i] != s2[i]) ans++;
    return ans;
}
int main()
{
    ofstream out;
    out.open("test.txt");
    Mat src;
    string s1, s2;
    int k;
    Mat img;
    s1 = PHA(src);
    out << "person.jpg" << "  " << s1 << endl;
    char path[] = { "person0.jpg" };
    for (int i = 0; i < 9; i++)
    {
        path[6] += 1;
        img = imread(path);
        s2 = PHA(img);
        k = dis(s1, s2);
        out << path << " " << s2 << " " << k << endl;
    }
    out.close();
    return 0;
}

参考资料
1.感知哈希算法–百度百科
2.Neal Krawetz的博客Looks like it

你可能感兴趣的:(计算机视觉)