Since you are looking to do a heat map grayscale to color based
transform, one of the easiest ways I can think to do this is to create
a second image that defines the grayscale intensity to color
transformation. Define a heat map image going from coolest on the top
to hotest on the bottom (sample image link below). In your filter,
sample the source image and then based on the grayscale intensity
sample the corresponding percentage based location from the heat map
image. For example if the grayscale intensity was 0.25, and your image
was 256 pixels tall, you would sample point (1, 64) from the heat map:
256 * 0.25 = 64.
This is a quick kernel example which should give you the general idea:
input image4 src;
input image4 heatmap;
output pixel4 dst;
pixel4 g = sampleNearest(src, outCoord());
dst = sampleNearest(heatmap, float2(1.0, g.r * 500.0));
For testing, I used this heat map image as the second input:
Thank you very much. Your idea works great. But now I have an issue.
I am using this pixel bender on Flash. There I am applying it as a filter. The problem is that I dont find a way to pass the gradient file as an input source to the shader. In my code I do:
shader = new Shader(new RasterFilter() as ByteArray); filter = new ShaderFilter(shader); shader.data.threshold.value = [0.2]; //this is another param i need shader.data.heatmap = new GradientImage() as BitmapData; // i embed the gradient and pass it as heatmap input //now I try to apply the filter map.foreground.filters=[filter];
But what I get is an error saying: "The Shader does not have the required number of inputs for this operation."
I looked at http://help.adobe.com/en_US/as3/dev/WS6FCADA8A-C82B-4d55-89AC-63CA9DEFF9C8.html for help.
"When you use a shader as a filter, the shader must be defined with at least one input. As the example shows, you do not set the input value in your code. Instead, the filtered display object or BitmapData object is set as the input image. If you use a shader that expects more than one input, you provide a value for any input beyond the first one."
But it does not tell you how to provide the value for the input beyong the first one!
These are the params I have in pixel bender:
input image4 src; input image4 heatmap; output pixel4 dst; parameter float threshold < minValue: float(0.0); maxValue: float(1.0); defaultValue: float(0.85);>;
Thanks in advance.
I think the syntax should be:
shader.data.heatmap.input = new GradientImage() as BitmapData;
This link goes into a little more detail:
why mess with bender when there's paletteMap method in BitmapData
Thanks! That worked. The doc is a bit unclear on these topics.
Yeah, that would be much better. But I need to not only pseudocolor the image, the filter also accepts other param to do some cut.
In any case what would you think is faster? PixelBender or paletteMap. If I understand correctly one of the advantages of PixelBender is that it runs on a different core while Flash uses only one.
Faster will depend a lot on your use case. With some overhead in
shuttling data between Flash and the graphics, Pixel Bender I've found
is better when dealing with larger images. Pixel Bender makes it
possible to apply the filter to video and other components in
real-time. Best to run a comparison test on your code if speed is the
yeah, agree with Daniel here completely. There is some overhead to moving data in and out of Pixel Bender. If you are doing a lot of processing in your kernel, or working on a large amount of data (or the precision of the math is critical), Pixel Bender is usually a win, but if you have the time to do a test that is always good.