C# 如何检查图像是否为另一图像的缩放版本
我正在寻找一种简单的方法来检查一个图像是否是另一个图像的缩放版本。它不需要非常快,只需要“相当”准确。并用.NET编写。而且是免费的 我知道,一厢情愿:-) 我非常确定,即使没有尝试过,将较大的图像转换为较小的比例并比较校验和也不起作用(特别是如果较小的版本是用另一个软件完成的,那么.NET) 下一种方法是缩小并比较像素。但首先,在所有像素上运行一个循环并得到一个布尔比较结果似乎是一个非常糟糕的主意,我确信会有一些像素被减少一点左右 想到图书馆了吗?早在大学里,我们就有一些MPEG7课程,所以我想结合使用一些“统计数据”,如色调分布、亮度等 关于这个话题有什么想法或链接吗 谢谢,C# 如何检查图像是否为另一图像的缩放版本,c#,.net,image,C#,.net,Image,我正在寻找一种简单的方法来检查一个图像是否是另一个图像的缩放版本。它不需要非常快,只需要“相当”准确。并用.NET编写。而且是免费的 我知道,一厢情愿:-) 我非常确定,即使没有尝试过,将较大的图像转换为较小的比例并比较校验和也不起作用(特别是如果较小的版本是用另一个软件完成的,那么.NET) 下一种方法是缩小并比较像素。但首先,在所有像素上运行一个循环并得到一个布尔比较结果似乎是一个非常糟糕的主意,我确信会有一些像素被减少一点左右 想到图书馆了吗?早在大学里,我们就有一些MPEG7课程,所以我
克里斯你必须在某个点或另一个点上循环像素。
一种易于实现但功能强大的方法是计算每个像素的单个颜色分量(RGB)之间的差异,找到平均值,然后查看它是否超过某个阈值。这当然不是最好的方法,但为了快速检查,它应该这样做。实现这一点的一个想法: 如果图像是10x10,而原始图像是40x40 循环10x10中的每个像素,然后检索代表该循环像素的4个像素 因此,对于较小图像中的每个像素,找到较大图像中相应的缩放像素量 然后,您可以获取4个像素的平均颜色,并与较小图像中的像素进行比较。您可以指定错误边界,即-10%或+10%边界被视为匹配,其他边界被视为失败 建立匹配和失败的计数,并使用边界来确定它是否被视为匹配
我认为这可能比将图像缩放到相同大小并进行1像素:1像素比较要好,因为我不确定调整大小的算法必须如何工作,并且可能会丢失一些细节,从而导致不太准确的结果。或者,是否有不同的方式和方法来调整图像的大小。但是,我也不知道如何调整大小取决于您如何操作。最简单的方法就是将最大的图像缩放为较小的图像大小,并比较色差。因为你不知道缩放是立方的还是线性的(或者其他的),你必须接受一个小的差异
不要忘记获取每个像素差的绝对值。;)我会说汤姆·古伦(Tom Gullen)所说的话,除非在比较之前,我只是将较大的图像缩小到较小的图像(否则,如果你将25x25与30x30或类似的图像进行比较,你只会遇到困难的数学问题) 根据图像大小,我可以考虑的另一件事是把它们都缩小到一个较小的图像。也就是说,如果你有一个是4000x4000,另一个是3000x3000,那么你可以将它们都缩小到200x200,并在该尺寸下进行比较
正如其他人所说,然后您需要使用阈值(最好是颜色组件)进行检查,并确定哪种公差效果最好。我建议这最好是通过反复试验来完成。在这方面我绝对没有权威或经验,我将尝试帮助你 我会从宽高比匹配开始,通过一些公差,除非你比较图像的裁剪部分,这会使事情变得更难 然后我会扫描像素的相似区域,没有精确性,再次需要一个公差水平。然后,当一个区域相似时,沿着一条直线将一个区域与另一个区域进行比较,然后找到另一个颜色相似的区域。黑与白会更难 如果你击中目标,你将有两个区域在一条直线上,有相似的补丁。对于两个点,它们之间有一个长度参考,因此现在可以看到缩放可能是什么。您也可以先缩放图像,但这不能解释切面不匹配的裁剪部分 现在在源图像中选择一个随机点并获取颜色信息。然后使用比例因子,在另一张图像上找到相同的随机点,看看颜色是否符合要求。用随机点做几次。如果很多人发现了相似的东西,那很可能是复制品 然后,您可能希望对其进行标记,以便进行进一步的CPU密集型检查。可以是逐像素比较,也可以是其他方式 我知道微软(Photosynth)使用“outline”(Photoshop中的那种东西)之类的过滤器去除图像颜色,只留下正方形线条,只留下图片的“组件”进行匹配(它们匹配边界和重叠) 为了提高速度,我会把问题分解成几个部分,真正思考人类是如何决定两张照片是相似的。对于非速度,彻底比较颜色可能会让你达到目的 简而言之,这个过程:
如果你在一张纸上随机打了4次孔,然后把它放在两张照片上,只要看到颜色通过,你就可以知道它们是否可能是副本,需要进一步检查。只需将较大的图像缩放回较小的图像的大小,然后,通过获取每个红色、绿色和蓝色分量中差值的绝对值来比较每个像素 然后,您可以设置一个阈值,以决定将其计算为匹配所需的接近程度,例如,如果95%以上的像素在颜色值的5%以内,则表示您有一个匹配
模糊匹配是必要的,因为您可能具有缩放伪影/抗锯齿效果。我认为这将是您最好的解决方案。首先检查纵横比。然后,如果图像大小不同,则将图像缩放到2个图像中较小的一个。最后,进行散列比较
public class CompareImages2
{
public enum CompareResult
{
ciCompareOk,
ciPixelMismatch,
ciAspectMismatch
};
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.Height / bmp1.Size.Width == bmp2.Size.Height / bmp2.Size.Width)
{
if (bmp1.Size != bmp2.Size)
{
if (bmp1.Size.Height > bmp2.Size.Height)
{
bmp1 = (new Bitmap(bmp1, bmp2.Size));
}
else if (bmp1.Size.Height < bmp2.Size.Height)
{
bmp2 = (new Bitmap(bmp2, bmp1.Size));
}
}
//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;
}
}
else cr = CompareResult.ciAspectMismatch;
return cr;
}
}