C#比较2个带容差的位图?
我想比较两个位图,但有容差。我当前的代码只在两个图像完全相同时才显示“ciCompareOk” 两者的大小和形状都相同,有时颜色更深或更浅。C#比较2个带容差的位图?,c#,image,bitmap,compare,C#,Image,Bitmap,Compare,我想比较两个位图,但有容差。我当前的代码只在两个图像完全相同时才显示“ciCompareOk” 两者的大小和形状都相同,有时颜色更深或更浅。 这看起来怎么能容忍 public static CompareResult Compare(Bitmap bmp1, Bitmap bmp2) { CompareResult cr = CompareResult.ciCompareOk; //Test to see if we have the same size of image
这看起来怎么能容忍
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
{
//Sizes are the same so start comparing pixels
for (int x = 0; x < bmp1.Width
&& cr == CompareResult.ciCompareOk; x++)
{
for (int y = 0; y < bmp1.Height
&& cr == CompareResult.ciCompareOk; y++)
{
if (bmp1.GetPixel(x, y) != bmp2.GetPixel(x, y))
cr = CompareResult.ciPixelMismatch;
}
}
}
return cr;
}
公共静态比较结果比较(位图bmp1、位图bmp2)
{
CompareResult cr=CompareResult.ciCompareOk;
//测试看我们是否有相同大小的图像
如果(bmp1.Size!=bmp2.Size)
{
cr=比较结果;Crizemismatch;
}
其他的
{
//大小相同,所以开始比较像素
对于(int x=0;x
对于图像的“不同”程度,有一些可能的测试用例,您需要采取的“匹配”方法变得越来越困难
- 简单的情况是,您希望图像的大小相同,并且包含相同的特征,除了像素在您陈述时稍微亮一点或暗一点之外。例如,如果要将位图图像保存一次为24位,然后再次保存为8位(无抖动)。这两幅图像在同一位置具有相同的特征,但每个像素的颜色略有不同
- 另一种可能是,拍摄位图图像,裁剪左侧的一行像素以创建第一个图像,然后裁剪右侧的一行以创建第二个图像
- 第三种可能是保存位图图像,然后在两个方向上将图像大小加倍以创建第二个(因此源中的一个像素变为输出中的四个像素)。我承认您已经有了尺寸检查代码来检测这个案例
- 第四种可能性(更多的是测试用例)是有一个白色的大图像,和一个黑色的大图像。我们希望它返回
,但不会引发异常cipixelsmismatch
如果我们只考虑第一种情况,那么你真正想要的是一个函数来比较两个<代码>颜色< /代码> s,并返回一个值,看看它们有多么不同。比较两种颜色的一种简单方法是计算红色、绿色和蓝色分量之间的毕达哥拉斯距离,例如
static int CompareColours(Color x, Color y)
{
return (int)(Math.Pow((int)x.R - y.R, 2) + Math.Pow((int)x.B - y.B, 2) + Math.Pow((int)x.G - y.G, 2));
}
这将返回一个介于0(当颜色相同时)和198608(介于黑白之间,即Math.Pow(256,2)*3
)之间的数字
这样,您可以将该函数应用于每对像素(每幅图像一个像素)并累积错误。在像素数上平均此误差,以确定整个图像上的平均像素误差,然后将其与阈值进行比较,以确定它们是否“相同”:
const decimal errorThreshold=0.0001D
十进制总误差=0;
对于(int x=0;xerrorThreshold)cr=CompareResult.ciPixelMismatch;
(我除以198608D
,以避免加法时出现整数溢出的可能性。averageError
是一个介于相同的0D
和完全不同的1D
之间的值。)
我还建议您看看StackOverflow上的其他一些问题。虽然这种像素颜色匹配适用于最简单的情况,但它不适用于其他情况。如果您需要更复杂的内容,其他问题答案中给出的方法将非常有用:
希望这有帮助
const decimal errorThreshold = 0.0001D
decimal totalError = 0;
for (int x = 0; x < bmp1.Width; x++)
{
for (int y = 0; y < bmp1.Height; y++)
{
totalError += CompareColours(bmp1.GetPixel(x, y), bmp2.GetPixel(x, y)) / 198608D;
}
}
decimal averageError = totalError / (bmp1.Width * bmp1.Height);
if ( averageError > errorThreshold ) cr = CompareResult.ciPixelMismatch;