Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

CONVERTIR UNE IMAGE EN NIVEAU DE GRIS


Information sur la source

Catégorie :Graphique Source .NET ( DotNet ) Classé sous : image, gris, niveau, conversion Niveau : Débutant Date de création : 06/10/2006 Date de mise à jour : 06/10/2006 15:43:56 Vu : 11 048

Note :
8 / 10 - par 2 personnes
8,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (8)
Ajouter un commentaire et/ou une note

Description

On peut convertir une image couleur en niveau de gris via une formule empirique liée aux composantes Bleu, vert, Rouge de l'image :

0.3 * bleu + 0.59 * vert + 0.11 rouge = niveau de gris

Cette formule peut être très largement améliorée, pour ne pas multiplier des nombres à virgules ( ce qui est coûteux en performance), en multipliant les coefficients par 256. On redivise le tout par 256 par la suite.
 

Source

  • Dim bitmaptest As Bitmap = New Bitmap("d:\image.jpg")
  • Dim bitmap As Bitmap = New Bitmap(bitmaptest) 'transforme en 32 bits :)
  • Dim width As Integer = bitmap.Width
  • Dim height As Integer = bitmap.Height
  • 'création de l'image 8 bits contenant le résultat
  • Dim bitmapNivGris As Bitmap = New Bitmap(width, height, PixelFormat.Format8bppIndexed)
  • 'Récupération de la palette 256 couleurs
  • Dim pal As ColorPalette = bitmapNivGris.Palette
  • Dim i As Integer
  • 'Redéfinition de la palette
  • For i = 0 To 255
  • pal.Entries(i) = Color.FromArgb((255 << 24) Or (i << 16) Or (i << 8) Or i)
  • Next
  • 'Réaffectation de la palette à l'image
  • 'car on ne possédait pas une référence (utilisez Reflector sur la Palette pour comprendre)
  • bitmapNivGris.Palette = pal
  • 'Lockbits des images initial et résultat
  • Dim bmpDataOld As BitmapData = bitmap.LockBits(New Rectangle(0, 0, width, height) _
  • , System.Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb)
  • Dim bmpDataNew As BitmapData = bitmapNivGris.LockBits(New Rectangle(0, 0, width, height) _
  • , ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed)
  • 'Copie des pixels dans un tableau contenant tous les composantes Bleu, vert, rouge, alpha
  • Dim oldPixel(width * height - 1) As Integer '4 octets = 4 composantes = 1 pixel
  • Marshal.Copy(bmpDataOld.Scan0, oldPixel, 0, oldPixel.Length)
  • Dim newPixel(bmpDataNew.Stride * height - 1) As Byte '1 octet = 1 pixel
  • 'Pas necessaire de recuperer les donnees de l'image vierge par un Marshal.Copy :-)
  • Dim locOld, x, y As Integer
  • 'tables de precalcul des multiplications pour le calcul de localisation des pixels
  • 'de l'ancienne image et de la nouvelle.
  • Dim multiOld(height - 1) As Integer
  • Dim multiNew(height - 1) As Integer
  • For y = 0 To height - 1
  • multiOld(y) = width * y
  • multiNew(y) = bmpDataNew.Stride * y
  • Next
  • 'tables de precalcul des multiplications pour le calcul du niveau de gris
  • Dim tabBleu(255) As Integer
  • Dim tabVert(255) As Integer
  • Dim tabRouge(255) As Integer
  • 'Initialisation
  • For y = 0 To 255
  • tabBleu(y) = 76 * y
  • tabVert(y) = 151 * y
  • tabRouge(y) = 28 * y
  • Next
  • For y = 0 To height - 1
  • For x = 0 To width - 1
  • 'calcul de la localisation du pixel
  • locOld = multiOld(y) + x
  • 'on calcule le niveau de gris sur 255
  • 'Formule ci-dessous en commentaires, à éviter car coûteuse
  • 'CByte(0.3 * oldPixel(loc) + 0.59 * oldPixel(loc + 1) + 0.11 * oldPixel(loc + 2))
  • 'on affecte le niveau de gris au pixel dans la nouvelle image
  • newPixel(multiNew(y) + x) = (tabBleu(oldPixel(locOld) And &HFF) + tabVert((oldPixel(locOld) And &HFF00) >> 8) + tabRouge((oldPixel(locOld) And &HFF0000) >> 16)) >> 8
  • Next
  • Next
  • 'on recopie notre nouveau tableau dans la nouvelle image
  • Marshal.Copy(newPixel, 0, bmpDataNew.Scan0, newPixel.Length)
  • bitmapNivGris.UnlockBits(bmpDataNew)
  • bitmap.UnlockBits(bmpDataOld)
Dim bitmaptest As Bitmap = New Bitmap("d:\image.jpg")
        Dim bitmap As Bitmap = New Bitmap(bitmaptest) 'transforme en 32 bits :)

        Dim width As Integer = bitmap.Width
        Dim height As Integer = bitmap.Height

        'création de l'image 8 bits contenant le résultat
        Dim bitmapNivGris As Bitmap = New Bitmap(width, height, PixelFormat.Format8bppIndexed)

        'Récupération de la palette 256 couleurs
        Dim pal As ColorPalette = bitmapNivGris.Palette

        Dim i As Integer
        'Redéfinition de la palette
        For i = 0 To 255
            pal.Entries(i) = Color.FromArgb((255 << 24) Or (i << 16) Or (i << 8) Or i)
        Next
        'Réaffectation de la palette à l'image 
        'car on ne possédait pas une référence (utilisez Reflector sur la Palette pour comprendre)
        bitmapNivGris.Palette = pal

        'Lockbits des images initial et résultat
        Dim bmpDataOld As BitmapData = bitmap.LockBits(New Rectangle(0, 0, width, height) _
        , System.Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb)
        Dim bmpDataNew As BitmapData = bitmapNivGris.LockBits(New Rectangle(0, 0, width, height) _
        , ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed)

        'Copie des pixels dans un tableau contenant tous les composantes Bleu, vert, rouge, alpha
        Dim oldPixel(width * height - 1) As Integer '4 octets = 4 composantes = 1 pixel
        Marshal.Copy(bmpDataOld.Scan0, oldPixel, 0, oldPixel.Length)

        Dim newPixel(bmpDataNew.Stride * height - 1) As Byte '1 octet = 1 pixel
        'Pas necessaire de recuperer les donnees de l'image vierge par un Marshal.Copy :-)

        Dim locOld, x, y As Integer

        'tables de precalcul des multiplications pour le calcul de localisation des pixels
        'de l'ancienne image et de la nouvelle.
        Dim multiOld(height - 1) As Integer
        Dim multiNew(height - 1) As Integer

        For y = 0 To height - 1
            multiOld(y) = width * y
            multiNew(y) = bmpDataNew.Stride * y
        Next

        'tables de precalcul des multiplications pour le calcul du niveau de gris
        Dim tabBleu(255) As Integer
        Dim tabVert(255) As Integer
        Dim tabRouge(255) As Integer

        'Initialisation
        For y = 0 To 255
            tabBleu(y) = 76 * y
            tabVert(y) = 151 * y
            tabRouge(y) = 28 * y
        Next

        For y = 0 To height - 1

            For x = 0 To width - 1
                'calcul de la localisation du pixel
                locOld = multiOld(y) + x
                'on calcule le niveau de gris sur 255 
                'Formule ci-dessous en commentaires, à éviter car coûteuse
                'CByte(0.3 * oldPixel(loc) + 0.59 * oldPixel(loc + 1) + 0.11 * oldPixel(loc + 2))

                'on affecte le niveau de gris au pixel dans la nouvelle image
                newPixel(multiNew(y) + x) = (tabBleu(oldPixel(locOld) And &HFF) + tabVert((oldPixel(locOld) And &HFF00) >> 8) + tabRouge((oldPixel(locOld) And &HFF0000) >> 16)) >> 8

            Next

        Next

        'on recopie notre nouveau tableau dans la nouvelle image
        Marshal.Copy(newPixel, 0, bmpDataNew.Scan0, newPixel.Length)

        bitmapNivGris.UnlockBits(bmpDataNew)
        bitmap.UnlockBits(bmpDataOld)

Conclusion

L'image résultat est bitmapNivGris.
 

Historique

06 octobre 2006 15:43:56 :
L'image de sortie est une image 8 bits indexée

Commentaires et avis

signaler à un administrateur
Commentaire de BruNews le 06/10/2006 15:57:46 administrateur CS

Salut,

Recherche de performance, virer aussi les multiplications inutiles, on va en gagner 3*255.
Dim tabBleu(256) As Integer
Dim tabVert(256) As Integer
Dim tabRouge(256) As Integer
Dim B As Integer, V As Integer, R As Integer
B = 0
V = 0
R = 0
For y = 0 To 255
  tabBleu(y) = B
  tabVert(y) = V
  tabRouge(y) = R
  B = B + 76
  V = V + 151
  R = R + 28
Next

gaffe que je ne suis pas VBiste alors vérifier ma syntaxe.
ciao...

signaler à un administrateur
Commentaire de Charles Racaud le 06/10/2006 16:39:45

Autres examples ici :
http://www.codyx.org/snippet_image-niveaux-gris_75.aspx

signaler à un administrateur
Commentaire de tkfe le 06/10/2006 16:51:26 administrateur CS

Très bonne remarque Brunews !

signaler à un administrateur
Commentaire de BruNews le 06/10/2006 17:33:16 administrateur CS

On pourrait encore gagner 256 comparaisons 'y <= 255 ?' en bas de boucle.
Il faut pour cela changer FOR par un DO LOOP afin de tendre vers 0, le compilo devrait donner un code nettement plus valable.
Pourquoi (le NEXT vb):
For y = 0 To 255
  'bla bla bla
Next
vaut compilé:
xor ebx, ebx
FORy:
  ; bla bla bla
  inc ebx
  cmp ebx, 255
  jbe FORy ; LE BOUCLAGE NEXT VB

Si on tendait vers 0:
yZERO:
  ; bla bla bla
  dec ebx
  jns yZERO

Le benef est tout net d'une comparaison par tour.
Pour cela placer au début B, V et R aux valeurs maxi, les décrémenter à chaque tour (76, 151 et 28).
Now je passe en syntaxe C, souvenirs VB trop lointains, tu traduiras:
y = 255;
do {
  tabBleu[y] = B;
  tabVert[y] = V;
  tabRouge[y] = R;
  B -= 76;
  V -= 151;
  R -= 28;
} while(--y >= 0);

signaler à un administrateur
Commentaire de Pym Corp le 24/10/2006 11:53:27

Passer par les colormatrix serait beaucoup plus rapide (et simple) non ?

signaler à un administrateur
Commentaire de tkfe le 24/10/2006 14:03:49 administrateur CS

Rapide et simple, oui, si on reste au format 32 bits. Par contre, si on veut sauvegarder l'image avec la taille la plus réduite possible, le format 8 bits indexé est sans aucun doute plus approprié...
Brunews apporte sans contestation une augmentation de la performance. Même si ce ne sont que quelques millisecondes sur une image de faible taille, cela pourait représenter quelques dixièmes de secondes sur une image plus importante.

signaler à un administrateur
Commentaire de jeron le 30/08/2008 14:42:08

super mais ou est l'exécutable ?

signaler à un administrateur
Commentaire de PCPT le 30/08/2008 16:38:32 administrateur CS

salut,

pas de zip, il te faut juste copier le code dans l'IDE VB.NET puis compiler toi-même le projet



PAS d'EXE : http://www.vbfrance.com/doc/faq.aspx#cs_noexe
Où TROUVER VS/VB : http://www.vbfrance.com/doc/faq.aspx#vb_lastide
QUE CONTIENT UN ZIP : http://www.vbfrance.com/doc/faq.aspx#vb_src

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Image en niveau de gris en C++ ou Autres [ par raftanelle ] Je cherche un programme en C++, VB, ou autres me permettant de créer des images en niveau de gris. Le niveau de gris dépend de la hauteur Z. Les coord Programme réalisant image en niveau de gis avec Coordonnées (x,y,z) [ par raftanelle ] Je cherche un programme en C++, VB, ou autres me permettant de créer des images en niveau de gris. Le niveau de gris dépend de la hauteur Z. Les coord transformation de niveau de gris d'une image [ par laura1978 ] Salut,Je suis nouvelle dans ce forum et j'ai un probleme en traitement d'image.je dois ecrire un algo en c++ pour la transformation du niveau de gris Traitement d'image, niveau de gris, seuillage,.... [ par nikko_s ] Bonjour à tous,Je souhaite effectuer divers traitements d'images pour parvenir à un comptage de population cellulaire sur des clichés 640 par 480 issu Conversion d'une image en niveaux de gris [ par nicolasheurtevin ] Bonjour,Je cherche à convertir une image en niveaux de gris. J'ai vu plusieurs sources où les auteurs balayent un à un les pixels de l'image source, e Conversion image eps -> jpeg (et tout en fait) [ par minimarc ] bonjour à vous,je souhaiterais savoir s'il existe un moyen de convertir une image eps vers le format jpeg, et pendant qu'on y ait de n'importe quel fo déclarer etutiliser RGB pour niveau de gris ? Comment faire ? [ par raftanelle ] J'ai toujours des difficulter. Je ne parviens pas &#224; utiliser RGB(10,10,10) Avec AUTOCAD 2000.sur Autocad 2004 je d&#233;clare Color1 comme &#231; Problème de Picturebox [ par cire2003 ] Lorsque je mets un picturebox dans ma fenêtre, je me retrouve avec un arrière plan gris (celui par default). En ce qui me concerne, je mets une image Transformation image niveau de gris ---> couleurs codées [ par delvpier ] Bonjour, quelqu'un pourrait-il me renseigner, ...ou écrire, un programme permettant de transformer une image(relief géographique)en niveaux de gris (0 tritement sur une image N/B [ par higgins91 ] Bonjour,Je recherche un moyen de faire comme un filtre passe haut sur une image, je m'explique:J'ai des images en niveau de gris (de 0 à 255) de taill


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,499 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.