-------------------開通頭條號--------------------
實驗名稱 |
圖像去噪 |
實驗目的 |
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。 實驗代碼參照問題一,選擇彩色圖片、算術均值濾波器和幾何均值濾波器進行彩色圖像去噪。 實驗結果如下圖(以椒鹽噪聲為例): 利用算術均值濾波器:
利用幾何均值濾波器:
|
實驗中的問題
|
實驗問題:幾何均值濾波以及諧波、逆諧波濾波沒有對應的庫函數 解決方法:通過學習書本對應章節,根據公式寫出程序
|
實驗結果
|
|