begin process at 2012 05 30 10:15:20
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive C/C++

 > 

Archives

 > 

Au secours

 > 

Traitement d'une image BMP


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Traitement d'une image BMP

dimanche 9 avril 2006 à 11:12:17 | Traitement d'une image BMP

emrod

Salut, j'ai fait un programme, mais j'ai un petit problème, en effet il ne marche pas bien :)
Je lis une image BMP qui me sert de modèle, par exemple une forme rouge sur un fond noir. Je détermine dans cette image les niveaux de rouge, de vert, et de bleu minimum et maximum (par exemple rouge_min=120, rouge_max=230, etc...).
Je lis ensuite une autre image qui contient le modèle, et je cherche à détecter ce modèle dans l'image. Je regarde donc pour chaque pixel s'il appartient ou non aux couleurs du modèle (rouge situé entre rouge_min et rouge_max, etc...).
Je crée ensuite une autre image, en recopiant les pixels du modèle (reconnu dans l'image précédente), et en mettant à 0 les autres pixels (pixels noirs) de manière à n'avoir dans l'image résultat que le modèle, extrait de l'image précédente.

Le problème, c'est que j'ai l'impression que ça fait n'importe quoi, déjà j'obtient une image résultat toute noire, et en plus les niveaux de rouge, vert et bleu de l'image modèle ne sont pas bien définies (par exemple, si j'ai un modèle toute rouge, le programme me retourne aussi du bleu et du vert).
En fait, j'ouvre l'image avec fopen(), je lis d'abord l'entête (de taille 54 octets), puis je lis à chaque fois l'image avec getc(), mais je ne suis pas sûr que ça fonctionne comme je pense. Je pensais qu'en faisant comme ça, on obtient à chaque fois une valeur de bleu, de vert ou de rouge (successivement), donc si je fais 3 fois getc() j'obtient les 3 couleurs d'un pixel. Ca marche comme ça ?


Bon, voici mon programme pour mieux comprendre :


_________________________________________________________________________________________________

#include <stdio.h>
 
#define MODELE "modele.bmp" // image BMP 24 bits
#define IMAGE "image2.bmp"  // image BMP 24 bits
#define RESULTAT "resultat.bmp"

int rouge_min=255;
int rouge_max=0;
int vert_min=255;
int vert_max=0;
int bleu_min=255;
int bleu_max=0;
 
int npix=0, npix_rouge=0, npix_vert=0, npix_bleu=0;



// définition des couleurs du modèle : niveaux (de rouge, vert et bleu) min et max du modèle (image MODELE)
void Modele(FILE *fp)
{
 int i, a;
    // lecture de l'entête
    for(i=0;i<54;i++)
        fgetc(fp); 
    i=0;
   
    while((a=fgetc(fp))!=EOF)
      {  if (a>0)
           switch(i)
             { case 0 : // couleur bleue
                 { if (a<=bleu_min)
                      bleu_min = a;
                   if (a>=bleu_max)
                      bleu_min = a;
                   npix_bleu++;
                   //printf("bleu : %d\n",a);
                 }
               case 1 : // couleur verte
                 { if (a<=vert_min)
                      vert_min = a;
                   if (a>=vert_max)
                      vert_max = a;
                   npix_vert++;
                   //printf("vert : %d\n",a);
                 }
              case 2 : // couleur rouge
                 { if (a<=rouge_min)
                      rouge_min = a;
                   if (a>=rouge_max)
                      rouge_max = a;
                   npix_rouge++;
                   //printf("rouge : %d\n",a);
                 }
             }
           i++;
           if (i==3) i=0;
        
      }            
         
    // si on n'a pas de pixels d'une couleur (rouge, vert, ou bleu), on définit le min et le max à 0
 if (npix_rouge == 0)
               { rouge_min = 0;
                 rouge_max = 0;
               }
    if (npix_vert == 0)
               { vert_min = 0;
                 vert_max = 0;
               }
    if (npix_bleu == 0)
               { bleu_min = 0;
                 bleu_max = 0;
               }
}




// reconnaissance du modèle dans l'image IMAGE et création de l'image RESULTAT contenant uniquement les pixels du modèle
void DetecteModele(FILE *fp1, FILE *fp2)
{
 int i=0, rouge, vert, bleu;
    // recopie de l'entete
    for(i=0;i<54;i++)
       fputc(fgetc(fp1),fp2); 
 
    //traitement
    // lit les 3 couleurs d'un pixel, pour toute l'image IMAGE
    while( ((bleu=fgetc(fp1))!=EOF) && ((vert=fgetc(fp1))!=EOF) && ((rouge=fgetc(fp1))!=EOF) )
      { //si les niveaux de rouge, vert et bleu du pixel appartiennent aux couleurs du modèle, on recopie le pixel
        if ( (rouge >= rouge_min) && (rouge <= rouge_max) && (vert >= vert_min) && (vert <= vert_max) && (bleu >= bleu_min) && (bleu <= bleu_max) )
          { fputc(bleu,fp2);
            fputc(vert,fp2);
            fputc(rouge,fp2);
            npix++;
          }
        // sinon on met un pixel noir
        else
          {
            fputc(0,fp2);
            fputc(0,fp2);
            fputc(0,fp2);
          }
      } 
}


 
main()
{
    FILE *fp, *fp1, *fp2; 
    char c;
        
    // détection modèle
    fp=fopen(MODELE,"rb");
    Modele(fp);
   
    // reconnaissance modèle
    fp1=fopen(IMAGE,"rb");
    fp2=fopen(RESULTAT,"w+b");
    DetecteModele(fp1,fp2);
   
    // affiche les paramètres calculés (vérification)
    printf("nombre de pixels du modele : %d\n",npix);
    printf("nombre de pixels rouges : %d\n",npix_rouge);
    printf("nombre de pixels verts : %d\n",npix_vert);
    printf("nombre de pixels bleus : %d\n",npix_bleu);
    printf("Niveau rouge min : %d\n",rouge_min);
    printf("Niveau rouge max : %d\n",rouge_max);
    printf("Niveau vert min : %d\n",vert_min);
    printf("Niveau vert max : %d\n",vert_max);
    printf("Niveau bleu min : %d\n",bleu_min);
    printf("Niveau bleu max : %d\n",bleu_max);
    scanf("%c",&c);
 
    fclose(fp);
    fclose(fp1);
    fclose(fp2);
}



_________________________________________________________________________________________________


Voici les images que j'ai utilisé :
modele: [ Lien ]
image2: [ Lien ]
Ce sont des images assez simples, pour tester le programme.

Merci de votre aide :)

dimanche 9 avril 2006 à 15:15:39 | Re : Traitement d'une image BMP

mogwai93

1)
                 { if (a<=bleu_min)
                      bleu_min = a;
                   if (a>=bleu_max)
                      bleu_min = a;
ce n'est pas plutot  ?
                 { if (a<=bleu_min)
                      bleu_min = a;
                   if (a>=bleu_max)
                      bleu_max = a;

2)
    for(i=0;i<54;i++)
        fgetc(fp); 
    i=0;  // <--- pourquoi le reinitialiser ??

3) pour les performances, ne pas lire octet par octet
deja
tu peux lire par bloc :
- entete
- point (int R, int G, int B)
sinon, tu lis d'un coup le fichier et tu boucles sur le buffer

4) je n'ai pas tout regarder
mais il ne faudrait pas que tu boucles sur la hauteur et la largeur des 2 images ?
et regarder dans l'image la + grande, si la petite est comprise dans la grande ?



dimanche 9 avril 2006 à 16:08:16 | Re : Traitement d'une image BMP

emrod

Merci pour ta réponse, mais je vais encore t'embêter :)

1) Ok, merci, c'était une erreur de frappe.

2) En fait j'utilise i pour faire 2 choses. D'abord pour lire l'entête en un bloc. Puis je le remet à 0 car i permet de définir si je lis la couleur bleue (i=0), verte (i=1) ou rouge(i=2). C'est juste pour ne pas utiliser une variable en plus.

3) Je veux bien, mais comment faire pour lire l'image autrement ? A part utilser fgetc() ? Moi j'aimerais bien lire d'un coup 3 couleurs (pour avoir un pixel à chaque fois), mais je ne sais pas trop comment faire. C'est quel type de variable une couleur, c'est un octet, un entier, ... ?
Avant j'utilisais une méthode assez complexe (que je captais pas trop car je précise que l'info n'est pas ma spécialité, moi j'ai juste fait un peu de C et pas de C++ donc je ne connais pas bien toutes les fonctions et bibliothèques), et je lisais tout d'un coup  et je le rangeais dans un buffer, puis je pouvais avoir chaque couleur en faisant un truc du style pixel.r, pixel.g, pixel.b, il n'y aurait pas un moyen de faire comme ça simplement (sans trop modifier mon programme) ?

4) Le problème c'est que je ne sais pas comment déterminer la hauteur et la largeur de mon image, il y a une fonction pour ça ? Ou c'est dans l'entête, et si oui comment l'avoir ?
Et puis, tu vois, la taille du modèle peut varier, car c'est un objet connu qu'on va rechercher dans une autre image (extraite d'une vidéo), et l'objet peut se trouver à n'importe quelle distance donc sa taille va varier. Et puis je devrais déterminer la distance de cet objet, j'aurais besoin de compter la hauteur de l'objet donc le nombre de pixels sur une même colonne (d'où l'utilité de connaitre la largeur et de la longueur de l'image).
dimanche 9 avril 2006 à 16:40:24 | Re : Traitement d'une image BMP

mogwai93

3) pour lire un fichier, tu peux utiliser fread
soit tu lis le fichier d'un coup
soit tu peux utiliser l'objet struct afin de definir une structure (R, G, B) où R, G et B seront déclarés en  CHAR ou BYTE  (256 bits)

4) oui c'est stocké dans l'entete
soit tu te fais ta methode de lecture
soit tu utilises ce que Windows a déja :

HBITMAP FileToBitmap(LPCTSTR lpFileName)
{
  HBITMAP hbmp = 0;
  HANDLE hProcessHeap = GetProcessHeap();
  HANDLE hFile = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
  if(hFile == INVALID_HANDLE_VALUE) return 0;
  DWORD dwFileSize = GetFileSize(hFile, 0), dwRead;
  LPVOID lpMem = HeapAlloc(hProcessHeap, 0, dwFileSize);
  if(ReadFile(hFile, lpMem, dwFileSize, &dwRead, 0) && dwRead == dwFileSize)
    hbmp = PictureToBitmap((LPBYTE)lpMem, dwFileSize);
   
  HeapFree(hProcessHeap, 0, lpMem);

  return hbmp;
}

puis
HBITMAP hBmpSrc=FileToBitmap("image.bmp");
       BITMAP bmpInfo;
        GetObject(hBmpSrc, sizeof(BITMAP), &bmpInfo);
        SIZE Taille;
        Taille.cx = bmpInfo.bmWidth;
        Taille.cy = bmpInfo.bmHeight;

dimanche 9 avril 2006 à 19:38:47 | Re : Traitement d'une image BMP

emrod

Merci pour ta réponse, mais il faut rajouter des bibliothèques (je sais pas si c'est ça le nom, mais les trucs du style #include <stdio.h> ), et je sais pas lesquelles.
Est-ce qu'il y a un moyen (un site par exemple) de trouver quelle bibliothèque il faut ajouter pour avoir le droit d'utiliser une certaine fonction ?
Là j'ai rajouté windows.h, mais PictureToBitmap ne marche pas, qu'est-ce qu'il faut rajouter d'autre ? (j'ai cherché mais j'ai pas trouvé sur internet). C'est surtout ça mon problème avec le C++, il y a trop de bibliothèques et j'en connais presque aucune (à part celles de base)...
dimanche 9 avril 2006 à 21:41:03 | Re : Traitement d'une image BMP

mogwai93

#include <olectl.h>

HBITMAP  PictureToBitmap(LPBYTE pmem, DWORD nSize)
{
  HRESULT hr;
  CoInitialize(0);
  HBITMAP hbmp_dst = 0;
  HGLOBAL hgbl =(HGLOBAL)GlobalAlloc(GMEM_FIXED, nSize);

  memcpy(hgbl, pmem, nSize);

  IStream* stream = 0;
  hr = CreateStreamOnHGlobal(hgbl, TRUE, &stream);
  if(!SUCCEEDED(hr) || !stream)
  {
      stream->Release();
      GlobalFree(hgbl);
      CoUninitialize();
      return NULL;
  //goto errPicture;
  }

  IPicture* picture = 0;
  hr = OleLoadPicture(stream, nSize, 0, IID_IPicture, (void**)&picture);
  if(!SUCCEEDED(hr) || !picture)
  {
      stream->Release();
      GlobalFree(hgbl);
      CoUninitialize();
      return NULL;
  //goto errPicture;
  }

  HBITMAP hbmp_src;
  picture->get_Handle((OLE_HANDLE *)&hbmp_src);
  if(!SUCCEEDED(hr) || !picture)
  {
      picture->Release();
      stream->Release();
      GlobalFree(hgbl);
      CoUninitialize();
      return NULL;
  //goto errHandle;
  }

  BITMAP bmp;
  GetObject(hbmp_src, sizeof bmp, &bmp);
  hbmp_dst = (HBITMAP)CopyImage(hbmp_src, IMAGE_BITMAP, 0, 0, 0);

errHandle:
  picture->Release();
errPicture:
  stream->Release();
errStream:
  GlobalFree(hgbl);
  CoUninitialize();
  return hbmp_dst;
}


et rajouter dans l'edition des liens
pour devc++ :
libolepro32.a
libole32.a
libuuid.a
(pour visual c++, ca doit etre la meme chose, sans le 'a' final)


sauf que ce code fonctionne pour les bmp, gif, jpg
donc on doit pouvoir simplifier, si tu n'utilises que du bmp..

tu peux tjs regarder cette source :
http://www.cppfrance.com/codes/LOADER-BMP-TRAITEMENT_33150.aspx

lundi 10 avril 2006 à 00:10:20 | Re : Traitement d'une image BMP

emrod

Merci pour ta réponse (je savais pas pour les liens à rajouter), mais j'ai trouvé quelque chose de plus simple pour avoir la largeur et la hauteur de l'image (c'est dans l'entête) :


BITMAPFILEHEADER fileheader;
BITMAPINFOHEADER infoheader;
DWORD width, height;
fread (&fileheader,14,1,fp);
fread (&infoheader,40,1,fp);
width = infoheader.biWidth; // largeur de l'image
height = infoheader.biHeight; // hauteur de l'image


Bon, là j'ai toujours des problèmes avec mon programme, mais je vais essayer d'utiliser ce que j'ai trouvé pour le modifier, en espérant que ça marche (j'essaie aussi de m'inspirer d'autres programmes).
Je remettrai un message si j'ai encore besoin d'aide.
Merci en tout cas pour ton aide !

lundi 10 avril 2006 à 09:43:36 | Re : Traitement d'une image BMP

buno

Administrateur CodeS-SourceS
Pour un exemple de traitement de fichiers BMP, voir ma source:
http://www.cppfrance.com/codes/LOADER-BMP-TRAITEMENT_33150.aspx

Buno
----------------------------------------
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai...
Le site de mon mariage


Cette discussion est classée dans : image, rouge, min, bleu, vert


Répondre à ce message

Sujets en rapport avec ce message

Importation d'un .png dans un tabeau [ par Davy8x ] Je voudrais importer une image au foramt .png dans un tableau en C.Si quelqu'un peu m'aider...Exemple :{Rouge,Vert,Bleu,Alpha,Rouge,Vert,Bleu,Alpha,Ro Images qui deviennent blanches [ par mogwai93 ] Bonjour J'ai créé une fenetre avec dessus des images provenant des ressources de l'executable lui-meme L'affichage est ok. de meme l'affichage es Comment charger une image 1024x768? [ par Slown ] Bonjour. J'ai trouvé un tutorial traitant sur le mapping. Voici le code: http://www.linuxgraphic.org/section3d/openGL/didacticiels/didac6/didac5.html  Comment mettre une image de fond dans un application MDI utilisant les MFC ??? [ par Sb01 ] Bonjour à tous Je suis entrain de réaliser une application MDI en utilisant les MFC et je souhaiterais mettre une image de fond dans mes fenêtres mai Boite de dialogue Afficher une image 256niveaux [ par SyN42 ] Bonjour, Dans ma boite de dialogue j'affiche une image dans un 1er temps en couleur avec la fonction StretchDIBits int OldMode = SetStretchBltMode(c [api] "Contraire" de LoadImage() [ par hoGan ] Bonjour, j'aimerais savoir si il existe une fonction qui, contrairement à LoadImage() qui affiche une image, l'enlève ? Quand on cliquerait sur un bou redimensionner une image [ par mogwai93 ] bonjourje redimensionne actuellement mes images avec StretchBltsauf que le ratio x et y, n'est pas le meme, d'où des distorsions :-(y a-t-il une metho [api] Image qui s'efface [ par hoGan ] Bonjour, voilà ce que je voudrais faire: lorsque j'appuie sur un bouton, faire apparaître une image, et faire en sorte que celle-ci ne disparaisse pa Librairie jpeg et bug : user breakpoint called from code 0x7c911230 [ par Ayla_21 ] Bonjour tout le mondeaprès des jours et des jours de bataille acharnée avec la librairie Jpeg, j'ai réussi à l'installer et à débugger quelques lignes Image TIF [ par Topsyko ] Bonjour,Je cherche à afficher une image TIF, avec Visual Studio.Net 2003, pour celaz je dois recupéré les valeurs des pixels, mias je n'y parvients pa


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
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 : 0,733 sec (3)

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