c# - 在 C# 中比较两个图像的算法

标签 c# image hash

我正在用 C# 编写一个工具来查找重复的图像。目前,我创建文件的 MD5 校验和并进行比较。

不幸的是,图像可能是:

  • 旋转 90 度。
  • 具有不同的尺寸(较小的图像但内容相同)。
  • 具有不同的压缩或文件类型(例如 jpeg 工件,见下文)。

higher resolution koala lower resolution koala

解决这个问题的最佳方法是什么?

最佳答案

这是一个使用 256 位图像哈希的简单方法(MD5 有 128 位)

  1. 将图片调整为16x16像素

16x16 resized

  1. 将颜色减少为黑色/白色(在此控制台输出中等于true/false)<

enter image description here

  1. 将 bool 值读入List<bool> - 这是散列

代码:

public static List<bool> GetHash(Bitmap bmpSource)
{
    List<bool> lResult = new List<bool>();         
    //create new image with 16x16 pixel
    Bitmap bmpMin = new Bitmap(bmpSource, new Size(16, 16));
    for (int j = 0; j < bmpMin.Height; j++)
    {
        for (int i = 0; i < bmpMin.Width; i++)
        {
            //reduce colors to true / false                
            lResult.Add(bmpMin.GetPixel(i, j).GetBrightness() < 0.5f);
        }             
    }
    return lResult;
}

我知道,GetPixel不是那么快,但在 16x16 像素的图像上它不应该是瓶颈。

  1. 将此散列值与其他图像的散列值进行比较并添加容差。(可以与其他散列值不同的像素数)

代码:

List<bool> iHash1 = GetHash(new Bitmap(@"C:\mykoala1.jpg"));
List<bool> iHash2 = GetHash(new Bitmap(@"C:\mykoala2.jpg"));

//determine the number of equal pixel (x of 256)
int equalElements = iHash1.Zip(iHash2, (i, j) => i == j).Count(eq => eq);

所以这段代码能够找到相同的图像:

  • 不同的文件格式(例如 jpg、png、bmp)
  • 旋转 (90, 180, 270),水平/垂直翻转 - 通过改变 i 的迭代顺序和 j
  • 不同的维度(需要相同的方面)
  • 不同的压缩(在质量损失的情况下需要容忍,例如 jpeg 伪影)- 您可以接受 99% 的平等是同一图像,50% 的平等是不同的图像。
  • colored 更改为 geyscaled,反之亦然(因为亮度与颜色无关)

更新/改进:

在使用这种方法一段时间后,我注意到可以做一些改进

  • replacing GetPixel为了更好的表现
  • 使用exeif-thumbnail而不是读取整个图像以提高性能
  • 而不是设置0.5f区分明暗 - 使用所有 256 个像素的不同中值亮度。否则,暗/亮图像被假定为相同,并且它能够检测亮度发生变化的图像。
  • 如果你需要fast计算,使用 bool[]List<bool>如果您需要存储大量哈希值以节省内存,请使用 Bitarray因为 bool 值没有存储在位中,所以它需要一个 byte !

关于c# - 在 C# 中比较两个图像的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35151067/

相关文章:

c# - 从主 ASP .NET 应用程序中分离出 Web API Controller

c# - Windows 窗体 PictureBox.Image 为空,即使窗体中显示了图像

c# - 在 Try/Catch 中包含 ExecuteReader 使其成功?

java - 如何在paintComponent方法中向图像添加颜色层?

html - 如何用图片填充div

java - 使用二叉搜索树和哈希创建字典

python - .py 文件中的哈希密码

database - 关于哈希盐的综合信息

c# - 未找到 WebApi Controller 测试方法

c# - ApplicationDataCompositeValue 的大小