Image Processing

Image Processing #

El procesamiento de imagenes es la manipulación de imagenes mediante procesos computacionales manejados por GPU y el uso de algoritmos que modifican las imagenes. En muchos de los casos se utilizan operaciones matematicas de nivel matricial para transformar los colores de las imagenes, o distorsionarlas como se lograria con efectos de amplificación.

1. Procesamiento #

Ejercicio 1:
Implemente una aplicacion para el procesamiento de imagenes / videos que soporte el uso de diferentes mascaras, incluyendo kernels de tamaño diferente a 3x3 y:

  • Una Herramienta de region de interes para aplicar selectivamente una mascara:
  • Una Herramienta de magnidicacion.
  • Una herramienta que integre Luma y otras herramientas.
Ejercicio 2.1:
Incluir el canal azul en la visualizacion UV, ya sea Azul + Verde ó Azul + Rojo.
Solucion Ejercicio 2.1:
Modificar el shader para que evalue 2 variables y reajuste el color dependiendo de una de las opciones seleccionadas, modificando uno de los canales dependiendo de la opcion.
CODIGO: app.js

let maskShader;
let img;
let video_src;
let video_on;
let cam_src;
let cam_on;
let ColorT;

let mask_mode;
let coloring;
let lenses;
//let maskmode;

function preload() {
  video_src = createVideo(['/visual_computing/vid/drift.mp4']);
  video_src.hide();
  
  cam_src = createCapture(VIDEO);
  cam_src.size(width, height);
  cam_src.hide();
  
  maskShader = readShader('/visual_computing/sketches/shaders/mask.frag', { varyings: Tree.texcoords2 });
  img = loadImage('/visual_computing/imgs/car.jpg');
}

function setup() {
  createCanvas(700, 700, WEBGL);
  noStroke();
  textureMode(NORMAL);
  
  //Camera selector
  cam_on = createCheckbox('Live', false);
  cam_on.style('color','black');
  cam_on.position(10,50);
  
  //Camera Controls
  cam_on.changed(() => {
    if(cam_on.checked()){
      maskShader.setUniform('texture',cam_src);
    }else{
       maskShader.setUniform('texture', img); 
    }
  });
  
  
  //Video Controls
  video_on = createCheckbox('Video', false);
  video_on.style('color', 'black');
  video_on.position(10, 30);
  
  //Video & image Switcher
  video_on.changed(() => {
    if (video_on.checked()) {
      maskShader.setUniform('texture', video_src);
      video_src.loop();
    } else {
      maskShader.setUniform('texture', img);
      video_src.pause();
    }
  });
  
  //Mask controls
  mask_mode = createCheckbox('Masks', false);
  mask_mode.position(10, 10);
  mask_mode.style('color', 'black');
  
  //Coloring checkbox
  coloring = createCheckbox('Coloring',false);
  coloring.position(165, 10);
  coloring.style('color','black');
  
  //Lenses checkbox
  lenses = createCheckbox('Lense',false);
  lenses.position(360, 10);
  lenses.style('color','black');
  
  //Shader apply
  shader(maskShader);
  maskShader.setUniform('texture', img);
  emitTexOffset(maskShader, img, 'texOffset');
  
  //Kernel selector
  sel = createSelect();
  sel.position(80, 10);
  sel.option('None');
  sel.option('Edges');
  sel.option('Sharpen');
  sel.option('Box Blur');
  sel.option('Emboss');
  
  
  sel.selected('None');
  
  //Coloring selector
  selC = createSelect();
  selC.position(245, 10);
  selC.option('None');
  selC.option('Luma');
  selC.option('Average');
  selC.option('HSV Value V');
  selC.option('HSL Value L');
  selC.option('Tint');
    
  selC.selected('None');
  
  //Color Picker
  colorT = createColorPicker(color(255,255,255));
  colorT.position(175, 30);
  
  //lenses parameters
  Rslider = createSlider(50.0, 150.0, 50.0);
  Rslider.position(360, 30);
  Rslider.style('width', '80px');
  let div1 = createDiv('Lens Radio');
  div1.style('font-size', '18px');
  div1.style('color', '#000000');
  div1.position(450, 30);
  
  Sslider = createSlider(0.0, 1.0, 0.0, 0.01);
  Sslider.position(360, 50);
  Sslider.style('width', '80px');
  let div2 = createDiv('Lens Amplitude');
  div2.style('font-size', '18px');
  div2.style('color', '#000000');
  div2.position(450, 50);
  
}

function draw() {
  background(0);
  
  //Mask Mode
  if (mask_mode.checked()){
    
    //Enable Masks Mode
    maskShader.setUniform('maskmode',true);
    maskShader.setUniform('coloringmode',false);
    
    //kernels
    if (sel.value()=='Edges') {
      maskShader.setUniform('mask', [-1, -1, -1, -1, 8, -1, -1, -1, -1]);
    }else if(sel.value()=='Sharpen'){
      maskShader.setUniform('mask', [0, -1, 0, -1, 5, -1, 0, -1, 0]);
    }else if(sel.value()=='Box Blur'){
      maskShader.setUniform('mask', [1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9]);
    }else if(sel.value()=='Emboss'){
      maskShader.setUniform('mask', [-2, -1, 0, -1, 1, 1, 0, 1, 2]);
    }else{
      maskShader.setUniform('mask', [0, 0, 0, 0, 1, 0, 0, 0, 0]);
    }
    
  }else if(coloring.checked()){
    
    
    //Enable Coloring Mode
    maskShader.setUniform('maskmode',false);
    maskShader.setUniform('coloringmode',true);
    
    if(selC.value()=="None"){
    maskShader.setUniform('HSVV',false);
    maskShader.setUniform('HSLL',false);
    maskShader.setUniform('grey_scale',false);
    maskShader.setUniform('average',false);
    maskShader.setUniform('Tint',false);
    
  }else if(selC.value()=="Luma"){
    maskShader.setUniform('grey_scale',true);
    maskShader.setUniform('average',false);
    maskShader.setUniform('HSVV',false);
    maskShader.setUniform('HSLL',false);
    maskShader.setUniform('Tint',false);
    
  }else if(selC.value()=="Average"){
    maskShader.setUniform('average',true);
    maskShader.setUniform('grey_scale',false);
    maskShader.setUniform('HSVV',false);
    maskShader.setUniform('HSLL',false);
    maskShader.setUniform('Tint',false);
    
  }else if(selC.value() =="HSV Value V"){
    maskShader.setUniform('HSVV',true);
    maskShader.setUniform('HSLL',false);
    maskShader.setUniform('average',false);
    maskShader.setUniform('grey_scale',false);
    maskShader.setUniform('Tint',false);
    
  }else if(selC.value() =="HSL Value L"){
    maskShader.setUniform('HSLL',true);
    maskShader.setUniform('HSVV',false);
    maskShader.setUniform('average',false);
    maskShader.setUniform('grey_scale',false);
    maskShader.setUniform('Tint',false);

  }else if(selC.value() =="Tint"){
    maskShader.setUniform('Tint',true);
    maskShader.setUniform('HSLL',false);
    maskShader.setUniform('HSVV',false);
    maskShader.setUniform('average',false);
    maskShader.setUniform('grey_scale',false);
    
    let RC = colorT.color();
    maskShader.setUniform('colorT',[red(RC),green(RC),blue(RC),1.0]);
    }
    
  }else if(lenses.checked()){
    maskShader.setUniform('lensemode',true);
    maskShader.setUniform('maskmode',false);
    maskShader.setUniform('coloringmode',false);
    
    maskShader.setUniform('mouseData',[mouseX,mouseY]);
    maskShader.setUniform('resolution',[width,height]);
    maskShader.setUniform('radio', Rslider.value());
    maskShader.setUniform('scale', Sslider.value());
  }else{
    maskShader.setUniform('lensemode',false);
    maskShader.setUniform('maskmode',false);
    maskShader.setUniform('coloringmode',false);
  }
  

  quad(-width / 2, -height / 2, width / 2, -height / 2, width / 2, height / 2, -width / 2, height / 2);
}
CODIGO: mask.frag
precision mediump float;

uniform bool maskmode;
uniform bool coloringmode;
uniform bool lensemode;

uniform bool grey_scale;
uniform bool average;
uniform bool HSVV;
uniform bool HSLL;
uniform bool Tint;

uniform vec4 colorT;

uniform sampler2D texture;

uniform vec2 texOffset;
uniform float mask[9];

varying vec2 texcoords2;

uniform vec2 mouseData;
uniform vec2 resolution;

uniform vec4 passerGL;

uniform float radio;
uniform float scale;

//--------------------------------------------------------------------------

float rim = 2.0;
vec2 handview = vec2(10.0,50.0);

vec2 curveGen(vec2 toPow, float dist){
  float x = dist/radio;
  return toPow * (1.0 - x) * exp (-2.0 * x * x);  
}

void Amplify (){
  
  vec2 UV = gl_FragCoord.xy / resolution.xy;
  gl_FragColor = texture2D(texture, UV);
  
  vec2 center = mouseData.xy;
  float dist = distance(gl_FragCoord.xy,center);
  
  vec2 distV = gl_FragCoord.xy - center;
  
  if (dist > radio && dist < radio + rim){
    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
  }
  
  if(abs(distV.x) < (handview.x / 2.0 ) && abs(distV.y + radio) < (handview.y) && dist >= radio + rim){
    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
  }
  
  if(dist < radio){
    vec2 trueUV = (gl_FragCoord.xy - (curveGen(distV,dist) * scale)) / resolution.xy ;
    gl_FragColor = texture2D(texture, trueUV);
  }
}

//--------------------------------------------------------------------------

void Convolution(){
  
    vec2 tc0 = texcoords2 + vec2(-texOffset.s, -texOffset.t);
    vec2 tc1 = texcoords2 + vec2(         0.0, -texOffset.t);
    vec2 tc2 = texcoords2 + vec2(+texOffset.s, -texOffset.t);
    vec2 tc3 = texcoords2 + vec2(-texOffset.s,          0.0);
    
    vec2 tc4 = texcoords2 + vec2(         0.0,          0.0);
    vec2 tc5 = texcoords2 + vec2(+texOffset.s,          0.0);
    vec2 tc6 = texcoords2 + vec2(-texOffset.s, +texOffset.t);
    vec2 tc7 = texcoords2 + vec2(         0.0, +texOffset.t);
    vec2 tc8 = texcoords2 + vec2(+texOffset.s, +texOffset.t);

    
    vec4 rgba[9];
    rgba[0] = texture2D(texture, tc0);
    rgba[1] = texture2D(texture, tc1);
    rgba[2] = texture2D(texture, tc2);
    rgba[3] = texture2D(texture, tc3);
    rgba[4] = texture2D(texture, tc4);
    rgba[5] = texture2D(texture, tc5);
    rgba[6] = texture2D(texture, tc6);
    rgba[7] = texture2D(texture, tc7);
    rgba[8] = texture2D(texture, tc8);

  
    vec4 convolution;
    for (int i = 0; i < 9; i++) {
      convolution += rgba[i]*mask[i];
    }

  
    gl_FragColor = vec4(convolution.rgb, 1.0); 
}

//--------------------------------------------------------------------------

float luma(vec3 texel){
    return 0.299 * texel.r + 0.587 * texel.g + 0.114 * texel.b;
  }

float favg(vec3 texel){
    return (texel.r + texel.g + texel.b ) / 3.0;
  }

float HSV (vec3 texel){
    return max(max(texel.r,texel.g),texel.b); ;
  }

float HSL (vec3 texel){
    float CMax = max(max(texel.r,texel.g),texel.b);
    float CMin = min(min(texel.r,texel.g),texel.b);
    return (CMax + CMin) / 2.0 ;
  }

float Ftint(float channel, float color){
    float N = channel * (color / 255.0);
    return N;
  }

void Coloring(){
  
  vec4 texel = texture2D(texture, texcoords2);
  
  if(grey_scale == true){
    gl_FragColor = vec4((vec3(luma(texel.rgb))), 1.0); 
  }else if(average == true){
    gl_FragColor = vec4((vec3(favg(texel.rgb))), 1.0); 
  }else if(HSVV== true){
    gl_FragColor = vec4((vec3(HSV(texel.rgb))), 1.0);
  }else if(HSLL== true){
    gl_FragColor = vec4((vec3(HSL(texel.rgb))), 1.0);
  }else if(Tint == true){
    gl_FragColor = vec4(Ftint(texel.r,colorT.x),Ftint(texel.g,colorT.y),Ftint(texel.b,colorT.z),1.0);
  }else{
    gl_FragColor = texel;  
  }
}

//--------------------------------------------------------------------------

void main() {
  
  if(maskmode == true){
    Convolution();
    Coloring();
  }else if(coloringmode == true){
    Coloring();
  }else if(lensemode == true){
    Amplify();
  }else{
    gl_FragColor = texture2D(texture, texcoords2);
  }
  
}