begin process at 2012 02 07 10:40:43
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Graphique

 > DETECTION DE CONTOURS

DETECTION DE CONTOURS


 Information sur la source

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

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Graphique Niveau :Débutant Date de création :20/12/2004 Vu / téléchargé :15 463 / 2 881

Auteur : Maegis

Ecrire un message privé
Commentaire sur cette source (5)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
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.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture ASCII ART : BMP TO HTM - TRANSFORME UNE IMAGE EN FICHIER HT...
Source avec Zip ETIRER/RÉTRÉCIR UNE IMAGE BMP SANS STRETCHBLT
Source avec Zip Source avec une capture BITMAP24 TO TEXT - TRANSFORME UNE IMAGE EN TEXTE VC++
Source avec Zip RESOLUTION D'EQUATIONS DE DEGRÉ 4 OU INFERIEUR
Source avec Zip Source avec une capture DEBUT DE MOTEUR D'AFFICHAGE OPENGL AVEC RENDU DE SKYBOX

 Sources de la même categorie

Source avec Zip APPLICATION DE DESSIN DE QUELQUES FIGURES par laguchori
Source avec Zip Source avec une capture HDR EXPOSURE FUSION par mecrosoft
Source avec Zip Source avec une capture IRC CLIENT MULTISERVEUR EN MFC (TXIRC) par TeniX
Source avec Zip ENTETE DU FICHIER BMP (BIPMAP) par k.Lutchi
Source avec Zip Source avec une capture XCOUPE : COUPE 2D par pop70

Commentaires et avis

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

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.

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

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

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




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
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,655 sec (4)

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