Color image [Résolu]

Messages postés
10
Date d'inscription
lundi 21 juillet 2008
Dernière intervention
28 février 2012
- - Dernière réponse : BunoCS
Messages postés
14285
Date d'inscription
lundi 11 juillet 2005
Dernière intervention
13 décembre 2018
- 27 janv. 2012 à 17:42
bonjour
je cherche comment calculer le nombre de couleur unique qui existe dans une image couleur

merci
Afficher la suite 

Votre réponse

7 réponses

Meilleure réponse
Messages postés
3982
Date d'inscription
mardi 8 mars 2005
Dernière intervention
7 novembre 2014
3
Merci
Bonjour,

Vu les précédentes questions de DevMln, c'est sûrement pour du Delphi. Merci de poster sur delphifr la prochaine fois.

Voilà un bout de code qui compte les couleurs différentes.
Il faut une form avec une TImage contenant une bitmap, et un bouton.

Le code est optimisé pour le cas ou il y a pas mal de couleurs différentes.
1/ On charge tous les pixels dans un tableau (Détail technique : on ne peut pas trier directement Scanline[0] à cause du padding).
2/ On trie ce tableau avec un quicksort (Détail technique : on utilise qsort de msvcrt.dll).
3/ On parcourt le tableau et on compte les changements de couleurs.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, jpeg;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  Form1: TForm1;

type TRGBA = packed record
  B: Byte;
  G: Byte;
  R: Byte;
  A: Byte;
end;

type TRGBAArray = packed array[0..MaxInt div SizeOf(TRGBA) - 1] of TRGBA;
type PRGBAArray = ^TRGBAArray;

// On va utiliser qsort de msvcrt pour trier les couleurs
type TComparatorFunction = function(lpItem1: Pointer; lpItem2: Pointer): Integer; cdecl;
procedure qsort(base: Pointer; num: Cardinal; size: Cardinal; lpComparatorFunction: TComparatorFunction) cdecl; external 'msvcrt.dll';

implementation

{$R *.dfm}

function PixelComparator(lpItem1: Pointer; lpItem2: Pointer): Integer; cdecl;
var
  lpPixel1: ^Cardinal;
  lpPixel2: ^Cardinal;
begin
  lpPixel1:= lpItem1;
  lpPixel2:= lpItem2;
  Result:= lpPixel1^ - lpPixel2^;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  x, y, i: Integer;
  lpLine: PRGBAArray;
  lpPixels: Array of TRGBA;
  nPixelCount: Integer;
  nColorsCount: Integer;
  previousColor: TRGBA;
begin
  with Image1.Picture.Bitmap do
  begin
    nPixelCount:= Width * Height;
    SetLength(lpPixels, nPixelCount);
    PixelFormat:= pf32bit;

    // On stocks tous les pixels de la bitmap dans lpPixels
    i:= 0;
    for y:= 0 to Height - 1 do
    begin
      lpLine:= Scanline[y];
      for x:= 0 to Width - 1 do
      begin
        lpPixels[i]:= lpLine[x];
        Inc(i);
      end;
    end;
  end;

  // On trie les pixels
  qsort(lpPixels, nPixelCount, SizeOf(TRGBA), PixelComparator);

  // Pour le fun, on met à jour l'image avec les valeurs triées
  with Image1.Picture.Bitmap do
  begin
    i:= 0;
    for y:= 0 to Height - 1 do
    begin
      lpLine:= Scanline[y];
      for x:= 0 to Width - 1 do
      begin
        lpLine[x]:= lpPixels[i];
        Inc(i);
      end;
    end;
  end;
  Image1.Invalidate;

  // On parcourt le tableau trier pour compter les uniques
  nColorsCount:= 1;
  previousColor:= lpPixels[0];
  for i:= 1 to nPixelCount - 1 do
  begin
    if Cardinal(lpPixels[i]) <> Cardinal(previousColor) then
    begin
      Inc(nColorsCount);
      previousColor:= lpPixels[i];
    end;
  end;
  ShowMessage('Il y a ' + IntToStr(nColorsCount) + ' couleurs différentes dans cette image.');
end;

end.


[ Déplacé sur delphifr ]

Merci cs_rt15 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 103 internautes ce mois-ci

Commenter la réponse de cs_rt15
Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Contributeur
Dernière intervention
11 avril 2018
0
Merci
bonjour,

Comme on ignore totalement ton langage de développement, on va te répondre ceci :
en faisant une double-boucle (boucles imbriquées) pour relever la couleur de chaque pixel et incrémenter un compteur chaque fois qu'elle correspond à celle à comptabiliser.
Et on ne peut à ce niveau bien évidemment ne rien te proposer d'autre !


____________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches d'autres forumeurs.
Pas d'aide en ligne installée ? ==> ne comptez pas sur moi pour simplement vous dire ce qu'elle contient
Commenter la réponse de ucfoutu
Messages postés
14285
Date d'inscription
lundi 11 juillet 2005
Dernière intervention
13 décembre 2018
0
Merci
Hello,
Regardes du côté de l'histogramme.
Et merci d'indiquer ton langage de développement afin que je déplace ta demande dans la bonne section.


@+
Buno, Admin CS
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Commenter la réponse de BunoCS
Messages postés
10
Date d'inscription
lundi 21 juillet 2008
Dernière intervention
28 février 2012
0
Merci
merci pour votre code il est bon
mais je travail avec c++ builder et je cherche a trouver la palette des couleurs qui sont similaire avec un seuil donné pour faire la segmentation de l'image



marci
Commenter la réponse de DevMln
Messages postés
3982
Date d'inscription
mardi 8 mars 2005
Dernière intervention
7 novembre 2014
0
Merci
Bin je re-déplace.

Cela dit, vu que tu connais un peu le Delphi et que C++ Builder et Delphi utilisent la même "bibliothèque standard" (TImage, ScanLine...), traduire le code ci-dessus pour C++ Builder ne devrait pas te poser de problème.

Cela dit, trouver les couleurs "similaires" et les couleurs "uniques", ce n'est pas pareil, donc le code ci-dessus ne vaut plus grand chose.

Par exemple, tu ne peux plus traiter les couleurs comme des entiers pour les comparer. Il faut considérer les composantes RGB séparément lors des comparaison.
Commenter la réponse de cs_rt15
Messages postés
10
Date d'inscription
lundi 21 juillet 2008
Dernière intervention
28 février 2012
0
Merci
corriger le code suivant
struct TRGBA {//= packed record
Byte B ;
Byte G ;
Byte R ;
Byte A ;
};
typedef TRGBA TRGBAArray [(MaxInt / sizeof(TRGBA)) - 1];
typedef TRGBAArray PRGBAArray ;


int x, y, i;

PRGBAArray lpLine ;
int nPixelCount,nColorsCount,Hauteur,Largeur;
TRGBA previousColor;

Graphics::TBitmap * image_origine= new Graphics::TBitmap();
image_origine->PixelFormat=pf24bit;
image_origine->Assign((TPersistent *)Image1->Picture->Graphic);
Hauteur = Image1->Picture->Bitmap->Height;
Largeur = Image1->Picture->Bitmap->Width;

TRGBA lpPixels[256*256];

//= Image1->Picture->Bitmap->Width * Image1->Picture->Bitmap->Height;
nPixelCount = Hauteur*Largeur;


// On stocks tous les pixels de la bitmap dans lpPixels
i= 0;
for (y= 0 ; y<Hauteur ;y++)
{
lpLine =(PRGBAArray )Image1->Picture->Bitmap->ScanLine[y];
for (x= 0; x<Largeur ;x++)
{
lpPixels[i]= lpLine[x];
i++;
}

}



// On trie les pixels

// QuickSort2(lpPixels,0,nPixelCount);
qsort(lpPixels, nPixelCount, sizeof(TRGBTriple), PixelComparator);

// Pour le fun, on met à jour l'image avec les valeurs triées

i=0;
for (y= 0 ; y<Hauteur ;y++)
{
// lpLine= image_origine->Bitmap->ScanLine[y];
lpLine =(PRGBAArray) Image1->Picture->Bitmap->ScanLine[y];
for (x= 0; x<Largeur ;x++)
{
lpLine[i]= lpPixels[x];
i++;
}

}


/*
// On parcourt le tableau trier pour compter les uniques
nColorsCount= 1;
previousColor= lpPixels[0];
for (i= 1; i< nPixelCount ;i++)
{
if (Cardinal(lpPixels[i])!= Cardinal(previousColor))
{
nColorsCount++;
previousColor= lpPixels[i][0];
}
}
*/
ShowMessage("Il y a " + IntToStr(nColorsCount) + " couleurs différentes dans cette image.");
}
meliani
Commenter la réponse de DevMln
Messages postés
14285
Date d'inscription
lundi 11 juillet 2005
Dernière intervention
13 décembre 2018
0
Merci
corriger le code suivant



@+
Buno, Admin CS
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Commenter la réponse de BunoCS

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.