-------------------开通头条号--------------------

实验名称

图像去噪

实验目的

1、掌握算术均值滤波器、几何均值滤波器、谐波和逆谐波均值滤波器进行图像去噪的算法

2、掌握利用中值滤波器进行图像去噪的算法

3、掌握自适应中值滤波算法

4、掌握自适应局部降低噪声滤波器去噪算法

5、掌握彩色图像去噪步骤

实验内容

1、均值滤波

具体内容:利用 OpenCV 对灰度图像像素进行操作,分别利用算术均值滤波器、几何均值滤波器、谐波和逆谐波均值滤波器进行图像去噪。模板大小为5*5。(注:请分别为图像添加高斯噪声、胡椒噪声、盐噪声和椒盐噪声,并观察滤波效果)

2、中值滤波

具体内容:利用 OpenCV 对灰度图像像素进行操作,分别利用 5*5 和 9*9尺寸的模板对图像进行中值滤波。(注:请分别为图像添加胡椒噪声、盐噪声和椒盐噪声,并观察滤波效果)

3、自适应均值滤波。

具体内容:利用 OpenCV 对灰度图像像素进行操作,设计自适应局部降低噪声滤波器去噪算法。模板大小 7*7(对比该算法的效果和均值滤波器的效果)

4、自适应中值滤波

具体内容:利用 OpenCV 对灰度图像像素进行操作,设计自适应中值滤波算法对椒盐图像进行去噪。模板大小 7*7(对比中值滤波器的效果)

5、彩色图像均值滤波

具体内容:利用 OpenCV 对彩色图像 RGB 三个通道的像素进行操作,利用算术均值滤波器和几何均值滤波器进行彩色图像去噪。模板大小为 5*5。

实验完成情况

1、 实验步骤:先为灰度图像添加高斯噪声、胡椒噪声、盐噪声和椒盐噪声,再分别利用算术均值滤波器、几何均值滤波器、谐波和逆谐波均值滤波器进行图像去噪。模板大小为5*5。

核心代码如下:

添加各类噪声:

IplImage* AddGuassianNoise(IplImage* src)    //添加高斯噪声

{

IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

IplImage* noise = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

CvRNG rng = cvRNG(-1);

cvRandArr(&rng,noise,CV_RAND_NORMAL,cvScalarAll(0),cvScalarAll(15));

cvAdd(src,noise,dst);

return dst;

}

IplImage* AddPepperNoise(IplImage* src)      //添加胡椒噪声,随机黑色点

{

IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

cvCopy(src, dst);

for(int k=0; k<8000; k++)

{

int i = rand()%src->height;

int j = rand()%src->width;

CvScalar s = cvGet2D(src, i, j);

if(src->nChannels == 1)

{

s.val[0] = 0;

}

else if(src->nChannels==3)

{

s.val[0]=0;

s.val[1]=0;

s.val[2]=0;

}

cvSet2D(dst, i, j, s);

}

return dst;

}

IplImage* AddSaltNoise(IplImage* src)       //添加盐噪声,随机白色点

{

IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

cvCopy(src, dst);

for(int k=0; k<8000; k++)

{

int i = rand()%src->height;

int j = rand()%src->width;

CvScalar s = cvGet2D(src, i, j);

if(src->nChannels == 1)

{

s.val[0] = 255;

}

else if(src->nChannels==3)

{

s.val[0]=255;

s.val[1]=255;

s.val[2]=255;

}

cvSet2D(dst, i, j, s);

}

return dst;

}

IplImage* AddPepperSaltNoise(IplImage* src)    //添加椒盐噪声,随机黑白点

{

IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

cvCopy(src, dst);

for(int k=0; k<8000; k++)

{

int i = rand()%src->height;

int j = rand()%src->width;

int m = rand()%2;

CvScalar s = cvGet2D(src, i, j);

if(src->nChannels == 1)

{

if(m==0)

{

s.val[0] = 255;

}

else

{

s.val[0] = 0;

}

}

else if(src->nChannels==3)

{

if(m==0)

{

s.val[0]=255;

s.val[1]=255;

s.val[2]=255;

}

else

{

s.val[0]=0;

s.val[1]=0;

s.val[2]=0;

}

}

cvSet2D(dst, i, j, s);

}

return dst;

}

各类滤波器实现:

//算术均值滤波器——模板大小5*5

IplImage* ArithmeticMeanFilter(IplImage* src)

{

IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

cvSmooth(src,dst,CV_BLUR,5);

return dst;

}

//几何均值滤波器——模板大小5*5

IplImage* GeometryMeanFilter(IplImage* src)

{

IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

int row, col;

int h=src->height;

int w=src->width;

double mul[3];

double dc[3];

int mn;

//计算每个像素的去噪后color值

for(int i=0;i<src->height;i++){

for(int j=0;j<src->width;j++){

mul[0]=1.0;

mn=0;

//统计邻域内的几何平均值,邻域大小5*5

for(int m=-2;m<=2;m++){

row = i+m;

for(int n=-2;n<=2;n++){

col = j+n;

if(row>=0&&row<h && col>=0 && col<w){

CvScalar s = cvGet2D(src, row, col);

mul[0] = mul[0]*(s.val[0]==0?1:s.val[0]);   //邻域内的非零像素点相乘

mn++;

}

}

}

//计算1/mn次方

CvScalar d;

dc[0] = pow(mul[0], 1.0/mn);

d.val[0]=dc[0];

//统计成功赋给去噪后图像。

cvSet2D(dst, i, j, d);

}

}

return dst;

}

//谐波均值滤波器——模板大小5*5

IplImage* HarmonicMeanFilter(IplImage* src)

{

IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

int row, col;

int h=src->height;

int w=src->width;

double sum[3];

double dc[3];

int mn;

//计算每个像素的去噪后color值

for(int i=0;i<src->height;i++){

for(int j=0;j<src->width;j++){

sum[0]=0.0;

mn=0;

//统计邻域,5*5模板

for(int m=-2;m<=2;m++){

row = i+m;

for(int n=-2;n<=2;n++){

col = j+n;

if(row>=0&&row<h && col>=0 && col<w){

CvScalar s = cvGet2D(src, row, col);

sum[0] = sum[0]+(s.val[0]==0?255:255/s.val[0]);

mn++;

}

}

}

CvScalar d;

dc[0] = mn*255/sum[0];

d.val[0]=dc[0];

//统计成功赋给去噪后图像。

cvSet2D(dst, i, j, d);

}

}

return dst;

}

//逆谐波均值大小滤波器——模板大小5*5

IplImage* InverseHarmonicMeanFilter(IplImage* src)

{

IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

//cvSmooth(src,dst,CV_BLUR,5);

int row, col;

int h=src->height;

int w=src->width;

double sum[3];

double sum1[3];

double dc[3];

double Q=2;

//计算每个像素的去噪后color值

for(int i=0;i<src->height;i++){

for(int j=0;j<src->width;j++){

sum[0]=0.0;

sum1[0]=0.0;

//统计邻域

for(int m=-2;m<=2;m++){

row = i+m;

for(int n=-2;n<=2;n++){

col = j+n;

if(row>=0&&row<h && col>=0 && col<w){

CvScalar s = cvGet2D(src, row, col);

sum[0] = sum[0]+pow(s.val[0]/255, Q+1);

sum1[0] = sum1[0]+pow(s.val[0]/255, Q);

}

}

}

//计算1/mn次方

CvScalar d;

dc[0] = (sum1[0]==0?0:(sum[0]/sum1[0]))*255;

d.val[0]=dc[0];

//统计成功赋给去噪后图像。

cvSet2D(dst, i, j, d);

}

}

return dst;

}

实验结果如图所示:(从左至右,从上至下分别为原图像、加噪图像、算术均值处理图像、几何均值处理图像、谐波均值处理图像、逆谐波均值处理图像)

(1)高斯噪声:

(2)胡椒噪声:

(3)盐噪声

(4)椒盐噪声

2、 实验步骤:先为灰度图像添加胡椒噪声、盐噪声和椒盐噪声,再分别利用5*5 和 9*9尺寸的模板对图像进行中值滤波。

核心代码如下:

IplImage* MedianFilter_5_5(IplImage* src){

IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

cvSmooth(src,dst,CV_MEDIAN,5);

return dst;

}

IplImage* MedianFilter_9_9(IplImage* src){

IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

cvSmooth(src,dst,CV_MEDIAN,9);

return dst;

}

实验结果如下图(灰度图像和加噪图像第一问中已给出,下面只列出分别利用5*5 和 9*9尺寸的模板对图像进行中值滤波后的图像):

灰度图像加胡椒噪声,分别利用5*5 和 9*9尺寸的模板对图像进行中值滤波。

灰度图像加盐噪声,分别利用5*5 和 9*9尺寸的模板对图像进行中值滤波。

灰度图像加椒盐噪声,分别利用5*5 和 9*9尺寸的模板对图像进行中值滤波。

3、 实验步骤:自适应均值滤波(以高斯噪声为例),先为灰度图像添加高斯噪声,再利用7*7尺寸的模板对图像进行自适应均值滤波。

核心代码如下:

IplImage* SelfAdaptMeanFilter(IplImage* src){

IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

cvSmooth(src,dst,CV_BLUR,7);

int row, col;

int h=src->height;

int w=src->width;

int mn;

double Zxy;

double Zmed;

double Sxy;

double Sl;

double Sn=100;

for(int i=0;i<src->height;i++){

for(int j=0;j<src->width;j++){

CvScalar xy = cvGet2D(src, i, j);

Zxy = xy.val[0];

CvScalar dxy = cvGet2D(dst, i, j);

Zmed = dxy.val[0];

Sl=0;

mn=0;

for(int m=-3;m<=3;m++){

row = i+m;

for(int n=-3;n<=3;n++){

col = j+n;

if(row>=0&&row<h && col>=0 && col<w){

CvScalar s = cvGet2D(src, row, col);

Sxy = s.val[0];

Sl = Sl+pow(Sxy-Zmed, 2);

mn++;

}

}

}

Sl=Sl/mn;

CvScalar d;

d.val[0]=Zxy-Sn/Sl*(Zxy-Zmed);

cvSet2D(dst, i, j, d);

}

}

return dst;

}

实验结果如图:

4、 实验步骤:自适应中值滤波(以椒盐噪声为例),先为灰度图像添加椒盐噪声,再利用7*7尺寸的模板对图像进行自适应中值滤波。

核心代码如下:

IplImage* SelfAdaptMedianFilter(IplImage* src){

IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);

int row, col;

int h=src->height;

int w=src->width;

double Zmin,Zmax,Zmed,Zxy,Smax=7;

int wsize;

//计算每个像素的去噪后color值

for(int i=0;i<src->height;i++){

for(int j=0;j<src->width;j++){

//统计邻域

wsize=1;

while(wsize<=3){

Zmin=255.0;

Zmax=0.0;

Zmed=0.0;

CvScalar xy = cvGet2D(src, i, j);

Zxy=xy.val[0];

int mn=0;

for(int m=-wsize;m<=wsize;m++){

row = i+m;

for(int n=-wsize;n<=wsize;n++){

col = j+n;

if(row>=0&&row<h && col>=0 && col<w){

CvScalar s = cvGet2D(src, row, col);

if(s.val[0]>Zmax){

Zmax=s.val[0];

}

if(s.val[0]<Zmin){

Zmin=s.val[0];

}

Zmed=Zmed+s.val[0];

mn++;

}

}

}

Zmed = Zmed/mn;

CvScalar d;

if((Zmed-Zmin)>0 && (Zmed-Zmax)<0){

if((Zxy-Zmin)>0 && (Zxy-Zmax)<0){

d.val[0]=Zxy;

}else{

d.val[0]=Zmed;

}

cvSet2D(dst, i, j, d);

break;

} else {

wsize++;

if(wsize>3){

CvScalar d;

d.val[0]=Zmed;

cvSet2D(dst, i, j, d);

break;

}

}

}

}

}

return dst;

}

实验结果如图:

5、 实验步骤:利用 OpenCV 对彩色图像 RGB 三个通道的像素进行操作,利用算术均值滤波器和几何均值滤波器进行彩色图像去噪。模板大小为 5*5。

实验代码参照问题一,选择彩色图片、算术均值滤波器和几何均值滤波器进行彩色图像去噪。

实验结果如下图(以椒盐噪声为例):

利用算术均值滤波器:

利用几何均值滤波器:

实验中的问题

实验问题:几何均值滤波以及谐波、逆谐波滤波没有对应的库函数

解决方法:通过学习书本对应章节,根据公式写出程序

实验结果

基于 opencv图像去噪的更多相关文章

  1. 基于OpenCV的火焰检测(一)——图像预处理

    博主最近在做一个基于OpenCV的火焰检测的项目,不仅可以检测图片中的火焰,还可以检测视频中的火焰,最后在视频检测的基础上推广到摄像头实时检测.在做这个项目的时候,博主参考了很多相关的文献,用了很多种 ...

  2. 基于 opencv 的图像处理入门教程

    前言 虽然计算机视觉领域目前基本是以深度学习算法为主,但实际上很多时候对图片的很多处理方法,并不需要采用深度学习的网络模型,采用目前成熟的图像处理库即可实现,比如 OpenCV 和 PIL ,对图片进 ...

  3. [转载]卡尔曼滤波器及其基于opencv的实现

    卡尔曼滤波器及其基于opencv的实现 源地址:http://hi.baidu.com/superkiki1989/item/029f65013a128cd91ff0461b 这个是维基百科中的链接, ...

  4. 基于Opencv和Mfc的图像处理增强库GOCVHelper(索引)

    GOCVHelper(GreenOpen Computer Version Helper )是我在这几年编写图像处理程序的过程中积累下来的函数库.主要是对Opencv的适当扩展和在实现Mfc程序时候的 ...

  5. 基于OpenCv的人脸检测、识别系统学习制作笔记之一

    基于OpenCv从视频文件到摄像头的人脸检测 在OpenCv中读取视频文件和读取摄像头的的视频流然后在放在一个窗口中显示结果其实是类似的一个实现过程. 先创建一个指向CvCapture结构的指针 Cv ...

  6. 基于opencv网络摄像头在ubuntu下的视频获取

     基于opencv网络摄像头在ubuntu下的视频获取 1  工具 原料 平台 :UBUNTU12.04 安装库  Opencv-2.3 2  安装编译运行步骤 安装编译opencv-2.3  参 ...

  7. 基于opencv的小波变换

    基于opencv的小波变换 提供函数DWT()和IDWT(),前者完成任意层次的小波变换,后者完成任意层次的小波逆变换.输入图像要求必须是单通道浮点图像,对图像大小也有要求(1层变换:w,h必须是2的 ...

  8. 基于opencv在摄像头ubuntu根据视频获取

     基于opencv在摄像头ubuntu根据视频获取 1  工具 原料 平台 :UBUNTU12.04 安装库  Opencv-2.3 2  安装编译执行步骤 安装编译opencv-2.3  參考h ...

  9. OpenCV2学习笔记(十四):基于OpenCV卡通图片处理

    得知OpenCV有一段时间.除了研究的各种算法的内容.除了从备用,据导游书籍和资料,尝试结合链接的图像处理算法和日常生活,第一桌面上(随着摄像头)完成了一系列的视频流处理功能.开发平台Qt5.3.2+ ...

随机推荐

  1. MySQL学习_计算用户支付方式占比_20161104

    计算用户支付方式占比 SELECT b.*#根据城市ID 年月排序 FROM ( SELECT a.* FROM ( #纵向合并 SELECT b1.ID,a1.城市,a1.收款方式,DATE_FOR ...

  2. 【LeetCode】017. Letter Combinations of a Phone Number

    题目: Given a digit string, return all possible letter combinations that the number could represent. A ...

  3. Scala学习——集合的使用和“_”的一些使用(中)

    1.空格加_可以表示函数的原型 命令行代码: scala> def fun1(name:String){println(name)} fun1: (name: String)Unit scala ...

  4. python 带参数运行

    近段时间学考,又爱上了游戏.LOL  nba2k 使命召唤 哎! 因为使命召唤的原因  有时候会卡住  然后点关闭没用. 然后任务管理器打不开 所以我想写个杀掉这个程序的东西.  当然写一下是简单.但 ...

  5. RestClient(接口请求)

    一.电子签章:通过接口,传入参数中有pdf文件,和其他参数,在文件上盖上电子签章. 引入:通过NuGet安装RestSharp,注意版本. 备注:如果后面程序运行有错,可以看是引用是否更改了web.c ...

  6. linux正则表达式基础

    linux中awk,sed,grep等 命令使用区别正则表达式基础 在最简单的情况下,一个正则表达式看上去就是一个普通的查找串.例如,正则表达式"testing"中没有包含任何元字 ...

  7. array mysql_fetch_row(resource result)

    array mysql_fetch_row(resource result) 函数返回从结果集result中取得的行生成的数组,若到了最后一行之后则返回false,每个结果的列存储在一个数组的单元中 ...

  8. LeetCode: 383 Ransom Note(easy)

    题目: Given an arbitrary ransom note string and another string containing letters from all the magazin ...

  9. 【Java】NIO中Channel的注册源码分析

    Channel的注册是在SelectableChannel中定义的: public abstract SelectionKey register(Selector sel, int ops, Obje ...

  10. js 常用排序

    1. 冒泡排序 原理:从第一个元素开始,把当前元素和下一个索引元素进行比较.如果当前元素大,那么就交换位置,重复操作直到比较到最后一个元素 function bubbleSort(arr) { if ...