利用图像加法消除高斯噪声资料.docx
《利用图像加法消除高斯噪声资料.docx》由会员分享,可在线阅读,更多相关《利用图像加法消除高斯噪声资料.docx(15页珍藏版)》请在冰豆网上搜索。
利用图像加法消除高斯噪声资料
图像处理-图像加法应用
第一章、图像加法的应用
图像的加法可用于平均以减少和去除图像采集中混入的噪声,在采集中实际图像的时候,由于各种不同的原因,常会有一些干扰或噪声混入到最后采集的图像中。
从这个意义上来说,实际采集到的图像
可看做是由原始场景图像
和噪声图像叠加而成的,即
第二章、算法思想
如果在图像个点的噪声是互不相关的,且噪声具有零均值的统计特性,则可以通过一系列的采集图像{g(x,y)}相加来消除噪声。
设M个图像相加再求平均值得到的一幅新图像,即
那么可以证明新的图像的期望值为
E
如果考虑新图像和噪声图像各自的均方差的关系,则
可见随着平均图像数量M的增加,噪声在每个像素的位置(x,y)的影响越来越小
第三章、实验
1.高斯噪声
U1和U2是来自(0,1)的等概率的样本
Z1和Z2即是均值为0高斯噪声的函数
C++函数实现
#include
#include
#include
doublegenerateGaussianNoise(doublemu,doublesigma)
{
constdoubleepsilon=std:
:
numeric_limits:
:
min();
constdoubletwo_pi=2.0*3.14159265358979323846;
staticdoublez0,z1;
staticboolgenerate;
generate=!
generate;
if(!
generate)
returnz1*sigma+mu;
doubleu1,u2;
do
{
u1=rand()*(1.0/RAND_MAX);
u2=rand()*(1.0/RAND_MAX);
}
while(u1<=epsilon);
z0=sqrt(-2.0*log(u1))*cos(two_pi*u2);
z1=sqrt(-2.0*log(u1))*sin(two_pi*u2);
returnz0*sigma+mu;
}
注:
以上均来及维基百科
https:
//en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
2.代码实现
环境:
visualstudio2013,OpenCV3.0,Windows7
原理及步骤:
1)通过高斯噪声函数得到噪声值
2)通过计算的噪声值利用OpenCV库对图像进行加噪处理
3)保存加噪图片
4)读取获得的噪声图片模拟采样图片
5)根据不同的图片数量叠加取平均值获得结果
源代码见附录或者查看Github
3.实验结果
1)原始图片
原始图片
通过程序进行高斯加噪声-1
噪声图片-1
噪声图片-2
噪声图片-3
输入命令进行加噪和降噪
程序命令截图
实验结果截图
4.实验结果分析
通过设置不同的图片值的大小得到的结果
M=5
明显可以看出与实际图像差距还是很大,
M=10
比起M=5时有明显的改善,但不是很理想
M=30
能明显的看出图片的噪点有明显下降
M=50,
M=100
从上述结果可以看出,图像的加法能够消除噪声,随着M(样本总数)的增大减噪效果越来越明显。
但是发现降噪过后的图片明显呈现较原图更暗的颜色,分析代码发现,可能是加噪的密度过高,修改代码后
加噪图片,密度比刚刚的要小一些
还原后的图片
还原后的图片与原图可以明显看出还原的更高了,所以还可以得出结论,噪点的密度可能会影响图片与原图的亮度比。
第四章、实验总结
通过这次图像算术运算的应用试验,掌握了基本的实验环境搭建。
深刻理解了图像加法用来消除噪声的原理,以及编码的实现。
虽然没有对减乘除等算法进行编码实验,但也能对其中的算法有理解和领悟。
通过次的实验能不仅收获更多的知识,而且还体会到了算法的精妙和算法的实际应用。
附录:
//ImageNoise.cpp:
定义控制台应用程序的入口点。
//
#include"stdafx.h"
#include
#include
#include
#include
#include
#include
#include
#include
usingnamespacecv;
usingnamespacestd;
/*
产生高斯噪声的函数,引自维基百科
*/
#defineTWO_PI6.2831853071795864769252866
doublegenerateGaussianNoise()
{
staticboolhasSpare=false;
staticdoublerand1,rand2;
if(hasSpare)
{
hasSpare=false;
returnsqrt(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))*TWO_PI;
returnsqrt(rand1)*cos(rand2);
}
voidaddNoise(Mat&picture){
intchannels=picture.channels();
intRows=picture.rows;
intCols=picture.cols*channels;
if(picture.isContinuous()){
Cols*=Rows;
Rows=1;
}
inti,j;
uchar*p;//获得picture的行的指针
for(i=0;i{
p=picture.ptr(i);//赋值为当前行指针
for(j=0;j{
if(j%5==0)
{
doubleval=p[j]+generateGaussianNoise()*128;
if(val<0)
val=0;
if(val>255)
val=255;
p[j]=(uchar)val;
}
}
}
}
MateliminateNoise(Mat*mypics,intsize){
//获取第一个文件
Matone=mypics[0];
Matout=one.clone();
//获得文件信息
intchannels=one.channels();
intRows=one.rows;
intCols=one.cols*channels;
if(one.isContinuous()){
Cols*=Rows;
Rows=1;
}
inti,j;
//uchar*p;//获得picture的行的指针
uchar**p=newuchar*[10];
uchar*out_p;
for(i=0;i{
//输出文件的行指针
out_p=out.ptr(i);
for(size_tz=0;z//赋值为当前行指针
p[z]=mypics[z].ptr(i);
for(j=0;j{
doubleval=0;
//累加每张图片每个像素点的值
for(size_tz=0;zval+=floor(p[z][j]);
//cout<//除以总数得到平均值
out_p[j]=(uchar)(val/size);
}
}
returnout;
}
voidManyImages(vectorImages,Mat&dst,intimgRows)
{
intNum=Images.size();//得到Vector容器中图片个数
//设定包含这些图片的窗口大小
MatWindow(300*((Num-1)/imgRows+1),300*imgRows,CV_8UC3,Scalar(0,0,0));
MatStd_Image;//存放标准大小的图片
MatimageROI;//图片放置区域
SizeStd_Size=Size(300,300);//每个图片显示大小300*300
intx_Begin=0;
inty_Begin=0;
for(inti=0;i{
x_Begin=(i%imgRows)*Std_Size.width;//每张图片起始坐标
y_Begin=(i/imgRows)*Std_Size.height;
resize(Images[i],Std_Image,Std_Size,0,0,INTER_LINEAR);//将图像设为标准大小
//将其贴在Window上
imageROI=Window(Rect(x_Begin,y_Begin,Std_Size.width,Std_Size.height));
Std_Image.copyTo(imageROI);
}
dst=Window;
}
int_tmain(intargc,_TCHAR*argv[])
{
//stringname="image.jpg";
//intImageSize=30;
intImageSize=atoi(argv[2]);
stringname=argv[1];
Matpic=imread(name);
//imshow("原始图片",pic);
//waitKey();
//根据数量生成图片
stringnewname;
for(size_ti=0;i{
MatnewImage=pic.clone();
addNoise(newImage);
ostringstreamss;
ss<<"noise"<
newname=ss.str();
imwrite(newname,newImage);
}
//根据生成的噪声图片,进行叠加
Mat*mypics=newMat[ImageSize];
//图片的通道
stringfile;
for(size_ti=0;i{
ostringstreamname;
name<<"noise"<
file=name.str();
mypics[i]=imread(file,1);
}
//获得消除噪声的输出
Mat&&out=std:
:
move(eliminateNoise(mypics,ImageSize));
ostringstreamss;
ss<<"output"<newname=ss.str();
imwrite(newname,out);
vectormanyimgV;
manyimgV.push_back(std:
:
move(pic));
manyimgV.push_back(out);
Matdst;
ManyImages(manyimgV,dst,2);
imshow("结果输出,左边为原始图片,右边为结果图片",dst);
waitKey(0);
deletemypics;
return0;
}