next up previous contents
Next: Reducción de ruido Up: Ondículas en la Informática Previous: Comparaciones

Editar imágenes

aplicamos las ondículas (principalmente las ondículas de Haar) para editar/pintar imágenes

en el campo de pintar imágenes se distingue normalemente entre dos tipos de imágines

cualquier cambio de resolución de imágenes basadas en un mapa de píxeles necesita un proceso de filtrado y/o interpolación, para evitar la aparencia de bloques grandes o efectos de ``aliasing''

cambiar la resolución de imágenes basadas en objetos resulta más fácil porque se puede trasladar la operación al objeto, sin embargo, es muy difícil conseguir un cambio apropriado de propriedades que no sean basadas en una descripción unidimensional (p.ej., cambiar el patrón del relleno)

unas propriedades avanzadas para un programa de pintar serían:

la idea principal consiste en usar la ondícula de Haar y la descomposición jerárquica (que resulta en una representación en forma de un árbol cuaternario o ``quadtree'')

se obtiene las siguientes ventajas:

las aplicaciones de tal sistema son más amplias

confinamos la discusión a imágenes cuadráticas con resoluciones de potencias de dos y no consideramos la extración eficiente de regiones

la estructura de datos del árbol cuaternario con los coeficientes de la descomposición se puede implementar como

class {
  rgba c;
  node root;
} quad_tree;

class {
  rgba      d[3];
  real      tau;
  quad_node child[4];

  rgba Decompose(int j, int x, int y);
  void Display(rgba c, int j) const;
  void DrawArea(rgba c) const;
  void Extrapolate(operation op, int x, int y);
  bool IsLeaf() const;
  int  Level() const;
} quad_node;

donde rgba es el tipo de datos de un pixel con sus cuatro canales rojo, verde, azul y alpha, y operacion es el tipo de datos para las operaciónes de pintar

la variable miembro tau será útil para la composición transparente que asumimos inicializada a 1

los coeficientes d[i] en cada nodo del árbol se obtienen calculando la descomposición jerárquica basado en la ondícula de Haar

cada nodo del árbol representa un área de la imagen, no hace falta guardar dicha área explícitamente porque sus coordenadas se puede derivar de la posición del nodo en el árbol

sin entrar en detalles asumimos que tengamos varios métodos

DrawArea(rgba c):
dibuja el área del nodo con el color pasado como parámetro
IsLeaf():
devuelve si el nodo es una hoja
Level():
devuelve el nivel del nodo en el árbol

el valor c de la raíz representa la media de todos los píxeles de la imagen

el árbol no está desarrollado al completo, nodos que contengan solamente coeficientes igual a cero están representados por punteros a nil

para editar una imagen hace falta tres operaciones básicas: visualizar, pintar, y actualizar (nota que no optimizamos para restringir las operaciones a la ventana/región donde de verdad hay que actuar)

visualizar:
si se quiere visualizar la imagen a nivel $j$, es decir, en resolución $2^j\times 2^j$ se llama a la siguiente rutina recursiva:

void quad_node::Display(
  rgba c,
  int  j
) {
  rgba ci[4];
  ci[0]=c+d[0]+d[1]+d[2];
  ci[1]=c-d[0]+d[1]-d[2];
  ci[2]=c+d[0]-d[1]-d[2];
  ci[3]=c-d[0]-d[1]+d[2];
  for(int i(0); i<4; i++)
    if(IsLeaf() || Level()==j)
      child[i].DrawArea(ci[i]);
    else
      child[i].Display(ci[i],j+1);
}

es decir, se visualiza el área cuando se haya llegado o bien a una hoja del árbol o bien al nivel deseado, el color que se usa para visualizar se calcula acumulando los detalles de cada nodo

nota que se hace como mucho una operación por pixel

pintar:
las operaciónes se realiza de la siguiente manera

(falta descripción)

actualizar:

(falta descripción)

rgba quad_node::Decompose(
  int j,
  int x,
  int y
) {
  if(Level()==j) return R.C(x,y);
  rgba ci[4];
  for(int i(0); i<4; i++)
    ci[i]=child[i].Decompose(j,x,y);

  d[0]=(ci[0]-ci[1]+ci[2]-ci[3])/4;
  d[1]=(ci[0]+ci[1]-ci[2]-ci[3])/4;
  d[2]=(ci[0]-ci[1]-ci[2]+ci[3])/4;
  return (ci[0]+ci[1]+ci[2]+ci[3])/4;
}

(falta descripción)

void quad_node::Extrapolate(
  operation op,
  int       x,
  int       y
) {
  for(int i(0); i<3; i++)
    switch(op) {
      case over: 
        d[i]*=1.0-F(x,y).c.alpha;
        break;
      case under:
        d[i]-=d[i].alpha*F(x,y).c;
        break;
      case in:   
        d[i] =d[i]*(1.0-F(x,y).c.alpha)+d[i].alpha*F(x,y).c;
        break;
      case erase:
        d[i]*=1.0-F.delta(x,y);
        break;
    }
  if(!IsLeaf())
    for(int i(0); i<4; i++)
      child[i].Extrapolate(op,x,y);
}

(falta descripción)

pintar en multiresolucion: http://www.cs.unc.edu/~ scheib/school/236/project/


next up previous contents
Next: Reducción de ruido Up: Ondículas en la Informática Previous: Comparaciones
© 2002, Dr. Arno Formella, Universidad de Vigo, Departamento de Informática