1

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

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

(似乎某些图像格式使用浮点数来存储 RGB 值......)

(我听说过图像不同的混合模式,它与我想要的相似,但会绝对 RGB 值,我希望结果具有负值)

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

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

(OpenGL 或 Quartz Composer 有用吗?)

谢谢。

4

1 回答 1

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(或任何您的范围)。

于 2012-09-06T17:55:44.813 回答