Color Keying Pixel Bender

Um die Arbeitsweise mit Pixel Bender (ehemals Hydra) auszuprobieren, habe ich einen Filter geschrieben, der in Echtzeit ein Green-Screen-Video filtert. Über einen Threshold-Regler lässt sich die Stärke des Filters regeln. Über drei Slider (RGB-Farbwert) kann die Keyfarbe festgelegt werden.

Hier das Beispiel zum Anschauen: Demo

Hinweis: Um das Beispiel zu betrachten, wird der Flash Player 10 (zurzeit in der Betaphase) benötigt.

Pixel Bender Colorkey Filter

Der Colorkey-Filter hat eine RGB-Farbe als Grundlage, also die Keyfarbe. Alle Werte, die dieser Farbe exakt entsprechen werden transparent gemacht. Des Weiteren werden alle ähnlichen Farben unsichtbar gemacht, wobei die Toleranz über den "Threshold" genauer geregelt werden kann.

Mit weiteren Bearbeitungsschritten wie Kantenglättung, etc. würde sich die Qualität des Filters sicherlich um einiges optimieren lassen. Außerdem ist das Grün im Beispielvideo relativ dunkel und wäre bei gutem Footage wesentlich besser zu filtern.

Der Filtercode für Pixel Bender lautet:

CODE:
  1. /*****************************************************************************
  2. *
  3. * by Florian Plag
  4. * www.video-flash.de
  5. *
  6. *****************************************************************************/
  7. 1.0;>
  8. // color keying
  9. kernel colorKey
  10. < namespace : "AIF";
  11. vendor : "Florian Plag";
  12. version : 1;
  13. description : "Color keying";>
  14. {
  15. input image4 src;
  16. output float4 dst;
  17. // Threshold
  18. parameter float threshold
  19. 0.0;
  20. maxValue: 1.0;
  21. defaultValue: 0.1;>;
  22. // key color (RGB)
  23. parameter float3 keyColor;
  24. void
  25. evaluatePixel()
  26. {
  27. // Obtain the input pixel color
  28. float4 inputColor = sampleNearest(src, outCoord());
  29. // tolerance for key color
  30. float3 keyCMinusThr = float3 ( (keyColor.r - threshold), (keyColor.g - threshold), (keyColor.b - threshold));
  31. float3 keyCPlusThr = float3 ( (keyColor.r + threshold), (keyColor.g + threshold), (keyColor.b + threshold));
  32. // if color is the key color (or similar)
  33. if ( ((inputColor.r> keyCMinusThr.r) && (inputColor.r r)) && ((inputColor.g> keyCMinusThr.g) && (inputColor.g g)) && ((inputColor.b> keyCMinusThr.b) && (inputColor.b b)) ) {
  34. // transparent pixel
  35. dst.rgba = float4(1.0, 1.0, 0.0, 0.0);
  36. }
  37. else {
  38. // keep source pixel
  39. dst.rgb = inputColor.rgb;
  40. // and source alpha
  41. dst.a = inputColor.a;
  42. }
  43. }
  44. }

Wie nutzt man Pixel Bender in Flash/Flex?

Anhand des Beispiels sieht man, wie man einen Pixel Bender Filter in Flex verwendet.

XML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. :Application
  3. xmlns:mx="http://www.adobe.com/2006/mxml"
  4. xmlns:test="*"
  5. width="800" height="800" backgroundImage="bgpattern.png"
  6. creationComplete="creationCompleteHandler()"
  7. >
  8. :Script>
  9. import flash.display.*;
  10. import flash.events.*;
  11. import flash.net.*;
  12. import flash.filters.*;
  13. import flash.utils.*;
  14. private var shader:Shader;
  15. private var shaderFilter:ShaderFilter;
  16. private var myVideo:Video;
  17. private var ns:NetStream;
  18. public function creationCompleteHandler():void {
  19. // new video
  20. myVideo = new Video(400,300);
  21. myUIComponent.addChild(myVideo);
  22. var nc:NetConnection = new NetConnection();
  23. nc.connect(null);
  24. ns = new NetStream(nc);
  25. ns.client = new Object();
  26. myVideo.attachNetStream(ns);
  27. ns.play("green-screen.flv");
  28. [Embed(source="colorkey.pbj", mimeType="application/octet-stream")]
  29. var Filter:Class;
  30. shader = new Shader(new Filter());
  31. updateFilter();
  32. }
  33. private function updateFilter():void {
  34. // set threshold (pixel bender filter parameter)
  35. shader.data.threshold.value = [mySlider.value];
  36. // set key color (pixel bender filter parameter)
  37. shader.data.keyColor.value = [mySliderR.value, mySliderG.value, mySliderB.value];
  38. // new shaderFilter
  39. shaderFilter = new ShaderFilter();
  40. shaderFilter.shader = shader;
  41. // apply filter
  42. if (myCheckBox.selected == true) {
  43. myUIComponent.filters = [shaderFilter];
  44. }
  45. else {
  46. myUIComponent.filters = null;
  47. }
  48. }
  49. ]]>
  50. :Script>
  51. :HBox>
  52. :Panel title="Color keying with Pixel Bender" width="300" height="180"
  53. headerColors="[0xc6d381, 0xc6d381]" paddingLeft="10" paddingTop="10" id="myParamPanel">
  54. :HBox>
  55. :Label text="Threshold"/>
  56. :HSlider id="mySlider" value="0.2" maximum="1.0" minimum="0.0" thumbRelease="updateFilter();" />
  57. :HBox>
  58. :HBox>
  59. :Label text="R"/>
  60. :HSlider id="mySliderR" value="0.37" maximum="1.0" minimum="0.0" thumbRelease="updateFilter();" />
  61. :HBox>
  62. :HBox>
  63. :Label text="G"/>
  64. :HSlider id="mySliderG" value="0.52" maximum="1.0" minimum="0.0" thumbRelease="updateFilter();" />
  65. :HBox>
  66. :HBox>
  67. :Label text="B"/>
  68. :HSlider id="mySliderB" value="0.25" maximum="1.0" minimum="0.0" thumbRelease="updateFilter();" />
  69. :HBox>
  70. :HBox>
  71. :CheckBox id="myCheckBox" label="Color key active" selected="true" change="updateFilter();" />
  72. :HBox>
  73. :Panel>
  74. :HBox>
  75. :VBox>
  76. :UIComponent id="myUIComponent" width="400" height="300" />
  77. :Button click="ns.pause()" label="Pause video"/>
  78. :Button click="ns.resume()" label="Continue video"/>
  79. :Button click="ns.seek(0);" label="Reset video"/>
  80. :VBox>
  81. :Application>

Link: Beispiel anschauen