高斯函数
最近测试一个项目场景,需要模糊视频,由于高斯模糊已经很常见了,所以我们就不再自己实现了。网上也有各种实现。
一 ffmpeg里面的高斯模糊实现
ffmpeg里面的锐化滤镜使用的就是一种快速的高斯模糊实现。
有兴趣的同学可以去看看论文。
二 视频编码的时候具体使用
-vf "unsharp=luma_msize_x=7:luma_msize_y=7:luma_amount=-0.7"
ffmpeg编码选项加速这个滤镜参数就可以了。亮度锐化值为负的时候,表示模糊。
三 模糊效果
左边是模糊的效果
四 实现源码
static void APPly_unsharp( uint8_t *dst, int dst_stride,
const uint8_t *src, int src_stride,
int width, int height, UnsharpFilterParam *fp)
{
uint32_t **sc = fp->sc;
uint32_t sr[MAX_MATRIX_SIZE - 1], tmp1, tmp2;
int32_t res;
int x, y, z;
const uint8_t *src2 = NULL; //silence a warning
const int amount = fp->amount;
const int steps_x = fp->steps_x;
const int steps_y = fp->steps_y;
const int scalebits = fp->scalebits;
const int32_t halfscale = fp->halfscale;
if (!amount) {
av_image_copy_plane(dst, dst_stride, src, src_stride, width, height);
return;
}
for (y = 0; y < 2 * steps_y; y++)
memset(sc[y], 0, sizeof(sc[y][0]) * (width + 2 * steps_x));
for (y = -steps_y; y < height + steps_y; y++) {
if (y < height)
src2 = src;
memset(sr, 0, sizeof(sr[0]) * (2 * steps_x - 1));
for (x = -steps_x; x < width + steps_x; x++) {
tmp1 = x <= 0 ? src2[0] : x >= width ? src2[width-1] : src2[x];
for (z = 0; z < steps_x * 2; z += 2) {
tmp2 = sr[z + 0] + tmp1; sr[z + 0] = tmp1;
tmp1 = sr[z + 1] + tmp2; sr[z + 1] = tmp2;
}
for (z = 0; z < steps_y * 2; z += 2) {
tmp2 = sc[z + 0][x + steps_x] + tmp1; sc[z + 0][x + steps_x] = tmp1;
tmp1 = sc[z + 1][x + steps_x] + tmp2; sc[z + 1][x + steps_x] = tmp2;
}
if (x >= steps_x && y >= steps_y) {
const uint8_t *srx = src - steps_y * src_stride + x - steps_x;
uint8_t *dsx = dst - steps_y * dst_stride + x - steps_x;
res = (int32_t)*srx + ((((int32_t) * srx - (int32_t)((tmp1 + halfscale) >> scalebits)) * amount) >> 16);
*dsx = av_clip_uint8(res);
}
}
if (y >= 0) {
dst += dst_stride;
src += src_stride;
}
}
}
声明:上面代码我也没怎么读懂,有兴趣的可以先去研究一下论文,再看这个代码。