【问题标题】:MSE calculation for grayscale images灰度图像的 MSE 计算
【发布时间】:2015-03-08 10:02:26
【问题描述】:

我有两张图片(原始图片和嘈杂图片)。我正在计算 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,因为它实际上给出了一些结果,还是我应该采取其他方法?

【问题讨论】:

    标签: c# image grayscale mse


    【解决方案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

    【讨论】:

    • 这个答案包含很多有效点,但它假设原始灰度 -> .NET 使用的 RGB 转换为 R、G 和 B 分量分配相同的权重。有这方面的文件吗?总是假设它使用一些亮度保持分布,例如 Y = 0.2126 R + 0.7152 G + 0.0722 B。忽略 RGB 分布的来源,您仍然可以认为亮度是灰度图像中 PSNR 的最佳方法。
    • 实际上,唯一的区别是在转换为灰色之前是否移动了 RGB。我应用的方法确实有点幼稚。如果你想要亮度,那么你想要int gray = (int)(R*0.3 + G*0.59+ B*0.11)(编辑答案)
    • 事后看来,我对 .NET 灰度的评论 -> RGB 转换确实是早上咖啡之前的胡言乱语。我会把它留在那里作为永久的耻辱。 :)
    • 那么,我在顶部的代码示例不对?我想,对于彩色图像,我也可以使用您的代码,唯一的区别是,对于彩色图像,您不需要将 R、G 和 B 乘以 0.3、0.59、0.11?
    • @Thomas 等等,它是用于最初是灰度的图像,还是用于将彩色图像转换为灰度?因为我有第一个案例。这个问题有点愚蠢和缓慢,但我很困惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 2021-05-23
    • 2019-07-10
    • 2019-12-01
    相关资源
    最近更新 更多