0

I am converting YUV to RGB and its working fine. Now, I want to detect all points within a certain range of a specified color, such as all red points. And accordingly display all red points and render everything else Black and White.

Which is the best way to detect the red points?

Here, is my fragment shader -

CODE

const char *Shaders::yuvtorgb = MULTI_LINE_STRING(
        varying mediump vec2 v_yTexCoord;
        varying mediump vec4 v_effectTexCoord;

        uniform sampler2D yTexture;
        uniform sampler2D uvTexture;

        // YUV to RGB decoder working fine.
        mediump vec3 yuvDecode(mediump vec2 texCoord)
        {
            // Get y
            mediump float y = texture2D(yTexture, texCoord).r;
            y -= 0.0627;
            y *= 1.164;

            // Get uv
            mediump vec2 uv = texture2D(uvTexture, texCoord).ra;
            uv -= 0.5;

            // Convert to rgb
            mediump vec3 rgb;
            rgb = vec3(y);
            rgb += vec3( 1.596 * uv.x, - 0.813 * uv.x - 0.391 * uv.y, 2.018 * uv.y);

            return rgb;
        }

   //Detects red color and outputs B&W image but with red points 
    mediump vec3 detectColor(mediump vec3 rgbColor)
    {
        mediump vec3 redTexture = vec3(rgbColor);

        mediump float r = redTexture.r;
        mediump float g = redTexture.g;
        mediump float b = redTexture.b;

        if (// Detect red color) {
            //if primary color is red
            //leave as it is
        } else {
            //primary color is not red
            //apply B&W image.
            mediump float y = texture2D(yTexture, v_yTexCoord.xy).r;
            y -= 0.0627;
            y *= 1.164;
            redTexture = vec3(y);
        }
        return redTexture;
    }

        void main()
        {
            mediump vec3 rgb = yuvDecode(v_yTexCoord.xy);
            rgb = detectColor(rgb);

            gl_FragColor = vec4(rgb, 1.0);
        }

);

Update:

Using OpenGLES 2.0

genpfault
  • 51,148
  • 11
  • 85
  • 139
asloob
  • 1,308
  • 20
  • 34
  • easiest is usually to calculate the Euclidean distance between RGB colors (or the square thereof, to avoid `sqrt()`). Weighted Euclidean distances like `√(2Δ²R+4Δ²G+Δ²B)` are used too. – Walter Tross Jul 01 '13 at 10:05
  • 2
    I think it depends on exactly what you mean by "within a certain range of a specified color". You can do this in RGB space as Walter suggests above or (particularly because you already have it) in YUV space. The shader in this question (http://stackoverflow.com/questions/16909816/can-someone-please-explain-this-fragment-shader-it-is-a-chroma-key-filter-gree) which does something similar (chroma-keying) actually converts RGB to YCrCb space just to do the comparison. – GuyRT Jul 01 '13 at 10:31
  • 2
    If you already have YUV data you might even want to use the UV data directly, since this would make the color detection more independent from luminance (but Ok, it really depends what *"certain range"* means in your case and if dark red is "equally red" as light red). If using RGB space, you could also use the "angle" between the color vectors to gain luminance independence if needed. – Christian Rau Jul 01 '13 at 11:21

0 Answers0