为什么aHash比dHash更好用
Why does aHash work better than dHash?
我对aHash和dHash有一些问题:http://www.hackerfactor.com/blog/?/archives/529-Kind-of-Like-That.html
我用了C++和OpenCV
问题是dHash比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 在插图和一些艺术品方面有一个特定的弱点。
更具体地说,对于任何对比度非常低或包含大面积纯色的图像,它都倾向于随机性。我正在处理一系列艺术照片,对于草图、线条绘制或艺术品本身由纯色通道框住的地方,这个问题尤其明显。
为什么会发生这种情况有点明显:固体区域很容易随机看到一个片段比相邻的片段略亮,即使是轻微的有损压缩伪影。但我对它的大小感到有些惊讶:简单地将图像缩放 50% 通常会导致肉眼无法区分的图像,但会产生接近随机性的 dhash 差异。
我已经看到了一些改进,通过比较不是关于>= 与 <,而是添加一些任意的偏差,例如需要>= (b + 15(。这里的原因是纯色相对丰富,但线性梯度(这将再次导致相同的病理(相对罕见。如果这仍然是一个问题,也可以使偏差随机但与位置相关,即"在 (x=3, y=5( 处加 12,在 x=20, y=5 处减去 3(。大量图像具有匹配图案的概率将远低于纯色和明确规定的渐变。
相关文章:
- C++:将控制台输出存储在宏中更好吗
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 初始化具有非默认构造函数的std::数组项的更好方法
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 为什么新的随机库比std::rand()更好
- 寻找一种更好的方法来表示无符号字符数组
- 哪种方法更好,性能明智
- 什么更好?返回对象指针列表?或返回指向对象列表的指针?
- 什么是更好的做法?通过指针或标识符传递类成员?
- 寻求更好地理解标准::访问
- 线程消息传递或更好:在"大师班"中访问其他班级的成员
- 有没有更好的方法来处理异常? try-catch块真的很丑
- 如何更好地检查两个 char 变量是否在一组值中?
- 有没有更好的方法对C++中的三个整数进行排序?
- 什么模板用法在阶乘中更好
- 平面缓冲区可以利用向量中的 0 吗?还是其他小波比哈尔变换更好?
- 我们应该如何使用枚举类进行索引(或者我们应该更好地避免这种情况)?
- Protobuf中重复字段的问题.使用重复字段进行序列化/反序列化的更好方法是什么?
- 比使用 s.str().c_str() 更好的表达?
- 为什么aHash比dHash更好用