opencv_contrib icon indicating copy to clipboard operation
opencv_contrib copied to clipboard

modules/img_hash/src/marr_hildreth_hash.cpp: error in kernel computation ?

Open orzel opened this issue 6 months ago • 3 comments

In modules/img_hash/src/marr_hildreth_hash.cpp:getMHKernel(), the line reads

kPtr[col] = (2-a)*std::exp(a/2);

While it seems it should be

kPtr[col] = (2-a)*std::exp(-a/2);

At least that's what the original code does: https://github.com/aetilius/pHash/blob/master/src/pHash.cpp#L610

CImg<float> *GetMHKernel(float alpha, float level) {
    int sigma = (int)4 * pow((float)alpha, (float)level);
    static CImg<float> *pkernel = NULL;
    float xpos, ypos, A;
    if (!pkernel) {
        pkernel = new CImg<float>(2 * sigma + 1, 2 * sigma + 1, 1, 1, 0);
        cimg_forXY(*pkernel, X, Y) {
            xpos = pow(alpha, -level) * (X - sigma);
            ypos = pow(alpha, -level) * (Y - sigma);
            A = xpos * xpos + ypos * ypos;
            pkernel->atXY(X, Y) = (2 - A) * exp(-A / 2);
        }
    }
    return pkernel;
}

And that also matches the formula given on wikipedia: https://en.wikipedia.org/wiki/Ricker_wavelet

orzel avatar May 21 '25 13:05 orzel

Once fixed, that would really be useful to fix/redo the tests from https://qtandopencv.blogspot.com/2016/06/introduction-to-image-hash-module-of.html

orzel avatar May 21 '25 18:05 orzel

There are other important problems with this code. For ex. it's not thread-safe. Or (related, but different) also all temporaries are class variables (blocks, blurImg, freImg, ...) for no good reason.

orzel avatar May 22 '25 18:05 orzel

In modules/img_hash/src/marr_hildreth_hash.cpp:getMHKernel(), the line reads

kPtr[col] = (2-a)*std::exp(a/2);

While it seems it should be

kPtr[col] = (2-a)*std::exp(-a/2);

/cc @stereomatchingkiss

s-trinh avatar Jun 17 '25 20:06 s-trinh