相似圖片搜索原理二(phash-c++實現)

理論來源 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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章