lanczos插值引起的振铃现象

文章目录

  在图像缩放领域,bicubic双立方插值算法一般是4抽头,而为了取得更好的画质,增加到6抽头或8抽头时,往往会采用lanczos(兰佐斯)插值算法。但是如果直接使用lanczos插值系数则会出现振铃现象,就是指放大或插值过程中,图像锐利边缘附近出现明暗交替的"波纹"或"鬼影"伪影,本质是插值核(如Sinc、Lanczos)的振荡特性与灰度阶跃卷积引发的吉布斯现象。吉布斯现象‌‌------有限带宽逼近不连续信号必然在跳变点附近产生约9%过冲及振铃;并非错误,而是数学必然。

1.放大振铃现象

1.1系数产生

  为了用FPGA实现6抽头,16相位的lanczos插值算法,用python代码产生了一组系数,代码如下。

python 复制代码
import math

# Parameters
PHASE_NUM = 16
TAP_NUM = 6
a = TAP_NUM/2 
SCALE = 2 ** 14
init_phase = -0.1/PHASE_NUM

def sinc(x):
    if abs(x) < 1e-10:
        return 1.0
    return math.sin(math.pi *x) / (math.pi * x)

def lanczos(x):
    if abs(x) >= a:
        return 0.0
    return sinc(x) * sinc(x / a)
    
# Generate coefficients
coeff_fixed = []
for phase in range(PHASE_NUM):
    frac = phase / PHASE_NUM
    for i in [-2, -1, 0, 1, 2, 3]:
        t = lanczos(i - frac + init_phase)
        it = int(t * SCALE)
        coeff_fixed.append(it)

for j in range(0,PHASE_NUM):
	print(f"phase[{j:2d}] = ", end="")
	for i in range(0,TAP_NUM):
		print(f"{coeff_fixed[j*TAP_NUM+i]:<5d}, ", end="")
	print("")

  生成的系数放大2^14倍,用于verilog代码使用。

powershell 复制代码
phase[ 0] = 20   , -83  , 16382, 85   , -21  , 0    ,
phase[ 1] = 206  , -840 , 16242, 1018 , -257 , 8    ,
phase[ 2] = 346  , -1444, 15873, 2087 , -529 , 33   ,
phase[ 3] = 442  , -1896, 15285, 3274 , -828 , 72   ,
phase[ 4] = 495  , -2201, 14495, 4558 , -1142, 126  ,
phase[ 5] = 510  , -2368, 13525, 5914 , -1457, 191  ,
phase[ 6] = 493  , -2412, 12402, 7311 , -1756, 262  ,
phase[ 7] = 451  , -2347, 11157, 8716 , -2020, 336  ,
phase[ 8] = 391  , -2194, 9823 , 10096, -2231, 404  ,
phase[ 9] = 321  , -1971, 8436 , 11414, -2368, 461  ,
phase[10] = 248  , -1698, 7029 , 12637, -2412, 499  ,
phase[11] = 177  , -1394, 5638 , 13732, -2345, 510  ,
phase[12] = 114  , -1079, 4295 , 14668, -2151, 487  ,
phase[13] = 63   , -766 , 3028 , 15419, -1818, 426  ,
phase[14] = 27   , -472 , 1863 , 15965, -1336, 322  ,
phase[15] = 5    , -207 , 820  , 16289, -701 , 172  ,

1.2modelsim仿真效果图

  对于文字,边框类图片,边缘比较明显。下面是水平垂直都放大2倍后的图,边缘不平滑,出现明暗相间的情况。

  对于彩色图像,也会有可能出现边缘变亮变暗的情况。

2.振铃现象改善

2.1系数产生

  为了解决振铃现象,最简单的方法就是给Lanczos 核加窗,牺牲一点锐度,压制吉布斯振铃。在原始 Lanczos 权重上,再乘一个窗函数,把核两端权重压到更低,削弱震荡。 直接在系数生成阶段修改,不用改卷积逻辑。常用的窗有汉宁窗 Hanning,汉明窗 Hamming,布莱克曼窗 Blackman。

  这里采用布莱克曼窗(Blackman Window),修改系数生成代码,

python 复制代码
import math

# Parameters
PHASE_NUM = 16
TAP_NUM = 6
a = TAP_NUM/2 
SCALE = 2 ** 14
init_phase = -0.1/PHASE_NUM

def sinc(x):
    if abs(x) < 1e-10:
        return 1.0
    return math.sin(math.pi *x) / (math.pi * x)

def lanczos(x):
    if abs(x) >= a:
        return 0.0
    return sinc(x) * sinc(x / a)
    
def blkman_win(x):
    if abs(x) >= a:
        return 0.0
    return 0.42 + 0.5*math.cos(math.pi * x / 3) + 0.08 * math.cos(2*math.pi * x / 3)

# Generate coefficients
coeff_fixed = []
for phase in range(PHASE_NUM):
    frac = phase / PHASE_NUM
    for i in [-2, -1, 0, 1, 2, 3]:
        t = lanczos(i - frac + init_phase) * blkman_win(i)
        it = int(t * SCALE)
        coeff_fixed.append(it)

for j in range(0,PHASE_NUM):
	print(f"phase[{j:2d}] = ", end="")
	for i in range(0,TAP_NUM):
		print(f"{coeff_fixed[j*TAP_NUM+i]:<5d}, ", end="")
	print("")

  生成的系数放大2^14倍,用于verilog代码使用。

powershell 复制代码
phase[ 0] = 2    , -52  , 16382, 53   , -2   , 0    ,
phase[ 1] = 26   , -529 , 16242, 641  , -33  , 0    ,
phase[ 2] = 45   , -910 , 15873, 1315 , -68  , 0    ,
phase[ 3] = 57   , -1194, 15285, 2062 , -107 , 0    ,
phase[ 4] = 64   , -1386, 14495, 2872 , -148 , 0    ,
phase[ 5] = 66   , -1492, 13525, 3726 , -189 , 0    ,
phase[ 6] = 64   , -1519, 12402, 4605 , -228 , 0    ,
phase[ 7] = 58   , -1479, 11157, 5491 , -262 , 0    ,
phase[ 8] = 50   , -1382, 9823 , 6360 , -290 , 0    ,
phase[ 9] = 41   , -1242, 8436 , 7191 , -307 , 0    ,
phase[10] = 32   , -1070, 7029 , 7961 , -313 , 0    ,
phase[11] = 23   , -878 , 5638 , 8651 , -304 , 0    ,
phase[12] = 14   , -679 , 4295 , 9241 , -279 , 0    ,
phase[13] = 8    , -483 , 3028 , 9714 , -236 , 0    ,
phase[14] = 3    , -297 , 1863 , 10058, -173 , 0    ,
phase[15] = 0    , -130 , 820  , 10262, -91  , 0    ,

2.2modelsim仿真效果图

  文字,边框类图片,放大边缘改善比较明显。

  彩色图像边缘也有改善。

3.其他改善措施

  除了修改系数,其他还有一些改善的方法。不过这些方法会增加一些额外的资源。

3.1局部数值限制

  对卷积输出结果做值域钳位:把插值输出限制在当前 6 个输入像素的最大值、最小值之间。原理:Lanczos 振铃会产生超出原图明暗范围的像素,强行钳位就能切掉波纹。

3.2边缘检测和动态切换插值核

(1)用简单梯度算子检测当前区域是否为强边缘;

(2)平坦区域:用标准 Lanczos(保细节);

(3)强边缘区域:自动切换为加窗 Lanczo。

  此方法消耗资源最多,往往不会使用。

3.3后处理滤波

  缩放结束后,串一级小型平滑滤波,压制残留振铃:

(1)3-tap 一维均值 / 高斯滤波(行方向)

(2)中值滤波(对椒盐状振铃、细线鬼影效果好)

  缺点:会轻微模糊整体画面,一般作为辅助手段,不做主方案。

3.4图像边界补边

(1)重复边缘像素 Repeat(最常用,FPGA 首选)

超出窗口的像素,直接复用画面最边缘像素。 例:最左侧 6-tap 窗口缺左侧像素 → 全部用第一列像素填充。逻辑简单、无跳变、抑制边界振铃效果好。

(2)镜像翻转 Mirror(画质最优,高端显示器 / TV 使用)

超出部分镜像反射像素,模拟连续画面,过渡最自然。

相关推荐
liuluyang5302 小时前
Verilog 中 wire 与 wor 的区别详解
fpga开发·verilog
盼小辉丶2 小时前
OpenCV-Python实战(26)——复杂场景下的实时物体检测与跟踪
python·opencv·计算机视觉
armwind2 小时前
openISP学习9-CSC-Color Space Conversion(色彩空间转换)
图像处理·计算机视觉
YOLO数据集集合17 小时前
智慧林业无人机巡检 松材线虫病害树木实例分割数据集 | 森林枯木识别 深度学习视觉
人工智能·深度学习·目标检测·计算机视觉·无人机
GateWorld1 天前
LCD显示技术完全指南:原理·制造·驱动·FPGA实现之点屏五 miniLVDS
fpga开发·lcd显示·fpga点亮屏幕·minilvds
却道天凉_好个秋1 天前
HEVC(一):环路滤波
人工智能·算法·计算机视觉·环路滤波
源代码杀手1 天前
基于ROS2+Gazebo+RIVE的40项计算机视觉前沿机器人项目(含视觉算法原理与源码获取方式)
算法·计算机视觉·机器人
armwind1 天前
openISP学习2-DPC(黑电平补偿)和BLC(黑电平补偿)
图像处理·计算机视觉
简简单单做算法1 天前
基于DNA算法的遥感图像加解密matlab仿真
计算机视觉·matlab·dna算法·遥感图像加解密