Detection de contours

Soyez le premier à donner votre avis sur cette source.

Vue 21 779 fois - Téléchargée 3 356 fois

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 / Exemple :


/*-----------------------------------------------------------------------------------------------*
//
//                                     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.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
8
Date d'inscription
mercredi 24 mai 2006
Statut
Membre
Dernière intervention
27 mars 2007

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!
Messages postés
101
Date d'inscription
vendredi 15 février 2002
Statut
Membre
Dernière intervention
6 août 2007

c'est exactement ça, on multiplie toutes les valeurs par la dureté ce qui intensifie les couleurs
Messages postés
921
Date d'inscription
vendredi 20 décembre 2002
Statut
Membre
Dernière intervention
23 septembre 2010

Et la dureté elle a quel rôle dans l'image finale ? J'ai l'impression qu'elle ne fait qu'éclairer le rendu...
Messages postés
101
Date d'inscription
vendredi 15 février 2002
Statut
Membre
Dernière intervention
6 août 2007

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.
Messages postés
921
Date d'inscription
vendredi 20 décembre 2002
Statut
Membre
Dernière intervention
23 septembre 2010

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

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.