Contactez-nous

1

Renforcer la netteté d’une image

30 juin 2006
par ARNO*

[SPIP 1.9 et GD2] Cela fait des semaines que je cherche un algorithme pour renforcer la netteté d’une image. Quelqu’un m’avait dit « La netteté, c’est comme le flou, mais dans l’autre sens »... D’accord, mais ça ne fait pas un algorithme...

Et aujourd’hui, je suis tombé sur l’excellente classe ImageFilter de Mathieu Delestre. J’y ai trouvé le principe d’un filtre simplifié permettant d’accentuer la netteté.

Adapté pour fonctionner avec SPIP, cela donne :

  1. function image_renforcement($im, $k=0.5)
  2. {
  3. $image = valeurs_image_trans($im, "renforcement-$k");
  4. if (!$image) return("");
  5.  
  6. $x_i = $image["largeur"];
  7. $y_i = $image["hauteur"];
  8. $im = $image["fichier"];
  9. $dest = $image["fichier_dest"];
  10. $creer = $image["creer"];
  11.  
  12. if ($creer) {
  13. $im = $image["fonction_imagecreatefrom"]($im);
  14.  
  15. $im_ = imagecreatetruecolor($x_i, $y_i);
  16. @imagealphablending($im_, false);
  17. @imagesavealpha($im_,true);
  18. $color_t = ImageColorAllocateAlpha( $im_, 255, 255, 255 , 127 );
  19. imagefill ($im_, 0, 0, $color_t);
  20.  
  21. for ($x = 0; $x < $x_i; $x++) {
  22. for ($y=0; $y < $y_i; $y++) {
  23.  
  24. $rgb[1][0]=imagecolorat($im,$x,$y-1);
  25. $rgb[0][1]=imagecolorat($im,$x-1,$y);
  26. $rgb[1][1]=imagecolorat($im,$x,$y);
  27. $rgb[2][1]=imagecolorat($im,$x+1,$y);
  28. $rgb[1][2]=imagecolorat($im,$x,$y+1);
  29.  
  30.  
  31. if ($x-1 < 0) $rgb[0][1] = $rgb[1][1];
  32. if ($y-1 < 0) $rgb[1][0] = $rgb[1][1];
  33. if ($x+1 == $x_i) $rgb[2][1] = $rgb[1][1];
  34. if ($y+1 == $y_i) $rgb[1][2] = $rgb[1][1];
  35.  
  36. $a = ($rgb[0][0] >> 24) & 0xFF;
  37. $r = -$k *(($rgb[1][0] >> 16) & 0xFF) +
  38. -$k *(($rgb[0][1] >> 16) & 0xFF) +
  39. (1+4*$k) *(($rgb[1][1] >> 16) & 0xFF) +
  40. -$k *(($rgb[2][1] >> 16) & 0xFF) +
  41. -$k *(($rgb[1][2] >> 16) & 0xFF) ;
  42.  
  43. $g = -$k *(($rgb[1][0] >> 8) & 0xFF) +
  44. -$k *(($rgb[0][1] >> 8) & 0xFF) +
  45. (1+4*$k) *(($rgb[1][1] >> 8) & 0xFF) +
  46. -$k *(($rgb[2][1] >> 8) & 0xFF) +
  47. -$k *(($rgb[1][2] >> 8) & 0xFF) ;
  48.  
  49. $b = -$k *($rgb[1][0] & 0xFF) +
  50. -$k *($rgb[0][1] & 0xFF) +
  51. (1+4*$k) *($rgb[1][1] & 0xFF) +
  52. -$k *($rgb[2][1] & 0xFF) +
  53. -$k *($rgb[1][2] & 0xFF) ;
  54.  
  55. $r=min(255,max(0,$r));
  56. $g=min(255,max(0,$g));
  57. $b=min(255,max(0,$b));
  58.  
  59.  
  60. $color = ImageColorAllocateAlpha( $im_, $r, $g, $b , $a );
  61. imagesetpixel ($im_, $x, $y, $color);
  62. }
  63. }
  64. $image["fonction_image"]($im_, "$dest");
  65. }
  66.  
  67. $class = $image["class"];
  68. if (strlen($class) > 1) $tags=" class='$class'";
  69. $tags = "$tags alt='".$image["alt"]."'";
  70. $style = $image["style"];
  71.  
  72. return "<img src='$dest'$tags />";
  73. }

Télécharger

La variable que l’on peut passer représente l’intensité de l’action :
— 0, pas d’accentuation ;
— 1, très (trop) forte accentuation.

La valeur idéale semble se situer entre 0.2 et 0.3.

L’utilité de ce filtre se révèle particulièrement sur les images réduites : la réduction provoque un léger floutage de l’image, et il est très utile d’apporter ensuite une légère accentuation de la netteté.

Par exemple, sur un document :

  1. [(#FICHIER|image_aplatir{png}|image_reduire{400})]
  2. [(#FICHIER|image_aplatir{png}|image_reduire{400}
  3. |image_renforcement{0.3})]

Télécharger

Notez que je convertis l’image au format PNG avant la réduction : sinon, en partant d’une image JPEG, on effectuerait 3 sauvegardes successives au format JPEG, et le renforcement de netteté ferait énormément ressortir les artefacts (défauts) dus à la compression.

Voici la première image : un fichier passé en PNG puis réduit :

L’image, après renforcement de la netteté, devient :

La différence me semble assez... nette.


Le réglage de l’intensité est assez délicat. On peut considérer en général :
— qu’une image très réduite, donc de très petite taille, aura besoin d’une accentuation plus importante (plus de 0,3) ;
— qu’une image peu réduite utilisera une faible accentuation de netteté (inférieure, voire très inférieure, à 0,3).

  • JLuc
    Janvier 2007

    Vu tes explications, ne faudrait il pas que la valeur par défaut soit 0,3 voire 0,25 plutôt que 0,5 ?

  • Zéas
    Mars 2007

    Salut (et merci pour tout ça).

    Quand j’essaye de faire fonctionner ce filtre, j’ai le message d’erreur suivant :

    Fatal error : Call to undefined function : a()

    qui fait référence à la ligne :

    $im = $image["fonction_imagecreatefrom"]($im) ;

    J’ai mal fait quelque-chose ? Ou bien est-ce parce que j’essaye d’appliquer le filtre à une image typo ?

  • ARNO*
    Mars 2007

    @Zéas :

    C’est un bug de la 1.9.1. Essaie avec SPIP 1.9.2 qui vient de sortir, elle corrige ce comportement.

  • Zéas
    Mars 2007

    OK merci pour cette réponse rapide.

    C’est vrai que je dois faire ça. Je vais passer directement à la toute récente 1.9.2a je crois. J’ai cru comprendre qu’elle était rapidement sortie après la 1.9.2 pour corriger pas mal de bugs.

  • Micheline
    Mai 2007

    Bonjour,

    Je m’appelle micheline et j’aimerais trouver des personnes qui pourraient me renforcer la netteté d’une photo au maximum. Très important pour moi car il s’agit d’une photo de mon copain dcd et je n’ai que celle-la alors s’il vous plait soyez sympa faites ca pour moi ? parceque moi en informatique et correction je suis complètement nulle. Merci pour ce que vous pourrez faire.

  • Juillet 2007

    J’ai lu avecintérêt ce que vous faites mais j’ai cependant une question : comment faire pour utiliser cela SANS que Spip s’y mêle ?

    Car apparement valeurs_image_trans() appartient à SPIP ?

    Merci d’avance

  • ARNO*
    Juillet 2007

    Il suffit de faire une fonction similaire (et plus simple, la nouvelle version est très complexe et liée au fonctionnement de SPIP).

    Voyez les variables retournées, elles sont assez simples :
    - "creer" gère le cache : si l’image destination existe déà, alors creer=false de façon à ne pas recalculer ; sinon creer=true ;
    - "fonction_imagecreatefrom" et "fonction_image" sont simplement le nom des fonctions GD d’ouverture et de création des images selon le format (JPG, PNG...) ;
    - les autre valeurs me semblent assez claires.

  • Mortimerpc
    Octobre 2010

    Bonjour à tous, Pourriez-vous me dire si à votre connaissance, il existe un traitement qui permette de trier automatiquement des images en foction de leur netteté. Merci d’avance

Qui êtes-vous ?
Votre message

Ce formulaire accepte les raccourcis SPIP [->url] {{gras}} {italique} <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.