begin process at 2012 02 13 01:03:59
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Graphique

 > DÉTECTION OPTIMALE DES CONTOURS: CANNY, DÉRICHE, SHENCASTAN

DÉTECTION OPTIMALE DES CONTOURS: CANNY, DÉRICHE, SHENCASTAN


 Information sur la source

Note :
10 / 10 - par 2 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Graphique Classé sous :traitement image, Canny, Deriche, ImAnalyse, contours Niveau :Initié Date de création :09/03/2008 Date de mise à jour :01/08/2008 13:48:49 Vu / téléchargé :23 904 / 2 078

Auteur : Pistol_Pete

Ecrire un message privé
Site perso
Ce membre participe au partage de revenus publicitaires
Commentaire sur cette source (39)
Ajouter un commentaire et/ou une note


 Description

Cliquez pour voir la capture en taille normale
En traitement de l'image, la détection de contours est une étape primordiale qui ne doit pas être négligée. Aussi, ce programme propose 4 algorithmes permettant de bien mieux appréhender le sujet.

Mais tout d'abord, il faut savoir ce que l'on entant par "bonne" détection des contours:
Canny le définissait de la sorte:
-Bonne détection : détecter un maximum de contours
-Bonne localisation : les points détectés doivent être les plus proches possibles du vrai contour.
-Réponse unique : minimiser le nombre de contours détectés plusieurs fois

Ces critères se traduisent par des conditions sur la réponse impulsionnelle du filtre et débouchent sur des détecteurs de contours très performants


L'opérateur de Canny: filtre RIF (réponse impulsionnel fini)
-On élimine tout d'abord le bruit de l'image/ convolution par un noyau gaussien
-Calcul du gradient de l'image dans les deux directions x et y
-Suppression des points du gradient qui ne correspondent pas à des maxima locaux.

Les opérateurs de ShenCastan et de Deriche:
Au filtre de Canny, on préfère souvent le détecteur de Deriche, qui répond exactement aux mêmes  
critères de qualité que celui de Canny, mais qui possède une réponse impulsionnelle infinie (filtre  
RII). Il a pu donc être synthétisé de façon récursive particulièrement efficace.
La différence avec Shen Castan reste les conditions initiales.

Sobel optimal:
Il s'agit du filtre de Sobel classique avec la suppression des non maxima

Les opérateurs de Marr Hildrech et de KangWang ont été implémenter mais le résultat de ces deux opérateurs ne correspondent pas à nos attentes.

Les 3 premiers filtres: Canny, Dériche et Shen Castan donne des résultats assez impressionnant.

Et pour tester toutes les méthodes de détection des contours, j'ai réalisé 2 scripts mettant en jeu tous les filtres sur 2 images différentes (1 ère image : image très bruité, seconde image :image naturel)
Ces scriptes sont accessibles directement par l'interface principale ou par le menu.

Voici la répartition des buffers
Buffer1:  Image initial
Buffer2:  filtre de Laplace v4
Buffer3:  filtre de Laplace v8
Buffer4:  filtre de Prewitt
Buffer5:  filtre de Sobel
Buffer6:  filtre de Canny
Buffer7:  filtre de Shen-Castan
Buffer8:  filtre de Deriche
Buffer9:  filtre de SobelOptimal

Source

  • //*****************************************************************************
  • //MORARD Vincent
  • //04 mars 2008
  • //vincent.morard@cpe.fr
  • //http://pistol.petesampras.free.fr
  • //*****************************************************************************
  • //******************************************************************************
  • //Shen_Castan.cpp
  • //Ce fichier regroupe les fonctions permettant de trouver les contours selon les
  • //critères de Shen-Castan.
  • //OUTLINE corespond au nombre de pixels que l'on ne prendra pas en compte lors
  • //de la convolution.
  • //Aussi, pour pouvoir effectuer la détection de contour à tous les pixels, y
  • //compris ceux du bord de l'image, on augmentera la taille de l'image de
  • //2*OUTLINE. C'est le rôle des fonctions embded et debed
  • //WINDOW_SIZE est un paramètre qui determine la taille de la fenêtre pour
  • //calculer le gradient adaptatif.
  • //
  • //plus b est faible plus il y a de détail (plus de bruit aussi)
  • //******************************************************************************
  • #include "CImage.h"
  • #include "AdvancEdge.h"
  • #define WINDOW_SIZE 7
  • #define OUTLINE 25
  • double b;
  • //*************************************************************************
  • //ShenCastan: Detection des contours optimaux:
  • //Procedure: On augmente d'abord la taille de l'image source en on convertit
  • //l'image initiale en float. On envoie cette
  • //nouvelle image à la fonction Shen avec ses nouvelles dimensions
  • //Une fois la fin du traitement, on remet les dimensions initiales et l'on place
  • //l'image obtenue dans le buffer de sortie.
  • //*************************************************************************
  • bool CImage::ShenCastan(CImage *ImgDest,double B)
  • {
  • float **Img=0;
  • int Largeur,Hauteur;
  • b=B;
  • if(hBmp==0){
  • MessageBox(NULL,"Shen-Castan : L'image source est vide",
  • NULL,MB_OK|MB_ICONWARNING);
  • return 0;
  • }
  • if(ImgDest != 0 && ImgDest != this)
  • ImgDest->Copy(this);
  • if(ImgDest == 0)
  • ImgDest=this;
  • GetBitmapBits(hBmp,Width*Height*4,ucBits);
  • //Ajout d'une bordure de OUTLINE pixel autours de l'image
  • Img=embed(OUTLINE,&Largeur,&Hauteur);
  • Shen(Img,Largeur,Hauteur);
  • //Retrait de la bordure
  • ImgDest->debed(Img,OUTLINE,Largeur,Hauteur);
  • SetBitmapBits(ImgDest->hBmp,Width*Height*4,ImgDest->ucBits);
  • ImgDest->ImgType=GRAY;
  • DesAllocT_float(Img,Largeur);
  • return 1;
  • }
  • //******************************************************************************
  • //Shen:
  • //C'est dans cette fonction que tout le traitement est effectué
  • //On reçoit en paramètre d'entrée l'image directement accessible en pixel
  • //ainsi que ses dimensions.
  • //L'image de sortie sera dans la variable Img
  • //******************************************************************************
  • void Shen(float **Img,int Largeur,int Hauteur)
  • {
  • float **BufFiltrer=0;
  • int **ImgBli=0;
  • BufFiltrer=AllocT_float(Largeur,Hauteur);
  • //On filtre le bruit en appliquant l'algo ISEF
  • ComputeISEF(Img,BufFiltrer,Largeur,Hauteur);
  • //On trouve les pixels de l'image qui on un Laplacian positif
  • ImgBli=ComputeBli(BufFiltrer,Img,Largeur,Hauteur);
  • //Detection des coutours à partir de l'ImgBli et de l'image filtrer
  • LocateZeroCrossings(Img,BufFiltrer,ImgBli,Largeur,Hauteur);
  • MaxContraste(Img,Largeur,Hauteur);
  • //Desallocation de la memoire allouer
  • DesAllocT_float(BufFiltrer,Largeur);
  • DesAllocT_int(ImgBli,Largeur);
  • }
  • //******************************************************************************
  • //ISEF (Infinite Symetrical Exponential Filter)
  • //Filtrage de l'image horizontalement et verticalement. L'image filtrer sera
  • //placée dans la variable y
  • //******************************************************************************
  • void ComputeISEF(float **x,float **y,int Largeur,int Hauteur)
  • {
  • float **Causal=0,**AntiCausal=0;
  • Causal=AllocT_float(Largeur,Hauteur);
  • AntiCausal=AllocT_float(Largeur,Hauteur);
  • //On applique d'abord le filtre dans la direction verticale
  • ApplyISEF_Vertical(x,y,Causal,AntiCausal,Largeur,Hauteur);
  • ApplyISEF_Horizontal(y,y,Causal,AntiCausal,Largeur,Hauteur);
  • //Libération de la mémoire
  • DesAllocT_float(Causal,Largeur);
  • DesAllocT_float(AntiCausal,Largeur);
  • }
  • //*******************************************************************************
  • //ApplyISEF_Vertical
  • //Filtrage vertical : Calcul des composantes causales et anticausales
  • //*******************************************************************************
  • void ApplyISEF_Vertical(float **x,float **y,float **Causal,float **AntiCausal,
  • int Largeur,int Hauteur)
  • {
  • int i,j;
  • float b1,b2;
  • b1 = (float)((1.0-b)/(1.0+b));
  • b2 = (float)(b*b1);
  • //Methode recurssive donc on calcule les pixels des bords de l'image
  • for(j=0;j<Hauteur;j++)
  • {
  • Causal[0][j]=b1*x[0][j];
  • AntiCausal[Largeur-1][j]=b2*x[Largeur-1][j];
  • }
  • //Calcul des composantes causales
  • for(i=1;i<Largeur;i++)
  • for(j=0;j<Hauteur;j++)
  • Causal[i][j]=(float)(b1*x[i][j]+b*Causal[i-1][j]);
  • //Calcul des composantes anti-causales
  • for(i=Largeur-2;i>=0;i--)
  • for(j=0;j<Hauteur;j++)
  • AntiCausal[i][j]=(float)(b2*x[i][j]+b*AntiCausal[i+1][j]);
  • //on calcule les pixels des bords de l'image de sortie
  • for(j=0;j<Hauteur-1;j++)
  • y[Largeur-1][j]=Causal[Largeur-1][j];
  • //On calcule l'image de sortie du premier filtre que l'on place dans la variable y
  • //Correspond a la somme des composantes causal et anti-causales
  • for(i=0;i<Largeur-2;i++)
  • for(j=0;j<Hauteur-1;j++)
  • y[i][j]=Causal[i][j]+AntiCausal[i+1][j];
  • }
  • //*******************************************************************************
  • //ApplyISEF_Horizontal
  • //Filtrage vertical : Calcul des composantes causales et anticausales
  • //*******************************************************************************
  • void ApplyISEF_Horizontal(float **x,float **y,float **Causal,float **AntiCausal,
  • int Largeur,int Hauteur)
  • {
  • int i,j;
  • float b1,b2;
  • b1 = (float)((1.0-b)/(1.0+b));
  • b2 = (float)(b*b1);
  • //on calcule les pixels des bords de l'image
  • for(i=0;i<Largeur;i++)
  • {
  • Causal[i][0]=b1*x[i][0];
  • AntiCausal[i][Hauteur-2]=b2*x[i][Hauteur-2];
  • }
  • //Calcul des composantes causales
  • for(j=1;j<Hauteur;j++)
  • for(i=0;i<Largeur;i++)
  • Causal[i][j]=(float)(b1*x[i][j]+b*Causal[i][j-1]);
  • //Compute anti causal component
  • for(j=Hauteur-3;j>=0;j--)
  • for(i=0;i<Largeur;i++)
  • AntiCausal[i][j]=(float)(b2*x[i][j]+b*AntiCausal[i][j+1]);
  • //Calcul des composantes anti-causales
  • for(i=0;i<Largeur-1;i++)
  • y[i][Hauteur-1]=Causal[i][Hauteur-1];
  • //On calcule l'image de sortie du premier filtre que l'on place dans la variable y
  • //Correspond a la somme des composantes causal et anti-causales
  • for(i=0;i<Largeur-1;i++)
  • for(j=0;j<Hauteur-2;j++)
  • y[i][j]=Causal[i][j]+AntiCausal[i][j+1];
  • }
  • //*******************************************************************************
  • //ComputeBli:
  • //On fait la différence des deux images et on compare le resultat à 0
  • //ImgBli est donc une image composé uniquement de 0 et de 1
  • //*******************************************************************************
  • int **ComputeBli(float **ImgFiltrer,float **ImgBuf,int nRows,int nCols)
  • {
  • int Row,Col;
  • int **ImgBli=0;
  • ImgBli=AllocT_int(nRows,nCols);
  • //On prend la difference entre l'image lisse et l'image originale.
  • //On calcule l'ImgBli en mettant a 1 tous les pixels ou le Laplacian est positif. 0 sinon
  • for(Row=0;Row<nRows;Row++)
  • {
  • for(Col=0;Col<nCols;Col++)
  • {
  • ImgBli[Row][Col]=0;
  • if(Row<OUTLINE || Row>=nRows-OUTLINE || Col<OUTLINE || Col>=nCols-OUTLINE)
  • continue;
  • ImgBli[Row][Col]=((ImgFiltrer[Row][Col]-ImgBuf[Row][Col])>0.0);
  • }
  • }
  • return ImgBli;
  • }
  • //*************************************************************************************
  • //LocateZeroCrossings
  • //Cette fonction permettra de déterminer pour tous les pixels de l'image s'il est un pixel
  • //appartenant à un contour ou non.
  • //**************************************************************************************
  • void LocateZeroCrossings(float **Orig,float **BufFiltrer,int **ImgBli,int nRows,int nCols)
  • {
  • int Row,Col;
  • for(Row=0;Row<nRows;Row++)
  • for(Col=0;Col<nCols;Col++)
  • {
  • //On ignore les pixels que l'on a ajoute pour le calcule
  • if(Row<OUTLINE || Row>=nRows-OUTLINE || Col<OUTLINE || Col>=nCols-OUTLINE)
  • Orig[Row][Col]=0.0;
  • //On verifie si ce pixel est un "zero crossing" pour le Laplacian
  • else if(IsCandidateEdge(ImgBli,BufFiltrer,Row,Col))
  • {
  • //On Calcule le gradian adaptatif
  • Orig[Row][Col]=ComputeAdaptativeGradient(ImgBli,BufFiltrer,Row,Col);
  • }
  • else
  • Orig[Row][Col]=0.0;
  • }
  • }
  • //**************************************************************************************
  • //IsCandidateEdge
  • //On regarde le pixel voisin en on regarde s'il y a un franchissement de zero.
  • //On effectue donc la multiplication des 2 pixels et on compare à 0
  • //**************************************************************************************
  • bool IsCandidateEdge(int **Buff,float **Orig,int Row,int Col)
  • {
  • //a positive z-c must have a positive 1st derivative,where positive z-c
  • //means the second derivative goes from + to - as we cross the edge
  • if(Buff[Row][Col]==1 && Buff[Row+1][Col]==0)
  • return (Orig[Row+1][Col]-Orig[Row-1][Col]>0 ? TRUE:FALSE); //positive z-c
  • else if(Buff[Row][Col]==1 && Buff[Row][Col+1]==0)
  • return (Orig[Row][Col+1]-Orig[Row][Col-1]>0 ? TRUE:FALSE); //positive z-c
  • else if(Buff[Row][Col]==1 && Buff[Row-1][Col]==0)
  • return (Orig[Row+1][Col]-Orig[Row-1][Col]<0 ? TRUE:FALSE); //negative z-c
  • else if(Buff[Row][Col]==1 && Buff[Row][Col-1]==0)
  • return (Orig[Row][Col+1]-Orig[Row][Col-1]<0 ? TRUE:FALSE); //negative z-c
  • return FALSE; //not a z-c
  • }
  • //*************************************************************************************
  • //ComputeAdaptativeGradient
  • //On calcule un seuil pour chaque pixel. Le seuil sera determiner grace aux pixels voisins
  • //présent dans la fenêtre WINDOW_SIZE
  • //*************************************************************************************
  • float ComputeAdaptativeGradient(int **Bli,float **Orig,int Row,int Col)
  • {
  • int i,j;
  • float SumOn,SumOff;
  • float AvgOn,AvgOff;
  • int NbOn,NbOff;
  • SumOn=0.0;
  • SumOff=0.0;
  • NbOn=0;
  • NbOff=0;
  • //On regarde par rapport aux pixels voisins, le nombre de pixel a 1 et a 0
  • for(i=(-WINDOW_SIZE/2);i<=(WINDOW_SIZE/2);i++)
  • for(j=(-WINDOW_SIZE/2);j<=(WINDOW_SIZE/2);j++)
  • {
  • if(Bli[Row+i][Col+j])
  • {
  • SumOn+=Orig[Row+i][Col+j];
  • NbOn++;
  • }
  • else
  • {
  • SumOff+=Orig[Row+i][Col+j];
  • NbOff++;
  • }
  • }
  • if(SumOff)
  • AvgOff=SumOff/(float)NbOff;
  • else
  • AvgOff=0.0;
  • if(SumOn)
  • AvgOn=SumOn/(float)NbOn;
  • else
  • AvgOn=0.0;
  • return (AvgOff-AvgOn);
  • }
  • //********************************************************************************
  • //embed
  • //Cette fonction retourne un pointeur sur un float qui de l'image initial ou l'on a
  • //ajouté des bordure de largeur et de hauteur de Width
  • //********************************************************************************
  • float **CImage::embed(int taille,int *L,int *H)
  • {
  • int i,j,I,J;
  • float **Img=0;
  • taille+=2;
  • *L=Width+2*taille;
  • *H=Height+2*taille;
  • Img=AllocT_float(*L,*H);
  • for(i=0;i<*L;i++)
  • for(j=0;j<*H;j++)
  • {
  • I=(i-taille+Width)%Width;
  • J=(j-taille+Height)%Height;
  • Img[i][j]=(float)GetPixel(I,J,GRAY);
  • }
  • return Img;
  • }
  • //********************************************************************************
  • //debed
  • //Cette fonction retourne inscrit l'image obtenue dans le buffer Dest en enlevant
  • //les bordures ajoutées
  • //********************************************************************************
  • void CImage::debed(float **Img,int taille,int L,int H)
  • {
  • int i,j;
  • taille+=2;
  • int Val;
  • for(i=taille;i<L-taille;i++)
  • for(j=taille;j<H-taille;j++)
  • {
  • Val=Limit((int)Img[i][j]);
  • SetPixel(i-taille,j-taille,Val,Val,Val);
  • }
  • }
  • //Etire le contraste au maximum.
  • //Attention tous les pixels negatifs sont mis a 0
  • void MaxContraste(float **Img,int nRows,int nCols)
  • {
  • int i,j;
  • float X,Scale,Vmin,Vmax;
  • Vmin=Img[50][50];
  • Vmax=Vmin;
  • for(i=0;i<nRows;i++)
  • {
  • for(j=0;j<nCols;j++)
  • {
  • if(i<OUTLINE || i>=nRows-OUTLINE || j<OUTLINE || j>=nCols-OUTLINE)
  • continue;
  • X=Img[i][j];
  • if(X<0){Img[i][j]=0;X=0;}
  • if(Vmin>X) Vmin=X;
  • if(Vmax<X) Vmax=X;
  • }
  • }
  • Scale = (float)(256.0/(Vmax-Vmin+1));
  • for(i=0;i<nRows;i++)
  • for(j=0;j<nCols;j++)
  • {
  • if(i<OUTLINE || i>=nRows-OUTLINE || j<OUTLINE || j>=nCols-OUTLINE)
  • continue;
  • Img[i][j]=((Img[i][j]-Vmin)*Scale);
  • }
  • }
//*****************************************************************************
//MORARD Vincent					
//04 mars 2008
//vincent.morard@cpe.fr
//http://pistol.petesampras.free.fr
//*****************************************************************************



//******************************************************************************
//Shen_Castan.cpp
//Ce fichier regroupe les fonctions permettant de trouver les contours selon les 
//critères de Shen-Castan. 
//OUTLINE corespond au nombre de pixels que l'on ne prendra pas en compte lors 
//de la convolution.
//Aussi, pour pouvoir effectuer la détection de contour à tous les pixels, y 
//compris ceux du bord de l'image, on augmentera la taille de l'image de 
//2*OUTLINE. C'est le rôle des fonctions embded et debed
//WINDOW_SIZE est un paramètre qui determine la taille de la fenêtre pour 
//calculer le gradient adaptatif.
//
//plus b est faible plus il y a de détail (plus de bruit aussi)
//******************************************************************************
#include "CImage.h"
#include "AdvancEdge.h"

#define WINDOW_SIZE		7	
#define OUTLINE 		25
double b;


//*************************************************************************
//ShenCastan: Detection des contours optimaux:
//Procedure: On augmente d'abord la taille de l'image source en on convertit 
//l'image initiale en float. On envoie cette 
//nouvelle image à la fonction Shen avec ses nouvelles dimensions
//Une fois la fin du traitement, on remet les dimensions initiales et l'on place 
//l'image obtenue dans le buffer de sortie.
//*************************************************************************
bool CImage::ShenCastan(CImage *ImgDest,double B)
{
	float **Img=0;
	int Largeur,Hauteur;

	b=B;
	if(hBmp==0){
		MessageBox(NULL,"Shen-Castan : L'image source est vide",
			NULL,MB_OK|MB_ICONWARNING);
		return 0;
	}

	if(ImgDest != 0 && ImgDest != this)
		ImgDest->Copy(this);

	

	if(ImgDest == 0)
		ImgDest=this;

	GetBitmapBits(hBmp,Width*Height*4,ucBits);

	//Ajout d'une bordure de OUTLINE pixel autours de l'image
	Img=embed(OUTLINE,&Largeur,&Hauteur);

	Shen(Img,Largeur,Hauteur);
	
	//Retrait de la bordure
	ImgDest->debed(Img,OUTLINE,Largeur,Hauteur);

	SetBitmapBits(ImgDest->hBmp,Width*Height*4,ImgDest->ucBits);
	ImgDest->ImgType=GRAY;

	DesAllocT_float(Img,Largeur);
	return 1;
}


//******************************************************************************
//Shen: 
//C'est dans cette fonction que tout le traitement est effectué
//On reçoit en paramètre d'entrée l'image directement accessible en pixel 
//ainsi que ses dimensions.
//L'image de sortie sera dans la variable Img
//******************************************************************************
void Shen(float **Img,int Largeur,int Hauteur)
{
	float **BufFiltrer=0;
	int   **ImgBli=0;

	BufFiltrer=AllocT_float(Largeur,Hauteur);

	//On filtre le bruit en appliquant l'algo ISEF
	ComputeISEF(Img,BufFiltrer,Largeur,Hauteur);
	
	//On trouve les pixels de l'image qui on un Laplacian positif 
	ImgBli=ComputeBli(BufFiltrer,Img,Largeur,Hauteur);

	//Detection des coutours à partir de l'ImgBli et de l'image filtrer
	LocateZeroCrossings(Img,BufFiltrer,ImgBli,Largeur,Hauteur);

	MaxContraste(Img,Largeur,Hauteur);

	//Desallocation de la memoire allouer
	DesAllocT_float(BufFiltrer,Largeur);
	DesAllocT_int(ImgBli,Largeur);


	
}

//******************************************************************************
//ISEF  (Infinite Symetrical Exponential Filter)
//Filtrage de l'image horizontalement et verticalement. L'image filtrer sera 
//placée dans la variable y
//******************************************************************************
void ComputeISEF(float **x,float **y,int Largeur,int Hauteur)
{
	float **Causal=0,**AntiCausal=0;

	Causal=AllocT_float(Largeur,Hauteur);
	AntiCausal=AllocT_float(Largeur,Hauteur);

	//On applique d'abord le filtre dans la direction verticale
	ApplyISEF_Vertical(x,y,Causal,AntiCausal,Largeur,Hauteur);
	ApplyISEF_Horizontal(y,y,Causal,AntiCausal,Largeur,Hauteur);
	
	

	//Libération de la mémoire
	DesAllocT_float(Causal,Largeur);
	DesAllocT_float(AntiCausal,Largeur);
	

}


//*******************************************************************************
//ApplyISEF_Vertical
//Filtrage vertical : Calcul des composantes causales et anticausales
//*******************************************************************************
void ApplyISEF_Vertical(float **x,float **y,float **Causal,float **AntiCausal,
						int Largeur,int Hauteur)
{
	int i,j;
	float b1,b2;
	b1 = (float)((1.0-b)/(1.0+b));
	b2 = (float)(b*b1);

	//Methode recurssive donc on calcule les pixels des bords de l'image
	for(j=0;j<Hauteur;j++)
	{
		Causal[0][j]=b1*x[0][j];
		AntiCausal[Largeur-1][j]=b2*x[Largeur-1][j];
	}

	//Calcul des composantes causales
	for(i=1;i<Largeur;i++)
		for(j=0;j<Hauteur;j++)
			Causal[i][j]=(float)(b1*x[i][j]+b*Causal[i-1][j]);

	//Calcul des composantes anti-causales
	for(i=Largeur-2;i>=0;i--)
		for(j=0;j<Hauteur;j++)
			AntiCausal[i][j]=(float)(b2*x[i][j]+b*AntiCausal[i+1][j]); 

	//on calcule les pixels des bords de l'image de sortie
	for(j=0;j<Hauteur-1;j++)
		y[Largeur-1][j]=Causal[Largeur-1][j];

	
	//On calcule l'image de sortie du premier filtre que l'on place dans la variable y
	//Correspond a la somme des composantes causal et anti-causales
	for(i=0;i<Largeur-2;i++)				
		for(j=0;j<Hauteur-1;j++)
			y[i][j]=Causal[i][j]+AntiCausal[i+1][j];

}

//*******************************************************************************
//ApplyISEF_Horizontal
//Filtrage vertical : Calcul des composantes causales et anticausales
//*******************************************************************************
void ApplyISEF_Horizontal(float **x,float **y,float **Causal,float **AntiCausal,
						  int Largeur,int Hauteur)
{
	int i,j;
	float b1,b2;
	b1 = (float)((1.0-b)/(1.0+b));
	b2 = (float)(b*b1);

	//on calcule les pixels des bords de l'image
	for(i=0;i<Largeur;i++)
	{
		Causal[i][0]=b1*x[i][0];
		AntiCausal[i][Hauteur-2]=b2*x[i][Hauteur-2];
	}

	//Calcul des composantes causales
	for(j=1;j<Hauteur;j++)
		for(i=0;i<Largeur;i++)
			Causal[i][j]=(float)(b1*x[i][j]+b*Causal[i][j-1]);

	//Compute anti causal component
	for(j=Hauteur-3;j>=0;j--)
		for(i=0;i<Largeur;i++)
			AntiCausal[i][j]=(float)(b2*x[i][j]+b*AntiCausal[i][j+1]); 

	//Calcul des composantes anti-causales
	for(i=0;i<Largeur-1;i++)
		y[i][Hauteur-1]=Causal[i][Hauteur-1];

	//On calcule l'image de sortie du premier filtre que l'on place dans la variable y
	//Correspond a la somme des composantes causal et anti-causales
	for(i=0;i<Largeur-1;i++)
		for(j=0;j<Hauteur-2;j++)
			y[i][j]=Causal[i][j]+AntiCausal[i][j+1];

}

//*******************************************************************************
//ComputeBli:
//On fait la différence des deux images et on compare le resultat à 0
//ImgBli est donc une image composé uniquement de 0 et de 1
//*******************************************************************************
int **ComputeBli(float **ImgFiltrer,float **ImgBuf,int nRows,int nCols)
{
	int Row,Col;
	int **ImgBli=0;

	ImgBli=AllocT_int(nRows,nCols);

	//On prend la difference entre l'image lisse et l'image originale.
	//On calcule l'ImgBli en mettant a 1 tous les pixels ou le Laplacian est positif. 0 sinon
	for(Row=0;Row<nRows;Row++)
	{
		for(Col=0;Col<nCols;Col++)
		{
			ImgBli[Row][Col]=0;
			if(Row<OUTLINE || Row>=nRows-OUTLINE || Col<OUTLINE || Col>=nCols-OUTLINE)
				continue;
			ImgBli[Row][Col]=((ImgFiltrer[Row][Col]-ImgBuf[Row][Col])>0.0);

		}
	}
	return ImgBli;

}


//*************************************************************************************
//LocateZeroCrossings
//Cette fonction permettra de déterminer pour tous les pixels de l'image s'il est un pixel
//appartenant à un contour ou non.
//**************************************************************************************
void LocateZeroCrossings(float **Orig,float **BufFiltrer,int **ImgBli,int nRows,int nCols)
{
	int Row,Col;
	
	for(Row=0;Row<nRows;Row++)
		for(Col=0;Col<nCols;Col++)
		{
			//On ignore les pixels que l'on a ajoute pour le calcule
			if(Row<OUTLINE || Row>=nRows-OUTLINE || Col<OUTLINE || Col>=nCols-OUTLINE)
				Orig[Row][Col]=0.0;

			//On verifie si ce pixel est un "zero crossing" pour le Laplacian
			else if(IsCandidateEdge(ImgBli,BufFiltrer,Row,Col))
			{
				//On Calcule le gradian adaptatif
				Orig[Row][Col]=ComputeAdaptativeGradient(ImgBli,BufFiltrer,Row,Col);
				
			}
			else
				Orig[Row][Col]=0.0;
		}
}

//**************************************************************************************
//IsCandidateEdge
//On regarde le pixel voisin en on regarde s'il y a un franchissement de zero.
//On effectue donc la multiplication des 2 pixels et on compare à 0
//************************************************************************************** 
bool IsCandidateEdge(int **Buff,float **Orig,int Row,int Col)	
{
	//a positive z-c must have a positive 1st derivative,where positive z-c
	//means the second derivative goes from + to - as we cross the edge

	if(Buff[Row][Col]==1 && Buff[Row+1][Col]==0) 
		return (Orig[Row+1][Col]-Orig[Row-1][Col]>0 ? TRUE:FALSE); //positive z-c

	else if(Buff[Row][Col]==1 && Buff[Row][Col+1]==0)
		return (Orig[Row][Col+1]-Orig[Row][Col-1]>0 ? TRUE:FALSE); //positive z-c

	else if(Buff[Row][Col]==1 && Buff[Row-1][Col]==0)
		return (Orig[Row+1][Col]-Orig[Row-1][Col]<0 ? TRUE:FALSE); //negative z-c

	else if(Buff[Row][Col]==1 && Buff[Row][Col-1]==0)
		return (Orig[Row][Col+1]-Orig[Row][Col-1]<0 ? TRUE:FALSE); //negative z-c


	return FALSE;		//not a z-c

}  

//*************************************************************************************
//ComputeAdaptativeGradient
//On calcule un seuil pour chaque pixel. Le seuil sera determiner grace aux pixels voisins
//présent dans la fenêtre WINDOW_SIZE
//*************************************************************************************
float ComputeAdaptativeGradient(int **Bli,float **Orig,int Row,int Col)
{
	int i,j;
	float SumOn,SumOff;
	float AvgOn,AvgOff;
	int NbOn,NbOff;

	SumOn=0.0;
	SumOff=0.0;
	NbOn=0;
	NbOff=0;

	//On regarde par rapport aux pixels voisins, le nombre de pixel a 1 et a 0
	for(i=(-WINDOW_SIZE/2);i<=(WINDOW_SIZE/2);i++)
		for(j=(-WINDOW_SIZE/2);j<=(WINDOW_SIZE/2);j++)
		{
			if(Bli[Row+i][Col+j])
			{
				SumOn+=Orig[Row+i][Col+j];
				NbOn++;
			} 
			else
			{
				SumOff+=Orig[Row+i][Col+j];
				NbOff++;
			}  
		}

		if(SumOff)
			AvgOff=SumOff/(float)NbOff;
		else 
			AvgOff=0.0;

		if(SumOn)
			AvgOn=SumOn/(float)NbOn;
		else
			AvgOn=0.0;
		return (AvgOff-AvgOn);
}



//********************************************************************************
//embed
//Cette fonction retourne un pointeur sur un float qui de l'image initial ou l'on a 
//ajouté des bordure de largeur et de hauteur de Width
//********************************************************************************
float **CImage::embed(int taille,int *L,int *H)
{
	int i,j,I,J;

	float **Img=0;


	taille+=2;
	*L=Width+2*taille;
	*H=Height+2*taille;
	Img=AllocT_float(*L,*H);

	for(i=0;i<*L;i++)
		for(j=0;j<*H;j++)
		{
			I=(i-taille+Width)%Width;
			J=(j-taille+Height)%Height;
			Img[i][j]=(float)GetPixel(I,J,GRAY);		
		}

		return Img;
}

//********************************************************************************
//debed
//Cette fonction retourne inscrit l'image obtenue dans le buffer Dest en enlevant 
//les bordures ajoutées
//********************************************************************************
void CImage::debed(float **Img,int taille,int L,int H)
{
	int i,j;
	taille+=2;
	int Val;
	for(i=taille;i<L-taille;i++)
		for(j=taille;j<H-taille;j++)
		{
			Val=Limit((int)Img[i][j]);

			SetPixel(i-taille,j-taille,Val,Val,Val);		
		}
}


//Etire le contraste au maximum.
//Attention tous les pixels negatifs sont mis a 0
void MaxContraste(float **Img,int nRows,int nCols)
{
	int i,j;
	float X,Scale,Vmin,Vmax;
	Vmin=Img[50][50];
	Vmax=Vmin;
	for(i=0;i<nRows;i++)
	{
		for(j=0;j<nCols;j++)
		{
			if(i<OUTLINE || i>=nRows-OUTLINE || j<OUTLINE || j>=nCols-OUTLINE)
				continue;
			X=Img[i][j];
			if(X<0){Img[i][j]=0;X=0;}
			if(Vmin>X) Vmin=X;
			if(Vmax<X) Vmax=X;
		}
	}

	Scale = (float)(256.0/(Vmax-Vmin+1));

	for(i=0;i<nRows;i++)
		for(j=0;j<nCols;j++)
		{
			if(i<OUTLINE || i>=nRows-OUTLINE || j<OUTLINE || j>=nCols-OUTLINE)
				continue;
			
			Img[i][j]=((Img[i][j]-Vmin)*Scale);

		}



}


 Conclusion

Pour avoir toute la documentation sur ce programme vous pouvez visiter le site internet d'ImAnalyse:

http://ImAnalyse.free.fr

 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


 Historique

01 août 2008 13:48:52 :
Mise à jour du code et de la documentation en ligne: http://ImAnalyse.free.fr

 Sources du même auteur

Source avec Zip Source avec une capture VISUALISATION DES IMAGES EN 3D SANS OPENGL
Source avec Zip Source avec une capture ANALYSE DE LA TEXTURE D'UNE IMAGE : FILTRE DE GABOR
Source avec Zip Source avec une capture VIEWER COMPLET POUR LE TRAITEMENT DE L'IMAGE : IMANALYSE
Source avec Zip Source avec une capture ALGORITHMES D'OPTIMISATION NON LINÉAIRE: DESCENTE DE GRADIEN...
Source avec Zip Source avec une capture CLASSE GRAPH: GESTION DES GRAPHIQUES DANS LES APPLICATIONS W...

 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

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture VIEWER COMPLET POUR LE TRAITEMENT DE L'IMAGE : IMANALYSE par Pistol_Pete
Source avec Zip Source avec une capture WAVELET: TRANSFORMÉE EN ONDELETTE DISCRÈTE POUR LES IMAGES par Pistol_Pete
Source avec Zip Source avec une capture TRAITEMENT DES VIDÉOS AVI: IMANALYSE par Pistol_Pete
Source avec Zip Source avec une capture IMANALYSE : LOGICIEL DE TRAITEMENT DE L'IMAGE + DITHERING [W... par Pistol_Pete
Source avec Zip Source avec une capture DÉTECTION DES CERCLES DANS UNE IMAGE: HOUGH par Pistol_Pete

Commentaires et avis

Commentaire de MuPuF le 13/03/2008 14:45:13

Une technique sympathique de détection des contours (tu dois la connaitre) est de flouter légèrement l'image (filtre passe bas) puis de soustraire le résultat à l'image de départ, ça donne un résultat pas mal et a l'avantage de sortir les petits défauts de l'image.

J'ai vu ça dans un cours que je suis actuellement en Angleterre, le prof traite d'image comme il traite le son, c'est vraiment intéressant.

Sinon, comme d'habitude, très bonne source. C ya !

Commentaire de Pistol_Pete le 13/03/2008 18:09:07

Salut
Merci de ton commentaire.
La technique que tu me proposes est exactement celle que j'utilise pour mes algos de shenCastan et de Deriche. En ce qui concerne:  "flouter légerement", je laisse le choix a l'utilisateur mais cella donne de bien meilleurs resultats en général lorsque l'on filtre l'image d'une maniere importante.
Ici les filtres passebas utilisés ont une frequence de coupure tres faible!

Ton prof a totalement raison de faire le rapprochement entre le traitement de l'image et du son, parcequ'il y a selon moi qu'une unique difference: une image est compose de 2 dimensions.
D'ailleurs dans cette source, on utilise les termes ISEF, filtre RIF, filtres RII qui sont des termes que l'on retrouve .... en traitement du signal.
A+

Commentaire de MuPuF le 13/03/2008 19:12:19

fine, super, j'ai compris mon prof, je devrais pouvoir piger ta source dès que je serai en meilleur état :D

Commentaire de MuPuF le 13/03/2008 19:14:11 10/10

et voila, 10/10 (pas habitué à la nouvelle interface).

Commentaire de Amel3 le 10/04/2008 12:47:26

bonjour
je vous remercie vraiment je voudrais juste vous dire que je cherche la direction de la route pas le detection du route moi j'ai fait la detection semi automatique de la route par le filtre de sobel et je cherche la direction de la route sachant que cette route ne dépasse pas 15 pixel
merci bq

fatima

Commentaire de Amel3 le 10/04/2008 12:50:26

bon si vous voulez je vous donne le code en matlab pour mieux me comprend
merci

Commentaire de gaceur le 26/04/2008 11:50:27

Salut,
je veux bien avoir une idée sur le code en matlab.

Commentaire de hhabla le 03/06/2008 08:16:58

Exellent comme résultat!!, mais est ce que c possible d'utiliser des images de différents formats, exp JPG, JPEG ect....Merci

Commentaire de Amel3 le 03/06/2008 11:15:01

bonjour
pour les images bmp(bitmap)
vous pouvez trensformer ces images en bmp
moi je cherche mnt le code de kalman
kalman c'es un filtre il est utiliser pour la detection précise des route
qui paut m'aider sur ce code je l'ai en matlab mais en c++ non
merci

Commentaire de Pistol_Pete le 03/06/2008 21:23:42

Salut HHABLA
Bien que c'est possible d'utiliser des images jpeg. Il faut pour cela les transform?es en bitmap.

Regarde ma derni?re source:
http://www.cppfrance.com/codes/IMANALYSE-LOGICIEL-TRAITEMENT-IMAGE-DITHERING-WIN32_46507.aspx

Tu peux ouvrir des images bmp, jpeg et png et appliquer n'importe quel traitement dessus

A+

Commentaire de Pistol_Pete le 03/06/2008 21:30:22

>>Garceur, je ne vois aucun int?r?t de passer d'un code C en un code matlab! Ou peut ?tre c'est pour faire un algorithme beaucoup plus long.
Mais matlab peut faire marcher des codes en c, il faut te renseigner.

>>Amel, j'ai pas compris ta derni?re question:
"pour les images bmp(bitmap) vous pouvez transformer ces images en bmp"???

Pour le filtre de Kalman, ?a n'a aucun rapport avec cette sources, mais peut ?tre dans une prochaine version...
A+

Commentaire de hhabla le 04/06/2008 10:27:44

Salut;
Désolée j'arrive pas a voir les résultats de votre dernière version, il y'a un bug je crois?!; en fait je pensais à la même chose c'est à dire utiliser une fonction de conversion vers Bmp puis utiliser les algorithmes implémentés, les fichiers sur lesquels je dois appliquer ces algorithmes c'est des .avi;

Commentaire de hhabla le 04/06/2008 10:59:23

justement le PB réside pendant l'ouverture des fichiers.....

Commentaire de Pistol_Pete le 05/06/2008 11:39:55

Salut

HHABLA: Peux tu me dire ce qui se passe pour la derniere version de mon programme.
Est ce que c'est l'executable qui ne marche pas (y a t'il un message d'erreur)?
Ou c'est a la compilation qu'il y a des erreurs?

Merci a toi de m'aider a debogguer mon prog.

A+

Commentaire de Pistol_Pete le 01/08/2008 13:54:30

Salut
Voici la dernière version de mon logiciel sans boggue connu.

La documentation en ligne est enfin à jour et disponible sur le site web du logiciel:

http://ImAnalyse.free.fr

Commentaire de jijodi le 21/10/2008 17:06:35

Bonjour
Est ce que vous pouvez me donnez le code de Kalman en Matlab
merci

Commentaire de Pistol_Pete le 21/10/2008 20:17:31

Salut
Cette section de commentaire est réservée pour parler de cette source. Donc sur les algos de Canny Dériche Shen Castan...

Kalman est ici hors sujet. Poster sur le forum pourra peut être te donner plus d'information.
A+

Commentaire de lolkais le 08/04/2009 15:52:21

Bonjour,
J'aurais besoin de votre aide pour ouvrir le fichier cpp , avec quel version de VB C++ et quelle bibliothéques.
Meric de  mindiquer comment faire sachant que je suis electronicien et nouveau sur la programmation

Commentaire de Pistol_Pete le 08/04/2009 17:07:00

Salut
Comment ouvrir un fichier cpp: en double cliquant dessus...
Ce code est compilé avec VC++ 2005 mais compile sans problème avec VS 2008.
Il suffit d'ouvrir le projet et de compiler, il ne devrait pas y avoir d'erreur.

A+

Commentaire de lolkais le 08/04/2009 20:59:29

Merci de votre répons e, j'utilise CB C++ 6.0 il m affiche l erreur suivante :
c:\documents and settings\kais\bureau\c8\imanalyse\sources\cimage.cpp(250) : error C2362: initialization of 'picture' is skipped by 'goto errPicture'
        c:\documents and settings\kais\bureau\c8\imanalyse\sources\cimage.cpp(236) : see declaration of 'picture'
Error executing cl.exe.
le fichier que j ouvre est Cimage?
Merci de m aider

Commentaire de Pistol_Pete le 09/04/2009 08:54:31

Tu peux faire toutes les déclarations de variable en début de fonction PUIS ensuite l'initialisation des mêmes variables. Sinon, reconstruit la fonction sans les goto.
A+

Commentaire de Samardum le 20/04/2009 15:21:35

Bonjour,

J'aimerai avoir plus d'information sur la méthode utilisée pour la création du noyau gaussien dans le code "Canny".En fait, je pose deux questions:
1- comment justifier l'utilisation des valeurs i allant de 0 à 20 dans la création du kernel du noyau gaussien mono dimension. Pourquoi pas d'autres valeurs?
2- La fonction de densité de probabilité est
  f(x) = 1/sigma*sqrt(2*pi)*exp (-1/2(x-moy/sigma)(x-moy/sigma))
alors pourquoi dans le code vous utilisez
  f(x) = 1/sigma*sigma*2*pi*exp(-1/2*x/sigme*x/sigma)

Merci de m'éclairer sur ces questions.

Commentaire de Pistol_Pete le 28/04/2009 16:17:30

Salut Samardum

Pour ta première question, la taille du noyau gaussien n'est pas constante. Par contre sa taille maximal est de 20 pixels. Suivant la valeur de l'écart type que l'utilisateur spécifie, la gaussienne est plus ou moins "étroite" et la taille du filtre change:
//Creation du masque gaussian
for(i=0;i<MAX_SIZE_MASK;i++)
{
Gaussien[i]=MeanGauss((float)i,s);
dGaussien[i]=dGauss((float)i,s);
if(Gaussien[i]<0.005)
{
  taille=i;                <<- ici on arrête le filtre
  break;
}
}  

Pour ta seconde question, le filtre est centré donc moy=0, mais par contre pour la normalisation, je ne sais plus pourquoi j'ai pas pris 1/sigma*sqrt(2*pi)
Mais je ne pense pas que cela change grand chose, ce n'est qu'un facteur de normalisation. (A tester tout de même)

A+

Commentaire de Samardum le 29/04/2009 10:04:42

Bonjour tout le monde,

Merci PISTOL_PETE d'avoir répondu à ma question mais je ne suis pas toujours convaincue.
Pour moi le filtre est certes conçu d'une manière dynamique mais tjrs est-il que dans ton code il aura une taille contante puisque les élèments du kernel tu les calcul à partir des indices (i : 0 jusqu'à maxsize, taille maximale fixée à 20).
J'aurai compris que le filtre aurai eu une taille différente s'il prenait les valeurs de l'image car ces dernières changent effectivement d'une image à une autre), mais ce n'est pas le cas !!!!

Je voudrai bien savoir comment on construit un noyau gaussien car la méthode que tu utilises, combien même elle donne de bons résultats mais elle n'a pas de fondement mathématique.

De ma part, g implémenté le filtre de Canny en IDL car je travaille particulièrement sur les images satellitaires et g utilisé un noyau 5*5 que g trouvé dans la littérature.

Merci de me donner des élèments de réponse ou de m'orienter si possible.

Merci.

Commentaire de Pistol_Pete le 29/04/2009 10:35:25

Salut
Je le répète, la taille de ce filtre n'est pas constante. Elle dépendra de la valeur de l'écart type du bruit de ton image. Si l'image est fortement bruité, l'écart type sera fort, et le filtre sera large pour avoir un filtrage important.
Le bruit dans ton image est indépendant de la taille de ton image.


Relit bien le bout de code que j'ai mis lors de mon précédent post: la taille de ce filtre correspond bien à "taille" (la variable). Le break, n'est pas inutile...

Tu dis:
"La construction du noyau gaussien n'a pas de fondement mathématique"
Bien sur que si! (A part peut être l'erreur de normalisation). Pour moi c'est LA méthode pour construire un noyau gaussien.

Aussi, cela ne sert à rien d'utiliser un noyau 2D parce que la convolution peut être séparable. Donc un noyau 1D que l'on applique en x et en y convient très bien et la complexité de l'algo diminue fortement.
A+

Commentaire de Samardum le 29/04/2009 10:49:00

Re,

J'ai compris à quoi sert le test d'interromption du calcul du kernel. Y'a pas de soucis pour ça. Tu as mis une une valeur seuil audessous de laquelle, tu arrête la formation du filtre.

Ma grande question, en revanche, est :
Qu'est ce qui justifie l'utilisation des indices (i=0,..maxsize) pour le calcul du kernel.
tu calcules la gaussienne des indices pour générer les élmts du kernel. Pourquoi?

Merci d'avance.

Commentaire de Pistol_Pete le 05/05/2009 13:54:17

Oui je me sert des indices pour calculer la valeur de la gaussienne parce qu'il faut bien discrétiser un jour notre gaussienne. C'est aussi, pour cela, que la normalisation est un peu différente dans la formule. Cependant, tu peux construire ta gaussienne comme tu le souhaites. (avec n'importe qu'elle pas de discrétisation).

A+

Commentaire de corvite le 26/11/2009 21:22:36 10/10

Bonjour,

Super boulot que vous avez effectué Pistol_Pete. Merci de l'avoir "posté" ici afin que nous puissions en profiter.

Je suis étudiant en informatique et je dois développer un projet qui en gros consiste à identifier des images... Afin d'atteindre ce but, je dois au préalable transformer mes images d'origine afin que l'identification soit plus aisé. Je voulais donc profiter de certaines fonctions de votre projet pour les adapter au mien.

Le soucis que j'ai, c'est que quand j'essaie de générer votre code avec VS 2008, j'ai l'erreur suivante : error C2065: 'IDC_HAND' : undeclared identifier

Pouvez-vous m'aider à corriger cette erreur?

Pour info, je dois développer mon projet en C#... Donc votre projet me servira principalement dans la compréhension des filtres qu'on peut appliquer sur les images. J'ai donc pas mal d'expérience avec les langages C# et JAVA mais beaucoup moins en C++.

Merci

Commentaire de Pistol_Pete le 27/11/2009 08:55:21

Salut

Merci de ton commentaire. L'erreur que tu obtients peux être très facilement corrigé en remplacant IDC_HAND par IDC_NO par exemple.
Si tu veux garder IDC_HAND, il corrigé la ligne suivante
#define _WIN32_WINNT     0x0400 => 0x0500

A+

Commentaire de corvite le 27/11/2009 12:22:32

Merci, c'est ce que j'ai fait quelques minutes après avoir posté mon commentaire et ça a marché ;)

Sinon, au plus je m'amuse avec ton "petit" soft, au plus je suis épaté ;)
Encore bravo pour ce travail.

A+

Commentaire de saidousguine le 03/01/2010 19:48:46

salut merci de votre code sources de c++ de filtres optimale de shen casten et duriche et cynnty mais le pb est ce que tu avais une cmde matlab de detecter les contour de image par filtre de shen casten ou duriche j'ai fait help au matlab mais il avait aucun réponse et aucun toolbox avait ces contour  donc j'ai besoin s'il vous plais une commande qui détecte les contour de image par les filtre optimal canny et shen casten et duriche et un tooolbox au matlab de ces contour et merci beaucoup

Commentaire de mohamedbenhlima le 12/02/2010 19:44:51

bjr, moi j'ai l'erreur suivante sur vc++ (error C2065: 'GET_WHEEL_DELTA_WPARAM' : undeclared identifier)

Commentaire de Pistol_Pete le 15/02/2010 16:32:20

Salut
Il faut que tu remplaces la définition de macro _WIN32_WINNT par celle la:
#define _WIN32_WINNT 0x0501
A+

Commentaire de Samardum le 26/04/2010 16:16:46

Bonjour tout le monde,

Concernant les filtres ISEF appliqués sur une image, j'aimerai savoir que signifie le paramètre b dans : f(x) = a x b (à la puissance valeur absolue de x)
avec 0<b<1

J'ai lu dans un commentaire dans votre code que plus b est faible, plus le bruit est important et plus il y'a de détails.

Pourquoi ?

Merci d'avance.

Commentaire de Pistol_Pete le 26/04/2010 17:11:57

Le filtre de ISEF dans Shen-Castan est construite de manière récursive: b est effectivement compris entre 0 et 1 et est appelé un smoothing factor, un facteur de lissage. Plus b est faible, et plus le lissage de limage est faible. On conservera donc plus de contours. A l'inverse, si b est élevé, le lissage de l'image sera important et moins de contours seront détectés.  

Si tu as une image très bruité, il vaut mieux prendre un b proche de 1.
A+

Commentaire de Samardum le 27/04/2010 09:29:55

Bonjour,
J'ai testé les filtres ISEF sur une image satellitaire (panchromatique avec une résolution spatiale de 10 m) avec un b = 0.2. Les résultats semblent correctes.
Merci beaucoup Pistol_Pete d'avoir éclairer ma lanterne.
A+

Commentaire de nguene79 le 08/03/2011 15:57:53

Salut j'aimerai traiter des images satellitaires en nuance de gris ( près de 8000 images) avec MATLAB ou tout autre logiciel pratique.
Le problème consiste à mesurer au niveau de chaque pixel un indice appelé CCD (cold cloud duration).
Le problème peut être décomposé  en 4 étapes:

1ere étape

- seuiller les images de façon à faire apparaitre uniquement les pixels dont la valeur pval est supérieure à 176

2eme étape

- sur une série de 12 images,en parcourant chacune d'elle, au niveau de chaque pixel, il faut incrémenter un compteur appelé CCD chaque fois que le pixel en question a une valeur supérieure à 176  

3eme étape

- A la fin de la série, après avoir parcouru les 12 images, Au niveau de chaque pixel, on doit disposer de la valeur du compteur CCD afin de savoir combien de fois la valeur de ce pixel a été supérieure à 176

4eme étape

-Le résultat doit être une image exprimant la valeur du compteur en chaque pixel.On pourra utiliser une table (look up table) qui renseignera en fonction de la couleur sur l'image de la valeur du compteur CCD

Merci de m'y aider.

Commentaire de Pistol_Pete le 08/03/2011 17:56:49

Salut

Il suffit de faire un seuil (un test pour chaque pixel) à 176 puis de maintenir une image compteur, il n'y a rien de compliquer.

Commentaire de altyok le 06/04/2011 17:10:03

salut PISTOL_PETE

je suis aller sur ton site et j'ai vu que tu fait bcp de programme sur le traitement de l'image et donc je pense que tu pourrais m'aider.
moi je cherche a réaliser une reconnaissance de forme sur un signal vidéo. j'ai une caméra qui film l'entrée d'un parking et je dois différencier les piétons des voitures et je pensais donc faire sa par reconnaissance de forme.
pense tu que ce projet peut être réalisable et aurais-tu une idée de départ.

merci
A+

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Filtre Canny-Derriche / Détection de contour d'un raster [ par nouse ] Salutj'aurais besoin d'un peu d'aideEst ce que qq 1 a un code permettant d'appliquer les filtres de canny-derriche ou de shen castan sur des images de Contours actifs et LevelSet [ par FiReTiTi ] Bonjour,dans le cadre de ma th&#232;se, je m'int&#233;resse ponctuellement aux contours actifs et levelset. J'ai une version des levelset qui fontionn Skins : form "polygonale" sans titre mais déplaçable quand même ? [ par steph12358 ] Salut à tousJe sais déjà faire une fenêtre polygonale. Histoire de ne plus voir un bout de la barre de titre qui dépasse j'ai supprimé la bordure (de Algorithme de Canny pour image YUV [ par amalgi ] Salut, je cherche un code source pour l'algorithme de Canny ( détection de contours) pour les images de types YUV(qcif,cif). J'ai trouvé pour les form algo canny [ par salma2011 ] Slt tt le monde,,Je veux detecter les contours d'une image avec l'algorithme de canny  en utilisant le langage c++  ..je veux un simple code( en c++ ) suivi des contours en c++ [ par salma2011 ] Salam tt le monde..je veux obtenir la matrice des suivi des contours d'une image apres la segmentation mais je sais pas comment la faire.Pour mieux ex [MATLAB]comment programmer la methode des contours actifs en matlab? [ par latorpille ] bonjour je voudrais programmer la méthode des contours actifs en matlab. je suis novice en info et je ne sais par ou commencer.si quelqu'un a des con détéction des blobs(contours) et filtre median-traitement d'image- [ par marouene2706 ] bonjour comme le titre l'indique, je cherche de l'aide pour la creation d'un filtre median en C d'une part, et d'une autre part , une idée pour la dét


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

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

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