流式运行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
相关产品推荐
相关产品推荐

