Color image [Résolu]

Signaler
Messages postés
10
Date d'inscription
lundi 21 juillet 2008
Statut
Membre
Dernière intervention
28 février 2012
-
Messages postés
14808
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
18 septembre 2020
-
bonjour
je cherche comment calculer le nombre de couleur unique qui existe dans une image couleur

merci

7 réponses

Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
11
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 ]
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
227
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
Messages postés
14808
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
18 septembre 2020
92
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...
Messages postés
10
Date d'inscription
lundi 21 juillet 2008
Statut
Membre
Dernière intervention
28 février 2012

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
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
11
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.
Messages postés
10
Date d'inscription
lundi 21 juillet 2008
Statut
Membre
Dernière intervention
28 février 2012

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
Messages postés
14808
Date d'inscription
lundi 11 juillet 2005
Statut
Modérateur
Dernière intervention
18 septembre 2020
92
corriger le code suivant



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