Как отсортировать пиксели и реализовать linearGradient в гистограмме webgl? - PullRequest
0 голосов
/ 20 ноября 2018

Я пытался реализовать гистограмму для изображения с помощью webgl.Я могу сделать это в javascript HTML5 Canvas, взяв массив длиной 255 и увеличив значения пикселов каждого индекса через 0-255 и используя createLinearGradient для создания гистограммы.

for(var c = 0; c < 256; c++){
    histogram[c] = 0;
}
var ctx = document.getElementById('canvas').getContext('2d');
var pixels= ctx.getImageData(0, 0, width, height).data;
for (var i = 0, j = 0; i < u8a.length; i++, j = j + 4) {
    histogram[pixels[j]]++; //increasing pixel index for histogram
}

И для реализациито же самое в WebGL, я имею в виду это jsfiddle , но я вижу, что гистограмма не сглажена и не отсортирована.

Итак, я застрял с двумя вещами здесь с WebGL:

-Как мы можем отсортировать значения пикселей от 0,0 (0) до 1,0 (255) в вышеупомянутой скрипке?

-Как сделать гистограмму гладкой в ​​webgl с / без линейного градиента?

Код:

precision mediump float;
uniform sampler2D u_histTexture;
uniform vec2 u_resolution;
uniform sampler2D u_maxTexture;
void main() {
    // get the max color constants
    vec4 maxColor = texture2D(u_maxTexture, vec2(0));
    // compute our current UV position
    vec2 uv = gl_FragCoord.xy / u_resolution;
    // Get the history for this color
    // (note: since u_histTexture is 256x1 uv.y is irrelevant
   vec4 hist = texture2D(u_histTexture, uv);
   // scale by maxColor so scaled goes from 0 to 1 with 1 = maxColor
   vec4 scaled = hist / maxColor;
   // 1 > maxColor, 0 otherwise
   vec4 color = step(uv.yyyy, scaled);
   float rr = 0.2989 * color.r + 0.5870 * color.g + 0.1140 * color.b;
       gl_FragColor = vec4(rr, rr, rr, 1);
}

Histogram ranging from 0 to 255 or 0 to 65536 if image is 16 bit

1 Ответ

0 голосов
/ 21 ноября 2018

Лучшее, что я могу понять, это то, что вы не хотите сортировать, а хотите сделать черно-белую гистограмму (все каналы r, g, b вместе).

Для этого вам нужно простоодин проход, который суммирует все каналы, а не 4 прохода, как это делается в настоящее время.

Вам необходимо внести изменения в следующие шейдеры и заменить некоторые вызовы рендеринга в javascript.

Изменить "hist-vs"to

attribute float pixelId;
uniform vec2 u_resolution;
uniform sampler2D u_texture;
void main() {
  vec2 pixel = vec2(mod(pixelId, u_resolution.x), floor(pixelId / u_resolution.x));
  vec2 uv = (pixel + 0.5) / u_resolution;
  vec4 color = texture2D(u_texture, uv);
  float colorSum = (color.r + color.g + color.b) / 3.0 ; 
  gl_Position = vec4((colorSum * 255.0 + 0.5) / 256.0 * 2.0 - 1.0, 0.5, 0, 1);
  gl_PointSize = 1.0;
}

Измените" max-vs "на

precision mediump float;
uniform sampler2D u_texture;
void main() {
  vec4 maxColor = vec4(0);
  for (int i = 0; i < 256; i++) {
    vec2 uv = vec2((float(i) + 0.5) / 256.0, 0.5);
    maxColor = max(maxColor, vec4(texture2D(u_texture, uv).rgb, 1));
  }
  gl_FragColor = maxColor;
}

Измените" show-fs "на

precision mediump float;    
uniform sampler2D u_histTexture;
uniform vec2 u_resolution;
uniform sampler2D u_maxTexture;    
void main() {
  vec3 maxColor = texture2D(u_maxTexture, vec2(0)).rgb;
  vec2 uv = gl_FragCoord.xy / u_resolution;
  vec3 hist = texture2D(u_histTexture, uv).rgb;
  gl_FragColor = vec4(step(uv.yyy, hist / maxColor) * uv.x, 1);
}

Изменения в javascript

Тогда в Javascript вместо того, чтобы вызывать первый шейдер 4 раза, нужно вызывать его только один раз.Кроме того, поскольку униформа маски не требуется, вам не нужно передавать ее в шейдер.

Цикл for, который первоначально выглядел как

  for (var channel = 0; channel < 4; ++channel) {
    gl.colorMask(channel === 0, channel === 1, channel === 2, channel === 3);
    twgl.setUniforms(histProgramInfo, {
      u_texture: tex,
      u_colorMult: [
        channel === 0 ? 1 : 0,
        channel === 1 ? 1 : 0,
        channel === 2 ? 1 : 0,
        channel === 3 ? 1 : 0,
      ],
      u_resolution: [img.width, img.height],
    });
    twgl.drawBufferInfo(gl, gl.POINTS, pixelIdBufferInfo);
  }

, заменит все эти строки на

* 1024.*
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...