opencv3/C++ PHash算法圖像檢索詳解
PHash算法即感知哈希算法/Perceptual Hash algorithm,計(jì)算基于低頻的均值哈希.對(duì)每張圖像生成一個(gè)指紋字符串,通過(guò)對(duì)該字符串比較可以判斷圖像間的相似度.
PHash算法原理
將圖像轉(zhuǎn)為灰度圖,然后將圖片大小調(diào)整為32*32像素并通過(guò)DCT變換,取左上角的8*8像素區(qū)域。然后計(jì)算這64個(gè)像素的灰度值的均值。將每個(gè)像素的灰度值與均值對(duì)比,大于均值記為1,小于均值記為0,得到64位哈希值。
PHash算法實(shí)現(xiàn)
將圖片轉(zhuǎn)為灰度值
將圖片尺寸縮小為32*32
resize(src, src, Size(32, 32));
DCT變換
Mat srcDCT; dct(src, srcDCT);
計(jì)算DCT左上角8*8像素區(qū)域均值,求hash值
double sum = 0; for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) sum += srcDCT.at<float>(i,j); double average = sum/64; Mat phashcode= Mat::zeros(Size(8, 8), CV_8U); for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) phashcode.at<char>(i,j) = srcDCT.at<float>(i,j) > average ? 1:0;
hash值匹配
int d = 0; for (int n = 0; n < srchash.size[1]; n++) if (srchash.at<uchar>(0,n) != dsthash.at<uchar>(0,n)) d++;
即,計(jì)算兩幅圖哈希值之間的漢明距離,漢明距離越大,兩圖片越不相似。
OpenCV實(shí)現(xiàn)
如圖在下圖中對(duì)比各個(gè)圖像與圖person.jpg的漢明距離,以此衡量?jī)蓤D之間的額相似度。
#include <iostream> 
#include <stdio.h>
#include <fstream>
#include <io.h>
#include <string>
#include <opencv2\opencv.hpp> 
#include <opencv2\core\core.hpp>
#include <opencv2\core\mat.hpp>
using namespace std; 
using namespace cv; 
int fingerprint(Mat src, Mat* hash);
int main()
{
 Mat src = imread("E:\\image\\image\\image\\person.jpg", 0); 
 if(src.empty())
 {
  cout << "the image is not exist" << endl; 
  return -1;
 }
 Mat srchash, dsthash;
 fingerprint(src, &srchash);
 for(int i = 1; i <= 8; i++)
 { 
  string path0 = "E:\\image\\image\\image\\person";
  string number; 
  stringstream ss; 
  ss << i; 
  ss >> number; 
  string path = "E:\\image\\image\\image\\person" + number +".jpg"; 
  Mat dst = imread(path, 0); 
  if(dst.empty())
  {
   cout << "the image is not exist" << endl; 
   return -1;
  }
  fingerprint(dst, &dsthash);
  int d = 0;
  for (int n = 0; n < srchash.size[1]; n++)
   if (srchash.at<uchar>(0,n) != dsthash.at<uchar>(0,n)) d++; 
  cout <<"person" << i <<" distance= " <<d<<"\n"; 
 }
 system("pause");
 return 0;
}
int fingerprint(Mat src, Mat* hash)
{
 resize(src, src, Size(32, 32));
 src.convertTo(src, CV_32F);
 Mat srcDCT; 
 dct(src, srcDCT);
 srcDCT = abs(srcDCT);
 double sum = 0;
 for (int i = 0; i < 8; i++)
  for (int j = 0; j < 8; j++)
   sum += srcDCT.at<float>(i,j);
 double average = sum/64;
 Mat phashcode= Mat::zeros(Size(8, 8), CV_8U);
 for (int i = 0; i < 8; i++)
  for (int j = 0; j < 8; j++)
   phashcode.at<char>(i,j) = srcDCT.at<float>(i,j) > average ? 1:0;
 *hash = phashcode.reshape(0,1).clone();
 return 0;
}
輸出漢明距離:
可以看出若將閾值設(shè)置為20則可將后三張其他圖片篩選掉。
以上這篇opencv3/C++ PHash算法圖像檢索詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持我們。
欄 目:C語(yǔ)言
下一篇:c++ 調(diào)用python傳輸圖片實(shí)例
本文標(biāo)題:opencv3/C++ PHash算法圖像檢索詳解
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/78.html
您可能感興趣的文章
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
 - 01-10深入理解C++中常見(jiàn)的關(guān)鍵字含義
 - 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
 - 01-10c++中inline的用法分析
 - 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
 - 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
 - 01-10C++大數(shù)模板(推薦)
 - 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
 - 01-10深入C/C++浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)方式詳解
 - 01-10深入理解C/C++混合編程
 


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
 - 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
 - 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
 - 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
 - 5c語(yǔ)言計(jì)算三角形面積代碼
 - 6什么是 WSH(腳本宿主)的詳細(xì)解釋
 - 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
 - 8正則表達(dá)式匹配各種特殊字符
 - 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
 - 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
 
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
 - 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
 - 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
 - 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
 - 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
 - 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
 - 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
 - 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
 - 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
 - 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
 
隨機(jī)閱讀
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
 - 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
 - 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
 - 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
 - 01-10delphi制作wav文件的方法
 - 01-10C#中split用法實(shí)例總結(jié)
 - 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
 - 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
 - 04-02jquery與jsp,用jquery
 - 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
 


