Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save pengdu/d2688fefd805291e9583b6e6a3900a68 to your computer and use it in GitHub Desktop.
Save pengdu/d2688fefd805291e9583b6e6a3900a68 to your computer and use it in GitHub Desktop.

以下是使用C++实现双边网格滤波算法的示例代码,不依赖于任何第三方库:

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

// 双边滤波器
float bilateral_filter(vector<vector<float>>& img, int x, int y, int size, float sigma_s, float sigma_r) {
    float weight_sum = 0;
    float result = 0;
    int half_size = size / 2;
    for (int i = -half_size; i <= half_size; i++) {
        for (int j = -half_size; j <= half_size; j++) {
            int x1 = x + i;
            int y1 = y + j;
            if (x1 >= 0 && x1 < img[0].size() && y1 >= 0 && y1 < img.size()) {
                float dist = pow(i, 2) + pow(j, 2);
                float weight = exp(-dist / (2 * pow(sigma_s, 2)));
                float diff = img[y1][x1] - img[y][x];
                float r_weight = exp(-pow(diff, 2) / (2 * pow(sigma_r, 2)));
                float total_weight = weight * r_weight;
                result += img[y1][x1] * total_weight;
                weight_sum += total_weight;
            }
        }
    }
    return result / weight_sum;
}

// 双边网格滤波器
vector<vector<float>> bilateral_grid_filter(vector<vector<float>>& img, int size, int num_iterations, float sigma_s, float sigma_r) {
    // 将图像像素分成网格
    int grid_size = size;
    int h = img.size();
    int w = img[0].size();
    int num_x = int(ceil(float(w) / grid_size));
    int num_y = int(ceil(float(h) / grid_size));

    // 对每个网格内的像素进行灰度值的平均化
    vector<vector<float>> grid(num_y, vector<float>(num_x));
    for (int y = 0; y < num_y; y++) {
        for (int x = 0; x < num_x; x++) {
            int x_min = x * grid_size;
            int y_min = y * grid_size;
            int x_max = min(x_min + grid_size, w);
            int y_max = min(y_min + grid_size, h);
            float mean = 0;
            for (int i = y_min; i < y_max; i++) {
                for (int j = x_min; j < x_max; j++) {
                    mean += img[i][j];
                }
            }
            mean /= (y_max - y_min) * (x_max - x_min);
            grid[y][x] = mean;
        }
    }

    // 对每个网格的灰度值进行双边滤波器处理
    for (int i = 0; i < num_iterations; i++) {
        for (int y = 0; y < num_y; y++) {
            for (int x = 0; x < num_x; x++) {
                // 计算当前网格的中心点
                int center_x = x * grid_size + grid_size / 2;
                int center_y = y * grid_size + grid_size / 2;

                // 计算当前网格的范围
                int x_min = x * grid_size;
                int y_min = y * grid_size;
                int x_max = min(x_min + grid_size, w);
                int y_max = min(y_min + grid_size, h);

                // 对当前网格内的像素进行双边滤波器处理
                for (int y1 = y_min; y1 < y_max; y1++) {
                    for (int x1 = x_min; x1 < x_max; x1++) {
                        img[y1][x1] = bilateral_filter(grid, x1 - x_min, y1 - y_min, size, sigma_s, sigma_r);
                    }
                }
            }
        }
    }

    return img;
}

int main() {
    // 读取图像
    int h = 512;
    int w = 512;
    vector<vector<float>> img(h, vector<float>(w));
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            img[y][x] = float(rand() % 256);
        }
    }

    // 使用双边网格算法进行滤波
    vector<vector<float>> filtered_img = bilateral_grid_filter(img, 5, 5, 5, 50);

    // 输出原始图像和滤波结果
    cout << "Original Image:" << endl;
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            cout << img[y][x] << " ";
        }
        cout << endl;
    }
    cout << endl;
    cout << "Filtered Image:" << endl;
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            cout << filtered_img[y][x] << " ";
        }
        cout << endl;
    }

    return 0;
}

在上述示例代码中,bilateral_filter函数表示双边滤波器,接受五个参数:img表示输入图像,xy表示当前像素的坐标,size表示滤波器的大小,sigma_s表示空间域标准差,sigma_r表示灰度域标准差。函数返回当前像素的滤波结果。

bilateral_grid_filter函数表示双边网格滤波器,接受五个参数:img表示输入图像,size表示滤波器的大小,num_iterations表示迭代次数,sigma_s表示空间域标准差,sigma_r表示灰度域标准差。函数返回滤波后的图像。

bilateral_grid_filter函数中,首先将图像像素分成网格,对每个网格内的像素进行灰度值的平均化。然后对每个网格的灰度值进行双边滤波器处理,使用bilateral_filter函数对当前网格内的像素进行双边滤波器处理。最后将滤波结果重新组合成图像。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment