Connaissez-vous un algorithme qui affiche une image de 256 niveaux de gris, mais seulement en utilisant des pixels soit noirs, soit blancs ?
Cet algorithme devrait utiliser le dithering : mais comment décider du nombre de pixels noirs et blancs constituant un niveau de gris précis ? Et aussi : comment le dithering peut-il permettre dessiner chacun des 256 niveaux de gris ?
Tu as le ratio pixel noir / pixel blanc à avoir sur ce pixel.
Après il faut que tu saches en combien de "sous-pixel" tu veux découper ton pixel d’origine
Par exemple, en découpant le gros pixel gris (100,100,100) en 51x51 "sous-pixel" j’obtiens ca :
Tu as le ratio pixel noir / pixel blanc à avoir sur ce pixel.
Parce que 255 = blanc et 0 = noir ?
Pas exactement, en RVB les couleurs vont de 0 à 255 : 0 étant « pas de cette couleur » et 255 « cette couleur au maximum ». Par exemple : (255,0,255) c’est maximum de rouge et de bleu, donc du violet ; (0,0,0) c’est rien de rouge, vert et bleu, donc du noir ; et (255,255,255) c’est du blanc.
Quand tu mélanges équitablement du rouge, vert et du bleu, tu as du gris :). D’où le fait que du gris en RVB c’est un triplet (X,X,X).
Donc diviser X par 255 donne le ratio "pixels blancs/ pixels noirs" plutôt non ?
Non. Si tu as 240/255, alors tu as beaucoup plus de blanc que de noir dans ton pixel.
Après il faut que tu saches en combien de "sous-pixel" tu veux découper ton pixel d’origine
Ce nombre de sous-pixels détermine quel gris appliquer (plus ou moins foncé) ?
Non. Le dithering, de ce que j’ai compris, c’est mélanger plusieurs pixel pour avoir l’impression d’en avoir qu’un seul d’une autre couleur (cf. l’image que tu donnes en exemple). Le nombre de sous pixel c’est pour savoir si tu divises ton pixel d’origine en 4, 16, 32, etc. petit carré.
C’est à toi d’apprécier ca il me semble. Encore une fois dans ton exemple, quand tu prends que 4 carrés, ca fait pas du violet, mais celui en bas à droite ressemble beaucoup plus à du violet.
Tout à fait d’accord. Ce que j’ai fait c’est : alterner pixel blanc/pixel noir, ca donne un damier, puis changer aléatoirement le des pixels pour trouver la nuance de gris qu’il faut. Y’a certainement plus malin.
Tout à fait d’accord. Ce que j’ai fait c’est : alterner pixel blanc/pixel noir, ca donne un damier, puis changer aléatoirement le des pixels pour trouver la nuance de gris qu’il faut. Y’a certainement plus malin.
Avec un damier avec la bonne proportion de noir/blanc ça n’irait pas ?
La bonne proportion, oui, mais la question est de comment répartir les noirs et les blancs. Si la répartition est régulière, on peut avoir un effet visuel non désiré (par exemple, si on a un carré 16x16, et qu’on a 1 point sur 3 en noir, on va voir des lignes en diagonale).
Généralement, une bonne solution est d’utiliser la fonction Gwend@l, mais on peut l’adapter.
Par exemple, sur un carré 16x16 (donc 256 pixels), on a déterminé qu’il faudrait idéalement 90 pixels noirs, la solution ’basique’ est :
1
2
3
pour i = 1 a 16
pour j = 1 a 16
si random(256) <= 90 alors noir sinon blanc
Une solution améliorée est :
1
2
3
4
5
6
7
8
9
10
cases_restantes = 256
cases_noires_restantes = 90
pour i = 1 a 16
pour j = 1 a 16
si random(cases_restantes) <= cases_noires_restantes alors
noir
cases_noires_restantes --
sinon
blanc
cases_restantes --
À débattre, j’en sais rien, mais il me semble que visuellement l’illusion marche mieux si c’est (proche d’) un damier. J’avais essayé purement aléatoire pour voir, mais on dirait un flash code
En matlab/octave c’est assez simple en plus !
1
2
3
4
5
6
7
8
9
10
gris=100;% la valeur de gris que tu veux, entre 0 et 255ratioNoirBlanc=gris/255;ligne=16;colonne=16;pixel=rand(ligne,colone);pixel(pixel>ratioNoirBlanc)=0;pixel(pixel<=ratioNoirBlanc)=1;imshow(pixel)
La bonne proportion, oui, mais la question est de comment répartir les noirs et les blancs. Si la répartition est régulière, on peut avoir un effet visuel non désiré (par exemple, si on a un carré 16x16, et qu’on a 1 point sur 3 en noir, on va voir des lignes en diagonale).
Dans ce cas là il faut augmenter le nombre de case jusqu’à ce que cela ne soit plus visible ?
En théorie, oui. En pratique, pas forcément. Ca dépend de la taille initiale de ton pixel (s’il fait 1cm² oui, faut le découper en petit morceau sinon ca va se voir…). Mais garde aussi à l’esprit que ca fait une image plus lourde à l’arrivée ! Tu remplaces 1 pixel par 4, 16, etc. pixels !
Tu négliges la profondeur d’un pixel dans cette remarque. Un pixel sur 256 niveaux de gris s’encode comme un octet. Si tes pixels ne contiennent que du noir ou du blanc tu peux en encoder 8 par octet.
Si on regarde attentivement la page Wikipédia, on peut lire ceci à propos d’un algorithme dit du "dithering" :
le tramage aléatoire ou tremblotement (dithering) […] compare la valeur de chaque pixel à un seuil aléatoire. Bien que cette méthode ne génère pas d’artefacts répétitifs, le bruit tend à déborder sur les détails de l’image.
Ainsi permet-il d’obtenir une image comme celle-ci : ici
Ok. Alors visiblement on ne parle pas de la même chose. Dans mon premier post j’explique comment approximer un pixel en nuance de gris par un ensemble de sous pixel noir et blanc.
Ici, ce que tu cherches toi à faire ce n’est pas exactement ca. Tu cherches à remplacer un pixel gris par un pixel noir ou blanc. Ce n’est pas la même chose. Du coup, pour ce que tu cherches à faire ton algorithme semble correct.
D’après mes souvenirs, Floyd-Steinberg fonctionne relativement bien et est très simple a implémenter.
EDIT: si l’image de départ est en RGB, pour faire du tramage en noir et blanc il faudra tout d’abord convertir les valeurs RGB en un scalaire d’une façon ou d’une autre (voir ici par exemple).
Connectez-vous pour pouvoir poster un message.
Connexion
Pas encore membre ?
Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte