我正试图在SurfaceView或GlSurfaceView上实现实时模糊,获得相机馈送和遇到这个:Grafika https://github.com/google/grafika
它有一个功能,可以让你应用一个实时模糊滤镜,但模糊不够强如下所示:https://www.youtube.com/watch?v=kH9kCP2T5Gg
Grafika类使用一个3 × 3的过滤器内核,根据我的理解,这是一个浮点值,当编辑时,它会对视图应用期望的效果。
下面是模糊代码:
'case CameraCaptureActivity.FILTER_BLUR:
programType = Texture2dProgram.ProgramType.TEXTURE_EXT_FILT;
kernel = new float[] {
1f/16f, 2f/16f, 1f/16f,
2f/16f, 4f/16f, 2f/16f,
1f/16f, 2f/16f, 1f/16f };
break;'
有没有人知道如何使用这些数字来加强模糊?
锐化有完全不同的分数:
'kernel = new float[] {
0f, -1f, 0f,
-1f, 5f, -1f,
0f, -1f, 0f };'
,我不太明白其中的模式。任何帮助都会很感激。
在wikipedia图像处理内核页面上解释了基本思想。这里的模糊示例与Grafika中的示例相同(并在您的问题中显示)。
这个想法是(x,y)处的像素是其周围像素的加权和,即
[x-1,y-1] [x,y-1] [x+1,y-1]
[x-1,y] [x,y] [x+1,y]
[x-1,y+1] [x,y+1] [x+1,y+1]
为了获得原始图像,我们将对除当前像素外的所有内容使用0的权重:
0 0 0
0 1 0
0 0 0
我们可以通过平均所有9个像素得到一个简单的模糊。如果我们为每个像素设置一个1的权重,像这样:
1 1 1
1 1 1
1 1 1
则值会溢出9倍,因为我们只是将9个像素加在一起——一些暗像素会非常亮,但任何中等亮度的像素都会被洗掉。因此,我们需要通过除以9来标准化该值。
在你的问题中显示的模糊示例中,我们对每个像素使用不同的权重:
1 2 1
2 4 2
1 2 1
总权重是1+2+1+2+4+2+1+2+1 = 16,所以我们需要将结果除以16。除法是相对昂贵的——记住我们在一张大图像上做了数百万次——但是我们可以通过将系数除以16来完全避免它。
对于你的问题中显示的锐化示例,我们给当前像素一个5的权重,并且从四个附近的像素中减去像素值,再次留下1的最终权重。如果所有像素的值大致相同,我们将计算5 *像素- 4 *像素==像素。如果附近的值不同——表明我们处于某种边缘——那么新的像素值将趋向于非常亮或非常暗。
你可以完成相当多的3x3过滤器内核,但在某些情况下,你可能需要使用一个更大的(例如,参见维基百科高斯模糊页面上的7x7)。这将增加您的处理时间,但幸运的是gpu非常擅长并行处理大量数学。