zoukankan      html  css  js  c++  java
  • 通过哈希指纹搜索图像


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

    (1)缩小尺寸:去除高频和细节的最快方法是缩小图片,将图片缩小到8x8的尺寸,总共64个像素。不要保持纵横比,只需将其变成8*8的正方形。这样就可以比较任意大小的图片,摒弃不同尺寸、比例带来的图片差异。
    (2)简化色彩:将8*8的小图片转换成灰度图像。
    (3)计算平均值:计算所有64个像素的灰度平均值。
    (4)比较像素的灰度:将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。
    (5)计算hash值:将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。

    比较两个图片的相似性,就是先计算这两张图片的hash指纹,也就是64位0或1值,然后计算不同位的个数(汉明距离)。如果这个值为0,则表示这两张图片非常相似,如果汉明距离小于5,则表示有些不同,但比较相近,如果汉明距离大于10则表明完全不同的图片。

     1 // 递归获得文件夹下面所有的图片路径
     2 void getFolderDayFile(CString pathStr, vector<CString>& strFileVector)
     3 {
     4     CString myDataPath, fdPath;
     5     myDataPath = pathStr + _T("\*.*");
     6     CString strTmp;
     7     CFileFind find;
     8     bool bf = find.FindFile(myDataPath);
     9 
    10     while(bf) {
    11         bf = find.FindNextFile();
    12         if(!find.IsDots())
    13         {
    14             fdPath = find.GetFilePath();
    15             if(find.IsDirectory())
    16                 getFolderDayFile(fdPath, strFileVector);        // 是文件夹,递归,继续查询
    17             else
    18             {
    19                 strTmp = fdPath.Right(4);                    // 是文件,判断是否是*.jpg文件
    20                 strTmp.MakeLower();
    21                 if(strTmp == ".jpg")
    22                     strFileVector.push_back(fdPath);
    23             }
    24         }
    25     }
    26     find.Close();
    27 }
    28 
    29 
    30 // 哈希指纹获取 
    31 vector<int> Perceptual_hash(IplImage *image)
    32 {
    33     IplImage * temp = cvCreateImage(cvSize(8,8),8,3);
    34     cvResize(image, temp, CV_INTER_CUBIC);        // 8*8大小--缩小尺寸
    35     IplImage * grayImg = cvCreateImage(cvSize(8,8),8,1);
    36     cvCvtColor(temp,grayImg,CV_BGR2GRAY);        // 转灰度--简化色彩
    37 
    38     char *data = (char *)grayImg->imageData;    // 新图象数据信息
    39     int  wp = grayImg->widthStep;
    40 
    41     int average = 0;
    42     for(int i = 0;i < 8;i++)
    43         for(int j = 0;j < 8;j++)
    44             average += data[i * wp + 3 * j];
    45     average /= 64;
    46     vector<int> VImg;
    47     for(int m = 0;m < 8;m++)
    48         for(int n = 0;n < 8;n++)
    49             if(data[m * wp + 3 * n] >= average)
    50                 VImg.push_back(1);
    51             else
    52                 VImg.push_back(0);
    53     return VImg;
    54 }
    55 
    56 
    57 // 通过哈希指纹搜索图片
    58 void Hash_search(IplImage *image, CString path)
    59 {
    60     vector<int> hash_image = Perceptual_hash(image);
    61     vector<CString> strFileVector;
    62     getFolderDayFile(path, strFileVector);
    63     printf("%d
    ", strFileVector.size());
    64 
    65     for(int i = 0;i < strFileVector.size();i++)
    66     {
    67         IplImage * src = cvLoadImage(strFileVector[i]);
    68         vector<int> hash_src = Perceptual_hash(src);
    69         int com = 0;
    70         for(int j = 0;j < 64;j++)
    71             if(hash_src[j] != hash_image[j])
    72                 com++;
    73         if(com <= 5) {            // 相似度量
    74             CString str;
    75             str.Format("D:\101_Image\%d.jpg",i);
    76             cvSaveImage(str, src);
    77         }
    78         cvReleaseImage(&src);
    79     }
    80 }

    搜索得到的图像(距离太小,只搜索到原图像):

    另附一个直方图搜索:

     1 // 通过直方图搜索图像
     2 void Histogram_search(IplImage *image, CString path)
     3 {
     4     CvHistogram * image_hist = Histogram_Image(image);
     5     vector<CString> strFileVector;
     6     getFolderDayFile(path, strFileVector);
     7     printf("%d
    ", strFileVector.size());
     8     for(int i = 0;i < strFileVector.size();i++) {
     9         IplImage * src = cvLoadImage(strFileVector[i]);
    10         CvHistogram * src_hist = Histogram_Image(src);
    11         // 直方图相似--Bhattacharyya距离
    12         double com = cvCompareHist(image_hist, src_hist, CV_COMP_BHATTACHARYYA);
    13         if(com < 0.1) {            // 相似度量
    14             CString str;
    15             str.Format("D:\101_Image\%d.jpg",i);
    16             cvSaveImage(str, src);
    17         }
    18         cvReleaseImage(&src);
    19     }
    20 }

    2021-06-04

  • 相关阅读:
    MT【296】必要性探路
    MT【295】线段比的仿射变换
    MT【294】函数定义的理解
    MT【293】拐点处切线
    MT【292】任意存在求最值
    MT【291】2元非齐次不等式
    MT【290】内外圆求三角最值
    MT【289】含参绝对值的最大值之三
    MT【288】必要性探路
    Xadmin-自定义字段支持实时编辑
  • 原文地址:https://www.cnblogs.com/2015-16/p/14851208.html
Copyright © 2011-2022 走看看