首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#中两幅图像的比较算法

C#中两幅图像的比较算法
EN

Stack Overflow用户
提问于 2016-02-02 10:35:55
回答 6查看 85.9K关注 0票数 83

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

不幸的是,这些图像可以是:

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

解决这个问题最好的办法是什么?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2016-02-02 12:44:44

下面是一种使用256位图像哈希(MD5有128位)的简单方法。

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

  1. 将颜色降为black/white (在此控制台输出中等于true/false )

  1. 将布尔值读入List<bool> --这是哈希

代码语言:javascript
运行
复制
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. 将此散列与其他图像中的哈希值进行比较,并添加一个容忍度。(与其他散列不同的像素数)

代码:

代码语言:javascript
运行
复制
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),水平/vertical翻转-通过改变ij的迭代顺序
  • 不同的尺寸(需要相同的方面)
  • 不同的压缩(在质量损失的情况下,像jpeg工件一样,需要容忍度)--您可以接受99%的相等性,可以是相同的图像,50%的是不同的图像。
  • 颜色改变为地鳞,反过来(因为亮度与颜色无关)

更新/改进:

使用此方法一段时间后,我注意到了一些可以改进的地方。

  • 替换 GetPixel获得更多性能
  • 使用注释-缩略图而不是读取整个映像以提高性能
  • 不要将0.5f设置为光和暗之间的不同--使用所有256个像素的不同的中值亮度。否则,假定暗/光图像是相同的,并且它能够检测亮度变化的图像。
  • 如果您需要快地计算,如果需要存储大量散列以节省内存,则使用bool[]List<bool>,使用Bitarray,因为布尔值不是在一点点存储,而是需要字节
票数 136
EN

Stack Overflow用户

发布于 2016-02-20 06:15:52

您可以检查比较两幅图像的算法,以查看可用的图像比较方法。

除非您想自己重新创建完整的算法,否则应该尝试使用已经存在的库或至少一部分代码(只要它们的许可对您来说是可以的)。

对于边缘检测和相关计算机视觉算法的开源C#实现,您可以尝试EmguCV,它是OpenCV的包装器。

票数 7
EN

Stack Overflow用户

发布于 2016-02-19 20:40:37

在将图像重采样到某种常见分辨率之后,您可以使用小波分解并比较这种分解的系数,而不是图像本身。只对第一个N个系数进行比较,将使该方法对噪声和其他伪影具有更强的鲁棒性。

有几种用于小波的C#实现。一个例子是https://waveletstudio.codeplex.com/

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35151067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档