使用GPUImage进行色度过滤视频?

时间:2012-09-17 15:48:40

标签: ios video transparency gpuimage

我正在尝试使用@ BradLarson的真棒GPUImage工具包,使用透明度键(RGB: 0x00FF00或全绿色)在我的应用程序中显示透明度的视频文件。但是,我遇到了GPUImageChromaKeyFilter过滤器的一些问题,我不太明白为什么。

我的源视频文件位于我的保管箱here(12 KB,3秒长,全绿背景,屏幕上只有一个正方形),

我使用了标题为SimpleVideoFilter的示例项目。

这是我尝试使用的代码(我只是替换了-viewDidLoad):

NSURL *sampleURL = [[NSBundle mainBundle] URLForResource:@"sample" withExtension:@"m4v"];
movieFile = [[GPUImageMovie alloc] initWithURL:sampleURL];

filter = [[GPUImageChromaKeyFilter alloc] init];
[filter setColorToReplaceRed:0 green:1 blue:0];
[filter setEnabled:YES];

[movieFile addTarget:filter];

GPUImageView *filterView = (GPUImageView *)self.view;
[filter addTarget:filterView];

[movieFile startProcessing];

根据文档(稀疏),此应该具有替换视频中所有绿色的效果。相反,我把它作为输出:

Screenshot of video

它告诉我视频正在播放(因此它正在复制到应用程序中),但它似乎没有进行任何色度键控。为什么会这样?我是否需要手动设置平滑值&门槛?我不应该,因为源只包含两种颜色(0x00FF000x000000)。

我也在设备上对此进行了测试,但无济于事。几乎所有其他我尝试使用的过滤器,例如GPUImageRGBFilterGPUImageSepiaFilter等。GPUImageChromaKeyFilter可能会被破坏吗?

任何有关这方面的帮助都会受到赞赏,因为此时我正在刮取视频的透明度。

2 个答案:

答案 0 :(得分:9)

与原始问题类似,我想在自定义视图层次结构上添加绿屏视频。直播视频。事实证明,使用标准的GPUImage ChromaKey过滤器是不可能的。它不是alpha混合,而是将绿色像素与背景像素混合在一起。例如,红色背景变为黄色,蓝色变为青色。

让它运作的方法包括两个步骤:

1)确保filterview具有透明背景:

filterView.backgroundColor=[UIColor clearColor];

2)修改GPUImageChromaKeyFilter.m

old: gl_FragColor = vec4(textureColor.rgb, textureColor.a * blendValue);
new: gl_FragColor = vec4(textureColor.rgb * blendValue, 1.0 * blendValue);

现在,视频中的所有键控(例如绿色)像素都变得透明,并且可以发现滤镜视图下方的任何内容,包括(在线 - )视频。

答案 1 :(得分:1)

我通过使用 GPUImageChromaKeyBlendFilter 并设置背景图片来实现它。我想知道,如果我们可以做到而不必设置背景。当我没有设置背景时,电影显示为白色,但添加背景渲染效果很好......

filter = [[GPUImageChromaKeyBlendFilter alloc] init];
[(GPUImageChromaKeyBlendFilter *)filter setColorToReplaceRed:0.0 green:1.0 blue:0.0];
[(GPUImageChromaKeyBlendFilter *)filter setThresholdSensitivity:0.4];

UIImage *inputImage = [UIImage imageNamed:@"background.png"];
sourcePicture = [[GPUImagePicture alloc] initWithImage:inputImage smoothlyScaleOutput:YES];
[sourcePicture addTarget:filter];
[sourcePicture processImage];