begin process at 2012 02 12 19:04:36
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Graphique

 > CONVERTIR UNE IMAGE EN NIVEAU DE GRIS

CONVERTIR UNE IMAGE EN NIVEAU DE GRIS


 Information sur la source

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

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
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 :15 977

Auteur : tkfe

Ecrire un message privé
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

 Sources de la même categorie

Source avec Zip Source avec une capture Source .NET (Dotnet) CREER UN GIF ANIMÉ par Le Pivert
Source avec une capture GRAPH PHP COURBE DE CHARGE par s.defaye
Source avec Zip Source avec une capture BOULE DE CRISTAL par BLUEBIBUBBLE
VB6 - DÉPLACEMENT D'UN CONTRÔLE SUR UN SEGMENT DE DROITE DÉL... par ucfoutu
Source avec Zip Source .NET (Dotnet) APPLICATION DE DESSIN par fsafsafsaf

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture Source .NET (Dotnet) CREER UN GIF ANIMÉ par Le Pivert
Source avec Zip Source .NET (Dotnet) EXPORTER LES IMAGES DE WORD ET D' EXCEL par Le Pivert
Source avec Zip Source avec une capture CLM'S ASCII ART par clementio
Source avec Zip Source avec une capture TRADUCTEUR VB6.VBP EN VB5.VBP par joro
Source avec Zip CONVERSION D'UNE IMAGE 2D EN IMAGE 3D par Geff

Commentaires et avis

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...

Commentaire de Charles Racaud le 06/10/2006 16:39:45

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

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

Très bonne remarque Brunews !

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);

Commentaire de Pym Corp le 24/10/2006 11:53:27

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

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.

Commentaire de jeron le 30/08/2008 14:42:08

super mais ou est l'exécutable ?

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 Reconnaissance d'image [VB5] [ par Fraizy ] Bonjour, Je fais un projet dans lequel je dois décoder une image en niveau de gris (un QR code simplifié en fait). L'image en niveau de gris n'est pa 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 Conversion VB6 vers VB2008 [ par patelec ] A l'ouverture d'un fichier *.vbp concu en VB6 j'obtiens le message suivant: Echec de la mise à niveau:Impossible de charger les composants suivants: M


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
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

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 4,384 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales