如果没有指定,这个问题只是建立在github上grafika项目中的CameraCaptureActivity
之上。
它具有内置的模糊效果,使用3x3内核
kernel = new float[] {
1f/16f, 2f/16f, 1f/16f,
2f/16f, 4f/16f, 2f/16f,
1f/16f, 2f/16f, 1f/16f };
然而,这种模糊效果还不够强,我正在寻找类似于UIVisualEffectView
在iOS上的高斯效果,它看起来像这样:
一个很好的平滑重模糊效果,但到目前为止最好的是:
正如你所看到的,它并没有那么光滑,而且有点方正。
我通过转换为5x5内核来实现这一点,该内核使用这个方便的工具生成,西格玛为30,内核大小为5。它产生以下内容:
kernel = new float[] {
0.039911f, 0.039978f, 0.04f, 0.039978f, 0.039911f,
0.039978f, 0.040044f, 0.040067f, 0.040044f, 0.039978f,
0.04f, 0.040067f, 0.040089f, 0.040067f, 0.04f,
0.039978f, 0.040044f, 0.040067f, 0.040044f, 0.039978f,
0.039911f, 0.039978f, 0.04f, 0.039978f, 0.039911f
};
为了让在Grafika
项目中工作,我不得不在Texture2dProgram
类中修改KERNEL_SIZE
和mTexOffset
KERNEL_SIZE
现在是25
,mTextOffset
现在是这样计算的:
public void setTexSize(int width, int height) {
float rw = 50.0f / width;
float rh = 50.0f / height;
float rw50 = rw * 0.5f;
float rh50 = rh * 0.5f;
mTexOffset = new float[] {
-rw, -rh, -rw50, -rh, 0f, -rh, rw50, -rh, rw, -rh,
-rw, -rh50, -rw50, -rh50, 0f, -rh50, rw50, -rh50, rw, -rh50,
-rw, 0f, -rw50, 0f, 0f, 0f, rw50, -0f, rw, 0f,
-rw, rh50, -rw50, rh50, 0f, rh50, rw50, rh50, rw, rh50,
-rw, rh, -rw50, rh, 0f, rh, rw50, rh, rw, rh
};
};
有人对我可以修改什么来实现类似iOS的模糊有什么建议吗(我认为iOS也在减轻像素)?我认为我真正出错的地方是setTextSize()计算,特别是50.0f
值,我只是凭空提取了它,并观察到它对的影响
使用实际模糊内核进行卷积是一项计算密集型任务,即使在GPU上也是如此。有一些技术可以使它更好地工作:
-
高斯核可以分解为X和Y分量,分别进行计算。这种技术被图像处理程序使用,因为它相对快速和准确。
-
您可以使用泊松圆盘采样来模糊图像,而不是使用高斯核。
-
您可以使用多通Kawase滤波器作为高斯滤波器的近似值。
-
对于给定的主观模糊质量,从较低分辨率的mip图进行采样将产生更好的性能。
-
您可以从纹素之间采样,以劫持纹理插值,并获得比其他情况下更多的抽头。
一旦你开始进行这些权衡,通常需要一些微调才能让它"看起来正确"。一个很好的总结可在基于GPU的快速实时图像模糊算法的研究中获得(Filip S.,2014)。