C#對比圖片相似度


第一步 縮小圖片尺寸

        將圖片縮小到8x8的尺寸, 總共64個像素. 這一步的作用是去除各種圖片尺寸和圖片比例的差異, 只保留結構、明暗等基本信息.

第二步 轉為灰度圖片

         將縮小后的圖片, 轉為64級灰度圖片.

第三步 計算灰度平均值

         計算圖片中所有像素的灰度平均值

第四步 比較像素的灰度

        將每個像素的灰度與平均值進行比較, 如果大於或等於平均值記為1, 小於平均值記為0.

第五步 計算哈希值

         將上一步的比較結果, 組合在一起, 就構成了一個64位的二進制整數, 這就是這張圖片的指紋.

第六步 對比圖片指紋

        得到圖片的指紋后, 就可以對比不同的圖片的指紋, 計算出64位中有多少位是不一樣的. 如果不相同的數據位數不超過5, 就說明兩張圖片很相似, 如果大於10, 說明它們是兩張不同的圖片.

 

 

 

using   System;
using   System.IO;
using   System.Drawing;
 
namespace   SimilarPhoto
{
      class   SimilarPhoto
      {
          Image SourceImg;
 
          public   SimilarPhoto(  string   filePath)
          {
              SourceImg = Image.FromFile(filePath);
          }
 
          public   SimilarPhoto(Stream stream)
          {
              SourceImg = Image.FromStream(stream);
          }
 
          public   String GetHash()
          {
              Image image = ReduceSize();
              Byte[] grayValues = ReduceColor(image);
              Byte average = CalcAverage(grayValues);
              String reslut = ComputeBits(grayValues, average);
              return   reslut;
          }
 
          // Step 1 : Reduce size to 8*8
          private   Image ReduceSize(  int   width = 8,   int   height = 8)
          {
              Image image = SourceImg.GetThumbnailImage(width, height, () => {   return   false  ; }, IntPtr.Zero);
              return   image;
          }
 
          // Step 2 : Reduce Color
          private   Byte[] ReduceColor(Image image)
          {
              Bitmap bitMap =   new   Bitmap(image);
              Byte[] grayValues =   new   Byte[image.Width * image.Height];
 
              for  (  int   x = 0; x<image.Width; x++)
                  for   (  int   y = 0; y < image.Height; y++)
                  {
                      Color color = bitMap.GetPixel(x, y);
                      byte   grayValue = (  byte  )((color.R * 30 + color.G * 59 + color.B * 11) / 100);
                      grayValues[x * image.Width + y] = grayValue;
                  }
              return   grayValues;
          }
 
          // Step 3 : Average the colors
          private   Byte CalcAverage(  byte  [] values)
          {
              int   sum = 0;
              for   (  int   i = 0; i < values.Length; i++)
                  sum += (  int  )values[i];
              return   Convert.ToByte(sum / values.Length);
          }
 
          // Step 4 : Compute the bits
          private   String ComputeBits(  byte  [] values,   byte   averageValue)
          {
              char  [] result =   new   char  [values.Length];
              for   (  int   i = 0; i < values.Length; i++)
              {
                  if   (values[i] < averageValue)
                      result[i] =   '0'  ;
                  else
                      result[i] =   '1'  ;
              }
              return   new   String(result);
          }
 
          // Compare hash
          public   static   Int32 CalcSimilarDegree(  string   a,   string   b)
          {
              if   (a.Length != b.Length)
                  throw   new   ArgumentException();
              int   count = 0;
              for   (  int   i = 0; i < a.Length; i++)
              {
                  if   (a[i] != b[i])
                      count++;
              }
              return   count;
          }
      }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM