利用CImage类对图像进行高斯噪声生成

    课上作业要求利用C里面的自带类库对图像做一个高斯噪声的生成,记录一下大概的原理和步骤。


    首先是对高斯函数的理解

   

    这个函数是一个高斯概率密度的分布表达式,表示为X~N(μ,σ²),其中μ表示均值,σ²表示方差,当μ=0,σ²=1时为标准正态分布。

    而高斯噪声是要求生成的噪声的概率密度函数符合高斯分布。我觉得可以理解为所有的噪声采样服从高斯分布的一种噪声。有关高斯噪声和高斯白噪声的理解参考

   hudalikm的一篇有关高斯噪声的文章文章

    高斯噪声的生成就是在图像所有像素上添加一个噪声信号:

        n(x,y)=o(x,y)+g(x,y)

    其关键是如何生成这个g(x,y)。当然x和y只是表示图像像素的坐标,对原像素值加上一个高斯采样值就可以生成一个高斯噪声。计算机中生成高斯采样的方法有很多,这里我使用的是比较常用的Box-Muller方法。该方法原理涉及到统计学的各种问题(反正我看一遍没太看懂),但实现过程非常简单。

    原理的话在白马负金羁的文章中有介绍

    使用方法是首先生成两个数a,b为在[0,1]的均匀分布随机采样;

    根据box-muller方法,对a,b做如下运算可以得到服从高斯分布的两个随机数

    使用任何一个都可以,我觉得这是二维的高斯采样,然后咱们在这里只需要选择任何一维都可以。

    最终生成的噪声点为

    n(x,y)=o(x,y)+(μ+N*σ);

    

接下来是利用CImage对图像进行处理阶段了


关于如何使用Cimage类的介绍,这里我参考了self_mind 的关于Cimage类的介绍 里面介绍的很详细。

下面我放上我的代码和效果图

宏定义和main函数部分

#include <atlimage.h>
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define MU 0			//均值
#define SIGMA 2			//方差
#define k 16
#define PI 3.1415926

using namespace std;
int addNoise(const CImage& input, CImage& noise);
double guass();
int makeNoise(CImage input);
int addNoise(const CImage& input, CImage& noise);
int main() {
	CString ImagePath = "E:\\1myRobotFile\\公式算法项目\\CameraCalibration\\input.jpg";
	CImage image, noise;
	//读入图片
	image.Load(ImagePath);
	makeNoise(image);

	cout << "successd" << endl;
	system("pause");

}
接下来是高斯噪声生成函数
double guass()
{
	//生成0-1的随机数
	double x1, x2;
	//生成0-1两个随机数
	x1 = rand() / ((double)RAND_MAX);
	x2 = rand() / ((double)RAND_MAX);
	if (x1 < 1e-100)
		x1 = 1e-100;
	x1 = (-2) * log(x1);
	x2 = x2 * PI * 2;
	double g = MU + (sqrt(x1) * cos(x2)) * SIGMA;

	//double g = MU + (sqrt(x1) * sin(x2)) * SIGMA;

	return g;
}

最后是输出高斯噪声模版和高斯噪声叠加图像

int makeNoise(CImage input)
{
	if (input == 0)
	{
		cout << "图片输入错误!" << endl;
		return 0;
	}

	//噪声图片的创建
	CImage gaussNoise, In;
	CString ImagePath = "E:\\1myRobotFile\\公式算法项目\\CameraCalibration\\input.jpg";
	In.Load(ImagePath);
	gaussNoise = input;
	//gaussNoise.Create(input.GetWidth(), input.GetHeight(), 8);
	//高斯噪音生成
	int r, g, b;
	for (int i = 0; i<gaussNoise.GetWidth(); i++)
	{
		for (int j = 0; j<gaussNoise.GetHeight(); j++)
		{
			r = guass();
			g = guass();
			b = guass();
			gaussNoise.SetPixelRGB(i, j, r, g, b);

		}
	}
	CString SImagePath = "E:\\1myRobotFile\\公式算法项目\\CameraCalibration\\noise.jpg";
	gaussNoise.Save(SImagePath);
	addNoise(In, gaussNoise);
}
//噪声和原图的相加
int addNoise(const CImage& input, CImage& noise)
{
	CImage addnoise;
	COLORREF pixel1;
	COLORREF pixel2;
	int r, g, b;
	if (input == 0 || noise == 0)
	{
		cout << "图片输入错误!" << endl;
		return 0;
	}
	addnoise = input;
	int w = addnoise.GetWidth();
	int h = addnoise.GetHeight();
	for (int i = 0; i < w; i++)
	{
		for (int j = 0; j<h; j++)
		{
			pixel1 = input.GetPixel(i, j);
			pixel2 = noise.GetPixel(i, j);
			/*r = GetRValue(pixel1);
			g = GetGValue(pixel1);
			b = GetBValue(pixel1);
			cout << r << "," << g << "," << b << endl;*/
			//r = GetRValue(pixel1) + GetRValue(pixel2) - 128;
			//g = GetGValue(pixel1) + GetGValue(pixel2) - 128;
			//b = GetBValue(pixel1) + GetBValue(pixel2) - 128;
			r = GetRValue(pixel1) + GetRValue(pixel2) *k;
			g = GetGValue(pixel1) + GetGValue(pixel2) *k;
			b = GetBValue(pixel1) + GetBValue(pixel2) *k;

			//cout << r << "," << g << "," << b << endl; 
			if (r>255)
			{
				r = 255;
			}
			if (g>255)
			{
				g = 255;
			}
			if (b>255)
			{
				b = 255;
			}
			if (r<0)
			{
				r = 0;

			}
			if (g<0)
			{
				g = 0;
			}
			if (b<0)
			{
				b = 0;
			}
			addnoise.SetPixelRGB(i, j, r, g, b);
		}
	}
	CString SImagePath = "E:\\1myRobotFile\\公式算法项目\\CameraCalibration\\output.jpg";
	addnoise.Save(SImagePath);

}

效果图如下

原图


噪声图像(μ=0,σ=2)

带有高斯噪声的图像

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值