锐化滤镜与卷积函数异常:输出存在突兀像素问题排查
卷积锐化滤镜出现突兀像素的原因及解决
问题描述
我在实现作业所需的滤镜卷积函数,模糊滤镜运行正常,但锐化滤镜输出虽大致可用,却有大量突兀像素。
- 我的输出:锐化后存在大量突兀亮/暗像素
- 预期输出:锐化效果自然,无突兀像素
我的代码
卷积函数
//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
相关产品推荐
相关产品推荐

