Android - 类似高斯模糊的效果 - OpenGL
Android - Gaussian blur like effect - OpenGL
在未指定的地方,此问题只是建立在 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 };
但是这种模糊效果不够强,我正在寻找类似高斯效果可以在 iOS 和 UIVisualEffectView
上做的事情,它看起来像这样:
一个很好的平滑重度模糊效果,但到目前为止我管理的最好的是:
如您所见,它没有那么光滑,而且有点方形。
我通过转换为使用此 handy tool 生成的 5x5 内核来实现此目的,sigma 为 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
class[=26 中的 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 映射中采样会产生更好的性能。
您可以从纹素之间进行采样,以劫持纹理插值并获得比其他方式更多的抽头。
一旦开始进行这些权衡,通常需要进行一些微调才能达到 "look right"。 An investigation of fast real-time GPU-based image blur algorithms(Filip S.,2014)提供了一个很好的总结。
在未指定的地方,此问题只是建立在 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 };
但是这种模糊效果不够强,我正在寻找类似高斯效果可以在 iOS 和 UIVisualEffectView
上做的事情,它看起来像这样:
一个很好的平滑重度模糊效果,但到目前为止我管理的最好的是:
如您所见,它没有那么光滑,而且有点方形。
我通过转换为使用此 handy tool 生成的 5x5 内核来实现此目的,sigma 为 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
class[=26 中的 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 映射中采样会产生更好的性能。
您可以从纹素之间进行采样,以劫持纹理插值并获得比其他方式更多的抽头。
一旦开始进行这些权衡,通常需要进行一些微调才能达到 "look right"。 An investigation of fast real-time GPU-based image blur algorithms(Filip S.,2014)提供了一个很好的总结。