Compressió fractal d'imatges

La teoria de fractals és apassionant, i la seva aplicació a la compressió d'imatges, quant menys, interessant

Descripció

Amb l'aplicació podràs:

  • Comprimir imatges amb aquest mètode fractal
  • Descomprimir imatges prèviament comprimides a un altre format d'imatge

Fa ús de les llibreries de plataforma, amb les següents característiques:

  • Multi-idioma
  • Multi-resolució (zoom configurable)
  • Opció de mode fosc
  • Notificació de nova versió


Ventajas:

  • Si es programa bé, és independent de la resolució de la imatge
  • És un mètode de compressió molt exòtic
  • Permet aprendre pel camí


Desavantatges:

  • El procés de compressió es molt lenttttt
  • No s'aconsegueixen ratis de compressió molt grans (al menys amb els paràmetres que jo he fet anar)

Descripció del codi

És una implementació d'aquest article algoritme de compressió fractal d'imatges publicat a l'IEEE a la meva època universitària

Es fa ús de la llibrería de triangulació incremental de Delaunay utilitzada a l'aplicació de Morphing


Algoritme a alt nivell:

  • Compressió:
    • La compressió fractal es caracteritza per què no es guarden valors de píxels, si no relacions entre regions de la imatge (entre triangles, en aquest cas).
    • Es divideix la imatge en una triangulació, amb els triangles de domini.
    • Es divideix la imatge en una altra triangulació, amb els triangles (més grans) per al codebook.
    • Les triangulacions són dinàmiques, es fa ús de l'algoritme split and merge en funció de la variança dels pixels dels triangles.
    • Un cop s'ha obtingut la triangulació per al codebook, d'escullen els 2^n triangles més representatius, que seràn el codebook, on el valor de n incidirà dràsticament en el temps de compressió, y una mica en al rati de compressió i en la qualitat obtinguda.
    • Després, per a cada triangle del domini, es busca el mapeig òptim amb un triangle del codebook (amb un criteri de mínim error quadratic mig (MSE))
    • El mapeig óptim de triangles es busca fent combinacions de:
      • Permutacions dels vèrtex (6 posibilidades)
      • Buscant un offset per a la mitjana
      • Buscant un factor d'escala entre 0 i 1 per a aplicar-lo a la desviació de la mitja (entre 0 y 1, per a evitar la divergencia al procés iteratiu de descompressió)
      Aquests paràmetres hauran de quantitzar-se amb pocs bits, per a que el temps i el rati de compressió siguin raonables, en compromís amb la qualitat obtinguda
  • Informació guardada a l'arxiu comprimit per a cada un dels canals:
    • Informació per a reproduir les dues triangulacions:
      • Triangles que fan split a cada iteració
      • Vèrtex extrets pel procediment de merge (al final de les iteracions de split)
    • L'elecció dels 2^n triangles del codebook
    • El mapeig óptim de cada triangle de domini:
      • Amb quin triangle del codebook mapeja (n bits)
      • La permutación de vèrtex óptima (6 combinaciones, 3 bits)
      • Offset (els autors indiquen que 6 bits és un bon compromís)
      • Escala (els autors indiquen que 6 bits és un bon compromís)
  • Descompressió (per a cada canal):
    • S'obtenen els triangles de les dues triangulacions.
    • S'obtenen els triangles del codebook.
    • S'itera fins a que hi hagi convergència:
      • El mapeig de tots els triangles de domini, des de els seus mapejos optims amb els triangles del codebook


Després de fer el màster d'I.A., em veig en condicoins d'innovar en l'obtenció dels triángles més representatius per al codebook, aplicant ni més ni menys que un K-medoids.

La innovació no se si millora o si empitjora l'algoritme, però evita que tingui que programar-lo jo (que a simple vista semblava difícil de programar).


Es divideix el processament en els diferents canals de la imatge (normalmente RGB).

Es fa ús de multiprocès (un fil per a cada canal).


Amb la versió v1.1, s'afegeix un reader compatible amb l' ImageIO estàndar.

Així doncs, podràs obrir una imatge comprimida amb l'aplicació (.dfc) simplement fent:

BufferedImage image = ImageIO.read("image.dfc");

Pantalles

Compressió fractal d'imatges v1.0 (2022-2024)

Veure video
Descarregar

Compressió fractal d'imatges v1.1 (2026)

Descarregar

Versions

image

L'aplicació és la implementació d'un algoritme de Compressió Fractal d'imatges explicada en un article d'IEEE de la meva època universitaria, basat en la triangulació de Delaunay i en codificació per blocs.

La meva primera versió d'aquest algoritme la vaig programar conjuntament amb un company d'universitat en una pràctica de l'assignatura de Televisió de l'últim curs de Teleco (plan 64 de Barcelona).

Internet encara estaba en els seus començaments i la programació depenia gairebé únicament d'un mateix i dels documents físics que poguessis aconseguir.

Me'n recordo d'haver programat una triangulació de Delaunay que no estava malament del tot, i que vam programar el split and merge, el càlcul dels triangles més representatius i també el càlcul dels mapejos òptims de triangles durant la codificació, però no vam aconseguir acabar l'aplicació (després d'haver-li dedicat tres mesos intensius de programació)

25 anys després, arriba una nova implementació de l'algoritme, aquest cop complerta, i en el temps rècord de dues setmanes

Està clar que alguna cosa s'aprèn en 25 anys, i a més, aquest cop amb la posibilitat de reutilitzar funcions per a manipular triangles que ja havia programat per a l'aplicació d'efecte de Morphing

I fent servir aquest cop, una llibrería de triangulació de Delaunay programada per professionals

Està clar que quan no tens que construir-te els maons, les parets creixen més ràpid ...


Vídeo de demostració

image

La novetat de la versió v1.1 és que afegeix un reader d'imatges comprimides fractalment amb la aplicació que és compatible amb ImageIO.

Així doncs es pot llegir una imatge comprimida amb l'aplicació (.dfc) d'aquesta manera:


BufferedImage image = ImageIO.read("image.dfc");


A la comparativa de la imatge en .jpg i al format de l'aplicació .dfc, es pot observar que la qualitat és pitjor que la de .jpg y que ocupa una mica més (com era d'esperar).

Però el resultat no està malament del tot.

Encara que donat l'alt temps de procesament que es pren per a comprimir, aquest tipus de compressió i la seva implementació a l'aplicació solo només tenen cert interés acadèmic.


05/04/2026 - 12/04/2026. Després d'haver recuperat l'evolució d'aquesta aplicació, em proposo fer proves amb imatges de veritat, i la provo amb una de "4000 x 3000" pixels.

Em trobo amb molts problemes:

  • El procés s'eternitza a les iteracoins de split (degut a les extenses triangulacions de fins al voltant de 400.000 triangles, i que es repetia la comprobació de la condició de split per a tots el triangles a cada iteració)
  • La memòria s'exhaureix desprès d'arribar al límit de 23 GB que tenia al meu sistema. Degut a que:
    • El resultat de les iteracions de split i merge es guardaven a una llista de boolean (al voltant de 16 iteracions x 2 tipus de triangulacions x 3 canals x 400.000 elements !!!!). Aixó fa un total de al voltant de 40.000.000 d'elements, cosa encara assumible)
    • A més, l'elecció del book de triangles més representatius (configurat a fog a 256), es feia amb un K-medoids (sobre 400.000 elements) (crec que la memòria necessària per aquest algorisme es O(n^2). Ara si que ja sens va de les mans ...)
    • I, per a més INRI, es feien aquest càlculs en paral.lel per als tres canals (rgb) !!
  • Un cop solucionats aquest problemes, aconsegueixo que es comprimeixi la imatge de (4000 x 3000), però veig que tarde entre 6 y 8 hores a fer el treball.

I em proposo solucionar-los:

  • Per a l'eternització dels split. Solució:
    • Augment de la mida mínima dels triangles per a fer split, de manera esglaonadamente proporcional al número de píxels de la imatge. Que resulta en una rebaixa del número de triangles de les triangulacions. A la imatge d'exemmple (4000 x 3000) es divideix el número de triangles per més de 4 (passem d'uns 400.000 triangles a uns 100.000 triangles).
    • A més, creo un Set amb els triangles que no compleixin amb el criteri de split (relatius a la variància dels valors dels seus píxels), per a no repetir-los a cada iteració. Ara vola !!
  • S'exhaureix la memòria del sistema. Solució:
    • Resultat de splits i merges guardats a llistes de booleans. Solució:
      • Com a mida que avancen les iteracions ds split, el número de triangles que fan split es radicalment més petit, s'estalvia memòria guardant els índex dels triangles que fan split en un Set.
    • Memòria de K-medoids (presumiblemente O(n^2)). Solució:
      • Com hem dividir el número de triangles 4 ..., la memória necessària per a aquest algorisme, aquesta reducció de triangles implica dividir la memòria ocupada per un factor de al voltant de 16.
    • Tres K-medoids en paral.lel (un per a cada canal). Solució:
      • Seqüenciarem els cálculs de les triangulacions i de l'elecció dels triangles més representatius per al code-book (amb K-medoids).
    • Hem dividit la memòria necessparia per al K-medoids per 48!!
  • El temps de processament amb imatges "de veritat", s'eternitza (la compressió de la imatge d'exemple tarda entre 6 y 8 hores) amb 3 fils, un per a cada canal. Solució:
    • Fer configurable el número de fils. (Configurant-lo a 23 fils (el meu sistema té 24 cores), el temps de processament es redueix a tres hores i mitja).
  • Efectes de la solució:
    • L'efecte de dividir el número de triangles per 4 es tradueix, evidentement, en una pèrdua notable de la qualitat de la imatge comprimida. Però en tenir tanta resolució, doncs no és tan important.
    • En dividir el número de triangles per 4, també es produeix que es divideixi la mida de l'arxiu comprimit, suposadament de l'ordre de per 4.

També em poso com a objetiu intentar minimizar la mida de l'arxiu comprimit, reorganitzant la informació a guardar.

La idea és indicir sobre tot a la codificació de les llistes d'index dels triangles que fan split a cadascuna de les iteracions, que la codificació original trivial era guardar un bit per triangle, indicant si feia split o no.

Penso un algorisme per a tractar de minimitzar el número de bits necesari per a guardar cadascun d'aquests índex.

Crec que no té desperdici ... si tens curiositat a aquest lloc web parlo dels punts clau en els que m'he basat.

Encara que potser hagés valgut més la pena buscar un compressor general sense pèrdues tipus zip o 7z i aplicar-lo a la globalitat de l'arxiu comprimit ... Potser per a la propera.


A l'última versió de l'entrega s'inclou una aplicació d'interfície de comandes, que tradueix un arxiu creat amb versions del codificador menys optimitzades, a l'última versión del codificador, que presumiblement ocupa menys.

En la última versión de la aplicación se incluye una aplicación de interfaz de comandos, que traduce un archivo creado con versiones del codificador menos optimizadas, a la última versión del codificador.

Provant aquest petita nova aplicació sobre un parell d'arxius amb la codificació original (un de 143x143 i un altre de 4000x3000), es veu que la mida de l'arxiu comprimit es redueix al voltant d'un 4% en ells.

Videos

Descàrregues