You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

锐化滤镜与卷积函数异常:输出存在突兀像素问题排查

卷积锐化滤镜出现突兀像素的原因及解决

问题描述

我在实现作业所需的滤镜卷积函数,模糊滤镜运行正常,但锐化滤镜输出虽大致可用,却有大量突兀像素。

  • 我的输出:锐化后存在大量突兀亮/暗像素
  • 预期输出:锐化效果自然,无突兀像素

我的代码

卷积函数

//don't mind the preserve variable
Image convolve_image(const Image &im, const Image &filter, bool preserve) {
    assert(filter.c == 1);
    Image ret;
    ret=Image(im.w,im.h,im.c);
    int dimch=im.c;
    int dimw=im.w;
    int dimh=im.h;
    int sizef=filter.w;

    for(int c=0; c<dimch; c++){
        for(int i=0; i<dimw; i++){
            for(int j=0; j<dimh; j++){
                float pixelnew=0;
                for(int a=0; a<sizef; a++){
                    for(int b=0; b<sizef; b++){
                        pixelnew=pixelnew+im.clamped_pixel(i-(sizef/2)+a,j-(sizef/2)+b,c)*filter.clamped_pixel(a,b,0);
                    }
                }
                ret(i,j,c)=pixelnew;
                
            }
        }
    }
    
    return ret;
}

锐化滤镜

Image make_sharpen_filter() {
    // TODO: Implement the filter
    Image ret=Image(3,3,1);
    
    ret(0,0,0)=0;
    ret(0,1,0)=-1;
    ret(0,2,0)=0;
    ret(1,0,0)=-1;
    ret(1,1,0)=5;
    ret(1,2,0)=-1;
    ret(2,0,0)=0;
    ret(2,1,0)=-1;
    ret(2,2,0)=0;
    

    return ret;
}

问题原因

锐化滤镜的卷积计算会产生超出图像像素正常范围(通常是01或0255,取决于图像存储格式)的数值,你的代码直接将计算结果赋值给输出像素,没有做范围截断(clamping),导致超出范围的数值被错误渲染,出现突兀的亮/暗像素。

比如,当卷积计算结果为负数时,若图像存储的是无符号整数,会被转换为很大的正数;若结果大于最大值,也会溢出,最终表现为突兀像素。而模糊滤镜的卷积核权重都是正数且总和通常为1,计算结果基本在正常范围内,所以没有这个问题。

解决方法

在将计算得到的pixelnew赋值给输出图像前,对其进行范围截断,确保数值落在图像的合法范围内:

修改卷积函数中赋值的那一行:

// 假设图像像素范围是0~1,如果是0~255则替换为0和255
ret(i,j,c) = std::max(0.0f, std::min(1.0f, pixelnew));

或者如果你的Image类有类似clamped_pixel的设置方法,也可以用它来处理:

ret.set_clamped_pixel(i,j,c,pixelnew);

另外,锐化核的权重总和是1(5-1-1-1-1=1),所以归一化不是必须的,关键是截断范围。

内容的提问来源于stack exchange,提问作者beginner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 16:50:31