本文是isp算法学习的第十五篇章,主要是讲述EE(Edge Enhance)。

1现象说明

EE模块在某些ISP主控中叫做sharpness或者sharpen,这些名称指代的模块是同一个,不用再纠结。主要就是在YUV域内弥补成像过程中图像的锐度损失,对边缘和细节进行加强,从而恢复场景本应具有的自然锐度。

1.1锐度下降原因

如下图所示,理想的边缘如左侧所示,是个高反差,对比强的边。而实际成像的效果是右侧的状况,反差变弱,且边缘过渡缓慢,给人的视觉冲击不够,也就看上去没有左侧清晰锐利。

造成边缘这种衰减的主要原因

一方面是镜头的物理性质的限制,具体的原因不做深入讨论,属于光学范畴,简单理解就是镜头本身就是低通属性,所以图像成像光信号经过镜头后相当于进行了一次低通滤波,会导致边缘衰减

另一方面就是Pipeline中例如去马赛克,NR等算法都是低通特性的,都会导致高频损失从而表现出锐度下降。

1.2锐化原理

由于图像中的细节和边缘在频域中主要体现为尖锐程度较高的高频段上,因此锐化基本思想就是增强图像分离后产生的高频分量在像素值中的比重。

我们在实际算法中的的做法就是将边缘反差过渡区域调整得更陡峭更突变,从而到达高反差,高对比实现锐利度的提升。如下图右下角图,白色为未处理的变化曲线,红色为处理后的效果,处理后过渡明显更快,反差更大,左上经过处理到右上后人眼视觉感觉也确实对比更强,更清晰。

2增强方法

算法又需要如何实际实现呢,其实这个和我们学习美术的时候一样,我们会描边,用2B把边缘描绘一遍,那么边缘在新图像中就会更清楚,其实算法也是这种思路,就是通过边缘算法提取图像边缘,然后将边缘“描绘”到原始图像上,那么边缘也就更加请处理。

上述的描边过程其实可以简化为以下的流程:

从上图中可以看出叠加后的图像确实清晰度有提升,但是感觉效果并不太好,主要因为鸟的主体部分加强了,但是后面的背景本来平坦的区域经过加强后也出现了很多颗粒感,看上去很难受。

所以针对这些问题我们需要优化算法,其实从这个框架看,我们唯一能做的其实就是一个优化边缘提取的filter,另外一个就是优化λ,所以实际用的时候往往采取一下框图:

经过filter提取的边缘经过一个边缘判决器,然后λ根据这个判决器的判决动态调整加强力度。

3算法

3.1sharpness Improve Adaptive to Edge Strength of Color

这里分成四个区域,分别有平坦区,soft边缘区,medium边缘区,hard边缘区,会生成叠加四个区域的边缘增强,最后再和原图进行叠加,就是锐化过的图像

比如一张图像经过算法后,显示的区域

最终看到增强对应的曲线,会对undershootovershoot进行限制

4代码演示

 1clc, clear, close all;
 2
 3preDelta = 2;   % 预滤波强度,值越大,边缘越强
 4th = 5;         % 边缘检测阈值
 5gain = 0.8;       % 边缘增强力度控制
 6
 7img = imread('./images/blurring.png');
 8figure();
 9imshow(img);
10title('org');
11
12[h, w, c] = size(img);
13% 转换成YUV空间的值
14img_yuv = rgb2ycbcr(img);
15y = img_yuv(:, :, 1);
16% 只对Y通道做高斯低通滤波,其中preDelta可以控制强度
17Iblur = imgaussfilt(y, preDelta);
18%原图去除低频信号,就是高频信号
19HighFC = y - Iblur;
20
21for i = 1: h
22    for j = 1: w
23        %判断是否为边缘,如果是边缘那么增强
24        if HighFC(i, j) > th
25            HighFC(i, j) = HighFC(i, j) * gain;
26        else
27            HighFC(i, j) = 0;
28        end
29    end
30end
31figure();
32imshow(HighFC);
33imwrite(HighFC, './images/edgeDemo.png');
34title('edge');
35
36y = y + HighFC;
37img_yuv(:, :, 1) = y;
38res = ycbcr2rgb(img_yuv);
39imwrite(res, './images/ee.png');
40figure();
41imshow(res);
42title('res');