C语言实现Box Blur算法
Box Blur(盒式模糊)是一种简单的图像模糊算法,它通过计算像素周围邻域内像素的平均值来实现模糊效果,下面我将提供一个完整的C语言实现。

(图片来源网络,侵删)
算法原理
Box Blur的核心思想是用一个固定大小的矩形窗口(称为"盒子")在图像上滑动,对每个像素,将其值替换为窗口内所有像素的平均值。
C语言实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 图像结构体
typedef struct {
int width;
int height;
unsigned char *data; // 假设是灰度图像,每个像素1字节
} Image;
// 创建新图像
Image* create_image(int width, int height) {
Image *img = (Image*)malloc(sizeof(Image));
img->width = width;
img->height = height;
img->data = (unsigned char*)malloc(width * height * sizeof(unsigned char));
return img;
}
// 释放图像内存
void free_image(Image *img) {
free(img->data);
free(img);
}
// Box Blur函数
Image* box_blur(Image *input, int radius) {
int width = input->width;
int height = input->height;
Image *output = create_image(width, height);
// 计算盒子大小 (2*radius + 1)
int box_size = 2 * radius + 1;
int box_area = box_size * box_size;
// 遍历图像每个像素
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
unsigned long sum = 0;
int count = 0;
// 遍历盒子内的像素
for (int dy = -radius; dy <= radius; dy++) {
for (int dx = -radius; dx <= radius; dx++) {
int nx = x + dx;
int ny = y + dy;
// 检查边界
if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
sum += input->data[ny * width + nx];
count++;
}
}
}
// 计算平均值并存储
output->data[y * width + x] = (unsigned char)(sum / count);
}
}
return output;
}
// 示例使用
int main() {
// 创建一个简单的测试图像 (5x5)
int width = 5, height = 5;
Image *test_img = create_image(width, height);
// 填充测试数据 (简单模式)
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
test_img->data[y * width + x] = (x + y) % 256;
}
}
printf("Original image:\n");
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
printf("%3d ", test_img->data[y * width + x]);
}
printf("\n");
}
// 应用Box Blur,半径为1
Image *blurred = box_blur(test_img, 1);
printf("\nBlurred image (radius=1):\n");
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
printf("%3d ", blurred->data[y * width + x]);
}
printf("\n");
}
// 释放内存
free_image(test_img);
free_image(blurred);
return 0;
}
优化版本
上面的实现是基础版本,效率不高,以下是优化后的版本,使用积分图像(Integral Image)来加速计算:
// 计算积分图像
void compute_integral_image(Image *input, unsigned long *integral) {
int width = input->width;
int height = input->height;
// 第一行
integral[0] = input->data[0];
for (int x = 1; x < width; x++) {
integral[x] = integral[x-1] + input->data[x];
}
// 剩余行
for (int y = 1; y < height; y++) {
integral[y * width] = integral[(y-1) * width] + input->data[y * width];
for (int x = 1; x < width; x++) {
integral[y * width + x] = integral[y * width + x - 1] +
integral[(y-1) * width + x] -
integral[(y-1) * width + x - 1] +
input->data[y * width + x];
}
}
}
// 使用积分图像的Box Blur
Image* box_blur_integral(Image *input, int radius) {
int width = input->width;
int height = input->height;
Image *output = create_image(width, height);
// 计算积分图像
unsigned long *integral = (unsigned long*)malloc(width * height * sizeof(unsigned long));
compute_integral_image(input, integral);
int box_size = 2 * radius + 1;
int box_area = box_size * box_size;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// 计算盒子区域的边界
int x1 = (x - radius) < 0 ? 0 : (x - radius);
int y1 = (y - radius) < 0 ? 0 : (y - radius);
int x2 = (x + radius) >= width ? (width - 1) : (x + radius);
int y2 = (y + radius) >= height ? (height - 1) : (y + radius);
// 计算区域面积
int area = (x2 - x1 + 1) * (y2 - y1 + 1);
// 使用积分图像计算区域和
unsigned long sum = integral[y2 * width + x2];
if (x1 > 0) sum -= integral[y2 * width + (x1 - 1)];
if (y1 > 0) sum -= integral[(y1 - 1) * width + x2];
if (x1 > 0 && y1 > 0) sum += integral[(y1 - 1) * width + (x1 - 1)];
// 计算平均值
output->data[y * width + x] = (unsigned char)(sum / area);
}
}
free(integral);
return output;
}
注意事项
- 边界处理:上述实现已经考虑了边界情况,当盒子超出图像边界时会自动调整。
- 性能:优化版本使用积分图像,时间复杂度从O(n²r²)降低到O(n²),其中n是图像像素数,r是半径。
- 扩展:对于彩色图像,可以分别对R、G、B三个通道应用Box Blur。
- 多次模糊:Box Blur多次应用(通常3次)可以近似高斯模糊的效果。
这个实现可以很容易地扩展到处理彩色图像(如RGB或RGBA格式),只需要对每个颜色通道分别应用Box Blur即可。

(图片来源网络,侵删)
