0

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

这是碎片着色器:

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 过滤器。

4

1 回答 1

0

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

所以操作的顺序大约是:

  1. 将原始图像绑定为纹理源
  2. 将目标纹理绑定为 FBO 颜色附件
  3. 通过 sobel 着色器将原始图像渲染到目标 FBO
  4. 将目标纹理取消绑定为 FBO 颜色附件并绑定为纹理源
  5. 将次要目标纹理绑定为 FBO 颜色附件
  6. 转到 3,根据需要经常重复。
于 2012-08-04T21:37:28.507 回答