快速二维中值滤波算法的实现(灰度+RGB图)

在CSDN的第一篇博客

摘要

本文主要完成对 Thomas S Huang, George J Yang, and Gregory J Yang. A Fast Two-Dimensional Median Filtering Algorithm[J]. IEEE Transactions on Acoustics Speech and Signal Processing, 1979, 27(1): 13-18. 论文中算法的实现。论文中算法应用于灰度图像,这里我也把它扩展到RGB图像,其基本原理是一致的,对于RGB图像需要对三个通道分别进行快速中值滤波。

算法流程及伪代码

算法流程

快速二维中值滤波算法主要有以下几个步骤:
(1)先建立第一个要处理的像素点的滤波器窗口灰度等级直方图,并找到这个窗口内所有像素点灰度值的中值,并计算窗口内小于中值的灰度值数量,存入ltmdn。
(2)将窗口中心移动到下一个像素点,同时更新灰度直方图为当前窗口的,并更新当前窗口的ltmdn。
(3)根据当前的ltmdn与窗口像素点总数/2的关系,向上/向下寻找当前窗口的灰度中值。
(4)若当前像素点不是某一行的最后一个,则转到步骤2;若当前像素点为某一行的最后一个,且不是要处理的最后一行,则将窗口中心移动到下一行的第一列的像素点,再转到步骤1;否则,流程结束。
注:处理彩色图像时,对于每一个像素点要建立RGB三个通道的滤波器窗口灰度直方图,并对每一个通道单独求中值以及更新直方图。
该算法忽略了对图像边界的滤波处理,边界值不进行中值滤波,直接保留原始的灰度值。

伪代码

1.  //Richard Chen
2.	Begin  
3.	hist[255]={
   0}//存储256级灰度  
4.	mdn //存储灰度中值  
5.	ltmdn //记录当前滤波器窗口中,灰度值小于mdn的像素点个数  
6.	window_x_size //滤波器窗口列数  
7.	window_y_size //滤波器窗口行数  
8.	th=window_x_size*window_y_size/2 //用于帮助寻找中值  
9.	left.column[window_y_size]//存储上一个窗口最左侧一列的数据  
10.	right.column[window_y_size]//存储当前窗口最右侧一列的数据  
11.	  
12.	for (i=window_y_size/2 +1;i<picture_y_size-window_y_size/2;i++)  
13.	{
     
14.	    先对每一行的第一个像素点构建灰度直方图,并找到当前窗口的中值mdn和对应的ltmdn  
15.	    for(j=window_x_size/2 +2 ;j<picture_x_size-window_x_size/2;j++)  
16.	    {
     
17.	        更新直方图,对于上一个窗口最左侧一列的数据,在直方图中删去,  
18.	        对于当前窗口最右侧一列的数据,加进直方图中,同时如果有灰度值小于mdn,ltmdn也要相应改变  
19.	        for(k=0;k<window_y_size;k++)  
20.	        {
     
21.	            hist[left.column[k]]--;  
22.	            if(left.column[k]<mdn)ltmdn--;  
23.	            hst[right.column[k]]++;  
24.	            if(right.column[k]<ltmdn)ltmdn++;  
25.	        }  
26.	        更新完直方图后,根据现在的ltmdn来快速寻找新的中值mdn  
27.	        if(ltmdn>th)  
28.	        {
     
29.	            while(ltmdn>th)  
30.	            {
     
31.	                mdn--;  
32.	                ltmd-=hist[mdn];  
33.	            }  
34.	        }  
35.	        else  
36.	        {
     
37.	            while(ltmdn+hist[mdn]<=th)  
38.	            {
     
39.	                ltmdn+=hist[mdn];  
40.	                mdn++;  
41.	            }  
42.	        }  
43.	  
44.	        将找到的中值mdn存入新图中对应的位置  
45.	        注:这里滤波结果应该存入新图中,不能存入原图,否则会对后续滤波产生影响。  
46.	    }  
47.	}  
48.	end  

程序代码

算法使用C++进行实现,并用其对三张图片进行了处理。三张图片分别为原始图片,在原始图片上添加了5%椒盐噪声的图片,在原始图片上添加了高斯噪声的图片,高斯噪声的均值为0,方差为1,为了增强噪声效果,我对每一个像素点的高斯噪声幅值增加到了原始幅值的10倍。
程序使用opencv读取和保存图片,中值滤波函数为自己写的(作业要求嘛…)

/***********************************************
*
* DIP homework: A Fast Two-Dimensional Median Filtering Algorithm
* Author: Richard Chen
* Date: 2019.12
* Institute: NJUST
* 功能:实现灰度图和彩色图的二维快速中值滤波算法,并于传统中值滤波进行了比较
*
************************************************/

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

clock_t startTime, endTime;

#define window_x_size 3 //定义窗口的大小
#define window_y_size 3
#define window_size window_x_size *window_y_size
#define th window_size / 2 //用于寻找中值

struct hist_3d
{
   
	int Blue[256] = {
    0 };
	int Green[256] = {
    0 };
	int Red[256] = {
    0 };
};

Mat Add_salt_noise(const Mat src, int num)
{
   
	Mat dst = src.clone();
	int n = 0, i = 0, j = 0, flag = 0;
	for (n = 0; n < num; n++)
	{
   
		//随机取行列
		i = rand() % dst.rows;
		j = rand() % dst.cols;
		flag = rand() % 2; //用于决定加椒还是加盐噪声 flag=0或1

		if (flag)
		{
   
			if (dst.channels() == 1) //图像通道判定  判别灰度图还是RGB图
			{
   
				dst.at<uchar>(i, j) = 255; //盐噪声
			}
			else
			{
   
				dst.at<Vec3b>(i, j)[0] = 255;
				dst.at<Vec3b>(i, j)[1] = 255;
				dst.at<Vec3b>(i, j)[2] = 255;
			}
		}
		else
		{
   
			if (dst.channels() == 1)
			{
   
				dst.at<uchar>(i, j) = 0; //椒噪声
			}
			else
			{
   
				dst.at<Vec3b>(i, j)[0] = 0;
				dst.at<Vec3b>(i, j)[1] = 0;
				dst.at<Vec3b>(i, j)[2] = 0;
			}
		}
	}
	return dst;
}

//生成高斯噪声
double generateGaussianNoise(double mu, double sigma)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值