begin process at 2008 07 06 16:06:48
1 205 627 membres
195 nouveaux aujourd'hui
14 119 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

DETECTION DE CONTOURS


Information sur la source

Catégorie :Graphique Niveau : Débutant Date de création : 20/12/2004 Vu / téléchargé: 7 909 / 2 192

Note :
9,5 / 10 - par 2 personnes
9,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (5)
Ajouter un commentaire et/ou une note

Description

Un simple programme de detection de contours , mais le chose qui change
c'est qu'on prend la norme du gradient de la composante R,G et B séparement
en chaque point de l'image et non la norme du gradient de la moyenne des
trois composantes, ce qui fait que le resultat est en couleur et ça rend pas mal
sur certaines images.

Je ne met pas le code des fonctions GetBmp24 et SaveBmp24, le projet entier est
dans le zip avec une image pour l'exemple.

Source

  • /*-----------------------------------------------------------------------------------------------*
  • //
  • // Detecte Contours
  • //
  • //Fait par : MaegisInstinct (maegisinstinct@free.fr)
  • //
  • //le : 19/12/2004 à 22:21:43
  • //
  • //Description : Detecte les contours d'une image
  • //
  • /*----------------------------------------------------------------------------------------------*/
  • #include <windows.h>
  • #include <math.h>
  • #include <stdlib.h>
  • struct PIXEL
  • {
  • BYTE b;
  • BYTE g;
  • BYTE r;
  • };
  • struct Gradpix
  • {
  • float r,g,b;
  • };
  • [...]
  • /*-----------------------------------------------------*/
  • //Retourne la norme du gradient en un point de l'image
  • /*-----------------------------------------------------*/
  • Gradpix NormeGrad(PIXEL* image,int x,int y,int width,int height)
  • {
  • Gradpix gradx = {0.0f,0.0f,0.0f};
  • Gradpix grady = {0.0f,0.0f,0.0f};
  • int nbcompx = 0;
  • int nbcompy = 0;
  • if (x != 0)
  • {
  • gradx.r += (float) image[x+y*width].r-image[x-1+y*width].r;
  • gradx.g += (float) image[x+y*width].g-image[x-1+y*width].g;
  • gradx.b += (float) image[x+y*width].b-image[x-1+y*width].b;
  • nbcompx++;
  • }
  • if (x != width-1)
  • {
  • gradx.r += (float) image[(x+1)+y*width].r-image[x+y*width].r;
  • gradx.g += (float) image[(x+1)+y*width].g-image[x+y*width].g;
  • gradx.b += (float) image[(x+1)+y*width].b-image[x+y*width].b;
  • nbcompx++;
  • }
  • gradx.r=gradx.r/(float)nbcompx; //on fait la moyenne
  • gradx.g=gradx.g/(float)nbcompx;
  • gradx.b=gradx.b/(float)nbcompx;
  • if (y != 0)
  • {
  • grady.r += (float) image[x+y*width].r-image[x+(y-1)*width].r;
  • grady.g += (float) image[x+y*width].g-image[x+(y-1)*width].g;
  • grady.b += (float) image[x+y*width].b-image[x+(y-1)*width].b;
  • nbcompy++;
  • }
  • if (y != height-1)
  • {
  • grady.r += (float) image[x+(y+1)*width].r-image[x+y*width].r;
  • grady.g += (float) image[x+(y+1)*width].g-image[x+y*width].g;
  • grady.b += (float) image[x+(y+1)*width].b-image[x+y*width].b;
  • nbcompy++;
  • }
  • grady.r=grady.r/(float)nbcompy;
  • grady.g=grady.g/(float)nbcompy;
  • grady.b=grady.b/(float)nbcompy;
  • Gradpix result = {(float)sqrt(gradx.r*gradx.r+grady.r*grady.r),
  • (float)sqrt(gradx.g*gradx.g+grady.g*grady.g),
  • (float)sqrt(gradx.b*gradx.b+grady.b*grady.b)};
  • return result;
  • }
  • /*------------------------------------------------------------------*/
  • //Genere une image contenant les contours de l'image passé en param
  • //durete : (entre 1 (soft) et 50 (tres dur))
  • /*------------------------------------------------------------------*/
  • PIXEL* DetecteContours(PIXEL* image,int width,int height,float durete)
  • {
  • int i,j;
  • Gradpix* grad = new Gradpix[width*height];
  • for(j=0;j<height;j++)
  • {
  • for(i=0;i<width;i++)
  • {
  • grad[i+j*width] = NormeGrad(image,i,j,width,height);
  • }
  • }
  • //On cherche le max et on normalise entre 0 et 255 et on genere l'image
  • Gradpix maxi={0.0f,0.0f,0.0f};
  • for (i=0;i<width*height;i++)
  • {
  • if (grad[i].r>maxi.r)
  • maxi.r=grad[i].r;
  • if (grad[i].g>maxi.g)
  • maxi.g=grad[i].g;
  • if (grad[i].b>maxi.b)
  • maxi.b=grad[i].b;
  • }
  • //On genere ensuite l'image en normalisant
  • PIXEL* data = new PIXEL[width*height];
  • durete = max(durete,1);
  • for (i=0;i<width*height;i++)
  • {
  • data[i].r = (BYTE) min(grad[i].r/maxi.r*255.0f*durete,255.0f);
  • data[i].g = (BYTE) min(grad[i].g/maxi.g*255.0f*durete,255.0f);
  • data[i].b = (BYTE) min(grad[i].b/maxi.b*255.0f*durete,255.0f);
  • }
  • return data;
  • }
  • /*--------------*/
  • //Fonction Main
  • /*--------------*/
  • int APIENTRY WinMain(HINSTANCE hInstance,
  • HINSTANCE hPrevInstance,
  • LPSTR lpCmdLine,
  • int nShowCmd)
  • {
  • PIXEL *data;
  • PIXEL *contours;
  • DWORD width,height;
  • char buffer[1024];
  • if (*lpCmdLine == 0)
  • {
  • MessageBox(NULL,"Faites glisser un fichier bmp 24bpp sur l'exe","Info",MB_OK);
  • return -1;
  • }
  • memcpy(buffer,lpCmdLine,strlen(lpCmdLine));
  • buffer[strlen(lpCmdLine)-1]=0; //On enleve le guillement droit
  • if (GetBmp24(buffer+1,&data,width,height))
  • {
  • contours = DetecteContours(data,width,height,2);
  • strcpy(buffer+strlen(lpCmdLine)-5,"-cont.bmp");
  • SaveBmp24(buffer+1,contours,width,height);
  • delete[] data;
  • delete[] contours;
  • return 0;
  • }
  • MessageBox(NULL,"Mauvais format de fichier","Erreur",MB_OK);
  • return -1;
  • }
/*-----------------------------------------------------------------------------------------------*
//
//                                     Detecte Contours
//
//Fait par         : MaegisInstinct (maegisinstinct@free.fr)
//
//le               : 19/12/2004 à 22:21:43
//
//Description      : Detecte les contours d'une image
//
/*----------------------------------------------------------------------------------------------*/
#include <windows.h>
#include <math.h>
#include <stdlib.h>


struct PIXEL
{
	BYTE b;
	BYTE g;
	BYTE r;
};

struct Gradpix
{
	float r,g,b;
};


 [...]
/*-----------------------------------------------------*/
//Retourne la norme du gradient en un point de l'image
/*-----------------------------------------------------*/
Gradpix NormeGrad(PIXEL* image,int x,int y,int width,int height)
{
	Gradpix	 gradx	= {0.0f,0.0f,0.0f};
	Gradpix	 grady	= {0.0f,0.0f,0.0f};
	int		nbcompx = 0;
	int		nbcompy = 0;


	if (x != 0)
	{
		gradx.r += (float) image[x+y*width].r-image[x-1+y*width].r;
		gradx.g += (float) image[x+y*width].g-image[x-1+y*width].g;
		gradx.b += (float) image[x+y*width].b-image[x-1+y*width].b;
		nbcompx++;
	}
	if (x != width-1)
	{
		gradx.r += (float) image[(x+1)+y*width].r-image[x+y*width].r;
		gradx.g += (float) image[(x+1)+y*width].g-image[x+y*width].g;
		gradx.b += (float) image[(x+1)+y*width].b-image[x+y*width].b;
		nbcompx++;
	}
	gradx.r=gradx.r/(float)nbcompx;		//on fait la moyenne
	gradx.g=gradx.g/(float)nbcompx;
	gradx.b=gradx.b/(float)nbcompx;

	if (y != 0)
	{
		grady.r += (float) image[x+y*width].r-image[x+(y-1)*width].r;
		grady.g += (float) image[x+y*width].g-image[x+(y-1)*width].g;
		grady.b += (float) image[x+y*width].b-image[x+(y-1)*width].b;
		nbcompy++;
	}
	if (y != height-1)
	{
		grady.r += (float) image[x+(y+1)*width].r-image[x+y*width].r;
		grady.g += (float) image[x+(y+1)*width].g-image[x+y*width].g;
		grady.b += (float) image[x+(y+1)*width].b-image[x+y*width].b;
		nbcompy++;
	}
	grady.r=grady.r/(float)nbcompy;
	grady.g=grady.g/(float)nbcompy;
	grady.b=grady.b/(float)nbcompy;
	
	Gradpix result = {(float)sqrt(gradx.r*gradx.r+grady.r*grady.r),
			          (float)sqrt(gradx.g*gradx.g+grady.g*grady.g),
			          (float)sqrt(gradx.b*gradx.b+grady.b*grady.b)};
	return result;
}


/*------------------------------------------------------------------*/
//Genere une image contenant les contours de l'image passé en param
//durete : (entre 1 (soft) et 50 (tres dur))
/*------------------------------------------------------------------*/
PIXEL* DetecteContours(PIXEL* image,int width,int height,float durete)
{
	int i,j;
	Gradpix* grad = new Gradpix[width*height];

	for(j=0;j<height;j++)
	{
		for(i=0;i<width;i++)
		{
			grad[i+j*width] = NormeGrad(image,i,j,width,height);
		}
	}

	//On cherche le max et on normalise entre 0 et 255 et on genere l'image
	Gradpix maxi={0.0f,0.0f,0.0f};
	for (i=0;i<width*height;i++)
	{
		if (grad[i].r>maxi.r)
			maxi.r=grad[i].r;
		if (grad[i].g>maxi.g)
			maxi.g=grad[i].g;
		if (grad[i].b>maxi.b)
			maxi.b=grad[i].b;
	}
	//On genere ensuite l'image en normalisant
	PIXEL* data = new PIXEL[width*height];
	durete = max(durete,1);
	for (i=0;i<width*height;i++)
	{
		data[i].r = (BYTE) min(grad[i].r/maxi.r*255.0f*durete,255.0f);
		data[i].g = (BYTE) min(grad[i].g/maxi.g*255.0f*durete,255.0f);
		data[i].b = (BYTE) min(grad[i].b/maxi.b*255.0f*durete,255.0f);
	}
	
	return data;
}

/*--------------*/
//Fonction Main
/*--------------*/
int APIENTRY WinMain(HINSTANCE hInstance,
					 HINSTANCE hPrevInstance,
					 LPSTR lpCmdLine,
					 int nShowCmd)
{
	PIXEL *data;
	PIXEL *contours;
	DWORD width,height;
	char buffer[1024];

	if (*lpCmdLine == 0)
	{
		MessageBox(NULL,"Faites glisser un fichier bmp 24bpp sur l'exe","Info",MB_OK);
		return -1;
	}
	memcpy(buffer,lpCmdLine,strlen(lpCmdLine));
	buffer[strlen(lpCmdLine)-1]=0;	//On enleve le guillement droit

	if (GetBmp24(buffer+1,&data,width,height))
	{
		contours = DetecteContours(data,width,height,2);
		
		strcpy(buffer+strlen(lpCmdLine)-5,"-cont.bmp");
		SaveBmp24(buffer+1,contours,width,height);
		delete[] data;
		delete[] contours;
		return 0;
	}
	MessageBox(NULL,"Mauvais format de fichier","Erreur",MB_OK);
	return -1;
}

Conclusion

Pour des raisons de taille excessive du zip, je n'ai pu mettre qu'une image riduculement petite, donc le resultat est un peu plus pixel.
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

  • signaler à un administrateur
    Commentaire de Saros le 21/12/2004 18:21:52

    C'est quoi la norme du gradient ?
    Sinon j'ai trouvé super interessant. Mais ça aurait été mieux de pouvoir modifier la dureté de la détection avec une interface utilisateur...
    10/10

  • signaler à un administrateur
    Commentaire de Maegis le 21/12/2004 19:50:19

    Si on appelle f la fonction qui a (x,y) associe la composante R du point (x,y) de l'image, le gradient c'est un vecteur de coords ( df/dx, df/dy ). En fait c'est les dérivées partielles de l'application.

  • signaler à un administrateur
    Commentaire de Saros le 21/12/2004 23:57:56

    Et la dureté elle a quel rôle dans l'image finale ? J'ai l'impression qu'elle ne fait qu'éclairer le rendu...

  • signaler à un administrateur
    Commentaire de Maegis le 22/12/2004 12:04:18

    c'est exactement ça, on multiplie toutes les valeurs par la dureté ce qui intensifie les couleurs

  • signaler à un administrateur
    Commentaire de rayasahnoun le 02/04/2007 11:55:22

    Bonjour,
    J'ai besoin d'une fonction pour faire la comparaison entre deux images bmp.
    Si je vais comparer pixel a pixel ca sera un peu lourd.
    Est ce que je dois detecter les contours au premier lieu puis comparer pixel a pixel dans le contour?
    merci!

Ajouter un commentaire

Pub



Appels d'offres

Plugin Dialer outlook
Budget : 2 000€
Travail graphique- ill...
Budget : 1 000€
creation de marque et ...
Budget : 1 000€

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Boutique

Boutique de goodies CodeS-SourceS