iOS:如何用GPU电源减去两个视频帧?

时间:2012-09-06 03:38:17

标签: ios image-processing opengl-es quartz-composer

我想用GPU处理能力进行两次RGB视频帧减法。 即,第一图像的每个像素的R,G,B值减去第二图像。 此外,结果希望具有负RGB值并存储在NSMutableArray中。 我使用AVCaptureSession来帮助我获取CMSampleBufferRef格式的原始视频帧。

1)任何图像格式都支持负RGB值?    或者我需要制作一个类似矩阵的类来存储图像?

(好像某些图像格式使用float存储RGB值...)

(我听说过Image Different Blend Mode,它类似于我想要的但是绝对是RGB值,我希望结果具有负值)

2)如何使用GPU处理能力进行减法?

(我可以用CPU做,但FPS太慢,大约5-6 FPS,但我希望它是30 FPS)

(OpenGL或Quartz Composer有用吗?)

感谢。

1 个答案:

答案 0 :(得分:3)

正如Hammer所指出的,我的开源GPUImage框架中的GPUImageDifferenceBlendFilter就是这样做的。它使用以下片段着色器来获得红色,绿色和蓝色通道的绝对差异:

 varying highp vec2 textureCoordinate;
 varying highp vec2 textureCoordinate2;

 uniform sampler2D inputImageTexture;
 uniform sampler2D inputImageTexture2;

 void main()
 {
     mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
     mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
     gl_FragColor = vec4(abs(textureColor2.rgb - textureColor.rgb), textureColor.a);
 }

如果您需要比较连续的视频帧,您还可以使用GPUImageBuffer来延迟旧帧与当前视频帧一起处理。我在框架中的FilterShowcase示例应用程序中有一个这样的示例。

我不太确定你的意思"结果想要具有负RGB值。"当前iOS设备支持纹理支持的帧缓冲区(渲染目标)的唯一纹理格式是32位BGRA。这意味着每个颜色通道的范围为0-255,不允许使用负值。您可以将该颜色范围的下半部分用于负值,而将顶部用于正值。

您可以使用如下所示的片段着色器修改我的GPUImageSubtractBlendFilter来执行此操作:

 varying highp vec2 textureCoordinate;
 varying highp vec2 textureCoordinate2;

 uniform sampler2D inputImageTexture;
 uniform sampler2D inputImageTexture2;

 void main()
 {
     lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
     lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);

     gl_FragColor = vec4((textureColor.rgb - textureColor2.rgb + 1.0) * 0.5, textureColor.a);
 }

您需要在读取像素后将0-255输出转换为-128 - 128(或任何范围)。