gblur 只有一个核心参数 sigma,单位是像素。 sigma=1 就把锐度砍到一成,3 以上基本认不出细节。
7.12 动了颜色,这一节动的是空间频率——把细节抹掉。 它是「遮挡敏感信息」与「背景虚化」两个实用效果的基础。
一、核心参数只有一个
gblur 做高斯模糊,sigma 就是「糊多远」:
ffmpeg -i s7.mp4 -vf gblur=sigma=5 out.mp4
sigma 是高斯分布的标准差,单位是像素。sigma 越大,糊的范围越宽。 经验值:1~2 轻微柔化,3~5 明显糊,10 以上基本认不出原图。
它还有个 steps 参数(默认 1),控制「分几步算」。
steps 越大越快但越不精确,做实时处理时可以调大,出片一般不用动。
二、实测五档 sigma 的锐度
锐度用拉普拉斯方差量:跟四邻域做差再求方差,边缘越硬数越大。
sigma 锐度 相对原图
不模糊 35759 100% 1 3515 9.8% 2 364 1.0% 3 64 0.2% 5 9 0.0% 10 3 0.0%
sigma 只加到 1,锐度就掉到原来的十分之一;加到 2 只剩 1%。
这个衰减比想象中快得多——「稍微糊一点」用 sigma=1 就够了。
为什么会这么快:高斯模糊是对每个像素取邻域加权平均, 而拉普拉斯方差只对「相邻像素差」敏感。相邻差被平均掉之后,方差是平方级往下掉的。
三、反向的滤镜:unsharp
unsharp 名字是「不锐化」,实际作用是锐化——
名字来自暗房工艺里的「反锐化掩模」:拿模糊版当遮罩,把差值加回去。
写法 锐度 比原图
unsharp=5:5:1.0 49515 138%
三个参数是「亮度矩阵宽 : 高 : 强度」。强度正数是锐化,负数是模糊。
所以 unsharp=5:5:-1.0 就是一个模糊,只是算法跟 gblur 不一样。
锐化不能过头:强度超过 2 之后边缘会出现白边与黑边的「描边感」, 那东西一旦编进片子就洗不掉。要做就轻一点,1.0 以下比较安全。
四、四个真实用途
模糊在实战里出现的地方比想象中多:
用途 怎么用
遮挡敏感信息 crop 出区域 → gblur 到认不出 → overlay 回去 做背景虚化 放大 → gblur 大 sigma → 主体 overlay 上去 模拟水面/毛玻璃 在倒影那一路加 sigma=1.5(7.8 用过) 掩盖低码率块效应 轻微 sigma=0.5 就能盖住
第一条里的「blur 到认不出」是有门槛的: sigma=5 只是「看着糊」,给人脸打码一般要 15 以上才真的不可复原。 这个门槛跟分辨率、人脸大小都有关,没有硬标准, 只能自己拿原图试着还原一次——还原得出来就说明还不够糊。
第四条值得多说一句:低码率视频的块效应是「8×8 的方格」, 轻微模糊能把方格的边软化掉,代价是整个画面都软一点。 与其事后糊,不如一开始就把码率给够。
五、动手 Demo:五档 sigma、一次 unsharp
下面这段代码先量原图的锐度,再跑五档 sigma,
最后跑一次 unsharp 看锐化能把数推到多高。
import av
from fractions import Fraction
TB = Fraction(1, 25)
c0 = av.open(u"s7.mp4")
BASE = [fr.to_ndarray(format=u"yuv420p") for fr in c0.decode(video=0)]
c0.close()
def run(filters, n=50):
g = av.filter.Graph()
b = g.add_buffer(width=160, height=90, format=u"yuv420p", time_base=TB)
p = b
for name, args in filters:
f = g.add(name, args) if args else g.add(name)
p.link_to(f)
p = f
sk = g.add(u"buffersink")
p.link_to(sk)
g.configure()
out = []
for i in range(n):
vf = av.VideoFrame.from_ndarray(BASE[i % len(BASE)], format=u"yuv420p")
vf.pts = i
vf.time_base = TB
b.push(vf)
while True:
try:
out.append(sk.pull().to_ndarray(format=u"rgb24"))
except Exception:
break
b.push(None)
while True:
try:
out.append(sk.pull().to_ndarray(format=u"rgb24"))
except Exception:
break
return out
import numpy as np
def sharp(a):
g = a.astype(np.float64).mean(axis=2)
lap = (-4 * g[1:-1, 1:-1] + g[:-2, 1:-1] + g[2:, 1:-1]
+ g[1:-1, :-2] + g[1:-1, 2:])
return float(lap.var())
base = sharp(run([], 1)[0])
print(u"--- 不模糊 %.0f" % base)
for s in (1, 2, 3, 5, 10):
v = sharp(run([(u"gblur", u"sigma=%d" % s)], 1)[0])
print(u" sigma=%-3d %6.0f 是原图的 %5.1f%%" % (s, v, v / base * 100))
v = sharp(run([(u"unsharp", u"5:5:1.0")], 1)[0])
print(u"--- unsharp=5:5:1.0 %.0f 是原图的 %.0f%%" % (v, v / base * 100))
实跑输出:
--------------------------------------------------------------------
7.13 模糊处理
--------------------------------------------------------------------
**① 模糊只有一个核心参数:sigma**
**`gblur` 的高斯模糊,`sigma` 就是「糊多远」:**
`ffmpeg -i s7.mp4 -vf gblur=sigma=5 out.mp4`
**sigma 是高斯分布的标准差,单位是像素。sigma 越大,糊的范围越宽。**
**经验值:1~2 是轻微柔化,3~5 明显糊,10 以上基本认不出原图。**
**② 实测四档 sigma 的锐度**
**锐度用拉普拉斯方差量:跟四邻域做差再求方差,边缘越硬数越大。**
sigma 锐度 相对原图
---------------------------------
不模糊 35759 100%
1 3515 9.8%
2 364 1.0%
3 64 0.2%
5 9 0.0%
10 3 0.0%
**sigma 只加到 1,锐度就掉到原来的十分之一;加到 3 只剩个位数百分比。**
**这个衰减比想象中快得多——「稍微糊一点」用 sigma=1 就够了。**
**③ 反过来的滤镜:unsharp**
**`unsharp` 名字是「不锐化」,实际作用是锐化(原始暗房工艺里的「反锐化掩模」):**
写法 锐度 比原图
----------------------------------------
unsharp=5:5:1.0 49515 138%
**三个参数是「亮度矩阵宽 : 高 : 强度」。强度正数是锐化,负数是模糊。**
**所以 `unsharp=5:5:-1.0` 等于一个模糊,效果跟 gblur 不同但都是糊。**
**④ 模糊的四个真实用途**
用途 怎么用
-----------------------------------------------------------------------
遮挡敏感信息 先 crop 出区域,blur 到认不出,再 overlay 回去
做背景虚化 放大画面 → gblur 大 sigma → 主体 overlay 上去
模拟水面/毛玻璃 在倒影那一路加 sigma=1.5(7.8 用过)
掩盖低码率块效应 轻微 sigma=0.5 就能盖住
**第一条里的「blur 到认不出」是有门槛的:**
**sigma=5 只是「看着糊」,给人脸打码一般要 15 以上才真的不可复原。**
**这个门槛跟分辨率和人脸大小都有关,没有硬标准,只能自己拿原图试着还原一次。**
六行数字跟本节那张表完全对上:35759 一路掉到 3。 sigma=1 就只剩 9.8%,这个衰减速度是本节的第一个要点。
最后一行 unsharp=5:5:1.0 到 138%,比原图还锐。
但 138% 这个数不代表「画质更好」——它只说明边缘对比被拉大了,
拉过头的部分就是肉眼看到的白边。
锐度这个指标只能横向比同一张图的不同处理,不能当成「画质评分」。 拿它当评分,最锐的永远是噪点最多的那一版。
30 秒实验
- 试 steps:把
gblur=sigma=5改成gblur=sigma=5:steps=4,比一比锐度。 - 反向锐化:把
unsharp的强度改成-1.0,看数掉到多少。 - 叠两层:接两个
gblur=sigma=2,看是不是等于一次sigma=2.8。
常见误区
- 把 sigma 当半径。它是标准差,糊的范围比半径大。
- 以为
unsharp是「模糊」。它是锐化,名字来自反锐化掩模。 - 拿锐度当画质分。它只反映边缘硬度,噪点多的版本反而更高。
自测三问(点开对答案)
1. `gblur` 的核心参数叫什么? —— `sigma`,高斯分布的标准差,单位像素。 2. sigma 从 0 加到 1,锐度掉多少? —— 掉到原来的十分之一左右(实测 9.8%)。 3. `unsharp` 是锐化还是模糊? —— 锐化。强度写负值才变模糊。- ☐ (本节完,下一节 7.14 视频颠抖)