欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用平均的方法去除噪声

程序员文章站 2022-06-30 14:18:23
...

                                         用平均的方法去除噪声

技术/方法

什么?平均?你是说滤波?

并不是!这种方法并不使用任何滤波(去噪)算法对图像进行处理。实际上,这种方法与滤波相反:你可以获得更为清晰的图像!

在平均法中,我们假设有一系列同一场景的一些图像,只不过每一幅图像具有不同的“噪声模式”。

一旦我们拥有多幅同一场场景的图像,是的,这种你在学校就学过的平均方法:相加之后除以图像的数量。

准备开始实验

首先,我们必须获取到多幅图像,每一幅图像中都有一些噪声。我们使用Photoshop以及自动选择模式生成25幅图像,每一幅图像中添加8%的高斯噪声。

开始编码

首先,确保你包含了OpenCV库中的cv.lib cvaux.lib cxcore.lib highgui.lib文件。

#include <cv.h>
#include <highgui.h>

现在,主函数为:

int main()
{
    IplImage* imgRed[25];
    IplImage* imgGreen[25];
    IplImage* imgBlue[25];

我们一开始定义了三个数组,用以包含25幅图像每一个通道。我们现在载入25幅图像。

  for(int i=0;i<25;i++)
    {
        IplImage* img;
        char filename[150];
        sprintf(filename, "%d.jpg", (i+1));
        img = cvLoadImage(filename);
        imgRed[i] = cvCreateImage(cvGetSize(img), 8, 1);
        imgGreen[i] = cvCreateImage(cvGetSize(img), 8, 1);
        imgBlue[i] = cvCreateImage(cvGetSize(img), 8, 1);
        cvSplit(img, imgRed[i], imgGreen[i], imgBlue[i], NULL);
        cvReleaseImage(&img);
    }

让我们一行一行查看上述代码。我们首先创建一个循环,在循环中我们创建保存图像的临时变量,随后,我们输入载入图像的名称。载入图像的名称可以是1.JPG 2.JPG等等,之后我们载入图像到 img变量。

下一步,我们分配了三个通道的内存。随后,我们把载入的图像分离成三个通道的图像,分别保存在刚刚分配的三个通道内存中。

现在,我们在添加如下代码段:

 CvSize imgSize = cvGetSize(imgRed[0]);
    IplImage* imgResultRed = cvCreateImage(imgSize, 8, 1);
    IplImage* imgResultGreen = cvCreateImage(imgSize, 8, 1);

    IplImage* imgResultBlue = cvCreateImage(imgSize, 8, 1);

    IplImage* imgResult = cvCreateImage(imgSize, 8, 3);

我们再次分配了三个通道的内存,用以保存平均法去噪的图像结果。

现在,实现平均去噪的方法:

for(int y=0;y<imgSize.height;y++)
    {
        for(int x=0;x<imgSize.width;x++)
        {
            int theSumRed=0;
            int theSumGreen=0;
            int theSumBlue=0;
            for(int i=0;i<25;i++)
            {
                theSumRed+=cvGetReal2D(imgRed[i], y, x);
                theSumGreen+=cvGetReal2D(imgGreen[i], y, x);
                theSumBlue+=cvGetReal2D(imgBlue[i], y, x);
            }
            theSumRed = (float)theSumRed/25.0f;
            theSumGreen = (float)theSumGreen/25.0f;
            theSumBlue = (float)theSumBlue/25.0f;
            cvSetReal2D(imgResultRed, y, x, theSumRed);
            cvSetReal2D(imgResultGreen, y, x, theSumGreen);
            cvSetReal2D(imgResultBlue, y, x, theSumBlue);
        }
    }

我们获取每一幅图像的每一个像素,然后我们定义像素的和,用以存放25幅噪声图像的每一个通道的像素和。随后,我们把每一个通道的像素和除以图像的数量,然后在把三通道的图像进行合并,生成最终的图像。

很简单?下面试图像的输出结果:

用平均的方法去除噪声
很多噪声的原始图像

 

用平均的方法去除噪声
结果图像。噪声都去哪呢?

理论知识

很奇妙是吧!?这仅仅使用了25幅图像的平均结果,如果图像越多,去噪效果越好。

 

图像中的噪声是随机的,有高斯随机噪声以及其他一些噪声。如下图是高斯噪声。

用平均的方法去除噪声
高斯噪声图像

假设我们把每一个像素的灰度值相加,之后再除以总的像素值,那么最终得到的结果将会是0或者近似0的结果

因此,如果我们把多幅不同模式的噪声图像没一个像素相加,之后在除以总的像素数量,那么,最终将使得噪声消除掉。

数学公式:

我们用gi代表25幅图像,因此,gi就是原始图像和噪声图像的和。即:

用平均的方法去除噪声

我们使用的平均方法可以表示为:

用平均的方法去除噪声

我们把k(实际实验是25幅)幅图像相加,然后在除以k。由高斯分布可知:

用平均的方法去除噪声

因此,通过上述方法,我们最后得的结果即为f(x,y),即图像的原始数据。

更多图像将得到更佳的效果:

用平均的方法去除噪声
原始图像
用平均的方法去除噪声
两幅图像的平均结果
用平均的方法去除噪声
五幅图像的评价结果
用平均的方法去除噪声
十五幅图像的评价结果
用平均的方法去除噪声
二十五幅图像的评价结果

翻译自:http://aishack.in/tutorials/noise-reduction-averaging-theory/

相关标签: 去噪