Color image

Résolu
DevMln Messages postés 10 Date d'inscription lundi 21 juillet 2008 Statut Membre Dernière intervention 28 février 2012 - 22 janv. 2012 à 11:38
BunoCS Messages postés 15331 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 7 décembre 2022 - 27 janv. 2012 à 17:42
bonjour
je cherche comment calculer le nombre de couleur unique qui existe dans une image couleur

merci

7 réponses

cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
25 janv. 2012 à 11:21
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 ]
3
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 228
22 janv. 2012 à 11:44
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
0
BunoCS Messages postés 15331 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 7 décembre 2022 103
22 janv. 2012 à 14:42
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...
0
DevMln Messages postés 10 Date d'inscription lundi 21 juillet 2008 Statut Membre Dernière intervention 28 février 2012
26 janv. 2012 à 11:26
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
26 janv. 2012 à 11:54
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.
0
DevMln Messages postés 10 Date d'inscription lundi 21 juillet 2008 Statut Membre Dernière intervention 28 février 2012
27 janv. 2012 à 16:59
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
0
BunoCS Messages postés 15331 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 7 décembre 2022 103
27 janv. 2012 à 17:42
corriger le code suivant



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