将修改后的像素存储回纹理内存中

时间:2012-08-04 15:36:45

标签: image-processing opengl-es opengl-es-2.0 glsl fragment-shader

您好我正在尝试使用openGL ES2.0实现图像重新定位算法。该算法首先使用Sobel滤波器然后使用图像差来分别检查边缘然后运动。然后,它使用这些值来创建矩阵,该矩阵将确定可以移除图像中的哪些像素。到目前为止,我已经使用片段着色器实现了sobel滤镜和图像差异。一旦我有了边缘图和运动图,我就添加了两个值,将它们归一化到0到1之间。现在我需要再次对这个规范化矩阵进行sobel滤波。但我不知道我是否可以将它存回纹理内存以再次将其加载为纹理。或者我应该将这些值存储在与图像大小相同的矩阵中?我如何使用GLSL做到这一点? (我是GLSL的初学者。这可能是一个愚蠢的问题:p)

这是frag着色器:

precision mediump float;
varying vec2 coordVar;  
uniform sampler2D s_baseMap;
uniform sampler2D s_lightMap;
void main() 
{
    vec4 baseColor; 
    float basemono;
    vec4 lightColor;
    float lightmono;
    float diffmap;
    baseColor = texture2D( s_baseMap, coordVar );
    lightColor = texture2D( s_lightMap, coordVar );
    //######TEMPORAL SALIENCY MAP#########
    basemono = baseColor .r * 0.299 + baseColor .g * 0.587 + baseColor .b * 0.114;
    lightmono = lightColor.r * 0.299 + lightColor.g * 0.587 + lightColor.b * 0.114;
    diffmap = basemono - lightmono;
    //######## SPATIAL SALIENCY MAP #######
    float pixelHSobel;
    float pixelVSobel;
    float pixel;
    mat3 sobelHoriz = mat3(
         0.125,  0.250, 0.125,
         0.000,  0.000, 0.000,
         -0.125,-0.250,-0.125);
         mat3 sobelVert = mat3(
         -0.125, 0, 0.125,
         -0.250, 0, 0.250,
         -0.125, 0, 0.125);
         float stepH = 1.0/800.0;
         float stepV = 1.0/600.0;
         float tmp1;
         float tmp2;
         float tmp3;
         float tmp4;
         float tmp5;
         float tmp6;
         float tmp7;
         float tmp8;
         float tmp9;
      // ####### Horizontal Sobel ######
         tmp1 = texture2D(s_baseMap, coordVar.st + vec2(-stepH, stepV)).r * sobelHoriz[0][0];
         tmp3 = texture2D(s_baseMap, coordVar.st + vec2(stepH, stepV)).r * sobelHoriz[2][0];
         tmp4 = texture2D(s_baseMap, coordVar.st + vec2(-stepH, 0.0)).r * sobelHoriz[0][1];
         tmp6 = texture2D(s_baseMap, coordVar.st + vec2(stepH,0.0)).r *sobelHoriz[2][1];
         tmp7 = (texture2D(s_baseMap, coordVar.st + vec2(-stepH, -stepV)).r *sobelHoriz[0][2]);
         tmp9 = (texture2D(s_baseMap, coordVar.st + vec2(stepH, -stepV)).r *sobelHoriz[2][2]);
         pixelHSobel = tmp1+tmp3 + tmp4 + tmp6+ tmp7 +  tmp9 + 0.5;
      // ####### Vertical Sobel #######
         tmp1 = texture2D(s_baseMap, coordVar.st + vec2(-stepH, stepV)).r * sobelVert[0][0];
         tmp2 = texture2D(s_baseMap, coordVar.st + vec2(0.0, stepV)).r * sobelVert[1][0];
         tmp3 = texture2D(s_baseMap, coordVar.st + vec2(stepH, stepV)).r * sobelVert[2][0];
         tmp4 = texture2D(s_baseMap, coordVar.st + vec2(-stepH, 0.0)).r * sobelVert[0][1];
        tmp5 = texture2D(s_baseMap, coordVar.st + vec2(0.0, 0.0)).r *sobelVert[1][1];
         tmp6 = texture2D(s_baseMap, coordVar.st + vec2(stepH,0.0)).r *sobelVert[2][1];
         tmp7 = (texture2D(s_baseMap, coordVar.st + vec2(-stepH, -stepV)).r *sobelVert[0][2]);
         tmp8 = (texture2D(s_baseMap, coordVar.st + vec2(0.0, -stepV)).r *sobelVert[1][2]);
         tmp9 = (texture2D(s_baseMap, coordVar.st + vec2(stepH, -stepV)).r *sobelVert[2][2]);
         pixelVSobel = tmp1 + tmp2 + tmp3 + tmp4 + tmp5 + tmp6 + tmp7 + tmp8 + tmp9 + 0.5;
         pixel = (sqrt(pixelVSobel*pixelVSobel +pixelHSobel*pixelHSobel));
         if (pixel <= 0.715)
         {
            pixel=0.0;
         }
         else
         {
            pixel=1.0;
         }
         // ###########IMPORTANCE MATRIX########### 
      float impmap = (pixel+diffmap)/2.0;
         // ########## display ######
          gl_FragColor = vec4(impmap,impmap,impmap,1.0);

我现在需要以某种方式在图像impmap上运行sobel滤镜。

1 个答案:

答案 0 :(得分:0)

使用帧缓冲对象(FBO)将sobel过滤写入纹理,而不是屏幕上的帧缓冲。然后,您可以绑定此纹理而不是原始图像,并在其上应用另一个过滤器传递。

因此操作顺序如下:

  1. 将原始图像绑定为纹理源
  2. 将目标纹理绑定为FBO颜色附件
  3. 通过sobel着色器渲染原始图像以定位FBO
  4. 取消绑定目标纹理作为FBO颜色附件并绑定为纹理源
  5. 将辅助目标纹理绑定为FBO颜色附件
  6. 转到3,根据需要重复。