如何通过 C# 比较两幅图片的相似度?
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过 C# 比较两幅图片的相似度?相关的知识,希望对你有一定的参考价值。
咨询区
Byyo
我在用 C# 实现一个可以查找重复图片的小工具,我目前是给每一个图片做一个 md5
码,然后通过 md5 值来判断图片是否相同。
但现实情况要复杂的多,比如:
图片被旋转了,比如:90°
图片大小不一致
不同的压缩比例和后缀名
请问是否有更好的方式来解决?
回答区
fubo
这种比较图片是否相同的解决思路,可以大概总结为下面四步。
调整图片大小为 16x16 像素
调整图片为
黑白
色,这样就可以用1/0
来表示。
将行列的
黑白点
读取到List
中,参考如下代码:
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
方法性能不是很高,但在 16*16
像素场景下应该不会有性能问题。
比较两幅图片所生成的
List
,然后再设置一个容忍值即可,参考如下代码:
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);
Fab
图片比较算法本质上来说是非常复杂的,除非你的场景一定要实现一个原创的相似度比较算法,否则我建议你使用一些市场上已存在的开源库,比如说:EmguCV
,它是一个开源的C#实现的边缘检测和相关的计算机视觉算法,包装了用 C 和 C++ 实现 的 OpenCV
上。
点评区
2013 年我在博客园写了一篇文章,用的是 Aforge.NET 识别 得仕卡 官网上的验证码,有兴趣的朋友可以去看一看,参考文章:https://www.cnblogs.com/huangxincheng/p/3495858.html 其实我也觉得场景允许,建议还是用开源的工具包。
以上是关于如何通过 C# 比较两幅图片的相似度?的主要内容,如果未能解决你的问题,请参考以下文章
如何度量两幅图像的相似度--结构相似度 SSIM 原理及代码