我想比较两个位图,但是要容忍。我的当前代码仅在两个图像完全相同的情况下才会显示“ciCompareOk”。
两者的尺寸和形状相同,有时颜色较深或较浅 怎么看起来容忍?
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;
}
答案 0 :(得分:0)
对于“不同”图像的可能性,有一些可能的测试用例,而你需要采取的“匹配”它们的方法变得越来越难。
ciPixelMismatch
,但不会抛出异常。如果我们只考虑第一种情况,那么你真正想要的是比较两个Color
并返回一个值的函数。比较两种颜色的简单方法是计算红色,绿色和蓝色成分之间的毕达哥拉斯距离,例如
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(当Color
s相同时)和198608(黑白之间,Math.Pow(256, 2) * 3
)之间的数字。
这样,您可以将函数应用于每对像素(每个图像一个)并累积错误。在像素数上平均此误差,以确定整个图像的平均像素误差,然后将其与阈值进行比较,以确定它们是否“相同”:
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;
(我除以198608D
以避免在添加时出现整数溢出的可能性。averageError
然后是0D
对于相同的值和1D
对于完全不同的值。 )
我还建议您在StackOverflow上查看其他一些问题。虽然这种像素颜色匹配适用于最简单的情况,但它不适用于其他情况。如果你需要更复杂的东西,那么在回答其他问题时给出的方法会很有用:
希望这有帮助