数字图像处理6---图像(相加)平均去除高斯噪音,OpenCV C++

图像相加:

图像平均的一种重要应用是在天文学领域,在该领域在非常低的照度下成像常常会导致传感器噪声;以至于单幅图像无法解析;

多次高斯模糊求平均值可以消除图像在低照度下的噪音


相加是连续积分的离散形式。也可以使用CCD或图像传感器的累积能力,通过长时间观察某一场景达到降噪的目的。
冷却也常常用于降低传感器噪音;

代码实现如下:

#include <cstdlib>
#include <cmath>
#include <limits>
#include <iostream>
#include <sstream>
#include <utility>
#include <vector>
#include <math.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

/*
产生高斯噪声的函数,引自维基百科
*/

double generateGaussianNoise()
{
    static bool hasSpare = false;
    static double rand1, rand2;

    if (hasSpare)
    {
        hasSpare = false;
        return sqrt(rand1) * sin(rand2);
    }

    hasSpare = true;

    rand1 = rand() / ((double)RAND_MAX);
    if (rand1 < 1e-100) rand1 = 1e-100;
    rand1 = -2 * log(rand1);
    rand2 = (rand() / ((double)RAND_MAX)) * CV_PI*2;
//    cout << "gaussi: " << sqrt(rand1) * cos(rand2) << endl;
    return sqrt(rand1) * cos(rand2);
}

//为图像添加高斯噪声
void addGaussianNoise(Mat &srcImag)
{
//    Mat dstImage = srcImag.clone();
    int channels = srcImag.channels();
    int rowsNumber = srcImag.rows;
    int colsNumber = srcImag.cols*channels;
    //判断图像的连续性
    if (srcImag.isContinuous())
    {
        colsNumber *= rowsNumber;
        rowsNumber = 1;
    }
    for (int i = 0; i < rowsNumber; i++)
    {
        for (int j = 0; j < colsNumber; j++)
        {
            //添加高斯噪声
            int val = srcImag.ptr<uchar>(i)[j] +
                generateGaussianNoise()*32;
            if (val < 0)
                val = 0;
            if (val>255)
                val = 255;
            srcImag.ptr<uchar>(i)[j] = (uchar)val;
        }
    }
//    return srcImag;
}


Mat eliminate_noise(vector<Mat> &img_vec)
{
    if( img_vec.empty() ){
        cerr << "image vector empty" << endl;
        Mat err;
        return err;
    }
    Mat average = Mat::zeros(img_vec.at(0).size(), CV_32FC3);
    int n = (int)img_vec.size();
    for(int i = 0; i < n; i++){
        accumulate(img_vec.at(i), average);//累加到average
    }
    average = average / n; //求出平均图像
    average.convertTo(average,CV_8U);

    return average;
}


int main(int argc, char* argv[])
{
//    string name ="image.jpg";
//    int ImageSize =30;
    int ImageSize = atoi(argv[2]);
    string name = argv[1];
    Mat pic = imread(name, IMREAD_COLOR);

//    根据数量生成图片
    vector<Mat> my_pics;
    string newname;
    for (size_t i = 0; i < (size_t)ImageSize; i++){
        Mat newImage = pic.clone();
        addGaussianNoise(newImage);
        ostringstream ss;
        ss << "noise" << i << ".jpg";
        newname = ss.str();
//        imwrite(newname, newImage);
        my_pics.push_back(newImage);
    }
    imshow("noise",my_pics.at(0) );
    cout << "add Noise end" << endl;

    //获得消除噪声的输出
    Mat out = eliminate_noise(my_pics);
    ostringstream ss;
    ss << "output" << ImageSize << ".jpg";
    newname = ss.str();
    Mat dest_img = out.clone();
    imwrite(newname, dest_img);
    cout << "deal end" << endl;
    imshow( "src", pic);
    imshow( "dst", dest_img);
    waitKey(0);

    return 0;
}

下面分别是原图,噪音图,5次,50次平均后的情况

猜你喜欢

转载自blog.csdn.net/cyf15238622067/article/details/87708940