图像处理——双边滤波

1 近期在学习双边滤波相关知识,其原理如下(以后补上):

2 灰度图双边滤波实现C++代码如下,网上大多数是基于8位灰度图和彩色图像的。(此次代码未经优化,可去除opencv依赖):

//灰度图双边滤波
void m_bilateralFilter(cv::Mat src,cv::Mat& dst,int radius,float sigma_r,float sigma_d)
{
	if (src.empty())
		return;
	if (dst.empty())
	{
		dst = src.clone();
	}
	if (src.depth() == CV_16U){
		for (int i = radius; i < src.rows - radius; i++)
			for (int j = radius; j < src.cols - radius; j++)
			{
				float sum_1 = .0f, sum_2 = .0f;
				for (int k = 0; k < 2 * radius - 1; k++)
					for (int l = 0; l < 2 * radius - 1; l++)
					{
						int dis_x = radius - k;
						int dis_y = radius - l;
						int coord_x_image = i - radius + k;
						int coord_y_image = j - radius + l;
						float dis_spatial = dis_x*dis_x + dis_y*dis_y;
						float dis_range = (src.at(i, j)
							- src.at(coord_x_image, coord_y_image))*(src.at(i, j)
							- src.at(coord_x_image, coord_y_image));
						float c_tmp = exp(-dis_spatial /
							(2 * sigma_d * sigma_d));
						float s_tmp = exp(-dis_range /
							(2 * sigma_r * sigma_r));
						sum_1 += c_tmp*s_tmp*src.at(coord_x_image, coord_y_image);
						sum_2 += c_tmp*s_tmp;

					}
				dst.at(i, j) = sum_1 / sum_2;
			}
	}
	else if (src.depth() == CV_8U)
	{
		for (int i = radius; i < src.rows - radius; i++)
			for (int j = radius; j < src.cols - radius; j++)
			{
				float sum_1 = .0f, sum_2 = .0f;
				for (int k = 0; k < 2 * radius - 1; k++)
					for (int l = 0; l < 2 * radius - 1; l++)
					{
						int dis_x = radius - k;
						int dis_y = radius - l;
						int coord_x_image = i - radius + k;
						int coord_y_image = j - radius + l;
						float dis_spatial = dis_x*dis_x + dis_y*dis_y;
						float dis_range = (src.at(i, j)
							- src.at(coord_x_image, coord_y_image))*(src.at(i, j)
							- src.at(coord_x_image, coord_y_image));
						float c_tmp = exp(-dis_spatial /
							(2 * sigma_d * sigma_d));
						float s_tmp = exp(-dis_range /
							(2 * sigma_r * sigma_r));
						sum_1 += c_tmp*s_tmp*src.at(coord_x_image, coord_y_image);
						sum_2 += c_tmp*s_tmp;

					}
				dst.at(i, j) = sum_1 / sum_2;
			}
	}
}

3 目前是基于单通道图像,效果如下:

原图:

图像处理——双边滤波_第1张图片

opencv 库的效果(cv::bilateralFilter(img_src, img_dst, 10,10 * 2, 10 / 2))

图像处理——双边滤波_第2张图片

该程序的效果(m_bilateralFilter(img_src, img_dst, 5, 10 * 2, 10 / 2))

图像处理——双边滤波_第3张图片

你可能感兴趣的:(图像处理,双边滤波)