Tuesday, May 21, 2013

Quitando la marca de agua


Desde hace unos años doy el curso de Procesamiento Digital de Imágenes, en la Facultad de Ciencias (UNAM), y en dicho curso se ven las diferentes técnicas que se usan para transformar imágenes, fotos, etcétera. Uno de los temas es el de la "marca de agua", que en esencia en un mensaje que se pone sobre la foto de manera que esté presente sin ocultar la imagen misma. Esto es como fusionar dos imágenes, una que contiene -por ejemplo- información de los derechos de la foto, o quién es el autor o el propietario de la misma, con la imagen per se. Por ejemplo, la siguiente imagen, de iStockPhoto, muestra la fotografía pero en medio tiene esa marca de agua inquitable. Podemos ver la fotografía y si queremos, podemos comprar la foto (la cual viene ya sin la marca de agua, desde luego).


Las marcas de agua digitales son muy fáciles de hacer y en general se utiliza un algoritmo, denominado como "image blending", el cual puede verse aquí (en Delphi 7):

begin
      //leemos pixel de la imagen 2
      L := Image2.Canvas.Pixels[x,y];
      B2 := ((L shr 16) and $FF);
      G2 := ((L shr 8) and $FF);
      R2 := (L and $FF);
   
      //leemos pixel de la imagen 1
      L := Image1.Canvas.Pixels[Xa,Ya];
      B1 := ((L shr 16) and $FF);
      G1 := ((L shr 8) and $FF);
      R1 := (L and $FF);

      //calculamos pixelblend para la imagen de salida
      blendpixelR := R1 * alpha + R2 * (1.0 - alpha);
      blendpixelG := G1 * alpha + G2 * (1.0 - alpha);
      blendpixelB := B1 * alpha + B2 * (1.0 - alpha);

      //pintamos pixel blended en imagen 3
      BlendPixelRi := trunc(BlendPixelR);
      BlendPixelGi := trunc(BlendPixelG);
      BlendPixelBi := trunc(BlendPixelB);

      Cuantos := RGB(BlendPixelRi,BlendPixelGi,BlendPixelBi);
      if ((B2=0) and (G2=0) and (R2=0))
         then Image3.Canvas.Pixels[xA,yA] := Cuantos //RGB(B1,G1,R1)
         else Image3.Canvas.Pixels[xA,yA] := RGB(R1,G1,B1);
     


Es decir, tomamos un pixel de cada imagen, y ponemos un porcentaje del primero en la imagen resultante y el resto del porcentaje del segundo pixel. Lo que se ve es que las imágenes se superponen como por ejemplo, en esta imagen:



Mediante esta técnica, por ejemplo, las empresas que venden fotos comerciales pueden sentirse seguras de que con la marca de agua evitan que la gente use sus fotografías sin pagar los derechos correspondientes.

Sin embargo, hay otras razones para poner esta marca de agua. Por ejemplo, en 1972, cuando se hizo en Reikjavyk, Islandia, el Campeonato Mundial de Ajedrez, entre Fischer y Spassky, Halldór Petursson (1916-1977), un artista local muy famoso, dibujó dieciocho estupendas caricaturas del denominado Match del Siglo.

Halldór Petursson, firmando un autógrafo


Hoy encuentro que la colección completa de las tarjetas postales de Petursson están a la venta (cuestan unos 250 dólares), y probablemente ya se vendieron, pues el anuncio ya tiene mucho tiempo en esta página.

Sin embargo, quien las vendía puso las imágenes de cada postal con una marca de agua que dice "PREVIEW". Así, se pueden ver las ilustraciones sin temor a que se las "roben" o "pirateen". Evidentemente tener las imágenes originales sería sensacional, pero la verdad es que no estoy dispuesto -si es que aún se venden- a pagar esa cantidad.

Entonces pensé que quizás podría eliminar la marca de agua. Finalmente doy un curso de proceso digital de imágenes y entiendo de estos temas. Con esto en mente me senté a analizar las fotografías de las postales, usando para ello Photoshop.

Hallé que, aunque son en blanco y negro, el escaneo de las imágenes se hizo en color (por ello la palabra PREVIEW se ve en un rojo claro). Si las originales hubiesen sido escaneadas en tonos de grises y de ahí puesta la marca de agua, el proceso de quitar la misma sería fácil, pues cada pixel -en blanco y negro- tendría el mismo valor para el Rojo - (R)ed, Verde - (G)reen y Azul (B)lue, en el dibujo. Hallé pues que cada pixel en tono de gris corresponde a casi el tono de gris, con R casi igual a G y casi igaul a B. Distan por una o dos unidades.

Considerando esto mi plan fue entonces:

  • Leer la imagen original
  • Leer cada pixel y ver si se trata de un pixel en tono de gris, por lo que asumí que la diferencia entre las componentes de color no pasaría de unas 5 unidades
  • Si es un pixel en blanco y negro, lo dejo igual. En caso contrario, lo paso a blanco (R=G=B=255).

Realizo este proceso en toda la imagen.

Hallé que las cosas casi  funcionaron correctamente. Desafortunadamente el blanco en un pixel de color rojo lo quitaba, pero si atrás había un punto oscuro, entonces éste era totalmente eliminado.

Decidí entonces sacar un promedio y probar. En lugar de poner un pixel blanco donde hay uno de color rojo, puse la suma de (R+G+B) / 3 y hallé que esto aclaró la marca de agua, pero no lo suficiente. Entonces le agregué una constante, que es el brillo y entonces el proceso quitó casi "mágicamente", la marca de agua de cada postal.

He aquí un par de ejemplos del proceso (dé click para hacerlas más grandes). Las imágenes completas las puse en el blog de fotos de Bobby Fischer, por quien le interese verlas.





El software -a quien le interese ver qué hice ya en términos de código- puede pedírmelo  a morsa@la-morsa.com y a vuelta de correo lo tendra de forma gratuita. La opción de quitar la marca de agua solamente funciona para las postales de Petursson, pero enseña la idea detrás del proceso.

No comments: