相似图片搜索原理二(phash-c++实现)

来源:互联网 发布:怎样改淘宝用户名 编辑:程序博客网 时间:2024/06/01 22:26

理论来源 http://blog.csdn.net/lu597203933/article/details/45798293

理论部分:

理论部分主要包括以下几个步骤:

<1> 图像缩放—将图像缩放到32*32大小

<2>灰度化—对32*32大小的图像进行灰度化

<3>离散余弦变换(DCT)—对32*32大小图像进行DCT

<4>计算均值—用32*32大小图片前面8*8大小图片处理并计算这64个像素的均值

<4>得到8*8图像的phash—8*8的像素值中大于均值的则用1表示,小于的用0表示,这样就得到一个64位二进制码作为该图像的phash值。

<5>计算两幅图像ahash值的汉明距离,距离越小,表明两幅图像越相似;距离越大,表明两幅图像距离越大。

这样做能够避免伽马校正或者颜色直方图调整带来的影响。

代码实现

using namespace std;
using namespace cv;

?#define phashlength 64 //去掉问好
const int size = 32;

float calc_dct_average(Mat_ img){
float sum = 0;
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j++){
sum += img(i, j);
}
}
return sum / 64;
}
void DCT(Mat img, Mat &low_img){
Mat dct_img;
low_img = Mat::zeros(8, 8, CV_32FC1);
img.convertTo(dct_img, CV_32FC1);
dct(dct_img, dct_img);
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j++){
low_img.at(i, j) = dct_img.at(i, j);
}
}
}
void calc_hash(Mat_ img, float average, bitset& bit){
for (int i = 0; i < 8; i++){
int pos = i * 8;
for (int j = 0; j < 8; j++){
bit.at(pos + j) = img.at(i, j) >= average ? 1 : 0;
}
}
}
int main(){
Mat img = imread(“1.jpg”), dct_img = Mat::zeros(8, 8, CV_32FC1);
bitset bit;

resize(img, img, Size(size, size));
cvtColor(img, img, CV_BGR2GRAY);
DCT(img, dct_img);
float average = 0;
average = calc_dct_average(dct_img);
calc_hash(dct_img, average, bit);
for (int i = 0; i < 64; i++){
cout << bit.at(i);
}
cout << endl;
Mat img1 = imread(“4.jpg”), dct_img1 = Mat::zeros(8, 8, CV_32FC1);
bitset bit1;

resize(img1, img1, Size(size, size));
cvtColor(img1, img1, CV_BGR2GRAY);
DCT(img1, dct_img1);
float average1 = 0;
average1 = calc_dct_average(dct_img1);
calc_hash(dct_img1, average1, bit1);
int num = 0;
for (int i = 0; i < 64; i++){
cout << bit1.at(i);
if (bit.at(i) != bit1.at(i))
num++;
}
cout << endl << num;
cin.get();
return 0;
}

0 0
原创粉丝点击