簡體   English   中英

pHash 返回不同的哈希長度

[英]pHash returning different hash lenght

我有以下代碼:

指紋.cpp:

#include <iostream>
#include <filesystem>

#include "ImageHash.h"

#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/imgcodecs.hpp>

using namespace std;


void usage (char** argv) noexcept  {
    cout << "Usage: " << argv[0] << " <image or dir>" << endl << "Example: " << argv[0] << " template.png" << endl;
}

int main(int argc, char** argv) {
    if (argc != 2) {
        usage(argv);
        return 1;
    }

    auto imgHash = ImageHash();

    if (std::filesystem::is_directory(argv[1])) {
        for (const auto& dirEntry : std::filesystem::recursive_directory_iterator(argv[1])) {
            auto filePath = dirEntry.path();
            std::string fileName = dirEntry.path().filename().string();
        
            cv::Mat img = cv::imread(filePath.string(), cv::IMREAD_GRAYSCALE);
            img.resize(8*8);

            /*cv::imshow("img", img);
            cv::waitKey();*/
            
            cout << fileName << "\t\t" << imgHash.getHashString(img) << endl;
        }

    }
    else if (std::filesystem::is_regular_file(argv[1])){
        cv::Mat img = cv::imread(argv[1], cv::IMREAD_GRAYSCALE);
        cout << std::filesystem::path(argv[1]).filename().string() << "\t\t" << imgHash.getHashString(img) << endl;
    }
    else {
        usage(argv);
    }

    return 0;
}

ImageHash.cpp:

#include "ImageHash.h"

#include <iomanip> 

using namespace std;

ImageHash::ImageHash()
{
    pHash = cv::img_hash::PHash::create();
}

std::string ImageHash::convertHashToString(vector<bool> hash) {
    std::string ret = "";
    double h = 0;
    for (unsigned int i = 0; i < hash.size(); i++) {
        if (hash[i]) {
            h += pow(2, (i % 8));
        }

        if (i % 8 == 7) {
            std::stringstream buffer;
            buffer << std::hex << std::setfill('0') << std::setw(2) << h;
            ret += buffer.str();
            h = 0;
        }
    }
    return ret;
}

std::vector<bool> ImageHash::hex_str_to_hash(std::string inputString) {
    std::vector<bool> hash;
    size_t size = inputString.size() / 2;
    for (int i = 0; i < size; i++) {
        std::string str2 = inputString.substr(i * 2, 2);
        if (str2.empty()) {
            continue;
        }

        unsigned int value = 0;
        std::stringstream SS(str2);
        SS >> std::hex >> value;
        for (int j = 0; j < 8; j++) {
            bool check = !!((value >> j) & 1);
            hash.push_back(check);
        }
    }
    return hash;
}

std::vector<bool> ImageHash::matHashToBoolArr(cv::Mat const inHash) {
    const unsigned char* data = inHash.data;
    std::vector<bool> v;
    for (int i = 0; i < 8; i++) {
        unsigned char c = data[i];
        for (int j = 0; j < 8; j++) {
            int shift = (8 - j) - 1;
            bool val = ((c >> shift) & 1);
            v.push_back(val);
        }
    }
    return v;
}

std::vector<bool> ImageHash::computeHash(cv::Mat const input) {
    cv::Mat inHash;
    pHash->compute(input, inHash);
    return matHashToBoolArr(inHash);
}

std::string ImageHash::getHashString(cv::Mat const input) {
    return convertHashToString(computeHash(input));
}

//returns hamming distance
int ImageHash::getHashDistance(std::vector<bool>& hash1, std::vector<bool>& hash2) {
    //assert(hash1.size() == hash2.size());
    
    /* ToDo: I don't know why the size is not the same but if if is lets add padding to the smaller one
    This does not seem to make it work*/
    if (hash1.size() != hash2.size()) {
        auto smaller = hash1.size() < hash2.size() ? &hash1 : &hash2;
        auto larger = hash1.size() < hash2.size() ? hash2 : hash1;
        smaller->resize(larger.size());
        std::fill(begin(*smaller) + larger.size(), end(*smaller), 0);
    }


    int dist = 0;
    for (unsigned int i = 0; i < hash1.size(); i++) {
        dist += (hash1[i] != hash2[i]);
    }
    return dist;
}

出於某種原因,根據輸入圖像,返回的散列具有不同的大小。 我試圖在 getHashDistance() 中添加一些填充,但我認為我不應該這樣做,因為現在當我計算兩個相似圖像之間的距離時,我得到了很大的距離,就好像它們不相似一樣。

你知道這是為什么嗎? 我正在將圖像大小調整為 8*8 img.resize(8*8); 我認為它會成功,但它不起作用。

謝謝,謝謝

auto imgHash = ImageHash();

是否是這里的 auto 關鍵字導致運行時對返回的類型(以及返回類型的大小)進行不同的推斷?

C++ 中的類型推斷(auto 和 decltype)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM