Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 比较位图列表中图像的最佳方法是什么_C#_Algorithm_Performance - Fatal编程技术网

C# 比较位图列表中图像的最佳方法是什么

C# 比较位图列表中图像的最佳方法是什么,c#,algorithm,performance,C#,Algorithm,Performance,我正在开发一个应用程序,在这个应用程序中,我可以在一个列表中加载多张图片,并将该列表中的每张图片相互比较,以便找到重复的图片 因此,首先我成功地获取了图片并将其加载到IList: 我会避免对同一个图像多次计算哈希值,并且只在图像中循环一次: public static void Main(string[] args) { var files = new Dictionary<string, string>(); foreach (var file in Directo

我正在开发一个应用程序,在这个应用程序中,我可以在一个列表中加载多张图片,并将该列表中的每张图片相互比较,以便找到重复的图片

因此,首先我成功地获取了图片并将其加载到
IList


我会避免对同一个图像多次计算哈希值,并且只在图像中循环一次:

public static void Main(string[] args)
{
    var files = new Dictionary<string, string>();
    foreach (var file in Directory.GetFiles("c:\\", "*.png"))
    {
        files.Add(file, CalculateHash(file));
    }

    var duplicates = files.GroupBy(item => item.Value).Where(group => group.Count() > 1);
}

private static string CalculateHash(string file)
{
    using (var stream = File.OpenRead(file))
    {
        var sha = new SHA256Managed();
        var checksum = sha.ComputeHash(stream);
        return BitConverter.ToString(checksum).Replace("-", String.Empty);
    }
}
publicstaticvoidmain(字符串[]args)
{
var files=newdictionary();
foreach(Directory.GetFiles(“c:\\”,“*.png”)中的var文件)
{
文件.Add(文件,CalculateHash(文件));
}
var duplicates=files.GroupBy(item=>item.Value).Where(group=>group.Count()>1);
}
私有静态字符串CalculateHash(字符串文件)
{
使用(var stream=File.OpenRead(File))
{
var sha=新的SHA256Managed();
var校验和=sha.ComputeHash(流);
返回BitConverter.ToString(校验和)。替换(“-”,String.Empty);
}
}
  • 无法确保具有相同哈希的两个图像相等

  • 如果哈希函数使用图像的所有字节,则可以更快地比较图像的字节,而不是计算哈希并进行比较

  • 可以多次计算每个图像的哈希值。你不需要这样做

  • 我建议采取以下措施:

  • 计算每个图像的哈希值并存储它

  • 使用一个映射或两个循环查找哈希冲突

  • 具有相同哈希的图像需要逐字节进行比较,以确保它们相等


  • 您已经在计算每个图像的哈希值,因此可以将其转换为例如
    字符串
    ,然后只需使用
    字典
    ,其中
    将是哈希值。您可以使用
    ContainsKey
    快速确定图像哈希是否已在列表中


    由于您是通过流打开图像文件,因此有一种更简单的方法可以从
    stream
    计算哈希值,如下所述。您可能需要倒带流来读取图像。

    而不是
    列表
    ,我会将其保存为定义为
    {image,Hash}
    的自定义类,以便哈希只需计算一次。如果处理图像,该类也可以负责。其他信息,如路径名,可能也很方便,这取决于应用程序的功能。你不应该在列表中浏览两次,因为
    list[a]=list[b]
    应该等于
    list[b]=list[a]
    @RubensFarias是的,这是我试图避免做的第一件事哦,这是一个有趣的方法,我没有想到过,谢谢但是这不起作用,因为两个具有相同元素的
    byte[]
    数组被认为是不相等的(对于GroupBy也是如此),所以这段代码不会检测到重复的数组(同样,
    Directory.GetFiles
    也会因为这样的参数而失败,但这不是很重要)。我刚修好。
    public static CompareResult Compare(Bitmap bmp1, Bitmap bmp2)
            {
                CompareResult cr = CompareResult.ciCompareOk;
    
                //Test to see if we have the same size of image
                if (bmp1.Size != bmp2.Size)
                {
                    cr = CompareResult.ciSizeMismatch;
                }
                else
                {
                    //Convert each image to a byte array
                    System.Drawing.ImageConverter ic =
                           new System.Drawing.ImageConverter();
                    byte[] btImage1 = new byte[1];
                    btImage1 = (byte[])ic.ConvertTo(bmp1, btImage1.GetType());
                    byte[] btImage2 = new byte[1];
                    btImage2 = (byte[])ic.ConvertTo(bmp2, btImage2.GetType());
    
                    //Compute a hash for each image
                    SHA256Managed shaM = new SHA256Managed();
                    byte[] hash1 = shaM.ComputeHash(btImage1);
                    byte[] hash2 = shaM.ComputeHash(btImage2);
    
                    //Compare the hash values
                    for (int i = 0; i < hash1.Length && i < hash2.Length
                                      && cr == CompareResult.ciCompareOk; i++)
                    {
                        if (hash1[i] != hash2[i])
                            cr = CompareResult.ciPixelMismatch;
                    }
                }
                return cr;
            } 
    
    public void ComparePictureList()
            {
    
                IList<Bitmap> picturesList = getPictures();
    
                foreach (var picture1 in picturesList)
                {
                    foreach( var picture2 in picturesList)
                    {
                        Compare(picture1, picture2);
                    }
                }
    
            }
    
       public Bitmap ConvertToBitmap(string fileName)
            {
                Bitmap bitmap;
                using (Stream bmpStream = System.IO.File.Open(fileName, System.IO.FileMode.Open))
                {
                    Image image = Image.FromStream(bmpStream);
    
                    bitmap = new Bitmap(image);
    
                }
                return bitmap;
            }
    
    public static void Main(string[] args)
    {
        var files = new Dictionary<string, string>();
        foreach (var file in Directory.GetFiles("c:\\", "*.png"))
        {
            files.Add(file, CalculateHash(file));
        }
    
        var duplicates = files.GroupBy(item => item.Value).Where(group => group.Count() > 1);
    }
    
    private static string CalculateHash(string file)
    {
        using (var stream = File.OpenRead(file))
        {
            var sha = new SHA256Managed();
            var checksum = sha.ComputeHash(stream);
            return BitConverter.ToString(checksum).Replace("-", String.Empty);
        }
    }