我今天大部分时间都在寻找一种生成已知图像密钥的函数,以便稍后进行比较以确定图像。我尝试使用SIFT和SURF描述符,但两者都太慢(并且商业用途需要付专利费)。我最新的尝试是创建一个DCT哈希,使用以下方法:
int mm_dct_imagehash(const char* file, float sigma, uint64_t *hash){
if (!file) return -1;
if (!hash) return -2;
*hash = 0;
IplImage *img = cvLoadImage(file, CV_LOAD_IMAGE_GRAYSCALE);
if (!img) return -3;
cvSmooth(img, img, CV_GAUSSIAN, 7, 7, sigma, sigma);
IplImage *img_resized = cvCreateImage(cvSize(32,32), img->depth, img->nChannels);
if (!img_resized) return -4;
cvResize(img, img_resized, CV_INTER_CUBIC);
IplImage *img_prime = cvCreateImage(cvSize(32,32), IPL_DEPTH_32F, img->nChannels);
if (!img_prime) return -5;
cvConvertScale(img_resized, img_prime,1, 0);
IplImage *dct_img = cvCreateImage(cvSize(32,32), IPL_DEPTH_32F, img->nChannels);
if (!dct_img) return -6;
cvDCT(img_prime, dct_img, CV_DXT_FORWARD);
cvSetImageROI(dct_img, cvRect(1,1,8,8));
double minval, maxval;
cvMinMaxLoc(dct_img, &minval, &maxval, NULL, NULL, NULL);
double medval = (maxval + minval)/2;
int i,j;
for (i=1;i<=8;i++){
const float *row = (const float*)(dct_img->imageData + i*dct_img->widthStep);
for (j=1;j<=8;j++){
if (row[j] > medval){
(*hash) |= 1;
}
(*hash) <<= 1;
}
}
cvReleaseImage(&img);
cvReleaseImage(&img_resized);
cvReleaseImage(&img_prime);
cvReleaseImage(&dct_img);
return 0;
}
这确实生成了我所寻找的类型之一,但当我尝试将其与已知哈希值数据库进行比较时,我得到了和正面一样多的误报。因此,我回到了起点,想向专家们请教。
你是否知道/有没有一个函数可以为提供的图像生成某种标识符/校验和,该标识符/校验和在类似图像之间保持相似,因此可以通过与数据库比较快速识别图像?简而言之,图像最适合哪种校验和类别?
我不是在寻找理论、概念、论文或想法,而是要找到实际可行的解决方案。我不想再花一天时间在死胡同里挖掘,感谢任何花时间编写代码的人。
进一步研究后,我知道AutoIt开发人员设计了PixelChecksum以使用“Adler-32”算法。我想下一步是找到C实现并让它处理像素数据。欢迎任何建议!