我想用GPU处理能力进行两个RGB视频帧减法。
即,第一图像的每个像素的R,G,B值与第二图像相减。
另外,结果要具有负RGB值并存储在NSMutableArray中。
我使用AVCaptureSession帮助我获取CMSampleBufferRef格式的原始视频帧。
1)是否有任何图片格式支持负RGB值?
还是我需要制作一个类似于矩阵的类来存储图像?
(好像某些图像格式使用float来存储RGB值...)
(我听说过“图像不同混合模式”,它与我想要的类似,但是将绝对RGB值,我希望结果具有负值)
2)如何使用GPU处理能力进行减法?
(我可以用CPU来完成,但是FPS太慢了,大约5-6 FPS,但是我希望它是30 FPS)
(OpenGL或Quartz Composer有帮助吗?)
谢谢。
最佳答案
正如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(或任何范围)。