相似图片搜索——感知哈希算法
发布时间
阅读量:
阅读量
本节将介绍一种基于认知机制的哈希编码方法
感知哈希算法(PHA)是哈希算法的一类,主要用来做相似图片的搜索工作。
算法原理
为图片生成一个指纹(字符串格式), 两张图片的指纹越相似, 说明两张图片就越相似。
算法步骤
缩小尺寸:将图片缩小到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 <iostream>
#include <stdio.h>
#include <fstream>
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的博客中有一篇名为《Looking Like It》的文章
全部评论 (0)
还没有任何评论哟~
