十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

海思ISP YUV域Sharpen锐化调试指南:从参数理解到量产落地

海思ISP YUV域Sharpen锐化调试指南:从参数理解到量产落地 在安防、车载和工业相机项目里海思ISP的图像质量调优一直是方案商最花时间的一环而其中YUV域的Sharpen(锐化)模块又是最考验调参耐心的位置。很多工程师刚接触时以为锐化就是把SharpenRatio往上拉画面越“硬”越好但真正跑完整条图像链路就会发现Sharpen同时牵扯清晰度、噪声、边缘伪影、编码码率四件事而且在YUV域调试时亮度通道和色度通道的参数互相牵制稍微改一个阈值画面可能就崩给你看。这篇文章把我在海思平台上反复调试YUV Sharpen参数的完整思路整理出来包含模块位置、参数含义、调试顺序、翻车现场和量产落地尽量把能直接复用的小技巧都写出来。1. 先把Pipeline位置搞清楚YUV域的Sharpen到底插在哪一级1.1 从Sensor到编码器Sharpen在整个ISP链路里的位置海思平台的ISP图像链路常见形态是Sensor输出RAW数据进入VI模块在VI内部完成坏点矫正、黑电平、去马赛克、3A统计、降噪等一系列RAW域操作输出YUV数据再送给VPSS做缩放、裁剪、帧率控制最后进入VENC编码。不同芯片的模块划分会有差异但整体思路是一致的。Sharpen这个模块就嵌在ISP处理的后半段也就是图像已经从Bayer格式转成YUV格式之后。在部分芯片上它和降噪NR、细节增强DRC放在一起作为YUV域的图像增强组合拳在另一些芯片上VPSS内部也会挂一个边缘增强模块用来在缩放之后做二次锐化。这个位置关系为什么重要因为放在不同阶段同样的参数产生的效果完全不同。RAW域的锐化处理的是Bayer排列的马赛克数据锐化核一旦跨过RGGB相邻像素很容易把伪彩色一起放大而YUV域的锐化至少是在色彩分离之后做的Y通道单独处理不会直接污染色度信息。海思把主要锐化能力放在YUV域本质上是把复杂度和风险都控制在一个更可控的范围内。1.2 为什么选YUV域而不是RAW域做锐化很多人有个疑问锐化不就是提取高频分量增强对比吗我在RAW域做和YUV域做有什么区别区别挺大。第一人眼对亮度细节的敏感度远高于色度细节YUV格式天然把亮度和色度分开Y通道单独做锐化可以在不放大色度噪声的前提下让画面看起来更清晰。如果放在RAW域亮度增强会连带影响色度插值导致边缘出现彩虹色边。第二YUV域的数据量比RAW域更可控。RAW域一个像素只包含一个颜色分量要判断一个边缘是亮度边缘还是颜色边缘需要先做局部插值逻辑复杂到了YUV域Y分量直接对应亮度变化梯度计算干净利落锐化核可以做得更准。第三YUV域的锐化能和降噪形成配合。海思的YUV域降噪一般会先做空域降噪和时域降噪把噪声压下去之后再进行锐化这样锐化算子拿到的高频分量里“真细节”占比更高。如果在RAW域直接锐化Bayer域的噪声模型和颜色插值误差会同时被放大后期想救都难。我的经验是理解这一层比记住几个参数名重要得多。因为实际调参时你会发现SharpenRatio拉高之后暗部噪点明显变多这时候能想到“先回NR那边压一压再回来重新平衡Sharpen”而不是死磕锐化参数就是因为你知道这两者在pipeline里的前后关系。1.3 别把VI里的Sharpen和VPSS里的锐化搞混海思方案的调试中有一个坑经常踩VI输出前的ISP Sharpen和VPSS通道里附带的边缘增强同时生效两边参数叠加起来锐化强度翻倍出现严重的白边而排查时只在其中一个模块里找问题。调试前一定要先理清你的平台里Sharpen到底有几级。有的项目用的是sensor直出RAW走VIVI里的ISP已经做了一轮YUV域SharpenVPSS又开了通道锐化来弥补缩放后的细节损失。这两级如果同时强开小分辨率输出比如720P、1080P时会特别容易看出一圈白色勾边。我的习惯是先把VPSS的增强关掉集中调VI里的ISP Sharpen等主路图像效果稳定后再按需打开VPSS侧的边缘增强且强度控制在很低的范围只用于补偿缩放损失。2. Sharpen参数逐个过一遍名字、含义、取值范围与典型误区海思SDK里Sharpen相关的结构体一般是ISP_SHARPEN_ATTR_S不同芯片版本的字段名会有差异但逻辑基本一致。下面说的参数名以常见SDK为准具体以你手里的实际头文件为准。我习惯把Sharpen参数分成三类增益类、门限类、抑制类。这样分类的好处是调试时思路清楚不会在十几个字段里迷失方向。2.1 增益类参数SharpenRatio与SharpenRatioUVSharpenRatio是锐化总强度也就是高频分量的放大倍数范围一般是0到255。这个参数最直观但也最容易误用。它控制的是整幅图像所有高频分量的增益包括真实边缘、纹理、以及噪声。只要把它拉高画面立刻变“脆”但代价是噪点同时变明显。这里有个反直觉的经验SharpenRatio不是线性地影响主观清晰度。在较低区间比如0到80每次增加10带来的清晰感提升非常明显到了120以上再往上加主观清晰度提升很小边缘过冲、白边、噪点颗粒感却快速恶化。所以我的调法通常把它当作一个“幅度上限”来约束而不是不断拉大它的值。SharpenRatioUV是色度通道的锐化增益。UV通道在大多数YUV420格式下只有Y分辨率的四分之一色度细节本来就少锐化过猛容易出现红蓝伪彩或者色度镶边。正常使用场景下这个值给得很保守甚至很多时候直接给0只依赖亮度锐化带来的整体清晰感。2.2 边缘与细节门限Cliff、CliffEnhance、DetailEnhanceCliff可以理解成“强边缘检测阈值”用来区分图像中的强边缘和弱纹理。梯度过大的像素会被当成物体轮廓锐化时走单独的处理路径梯度较小的像素则进入细节增强路径。如果Cliff设得太低很多平坦区域的微小波动也会被当成边缘画面会显得脏如果设得太高真正的轮廓得不到强化画面看起来“软”。CliffEnhance和Cliff是搭配使用的它控制强边缘的额外增强量。对着一个黑色文字或者建筑物轮廓你会希望这条边锐利、干净没有白边。CliffEnhance太高白边会出现太低边缘发虚。一般从中间值起步观察一条斜边的过渡区域再微调。DetailEnhance负责弱边缘和纹理细节的增强比如布料的纹路、树叶的叶脉、远处建筑表面的窗格。这个参数对主观清晰度贡献很大但也最容易带来噪声问题因为弱纹理在频率特征上和细小噪点非常接近。我的经验是DetailEnhance的调节一定要配合NoiseCoeff一起看不能单独只拉一个方向。2.3 亮度门限与噪声抑制SharpenLuma、NoiseCoeff、EdgeSoftenSharpenLuma是亮度门限图像中暗于这个门限的区域会降低甚至停止锐化这是专门用来保护暗部噪声的。低照度场景下暗部区域的信噪比很低没必要的锐化会让整块暗部都变成噪点颗粒。把它调高暗部变干净了但也要小心暗部细节很容易被压成一片死黑需要根据实际场景来回试探。NoiseCoeff是高频噪声抑制系数它的作用是让锐化算子根据局部纹理特征自动调整增益判断为噪声的高频分量会被压低判断为细节的才保留增强。这个参数在暗光场景是救命的但调太高会把真实细节一起抹掉画面看起来很干净却没有质感。EdgeSoften是边缘柔化强度专门用来抑制过冲和振铃。它相当于在锐化之后加了一道平滑处理把边缘两侧被过度拉高的亮带和暗带稍微抹平一点。锐化强度比较大的时候EdgeSoften给到20到40左右能明显改善白边问题代价是极限解析力会有轻微下降。注意这几个参数的取值范围虽然多数平台都是0到255但实际有效区间往往只在一小段。比如SharpenRatio的有效观感区间可能是40到160超过这个区间要么无效要么画面已经崩了。调试时先做一次“扫值”实验每个参数从低到高过一遍记录肉眼可见的变化区间比盲目查表高效得多。3. 一套可以照着做的调试流程环境、顺序与评价方法3.1 调试前的环境准备图卡、光源与预览链路Sharpen的调试必须先建立一套稳定的观察环境否则参数改来改去都无法判断是算法效果还是环境变化。分辨率测试卡建议用ISO 12233增强型它包含低频到高频的楔形线能直观看到极限解析力到哪个位置。光源用标准D65灯箱照度控制在500到1000 lux用照度计实测确认。相机固定在三脚架上不能手持手部抖动在长焦下会被锐化放大直接影响判断。实时观察链路也有讲究。如果通过编码器压缩后再看画面码率不够时压缩伪影会被误认为是锐化出来的边缘干扰判断。调试阶段建议直接用HDMI或者SDI输出原始画面或者用海思调试工具的抓图功能保存BMP/YUV原始帧而不是看压缩后的JPEG。另外记得先把3A调到稳定状态自动曝光目标值设定好白平衡锁定在标准色温对焦锁定在测试卡中心。焦距稍有变化解析力会有几个档位的差异这种情况下调出来的锐化参数没有可信度。3.2 建议的调参顺序先亮度后色度先增益后抑制很多人拿到Sharpen参数列表从第一项往下挨个调调完发现互相干扰又回炉重来。正确顺序应该是先亮度后色度先增益后抑制。我一般这样做先把SharpenRatio和SharpenRatioUV全部置0跑一遍画面记住这个“无锐化基线”。打开SharpenRatio每次增加20观察ISO 12233楔形线上的极限分辨率记录从哪个位置出现白边。保持SharpenRatio在可接受范围内开始调DetailEnhance观察细纹理的呈现强度。再调Cliff和CliffEnhance控制强边缘的锐利度和白边平衡。加入NoiseCoeff和SharpenLuma重点观察暗部区域是否出现颗粒噪声。最后才给SharpenRatioUV一个小值比如10到30观察彩色边缘是否有渗出。所有参数确定后用EdgeSoften微调过冲问题。这个顺序的核心逻辑是先确定整体能量再分配细节权重最后做风险控制。前面每一个参数都在改变图像的高频成分分布后面抑制类参数是为了收拾前面的副作用顺序反了很容易陷入死循环。3.3 用ISO 12233和实际场景交叉判断调参效果测试卡只能反映解析力不能反映真实观感。锐化调得好不好最终要过两关测试卡上能看到清晰的极限线对实景画面又不能有明显的塑料感。我的做法是先拍测试卡用软件量化解析力比如观察楔形线在哪个频率位置后开始糊掉。记录这个位置对应的参数值然后换成实际场景拍建筑外墙、树叶、人脸、金属拉丝表面。人脸皮肤是锐化最敏感的样本如果脸颊位置的噪点和毛孔纹理被异常放大说明DetailEnhance或者SharpenRatio偏高。测试卡和实景的结论经常不一致。测试卡上解析力很高的参数实景人脸可能已经没法看实景观感很好的参数测试卡的分辨率数值可能不是最高。这时候优先保实景观感因为用户实际看到的是画面而不是测试卡但要留好记录说明当前参数是主观画质和解析力折中的结果。4. 调试中容易翻车的四个典型问题与排查链路4.1 白边和过冲先从增益动手再动阈值白边是最常见的锐化副作用现象是黑色边缘外侧出现一圈亮线物体边缘像被描边一样。排查顺序很重要。先不要急着调参数把SharpenRatio临时降一半如果白边明显减弱说明主因是增益过高。这时候可以选择降低Ratio但如果你希望保持这个清晰度就往Cliff和CliffEnhance方向调把Cliff略微提高让强边缘的锐化路径更保守同时降低CliffEnhance减少强边缘额外增强量。如果降Ratio之后白边仍然存在而且更集中在高频细节区域比如文字边缘、布料纹理边缘那问题可能出在DetailEnhance上。弱纹理在锐化时因为梯度判断不当被当成了强边缘走了CliffEnhance的高增益路径出现白边。最后再用EdgeSoften收尾。这个参数相当于最后一道保险幅度不要太大20左右的增量通常就够了。调完白边后会有一个副作用极限分辨率看起来会轻微下降如果画面因此开始发软就说明之前Ratio和DetailEnhance的搭配还是高了一档要往下退。4.2 低照度下噪点被锐化放大低照度场景下最典型的翻车是暗部区域出现明显的颗粒噪点而且压缩后变成色块。很多工程师以为是降噪不够拼命加NR结果细节也被抹掉画面变成水彩画。正确的排查链路是先看NoiseCoeff当前值如果很低它基本没有起到动态抑制噪声的作用高频噪声和真实细节一起被SharpenRatio放大了。把NoiseCoeff往高调同时观察暗部细节的保留情况找到一个“噪点基本可控、暗部纹理还没糊”的中间点。再看SharpenLuma这个门限是防暗部噪点的第二道防线。低照度场景可以适当调高这个门限让暗部区域进入锐化抑制状态。但这种做法的代价是暗部细节的层次感会变差所以门限也不能无脑拉高。还有一个容易被忽略的问题如果整个画面的亮度都不高SharpenLuma过高就会导致全画面锐化强度偏低画面发软。这种情况下正确的方向是提升曝光亮度或调整NR参数而不是硬调锐化。4.3 强边缘附近出现振铃振铃一般出现在高对比度边缘附近表现为边缘两侧出现一层层明暗交替的波浪纹像涟漪一样。振铃产生的根源是锐化滤波核在频域上有明显的旁瓣当强边缘输入时高频分量被过度放大滤波核的旁瓣在空间域形成波纹。遇到振铃首先降低CliffEnhance这是强边缘增强路径的主要贡献者。如果效果不够把SharpenRatio整体降一点这是釜底抽薪。EdgeSoften对振铃有直接的抑制作用因为它本质上就是在边缘区域做平滑。把EdgeSoften从10往上加用测试卡的黑色斜边观察波纹是否消失。需要注意的是EdgeSoften过高时锐化效果会被削弱得很厉害所以要结合主观画面来定位不能只看某个孤立问题。4.4 白天参数到晚上直接失效的问题很多项目调出白天效果不错的锐化参数一到晚上画面就崩不是噪点爆炸就是边缘变色。原因很简单白天场景信噪比高锐化可以开得比较大夜间信噪比低同样参数会放大噪点。海思平台通常会提供场景切换机制比如在sensor工作模式切换时调整ISP参数或者在代码里注册场景变化回调。建议针对白天、夜晚、暗光、强背光各准备一套Sharpen参数场景切换时同步刷新。夜间场景的锐化调试不要直接在晚上对着街景调那样变量太多。可以先用中性灰布或者低照度环境下的均匀面做基准先把噪点水平控制在可接受范围再加入真实景物微调。这样即使参数还不是最优至少不会出现噪点压不住的问题。5. 参数固化与量产落地把调好的效果稳定带到产品里5.1 用SDK接口把Sharpen参数写进代码里调试工具调好的参数最终要固化到固件里。海思平台一般用PC调试工具连板端在线修改ISP寄存器后可以导出配置但很多工程师忽略了一个问题调试工具上生效的参数和代码里设置的参数是否在同一级。使用SDK设置时要注意锐化的设置通过ISP模块的Set接口下发。先创建一个结构体比如ISP_SHARPEN_ATTR_S把所有字段赋好值再调用设置接口并指定pipeId。示例代码如下ISP_SHARPEN_ATTR_S stSharpen; memset(stSharpen, 0, sizeof(stSharpen)); stSharpen.bEnable HI_TRUE; stSharpen.u8SharpenRatio 120; stSharpen.u8SharpenRatioUV 20; stSharpen.u8SharpenLuma 40; stSharpen.u8SharpenThdr 0; stSharpen.u8Cliff 80; stSharpen.u8CliffEnhance 60; stSharpen.u8EdgeSoften 20; stSharpen.u8DetailEnhance 50; stSharpen.u8NoiseCoeff 60; HI_S32 s32Ret HI_MPI_ISP_SetSharpenAttr(pipeId, stSharpen); if (s32Ret ! HI_SUCCESS) { printf(set sharpen attr failed: 0x%X\n, s32Ret); }代码里落下之后还要确认管道是否处于可设置的运行状态。比如在线模式下部分ISP参数需要走特定的下发流程才会生效或者需要触发一次ISP配置更新。如果设置了之后画面没有变化先检查pipeId是否正确再检查通道是否处于异常状态不要怀疑参数没写进去。5.2 不同Sensor和镜头组合的参数适配问题很多团队在一个sensor上调出一套完美的Sharpen参数换镜头或者换sensor之后直接沿用结果画面出现各种问题。原因是不同sensor的噪声底和量子效率不同同一个NoiseCoeff对高噪声sensor可能形同虚设对低噪声sensor反而抹掉细节。镜头的MTF曲线差异更大解析力高的镜头锐化参数可以稍微保守本身偏软的镜头为了追求主观清晰度只能把SharpenRatio调高但随之而来的噪声问题必须靠NR侧承担。我在量产项目里通常会给每个镜头模组建立一份参数记录表至少记录四档白天强光、白天多云、夜晚低照、室内混合光源。每次换模组或换镜头先用标准测试卡过一遍把SharpenRatio、Cliff、DetailEnhance、NoiseCoeff四组基础参数重新校准。实际量产验证过一两个模组之后你会发现不同模组之间虽然参数有差异但变化规律其实很接近校准速度会越来越快。最后分享一个我个人的习惯每次调Sharpen前先把调试固件版本、图卡距离、光线照度、当前分辨率这几项记录下来方便两个参数组之间做对比。另外永远不要让SharpenRatio接近量程上限。海思在量产项目里对锐化参数的态度普遍偏保守把边留出来给后续sensor差异、镜头差异都留一些余量比一开始就顶满更稳妥。
返回列表