(超详细)实现计算图片相似度MSE和PSNR

这是本菜鸡在《信息隐藏》这门选修课中遇到的其中一个问题,在网络上找到的绝大部分实现都是直接调库啊啥的,而且就MSE和PSNR的理论公式中的数值表达都没有一个具体的定义,导致我想自己动手实现就无从下手,反正我在国内的帖子翻了个遍是没找到,最后在国外的Overstatckflow论坛上看到一个较为清楚的定义说明,下面会介绍到

文章目录

  • 图片相似度介绍
  • 一、MSE介绍
  • 二、PSNR介绍
  • 三、具体实现
    • 1.MSE公式
    • 2.PSNR公式
    • 3.参数介绍
    • 4.核心代码实现
    • MSE:
    • PSNR:
    • 5.演示界面
  • 四、总结


图片相似度介绍

计算图像变化后的质量,最直接的思路即比较degrade后的图像与真实图像(distortion-free)之间的差剖面,即可视误差,通过视觉感官评价图像质量。
而PSNR 和 MSE 就是基于简单直接的思路确定的指标
本程序以C#语言实现,想要自己通过其他语言实现的小伙伴也是可以借鉴一下的,下面对计算公式的参数有具体的说明

一、MSE介绍

MSE(Mean Squared Error),均方误差,各测量值误差的平方和的平均值的平方根。

二、PSNR介绍

PSNR(Peak Signal to Noise Ratio),峰值信噪比,是一种评价图像的客观标准,最广泛使用的评鉴画质的客观量测法,不过许多实验结果都显示,PSNR的分数无法和人眼看到的视觉品质完全一致,有可能PSNR较高者看起来反而比PSNR较低者差。这是因为人眼的视觉对于误差的敏感度并不是绝对的,其感知结果会受到许多因素的影响而产生变化(例如:人眼对空间频率较低的对比差异敏感度较高,人眼对亮度对比差异的敏感度较色度高,人眼对一个区域的感知结果会受到其周围邻近区域的影响)

三、具体实现

在介绍具体实现前,有必要了解一下他们的具体数学公式,

1.MSE公式

(超详细)实现计算图片相似度MSE和PSNR_第1张图片

2.PSNR公式

(超详细)实现计算图片相似度MSE和PSNR_第2张图片

3.参数介绍

其中,M,N分别表示图像的
MAXi:代表图像中像素的最大灰度值,一般采用255,即2^8-1
可以明显地看到,PSNR其实是MSE的线性转化,计算出MSE那么PSNR也就出来了
当看到I(i,j)和K(i,j)的时候我很纳闷这代表什么含义,国内的些帖子上有的介绍是图片指定坐标位置的像素,有的干脆直接说是图片。
我们都知道计算机处理图片的时候是将一个图片表示为矩阵,而每个小矩阵中的颜色对应一个数字,较大的数字代表较深的颜色,而RGB(以24bpp为例)还另外分三通道,每个通道的分量值都是如此
(超详细)实现计算图片相似度MSE和PSNR_第3张图片

那么,式子中的I(i,j)和K(i,j)具体代表什么含义呢?
Overstackflow论坛上的一个大佬是这么说的:

  1. Start with red channel
  2. Compute the difference between each pixel’s gray level value in the two image’s red channels pixel-by-pixel (redA(0,0)-redB(0,0) etc for all pixel locations.
  3. Square the differences of every one of those pixels (redA(0,0)-redB(0,0)^2
  4. Compute the sum of the squared difference for all pixels in the red channel
  5. Repeat above for the green and blue channels
  6. Add the 3 sums together and divide by 3, i.e, (redsum+greensum+bluesum)/3
  7. Divide by the area of the image (WidthHeight) to form the mean or average, i.e., (redsum+greensum+bluesum)/(3Width*Height) = MSE

根据它的描述,公式中I(k,j)的定义即是图片中(i,j)所在像素中的红、蓝、绿三组颜色通道各自对应的分量灰度值的差的平方之和再除以3,我整理的公式如下
(超详细)实现计算图片相似度MSE和PSNR_第4张图片

4.核心代码实现

MSE:

 public double Red_Gray(Bitmap a,Bitmap b, int i, int j)
        {
           return  Math.Pow(Convert.ToDouble(a.GetPixel(i, j).R) 
               -Convert.ToDouble(b.GetPixel(i, j).R),2);
        }
        public double Blue_Gray(Bitmap a, Bitmap b, int i, int j)
        {
            return Math.Pow(Convert.ToDouble(a.GetPixel(i, j).B)
                - Convert.ToDouble(b.GetPixel(i, j).B), 2);
        }
        public double Green_Gray(Bitmap a, Bitmap b, int i, int j)
        {
            return Math.Pow(Convert.ToDouble(a.GetPixel(i, j).G)
                - Convert.ToDouble(b.GetPixel(i, j).G), 2);
        }
        public double MSE(Bitmap a,Bitmap b)
        {
            int M = a.Height;
            int N = a.Width;
            double temp_Red=0;
            double temp_Blue = 0;
            double temp_Green = 0;
            for (int i=0;i<N;i++)
            {
                for(int j=0;j<M;j++)
                {
                    temp_Red +=Red_Gray(a, b, i, j);
                    temp_Blue +=Blue_Gray(a, b, i, j);
                    temp_Green +=Green_Gray(a, b, i, j);
                }
            }
            return (temp_Blue+temp_Green+temp_Red)/(M * N*3);
        }

PSNR:

  public double PSNR(Bitmap a, Bitmap b)
        {
            return (20*Math.Log10(255)-10*Math.Log10(MSE(a,b)));
        }

其实问题的关键就是对式子中I(i,j)和K(i,j)的数值处理上

5.演示界面

我通过三种图片处理的效果进行了分析
噪声处理:
(超详细)实现计算图片相似度MSE和PSNR_第5张图片
模糊处理:

(超详细)实现计算图片相似度MSE和PSNR_第6张图片

拉普拉斯锐化:

(超详细)实现计算图片相似度MSE和PSNR_第7张图片

表格分析:
(超详细)实现计算图片相似度MSE和PSNR_第8张图片

参考资料

https://stackoverflow.com/questions/20271479/what-does-it-mean-to-get-the-mse-mean-error-squared-for-2-images


四、总结

根据表格中对结果的汇总,不难看出MSE和图片相似度的变化成正比,前后图片差距越大MSE的值越高,而PSNR与之相反,图片差距越大PSNR的值反而越小。

如果在作业上或者其他方面上帮到您的话不妨点个赞吧

你可能感兴趣的:(c#,图像处理)