C# 灰度图像的均方误差计算

C# 灰度图像的均方误差计算,c#,image,grayscale,mse,C#,Image,Grayscale,Mse,我有两个图像(原始图像和嘈杂图像)。我在计算PSNR。我是为彩色RGB图像做的,但我不知道如何处理灰度。正如我所读到的,MSE计算是不同的。对于RGB,正如您在以下代码中看到的那样(我使用的是Visual C#): for(int i=0;i

我有两个图像(原始图像和嘈杂图像)。我在计算PSNR。我是为彩色RGB图像做的,但我不知道如何处理灰度。正如我所读到的,MSE计算是不同的。对于RGB,正如您在以下代码中看到的那样(我使用的是Visual C#):

for(int i=0;i

这里我用R,G,B的像素来操作,但是我不知道在灰度图像的情况下应该怎么做。我可以也使用RGB吗,因为它实际上给出了一些结果,或者我应该采取其他措施

要生成灰度,您可以根据平均值生成图片(无需改变您的实现)。我假设您的图像是bmp1=灰度图像和bmp2=噪声图像

for (int i = 0; i < bmp1.Width; i++)
{
    for (int j = 0; j < bmp1.Height; j++)
    {
        // As a grayscale image has rthe same color on all RGB just pick one
        int gray1 = bmp1.GetPixel(i, j).R;
        int gray2 = bmp2.GetPixel(i, j).R;
        double sum = Math.Pow(gray1 - gray2, 2)
        mseGray += sum;
    }
}
mse = (mseGray) / ((bmp1.Width * bmp1.Height) * 3);
for(int i=0;i
同时,一次获取一个像素是一个缓慢的过程,需要考虑使用索引,并且在循环中进行优化。它的性能应该是原来的十倍

您需要将位图制作成一个可索引的img,我在本例中假设它的BitmapSource。有趣的部分是循环和索引构建,而不是预编码,预编码只是为了使图像可索引

var height = bmp1.Height;
var width = bmp1.Width;
var pixelBytes1 = new byte[height * width * 4];
var pixelBytes2 = new byte[height * width * 4];
bmp1.CopyPixels(pixelBytes1, stride, 0);
bmp2.CopyPixels(pixelBytes2, stride, 0);

for (int x = 0; x < width; x++)
{
    int woff = x * height;
    for (int y = 0; y < height; y++)
    {(R*0.3 + G*0.59+ B*0.11)
        int index = woff + y;
        int gray1 = bmp1[index];
        int gray2 = bmp2[index];
        double sum = Math.Pow(gray1 - gray2, 2)
        mseGray += sum;
    }
}
mse = (mseGray) / ((bmp1.Width * bmp1.Height) * 3);
var height=bmp1.高度;
变量宽度=bmp1.宽度;
var pixelBytes1=新字节[高度*宽度*4];
var pixelBytes2=新字节[高度*宽度*4];
bmp1.CopyPixels(像素字节1,步幅,0);
bmp2.CopyPixels(像素字节2,步幅,0);
对于(int x=0;x
编辑:

我有一个问题,你的PSNR的实施,虽然我认为它不是每个定义 下面是一个来自java的示例(非常类似于C#)

此答案包含许多有效点,但它假定.NET使用的原始灰度->RGB转换为R、G和B分量分配相等的权重。有关于这方面的文件吗?始终假定它使用一些亮度保持分布,如Y=0.2126 R+0.7152 G+0.0722 B。忽略RGB分布的来源,您仍然可以认为亮度是灰度图像中PSNR的最佳方法。实际上,唯一的区别是,如果在转换为灰度之前移动RGB。我采用的方法确实有点幼稚。如果你想要亮度,那么你需要
intgray=(int)(R*0.3+G*0.59+B*0.11)
(编辑了答案)事后来看,我对.NET灰度->RGB转换的评论确实是在早晨喝咖啡之前。我将把它留在那里,作为永久的耻辱象征。:)那么,我上面的代码示例不正确?我想,对于彩色图像,我也可以使用您的代码,唯一的区别是,对于彩色图像,您不需要将R、G和B乘以0.3、0.59、0.11?@Thomas Wait,是用于最初是灰度的图像,还是用于将彩色图像转换为灰度?因为我有第一个病例。这个问题有点愚蠢和缓慢,但我感到困惑。
var height = bmp1.Height;
var width = bmp1.Width;
var pixelBytes1 = new byte[height * width * 4];
var pixelBytes2 = new byte[height * width * 4];
bmp1.CopyPixels(pixelBytes1, stride, 0);
bmp2.CopyPixels(pixelBytes2, stride, 0);

for (int x = 0; x < width; x++)
{
    int woff = x * height;
    for (int y = 0; y < height; y++)
    {(R*0.3 + G*0.59+ B*0.11)
        int index = woff + y;
        int gray1 = bmp1[index];
        int gray2 = bmp2[index];
        double sum = Math.Pow(gray1 - gray2, 2)
        mseGray += sum;
    }
}
mse = (mseGray) / ((bmp1.Width * bmp1.Height) * 3);