• 图像相似度计算之哈希值方法OpenCV实现


    http://blog.csdn.net/fengbingchun/article/details/42153261

    图像相似度计算之哈希值方法OpenCV实现

     分类:
     
     

    感知哈希算法(perceptual hash algorithm),它的作用是对每张图像生成一个“指纹”(fingerprint)字符串,然后比较不同图像的指纹。结果越接近,就说明图像越相似。

    实现步骤:

    1.      缩小尺寸:将图像缩小到8*8的尺寸,总共64个像素。这一步的作用是去除图像的细节,只保留结构/明暗等基本信息,摒弃不同尺寸/比例带来的图像差异;

    2.      简化色彩:将缩小后的图像,转为64级灰度,即所有像素点总共只有64种颜色;

    3.      计算平均值:计算所有64个像素的灰度平均值;

    4.      比较像素的灰度:将每个像素的灰度,与平均值进行比较,大于或等于平均值记为1,小于平均值记为0;

    5.      计算哈希值:将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图像的指纹。组合的次序并不重要,只要保证所有图像都采用同样次序就行了;

    6.      得到指纹以后,就可以对比不同的图像,看看64位中有多少位是不一样的。在理论上,这等同于”汉明距离”(Hamming distance,在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数)。如果不相同的数据位数不超过5,就说明两张图像很相似;如果大于10,就说明这是两张不同的图像。

    以上内容摘自:http://www.ruanyifeng.com/blog/2011/07/principle_of_similar_image_search.html

    下面是用OpenCV实现的测试代码:

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. string strSrcImageName = "src.jpg";  
    2.   
    3. cv::Mat matSrc, matSrc1, matSrc2;  
    4.   
    5. matSrc = cv::imread(strSrcImageName, CV_LOAD_IMAGE_COLOR);  
    6. CV_Assert(matSrc.channels() == 3);  
    7.   
    8. cv::resize(matSrc, matSrc1, cv::Size(357, 419), 0, 0, cv::INTER_NEAREST);  
    9. //cv::flip(matSrc1, matSrc1, 1);  
    10. cv::resize(matSrc, matSrc2, cv::Size(2177, 3233), 0, 0, cv::INTER_LANCZOS4);  
    11.   
    12. cv::Mat matDst1, matDst2;  
    13.   
    14. cv::resize(matSrc1, matDst1, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC);  
    15. cv::resize(matSrc2, matDst2, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC);  
    16.   
    17. cv::cvtColor(matDst1, matDst1, CV_BGR2GRAY);  
    18. cv::cvtColor(matDst2, matDst2, CV_BGR2GRAY);  
    19.   
    20. int iAvg1 = 0, iAvg2 = 0;  
    21. int arr1[64], arr2[64];  
    22.   
    23. for (int i = 0; i < 8; i++) {  
    24.     uchar* data1 = matDst1.ptr<uchar>(i);  
    25.     uchar* data2 = matDst2.ptr<uchar>(i);  
    26.   
    27.     int tmp = i * 8;  
    28.   
    29.     for (int j = 0; j < 8; j++) {  
    30.         int tmp1 = tmp + j;  
    31.   
    32.         arr1[tmp1] = data1[j] / 4 * 4;  
    33.         arr2[tmp1] = data2[j] / 4 * 4;  
    34.   
    35.         iAvg1 += arr1[tmp1];  
    36.         iAvg2 += arr2[tmp1];  
    37.     }  
    38. }  
    39.   
    40. iAvg1 /= 64;  
    41. iAvg2 /= 64;  
    42.   
    43. for (int i = 0; i < 64; i++) {  
    44.     arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0;  
    45.     arr2[i] = (arr2[i] >= iAvg2) ? 1 : 0;  
    46. }  
    47.   
    48. int iDiffNum = 0;  
    49.   
    50. for (int i = 0; i < 64; i++)  
    51.     if (arr1[i] != arr2[i])  
    52.         ++iDiffNum;  
    53.   
    54. cout<<"iDiffNum = "<<iDiffNum<<endl;  
    55.   
    56. if (iDiffNum <= 5)  
    57.     cout<<"two images are very similar!"<<endl;  
    58. else if (iDiffNum > 10)  
    59.     cout<<"they are two different images!"<<endl;  
    60. else  
    61.     cout<<"two image are somewhat similar!"<<endl;  
  • 相关阅读:
    如何用conda安装软件|处理conda安装工具的动态库问题
    用 Anaconda 完美解决 Python2 和 python3 共存问题
    转录组数据库介绍
    突变注释工具SnpEff,Annovar,VEP,oncotator比较分析--转载
    BioConda--转载
    生信软件的好帮手-bioconda--转载
    一些WGS健康体检网站和公司
    基于R进行相关性分析--转载
    R语言 sub与gsub函数的区别
    Docker安装
  • 原文地址:https://www.cnblogs.com/donaldlee2008/p/5277914.html
Copyright © 2020-2023  润新知