首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

圖像相似度計算:感知哈希算法原理與 OpenCV 實現

     編輯:關於C++

感知哈希算法步驟

  1. 縮小:將圖像 resize 到 8×8 = 64 像素,去除細節,保留結構
  2. 灰度化:轉為 64 級灰度(或直接用灰度均值)
  3. 計算平均值:64 個像素灰度均值
  4. 二值化:≥均值 → 1,<均值 → 0,得到 64 位指紋
  5. 比較:計算兩指紋漢明距離(異位數)。≤5 相似,>10 不同

OpenCV 實現

#include 
#include 
using namespace cv;
using namespace std;

uint64_t phash(const Mat& img) {
    Mat gray, small;
    cvtColor(img, gray, COLOR_BGR2GRAY);
    resize(gray, small, Size(8,8), 0,0, INTER_CUBIC);
    Scalar mean = cv::mean(small);
    uint64_t hash = 0;
    for (int i=0; i<8; ++i) {
        uchar* row = small.ptr(i);
        for (int j=0; j<8; ++j) {
            hash = (hash<<1) | (row[j] >= mean[0]);
        }
    }
    return hash;
}

int hammingDist(uint64_t a, uint64_t b) {
    return __builtin_popcountll(a ^ b);
}

int main() {
    Mat img1 = imread("1.jpg"), img2 = imread("2.jpg");
    uint64_t h1 = phash(img1), h2 = phash(img2);
    int dist = hammingDist(h1, h2);
    cout << "Hash1: " << hex << h1 << "\nHash2: " << h2 << "\nDistance: " << dec << dist << endl;
    if (dist <= 5) cout << "Very similar\n";
    else if (dist <= 10) cout << "Somewhat similar\n";
    else cout << "Different images\n";
    return 0;
}

關鍵細節

  • INTER_CUBIC 三次插值縮放質量較好
  • 灰度均值用 `cv::mean` 計算
  • 指紋用 64 位無符號整數存儲,位操作極快
  • 漢明距離用 GCC 內建 `__builtin_popcountll`
  • 對旋轉、縮放、壓縮有較好魯棒性;對裁剪、透視變化敏感

擴展:差值哈希

計算相鄰像素差值而非與均值比較,對平移更魯棒。實現類似,只需將比較邏輯改為 `row[j] > row[j+1]`。

感知哈希是圖像去重、版權檢測、內容檢索的基礎工具,理解其原理與實現細節,可快速構建圖像相似度系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved