Bilateral filter&Adaptive bilateral filtering
双边滤波的思想是抑制与中心像素差别太大的像素,简单的来说:起到滤波保边的效果。
目录
双边滤波算法
思想:
双边滤波算法考虑到了空间域和值域两个方面,实现双边滤波的基本思路是:
对于模板的各个点来说:
1、从空间域出发,计算出模板的点与目标点的距离(利用勾股定理),然后计算得出空域权重
2、从值域出发,计算出模板的点与目标点值的差值(取绝对值),然后计算得到值域权重
4、同时让模板各个点的像素值乘以该点的w,并加起来得到sum_pixel
5、最后让sum_pixel除以sumw就得到目标点最终的像素值了
数学表达式:
其中i,j是变化的,(i, j)对应模板的各个点,(k,l)是你要求的像素点,也就是模板的中心点
代码实现
/*
sigma_color参数是上式中的σd, sigma_space参数是上式中的σr
*/
#pragma once
#include "core/core.hpp" //3个opencv库的头文件
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
static void bilateralFilter_8u(const Mat& src, Mat& dst, int d, double sigma_color, double sigma_space, int borderType)
{
int cn = src.channels();//获得图片的通道数
int i, j, k, maxk, radius;
Size size = src.size();
CV_Assert((src.type() == CV_8UC1 || src.type() == CV_8UC3) &&
src.type() == dst.type() && src.size() == dst.size() &&
src.data != dst.data);
if (sigma_color <= 0)
sigma_color = 1;
if (sigma_space <= 0)
sigma_space = 1;
double gauss_color_coeff = -0.5 / (sigma_color*sigma_color);//分母值
double gauss_space_coeff = -0.5 / (sigma_space*sigma_space);//分母值
if (d <= 0)
radius = cvRound(sigma_space*1.5);//进行四舍五入
else
radius = d / 2;
radius = MAX(radius, 1);
d = radius * 2 + 1;
Mat temp;
copyMakeBorder(src, temp, radius, radius, radius, radius, borderType);
/*复制图像并且制作边界。(处理边界卷积)
目的是为了放大图像好做图像的边界处理*/
vector<float> _color_weight(cn * 256);//用来存放值域差值对应的权重
vector<float> _space_weight(d*d);//用来存放空间距离对应的权重
vector<int> _space_ofs(d*d);//用来存放模板各点与锚点(中心点)的偏移量
float* color_weight = &_color_weight[0];
float* space_weight = &_space_weight[0];
int* space_ofs = &_space_ofs[0];
// initial