BradLarson / GPUImage2

GPUImage 2 is a BSD-licensed Swift framework for GPU-accelerated video and image processing.
BSD 3-Clause "New" or "Revised" License
4.88k stars 611 forks source link

Median blending more than two images #49

Open asadm opened 8 years ago

asadm commented 8 years ago

I am trying to blend multiple layers in order to reduce noise. I see that I can blend two images, but is it possible to blend more than that (say 5 images) using GPUImage?

Thanks

asadm commented 8 years ago

My progress so far:

I see that GPUImage can support up to 5 input images to the shader. So I kinda solved it with following fragment shader code:

varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
varying highp vec2 textureCoordinate3;
varying highp vec2 textureCoordinate4;
varying highp vec2 textureCoordinate5;

uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
uniform sampler2D inputImageTexture3;
uniform sampler2D inputImageTexture4;
uniform sampler2D inputImageTexture5;

// MedianOfFive from http://stackoverflow.com/a/2117018
float MedianOfFive(float a, float b, float c, float d, float e)
{
    return b < a ? d < c ? b < d ? a < e ? a < d ? e < d ? e : d
    : c < a ? c : a
    : e < d ? a < d ? a : d
    : c < e ? c : e
    : c < e ? b < c ? a < c ? a : c
    : e < b ? e : b
    : b < e ? a < e ? a : e
    : c < b ? c : b
    : b < c ? a < e ? a < c ? e < c ? e : c
    : d < a ? d : a
    : e < c ? a < c ? a : c
    : d < e ? d : e
    : d < e ? b < d ? a < d ? a : d
    : e < b ? e : b
    : b < e ? a < e ? a : e
    : d < b ? d : b
    : d < c ? a < d ? b < e ? b < d ? e < d ? e : d
    : c < b ? c : b
    : e < d ? b < d ? b : d
    : c < e ? c : e
    : c < e ? a < c ? b < c ? b : c
    : e < a ? e : a
    : a < e ? b < e ? b : e
    : c < a ? c : a
    : a < c ? b < e ? b < c ? e < c ? e : c
    : d < b ? d : b
    : e < c ? b < c ? b : c
    : d < e ? d : e
    : d < e ? a < d ? b < d ? b : d
    : e < a ? e : a
    : a < e ? b < e ? b : e
    : d < a ? d : a;
}

void main()
{
    mediump vec4 image1 = texture2D(inputImageTexture, textureCoordinate);
    mediump vec4 image2 = texture2D(inputImageTexture2, textureCoordinate2);
    mediump vec4 image3 = texture2D(inputImageTexture3, textureCoordinate3);
    mediump vec4 image4 = texture2D(inputImageTexture4, textureCoordinate4);
    mediump vec4 image5 = texture2D(inputImageTexture5, textureCoordinate5);

    mediump float ra,ga,ba;

    ra = MedianOfFive(image1.r,image2.r,image3.r,image4.r,image5.r);
    ga = MedianOfFive(image1.g,image2.g,image3.g,image4.g,image5.g);
    ba = MedianOfFive(image1.b,image2.b,image3.b,image4.b,image5.b);

    gl_FragColor = vec4(ra, ga, ba, 1.0);
}

and then compiling as suggested in README.md about writing custom filters.

I still don't know if there is a better way of doing this.