灰度图像的MSE计算

时间:2015-03-08 10:02:27

标签: c# image grayscale mse

我有两张图片(原始和嘈杂)。我正在计算PSNR。我有点做了彩色RGB图像,但我不知道怎么用灰度。正如我读到的,MSE计算是不同的。对于RGB我就像你在下面的代码中看到的那样(我使用的是Visual C#):

for (int i = 0; i < bmp1.Width; i++)
            {
                for (int j = 0; j < bmp1.Height; j++)
                {
                    mseR += Math.Pow(bmp1.GetPixel(i, j).R - bmp2.GetPixel(i, j).R, 2);
                    mseG += Math.Pow(bmp1.GetPixel(i, j).G - bmp2.GetPixel(i, j).G, 2);
                    mseB += Math.Pow(bmp1.GetPixel(i, j).B - bmp2.GetPixel(i, j).B, 2);

                }
            }
      mse = (mseR + mseG + mseB) / ((bmp1.Width * bmp1.Height) * 3);

这里我用像素的R,G,B进行操作。但我不知道在灰度图像的情况下我应该采取什么。我可以使用RGB吗?因为它实际上会产生一些结果,或者我应该采取其他措施?

1 个答案:

答案 0 :(得分:1)

要制作灰度图像,您可以使图像超出平均值(无需更改实现)。我假设你的图像是bmp1 = grayImage和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);

同时获取一个像素是使用索引和循环优化的过程缓慢。它应该提供大约十倍的性能。

你需要将位图变成一个可索引的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);

编辑:

http://www.mathworks.com/matlabcentral/answers/49906-how-to-calculate-psnr-of-compressed-images-and-how-to-compare-psnr-of-images-compressed-by-two-diff

虽然我认为它不符合定义,但我对PSNR的实现存在问题 这是java的一个例子(非常类似于C#) http://www.cyut.edu.tw/~yltang/program/Psnr.java