Accueil > Forum > > > > Traitement d'une image BMP
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
|
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
Livres en rapport
|
Derniers Blogs
POUR RAPPEL ! LES SPéCIFICATIONS DES PROTOCOLES OFFICE ET SHAREPOINT SONT DISPONIBLES SUR MSDNPOUR RAPPEL ! LES SPéCIFICATIONS DES PROTOCOLES OFFICE ET SHAREPOINT SONT DISPONIBLES SUR MSDN par neodante
Quelle est le point commun entre : Microsoft il y a 10 ans et Apple aujourd'hui ? Réponse: avoir une politique de protocoles propriétaires et fermés :) Car pour rappel (si si je vous assure c'est important de le rappeler), la majorité des spécifications e...
Cliquez pour lire la suite de l'article par neodante JOYEUX ANNIVERSAIRE NIXJOYEUX ANNIVERSAIRE NIX par ebartsoft
Souhaitons un bon et joyeux anniversaire à notre hôte à tous, Nix.
Je ne le répéterais jamais assez mais sans lui rien ne serait possible. Il défit en permanence les lois de la gravité et comme il le dit si bien, si tu lui fais confiance ça devra...
Cliquez pour lire la suite de l'article par ebartsoft IMAGINE CUP 2012, MAKE A SIGN EN FINALEIMAGINE CUP 2012, MAKE A SIGN EN FINALE par junarnoalg
Voilà qui est fait, la nouvelle est officielle ! L'équipe belge "Make a Sign" va au pays des kangourous défendre son projet dans la catégorie Software Design. http://www.imaginecup.com/CompetitionsContent/Competition/WorldwideFinalists.aspx V...
Cliquez pour lire la suite de l'article par junarnoalg KINECT 1.5 IS OUT !KINECT 1.5 IS OUT ! par Vko
La version 1.5 du Kinect For Microsoft vient tout juste de sortir ! Plein de nouveautés: Tracking de squelette en Near Mode Détection en position assise Détection faciale avec un SDK dédié Documentation et des guideline (enfin) Un out...
Cliquez pour lire la suite de l'article par Vko LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) par richardc
Mise à jour des Web API du 14 Mai
Réservez dès maintenant votre journée du 20 juin pour le Windows Azure Dev Camp 2012 à Paris
Mise à jour de Team Foundation Service
MechCommander 2 sur Windows 8
Entity Framework 5 Release Candidate e...
Cliquez pour lire la suite de l'article par richardc
Forum
MATLAB PROGRAMME MATLAB PROGRAMME par wahab1087
Cliquez pour lire la suite par wahab1087 RGB2GRAYRGB2GRAY par musa18
Cliquez pour lire la suite par musa18
Logiciels
sDEVIS-FACTURES vlPRO (8.1.0.3)SDEVIS-FACTURES VLPRO (8.1.0.3)sDEVIS-FACTURES vlPRO a été mis au point pour les particuliers, créateurs, entrepreneurs, artisa... Cliquez pour télécharger sDEVIS-FACTURES vlPRO 974 Application Server (12.2.4.6)974 APPLICATION SERVER (12.2.4.6)Développez de puissantes applications dans un environnement de 'cloud computing', clusterisé, séc... Cliquez pour télécharger 974 Application Server vPicture (1.4.2.1)VPICTURE (1.4.2.1)Avec vPicture, hébergez vos images facilement et rapidement.
vPicture est un utilitaire simple, ... Cliquez pour télécharger vPicture Easy-Planning (2.2.1.6)EASY-PLANNING (2.2.1.6)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté au... Cliquez pour télécharger Easy-Planning COM-BACKUP (2.0)COM-BACKUP (2.0)
COM-BACKUP est un logiciel de sauvegarde qui permet de planifier les sauvegardes de vos dossiers ...
Cliquez pour télécharger COM-BACKUP
|