我在使用aHash和dHash时遇到一些问题:
http://www.hackerfactor.com/blog/?/archives/529-Kind-of-Like-That.html

我用过C++和OpenCV

问题在于,dHash的性能比aHash差。尽管从理论上讲,它应该更好。例如:
我选择了一张图片,对其进行了一些处理,然后计算出原始图像和修改后图像的哈希值之间的汉明距离。
The result is there

这是aHash的功能

__int64 calcImageHash(IplImage* src, bool show_results)
{
    if(!src){
        return 0;
    }
    IplImage *res=0, *gray=0, *bin =0;
    res = cvCreateImage( cvSize(8, 8), src->depth, src->nChannels);
    gray = cvCreateImage( cvSize(8, 8), IPL_DEPTH_8U, 1);
    bin = cvCreateImage( cvSize(8, 8), IPL_DEPTH_8U, 1);
    cvResize(src, res);
    cvCvtColor(res, gray, CV_BGR2GRAY);
    CvScalar average = cvAvg(gray);
    printf("[i] average: %.2f \n", average.val[0]);
    cvThreshold(gray, bin, average.val[0], 255, CV_THRESH_BINARY);
    __int64 hash = 0;
    int i=0;
    for( int y=0; y<bin->height; y++ ) {
        uchar* ptr = (uchar*) (bin->imageData + y * bin->widthStep);
        for( int x=0; x<bin->width; x++ ) {
            if(ptr[x]){
                hash |= (__int64)1<<i;
            }
            i++;
        }
    }
    printf("[i] hash: %I64X \n", hash);
    cvReleaseImage(&res);
    cvReleaseImage(&gray);
    cvReleaseImage(&bin);
    return hash;
}

和功能为dHash
__int64 calcImageHash(IplImage* src, bool show_results)
{
    if(!src)
    {
        return 0;
    }

    IplImage *res=0, *gray=0;
    res = cvCreateImage( cvSize(9,8), src->depth, src->nChannels);
    gray = cvCreateImage( cvSize(9,8), IPL_DEPTH_8U, 1);
    cvResize(src, res);
    cvCvtColor(res, gray, COLOR_BGR2GRAY);
    __int64 hash = 0;
    int i=0;
    cout<<gray->height;
    for( int y=0; y<gray->height; y++ ) {
        uchar* ptr = (uchar*) (gray->imageData + y* gray->widthStep);
        for( int x=0; x<gray->width-1; x++ ) {
            if( ptr[x+1] > ptr[x] ){
                hash |= (__int64)1<<i;
            }
            i++;
        }
    }
    printf("[i] hash: %I64X \n", hash, "\n");
    std::cout<<endl;
    cvReleaseImage(&res);
    cvReleaseImage(&gray);
    return hash;
}

最佳答案

以防万一也有人遇到这个问题,我注意到dhash在插图和某些艺术品方面有一个特定的弱点。
更具体地说,对于对比度非常低或包含大面积纯色的任何图像,它倾向于随机性。我正在处理艺术照片集,对于素描,线条画或艺术品本身由纯色passepartout框住的问题尤其明显。
发生这种情况的原因在某种程度上是显而易见的:实心区域可能会随机地看到一个片段比相邻片段的亮度略高一些,甚至有很小的有损压缩失真。但是我对它的大小感到有些惊讶:将图像缩放50%通常会导致肉眼无法分辨图像,但是dhash差接近随机性。
通过比较不是> = vs >(b + 15),我看到了一些改进。这里的理由是纯色相对丰富,但是线性渐变(将再次导致相同的病理类型)相对很少。如果仍然存在问题,也可以使偏差随机,但取决于位置,即e。 “在(x = 3,y = 5)处加12,在x = 20,y = 5处减去3。具有匹配图案的大量图像的概率将远低于纯色且规定良好的图像渐变。

10-07 21:29