You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

流式运行YOLOv4时,如何用高斯模糊填充检测框实现人脸模糊?

实现YOLOv4 Tiny人脸检测框高斯模糊填充的修改步骤

1. 定位核心修改函数

你需要修改的是src/image.c中的draw_detections_v3函数(detector.c的绘图逻辑最终会调用这个函数),而非直接改动detector.c。这个函数负责处理所有检测框的绘制与标签渲染。

2. 添加高斯模糊功能

方式一:使用Darknet原生实现(无需OpenCV)

先在src/image.h中声明模糊函数:

void gaussian_blur_image(image im, int size, float sigma);

再在src/image.c中实现该函数:

void gaussian_blur_image(image im, int size, float sigma) {
    image temp = copy_image(im);
    int kernel_size = size;
    int half = kernel_size / 2;
    float *kernel = calloc(kernel_size*kernel_size, sizeof(float));
    float sum = 0;

    // 生成高斯核
    for(int i = 0; i < kernel_size; ++i){
        for(int j = 0; j < kernel_size; ++j){
            float x = i - half;
            float y = j - half;
            kernel[i*kernel_size + j] = exp(-(x*x + y*y)/(2*sigma*sigma));
            sum += kernel[i*kernel_size + j];
        }
    }
    // 归一化核权重
    for(int i = 0; i < kernel_size*kernel_size; ++i) kernel[i] /= sum;

    // 对图像每个通道执行模糊
    for(int c = 0; c < im.c; ++c){
        for(int y = 0; y < im.h; ++y){
            for(int x = 0; x < im.w; ++x){
                float val = 0;
                for(int ky = 0; ky < kernel_size; ++ky){
                    for(int kx = 0; kx < kernel_size; ++kx){
                        int yy = y + ky - half;
                        int xx = x + kx - half;
                        if(yy >= 0 && yy < im.h && xx >=0 && xx < im.w){
                            val += kernel[ky*kernel_size + kx] * temp.data[c*im.h*im.w + yy*im.w + xx];
                        }
                    }
                }
                im.data[c*im.h*im.w + y*im.w + x] = val;
            }
        }
    }
    free_image(temp);
    free(kernel);
}

方式二:调用OpenCV简化实现(需确保Darknet编译时链接OpenCV)

在src/image.c顶部添加头文件引用:

#include <opencv2/opencv.hpp>
using namespace cv;

然后实现模糊函数:

void gaussian_blur_image(image im, int size, float sigma) {
    Mat mat = image_to_mat(im);
    GaussianBlur(mat, mat, Size(size, size), sigma);
    mat_to_image(mat, im);
}

注:image_to_mat和mat_to_image是Darknet自带的格式转换函数,定义在src/image_opencv.c中。

3. 修改检测框绘制逻辑,插入模糊处理

找到src/image.c中draw_detections_v3函数里处理单条检测结果的代码段:

for (int i = 0; i < num; ++i){
    box b = boxes[i];
    if (b.w < .001 || b.h < .001) continue;
    float left  = (b.x - b.w/2.)*im.w;
    float right = (b.x + b.w/2.)*im.w;
    float top   = (b.y - b.h/2.)*im.h;
    float bot   = (b.y + b.h/2.)*im.h;

    if(left < 0) left = 0;
    if(right > im.w-1) right = im.w-1;
    if(top < 0) top = 0;
    if(bot > im.h-1) bot = im.h-1;

在这段代码后添加模糊处理逻辑:

// 裁剪出人脸区域子图像
image face_crop = crop_image(im, left, top, right-left, bot-top);
// 执行高斯模糊,size为核尺寸(需奇数),sigma为模糊程度,可自行调整
gaussian_blur_image(face_crop, 21, 3);
// 将模糊后的子图像贴回原图像
paste_image(face_crop, im, left, top);
// 释放子图像内存,避免泄漏
free_image(face_crop);

4. 重新编译并运行

回到Darknet根目录,执行编译命令:

make -j$(nproc)

编译完成后,用你原来的命令启动检测:

./darknet detector demo data/obj.data cfg/custom-yolov4-tiny-detector.cfg custom-yolov4-tiny-detector_best.weights -c 0

即可看到检测到的人脸区域被高斯模糊填充。

注意事项

  • 若未编译OpenCV支持,优先选择Darknet原生模糊实现,避免链接错误。
  • 模糊核尺寸(如21)和sigma值可根据实际视觉效果调整,核尺寸必须为奇数。
  • 若不需要保留检测框,可注释掉函数中draw_box_width相关的绘制代码。

内容的提问来源于stack exchange,提问作者JAYJUS100

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 09:45:49