做海思方案的项目,调试到YUV域Sharpen这步,基本就到了画质能不能真正“出片”的关键阶段。不少刚入行的朋友把锐化当成一个简单的“强度”旋钮,拧大了清楚,拧小了模糊——其实远没这么简单。YUV域的Sharpen参数,一边连着清晰度MTF,一边牵着噪声和振铃,调不好就是“看着清楚但很脏”,或者“看着干净但像蒙了一层雾”。这篇文章就围绕海思ISP平台上YUV Sharpen参数调试,从链路位置、参数含义、实操步骤到踩坑排查,把多年调ISP图像质量的思路完整讲清楚。适合正在做海思IPC、车载、工业相机方案,刚接手画质调试的工程师,也适合想系统理解ISP锐化原理的同学。
1. 认识YUV Sharpen:ISP链路里它到底在哪个环节
1.1 从RAW到YUV的ISP流水线
海思平台(比如常用的Hi3516系列、Hi3519系列)的ISP链路,核心可以分成两大段:RAW域处理和YUV域处理。RAW域做的是坏点校正、黑电平、去马赛克(Demosaic)、白平衡、CCM、Gamma这些偏“底层”的操作。到了YUV域,信号已经变成亮度Y和色度C分离的格式,这时候再做降噪(2DNR/3DNR)、锐化(Sharpen)、动态范围处理、色彩增强等。
YUV Sharpen就处在YUV域这一段,而且通常紧跟着降噪模块。这个位置关系非常关键——锐化参数是要配合降噪结果来调的。降噪不干净就去锐化,噪点会被同步放大;降噪太狠,细节纹理又被抹掉,后面锐化再猛也救不回来。我之前接过一个项目,3DNR强度拉得过高,画面暗部细节几乎全平了,结果锐化参数调到很大还是觉得“塑料感”,最后回头把降噪强度降下来,锐化只用了原来的一半,画面反而自然多了。这个先后关系,希望大家一开始就记住。
1.2 YUV域锐化与RAW域锐化的区别
锐化不一定只在YUV域做,有些平台在RAW域也有边缘增强,但海思方案里大家常说的Sharpen调试,绝大多数指的是YUV域的亮度锐化。YUV域锐化是专门针对亮度Y通道做细节增强的,两个色度通道UV一般不参与,或者只做很弱的联动处理。
这么做的好处很明显:可以和降噪、色彩处理独立调节,互相干扰小。YUV域的锐化实现,本质上就是对Y通道做一个高通滤波,再把高通分量按一定增益叠回原图,也就是类似Unsharp Mask的思路。但有个问题需要特别注意:信号到了YUV域,已经经过Demosaic和Gamma,细节的“能量分布”和RAW域完全不同。Gamma本身是压缩暗部、拉伸亮部的,这会导致暗部噪声在YUV域被放大,锐化一旦没控制好,暗部先花掉。所以你在YUV域做锐化时,一定要清楚:这不是一个简单的边缘提取,而是和一个已经做过色彩变换、亮度映射的信号打交道。
1.3 锐化对画质指标的影响
锐化直接影响MTF(调制传递函数)、限线频率和主观观感。调试时用ISO12233测试卡,可以看到锐化强度上去以后,高频分界线更清晰,限线读数也会提高,但噪声和振铃同步增加。所以千万不能只盯着分辨率卡上那几组线,还要同时看Skintone、枯叶图这些更接近真实场景的测试元素。
我用一个比较简单的方法来评估:把锐化的效果拆成“边缘响应”和“纹理响应”。边缘响应看黑白交界处的过冲和陡峭程度,纹理响应看枯叶图里那些不规则色块能不能保持自然质感。这两者经常是冲突的——边缘响应拉得太高,纹理区域就会显得干涩、发硬。理想的锐化参数,是让边缘有适度陡峭,同时纹理区域保持自然的颗粒感和层次。这背后其实牵扯到人眼的对比敏感度函数,不同频率下的敏感度不一样,这也是为什么很多平台会把锐化做成多频段、分增益的方式,而不是一个单一系数解决所有问题。
2. 海思YUV Sharpen核心参数逐个拆解
2.1 锐化强度与增益控制
锐化强度(很多平台叫Strength或者Shoot Gain)是最直观的参数,决定边缘增强的幅度。海思SDK里一般通过ISP的Sharpen模块接口下发一组系数,这套系数往往不是单一数值,而是按像素亮度或边缘梯度分段的增益表。
我调参的习惯是:先给一个整体偏大的强度,再把阈值和Limit收紧,而不是从零开始慢慢往上加。因为从小往大加,你得抓很多帧去对比,效率低;先大后小则能用最快速度找到“过头”的边界。增益表分段也很讲究,比如按梯度分段,低梯度的平坦区域给低增益,中高梯度的边缘给高增益。这样能避免天空、墙面这种大面积平坦区域因为锐化出现颗粒感。
这里要注意,强度参数尽量不要一个全局值打天下。我做过一个夜间监控项目,画面里有大面积的暗部天空,也有零星的路灯和高亮招牌,如果全局增益给太大,暗部噪点真的无法直视。后来我把增益表按亮度做了分段,暗部直接压低,亮部反而给多一点,观感立刻就不一样了。
2.2 边缘阈值与噪声抑制
阈值(Threshold,有的平台叫Coring)是YUV Sharpen调试里最关键的参数之一。它的作用是判断“哪些像素算边缘,哪些算噪声”。像素梯度低于阈值的,就当作噪声区域,不参与锐化;高于阈值的才算边缘,按增益表去增强。
这个参数设置低了,噪点会被当成边缘,锐化后画面变得很脏,像蒙了一层砂纸;设置高了,真实细节又被丢弃,画面显得很平、很假。具体怎么找平衡点?我一般会先测出当前场景的底噪水平。举个例子,某个sensor在增益16倍、暗场环境下的Y通道噪声标准差大约在2.8左右(8bit亮度值),那阈值可以先设在6~9附近,差不多是噪声标准差的2~3倍。然后再看ISO12233上的细线纹理能不能保留,如果细线纹理开始断线,说明阈值高了,往回降一点。
阈值调试很容易犯的错误是只看实验室暗场,不看实际场景。实景里有树叶、草地、布纹这些天然纹理,它们的梯度和噪声相差并不大,阈值卡得太死,画面就会丢失自然质感,看起来像“磨过皮”。所以我建议阈值初调在实验室做,微调一定要拿到室外或者实际场景里做。
2.3 锐化半径与核大小
锐化半径决定增强效果的影响范围。半径太小,只强调像素级边缘,画面看起来很“硬”,会有那种刀刻一样的假边;半径大一些,边缘过渡更柔和,更接近真实物体的质感,但计算量变大,也更容易在边缘两侧出现振铃。
海思平台一般有可编程的抽头系数,可以通过参数控制高通滤波器的带宽。实际效果上,你可以理解成卷积核的尺寸和权重分布。调试时,我习惯对着ISO12233里的白线或者西门子星图看线宽变化。如果线边缘出现“双线”或者明显变粗,多半是半径过大或者滤波器带宽太宽,这时候要缩小半径,让能量更集中在边缘附近。
还有一点,半径参数和分辨率是强相关的。同一套半径,在1080p下看着正常,切到4K分辨率就会显得锐化不足,因为像素密度变了,边缘在像素层面的“跨度”不一样。换分辨率或者换sensor输出尺寸时,锐化半径一定要重新评估。
2.4 过冲/下冲限制
过冲(Overshoot)和下冲(Undershoot),就是锐化后在亮侧边缘出现一圈白边、暗侧出现一圈黑边的现象。锐化本质是加了一个高通分量,如果不做限制,高通分量会把亮侧推过头、暗侧压过头。
平台一般会提供Clamp或者Gain Limit参数,限制锐化输出不超过原始像素值的一定比例。这个环节是“锐得干净”的关键。我习惯把亮侧和暗侧的Limit分开调,因为人眼对亮环和暗环的敏感度不一样,暗侧稍微有一点黑边容易被感知,亮侧反而容忍度高一些。实际项目中,我把暗侧Limit收得比亮侧紧,边缘观感会自然很多。
过冲限制还有个好处:能防止画面出现“塑料感”。有些方案为了追求分辨率测试卡读数,把锐化调得很猛,Limit又放得很大,结果人脸轮廓、建筑物边缘全部带一圈明显的光晕。这种错误我见过太多了,所以每调完一组锐化参数,我都会特意找高光反射和逆光的边缘看一圈,确认没有光晕再往下走。
2.5 Y/C通道与区域控制
YUV域的Sharpening虽然基本只在Y通道生效,但色度通道也不是完全没有关系。高频亮度变化有时会引起色度串扰,画面上出现色边。这时候需要配合色度Coring做处理,把UV通道在低饱和度、低梯度区域的异常信号压一压。
另外一个经常被忽略的点是区域控制。真实场景里,天空、墙面、人脸这些大面积平坦区域,和草地、头发、织物这些纹理区域,需要的锐化策略完全不同。海思ISP一般支持多区域或按亮度分段的参数映射。我会把画面按亮度分成暗部、中间调、亮部三档,分别给不同的强度。暗部主要防噪声,给低增益甚至零增益;中间调是人眼最敏感的区域,给中等增益;亮部可以稍微激进一点,但也要注意高光边缘的过冲。按亮度分区还有一个好处:夜场景的低照度画面往往整体偏暗,暗部占比大,如果条件允许,可以直接给夜间模式单独调一套参数,避免白天锐化参数在夜间直接“翻车”。
3. YUV Sharpen参数调试完整实操流程
3.1 调试环境搭建与准备工作
工欲善其事,必先利其器。做YUV Sharpen调试之前,环境搭建这块不能省。我常用的设备有:标准光源箱或可调色温光源、ISO12233分辨率卡、枯叶图(Dead Leaves)、透射式灰阶卡、三脚架,以及海思的PC端ISP调试工具(不同SDK版本的工具名称和界面会有差异,但基本功能都差不多)。
光源要把色温固定在目标场景的典型范围,比如安防设备常规用D65,室内产品可能用D50或者暖白光。光照度也要定下来,别让AE自己跑来跑去,最好把曝光锁在一个固定的目标亮度,避免锐化评估被亮度变化干扰。相机或者开发板要固定在三脚架上,绝对不能手持,稍微的晃动都会影响高频细节的评估。
调试前还有一件事很重要:把ISP里其他模块先稳住。AE、AWB、降噪都要初步调到可用状态,尤其是降噪。如果降噪还没调稳,锐化调的再准,一换场景噪声水平变了,结论全部作废。我会在调试记录里记下每个模块当时的版本参数,这样回头复现的时候不会一脸懵。
3.2 静态图卡调试方法
静态图卡是锐化参数的基础。具体流程我习惯这么走:
第一步,关闭锐化,抓一组baseline。这组数据记录了当前降噪和镜头的原始表现,是后面所有对比的参照。
第二步,把强度增益设到初始值,我一般用最大强度的30%左右,抓帧看效果。然后每增加10%抓一帧,重点看ISO12233不同限线区域的分界,以及枯叶图的纹理自然度。
第三步,固定一个初步合适的强度之后,开始扫阈值。阈值从高到低扫描,观察两个极端:阈值很高时,画面细节全无;阈值很低时,噪声颗粒开始出现。我通常在这两个极端的中间段再细分4~5档,找“细节保留足够但噪声不放大”的临界点。
第四步,调半径和Limit。这时候要放大看边缘,特别关注黑白交界线的过冲情况。半径和Limit会有一定的耦合效应,半径大时即使Limit不大也可能出现明显振铃,所以这两个参数要交叉着调,不能单边收敛。
第五步,把所有参数固化下来,导出配置文件。静态图卡阶段不需要追求一次到位,但要有详细的记录,最好每个参数档位都存一张抓图,方便回看。
3.3 动态场景与实景评估
很多工程师卡在“测试卡很清晰,实景很脏”这一步。原因在于实景的纹理频率、运动状态、噪声水平都比死板的测试卡复杂得多。动态场景要重点观察两个东西:运动物体的边缘残影,以及静止区域有没有因为时间域降噪和锐化的联动产生闪烁。
我做动态评估时,通常会找一个车流较多的路口,或者风吹树叶的环境。用实时预览去观察画面,发现有移动的车辆边缘出现“彗尾”或者“闪烁感”,先怀疑3DNR的时域强度,再看锐化的增益是否过高。这里有个比较容易踩的坑:一旦打开3DNR,它的时域滤波会逐帧累积,静止区域的噪声会被压得很低,这会给锐化造成“表面很干净”的假象。一旦场景运动起来,时域滤波失效,噪声回到正常水平,锐化就会把噪声重新放大。所以动态评估时,一定要关掉或者降低3DNR,看看静态场景下的锐化参数在纯空域条件下会不会翻车。
实景评估时我还会抓几组暗部细节的对比。光线复杂的环境里,暗部的噪声水平远高于测试卡环境,我在2.2里提过按亮度分区,这里就是真正检验它的地方。如果暗部有颗粒沸腾的感觉,不要犹豫,把暗部增益继续压低。
3.4 参数下发与固化
参数调试完,要把配置固化到板子上。海思平台一般通过SDK的ISP配置接口,保存成XML或二进制格式的配置文件,设备启动时自动加载。我自己习惯在调试机上用工具保存配置,再把配置文件和sensor驱动、其他ISP模块的配置放在一起管理,方便版本回溯。
这里提醒三点。第一,不同sensor、不同分辨率、不同帧率,很可能需要单独一组锐化参数。我见过有人一套参数从1080p切到4K不重新调,结果边缘虚得一塌糊涂,并不是镜头不行,是分辨率变了锐化半径没有跟着变。第二,白天的参数不能直接给晚上用。夜间的噪声水平和动态范围完全不同,沿用白天参数后,画面要么脏、要么假。第三,如果有宽动态或HDR模式,参数组又得单独确认一遍——HDR的合成会引入额外的噪声和鬼影,锐化策略和普通模式差异很大。
我把参数下发到板子上以后,一定会做一次断电重启测试,确认配置能正常加载,顺便看启动时间和首帧画质有没有异常。这一项放在最后做,能帮你少挨很多弋。
4. 常见问题与排查技巧
4.1 边缘白边/黑边过重
这是YUV Sharpen调试中出现频率最高的问题。画面里只要有大光比边缘,比如屋檐、电线杆、人脸轮廓,就会出现明显的亮边或暗边。
排查思路:先看Overshoot/Undershoot Limit是不是给得太大。锐化分量由强度、阈值、Limit共同决定,Limit是最后的“闸门”,它放得太宽,过冲一定明显。你可以把Limit值降下来一半,看边缘光晕是不是立刻缓解。如果Limit降下来以后光晕消失了,说明问题在Limit;如果光晕还在,再看半径是不是太大,导致边缘增强范围过宽。
我一般会在ISO12233卡上找一条黑白交界线,放大后看亮侧的灰度曲线。如果亮侧出现过冲幅度超过原始亮侧像素值5%以上的峰值,基本就可以判断为Limit偏大或者增益表的中高频段增益过高。解决方法是把亮侧Limit收紧,同时把分段增益表里对应高频段的增益降一点,两个动作配合做,效果最明显。
4.2 噪声被锐化放大
第二个高频翻车现场是噪声颗粒被锐化放大,画面像上了一层细砂。尤其是暗部区域和夜晚场景,特别容易出现。
排查思路:先确认阈值(Coring)是否过低。你可以把阈值直接拉到当前噪声标准差的3倍左右,看画面是否立刻变干净。如果变了,说明就是阈值问题。另一个排查点是降噪模块是否稳定。如果2DNR/3DNR的输出本身就不稳定,锐化会把残余噪声当成细节做增强,这时候你单纯调锐化阈值是治标不治本。
正确做法是先回去把降噪调稳,尤其注意时域降噪在静态场景的收敛速度。然后回到锐化,把暗部区域的增益压低。我自己的经验是:宁可让暗部损失一点细节,也不能让暗部噪点“沸腾”。因为人眼对暗部噪声的敏感度极高,它是画质最直观的扣分项。
4.3 锐化后色彩异常
有时候锐化调完,边缘附近会出现彩色的边,或者物体轮廓周围出现红红绿绿的杂点。遇到这种情况,不要急着去动色度锐化,先判断是不是亮度锐化引起的色度串扰。
简单验证方法:把色度通道相关的处理完全关闭,只用Y通道锐化,看色边是否还在。如果还在,说明是YUV通道之间发生串扰——很可能是锐化后的亮度信号和色度信号在叠加时没对齐,或者是Gamma和色彩校正模块的相位延迟不同步导致。这种问题排查起来比较麻烦,通常需要检查YUV数据通路中各个模块的延时配置。
如果验证发现色边是打开色度相关处理后才出现的,那重点检查色度Coring阈值是不是设得过大或过小。过小时,色度通道的低饱和杂讯会被放大;过大时,真实色彩的边缘反而会出现轮廓偏移。实际项目里,我一般把色度Coring设在比亮度阈值更保守的位置,取亮度阈值的1.5到2倍,效果比较均衡。
4.4 不同分辨率/场景切换时的参数适配
摄像头在1080p、4K之间切换,或者从白天切到夜晚,如果锐化参数还是同一套,画面表现会非常不稳定。白天正常的参数,晚上画面可能会明显变脏;1080p下锐度刚好的参数,4K下可能会显得模糊。
这个问题没有捷径,就是做多组参数预设。我建议按“分辨率+亮度场景”的组合来管理:
- 1080p白天、1080p夜晚、4K白天、4K夜晚,至少四组基础参数;
- 如果产品支持HDR,再为HDR场景单独做一组;
- 如果镜头有变倍,不同焦段最好也分开标定。
预设切换不能简单地写死,还要考虑切换时的平滑过渡。直接在白天夜晚切换瞬间把锐化强度从低跳到高,人眼很容易察觉画面“抖”了一下。海思平台一般支持参数的渐变下发,我会利用这个机制,让锐化参数在两到三秒内平滑过渡到目标值,观感会自然很多。
最后再分享一点个人体会。YUV Sharpen调试最忌讳“头痛医头”。你先要弄清楚当前画质问题是噪声引起的、镜头解像力不足引起的,还是锐化本身不合理引起的。很多情况下,你把降噪和锐化当一个整体来调,效果会比单拧一个参数好得多。我也是踩过几次坑才总结出这套流程:先测底噪,再定阈值,再调增益,最后收Limit。按这个顺序走,至少不会把画面调得又脏又硬。希望这篇实战笔记能帮你少绕一点弯路。