IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Discussion :

[Image] Détecteur de Harris pour ImageJ


Sujet :

Contribuez

  1. #61
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par mobi_bil Voir le message
    1 : Pourquoi vous vérifiez si la valeur absolue de harris et laplacian est inférieure à 1 ? ( ce n'est pas le cas de l'ancien detecteur HarrisFast).
    Dans l'implémentation HarrisFast, il y a aussi un seuil (paramètre minMeasure de la méthode filter()).

    Dans Harris-Laplace j'ai mis une valeur en dur dans le code. J'ai codé cette implémentation rapidement alors elle n'est sans doute pas aussi aboutie que les autres. Libre à chacun de la modifier selon ses besoins.

    2 : Est ce que le but de diviser la valeur de harris par 255*255 est de manipuler de petites valeurs ?
    Dans la plupart des documents mathématiques sur le traitement d'image, on utilise des valeurs d'intensité entre 0 et 1. Cette division sert a cela. Dans l'implémentation HarrisFast je divisais les éléments de la matrice (avant le calcul de la mesure). Ici je divise le résultat.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  2. #62
    Membre du Club
    Inscrit en
    Juillet 2009
    Messages
    81
    Détails du profil
    Informations personnelles :
    Âge : 35

    Informations forums :
    Inscription : Juillet 2009
    Messages : 81
    Points : 65
    Points
    65
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Continuons avec l'extraction des points caracteristiques. Apres les contours (Canny), passons maintenant aux coins avec Harris.

    Le detecteur de Harris est un detecteur assez simple qui permet d'extraire les "coins" des contours. Les points récupérés sont souvent utilisés dans les algorithmes de reconnaissance de forme.



    plus d'info: http://en.wikipedia.org/wiki/Corner_detection

    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
     
    import ij.IJ;
    import ij.ImagePlus;
    import ij.gui.GenericDialog;
    import ij.plugin.filter.PlugInFilter;
    import ij.process.ByteProcessor;
    import ij.process.ImageProcessor;
     
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
     
     
    /**
     * Harris Corner Detector
     * 
     * @author Xavier Philippeau
     *
     */
    public class Harris_ implements PlugInFilter {
     
    	// corners list
    	List<int[]> corners = new ArrayList<int[]>();
     
    	// halfwindow size (integration, kernels)
    	private int halfwindow = 0;
     
    	// variance of gaussians
    	private double gaussiansigma = 0;
     
    	// corner filtering
    	private int minDistance = 0;
    	private int minMeasure = 0;
     
    	// Gradient kernel
    	GradientVector gradient = new GradientVector();
     
    	//	 About...
    	private void showAbout() {
    		IJ.showMessage("Harris...","Harris Corner Detector by Pseudocode");
    	}
     
    	public int setup(String arg, ImagePlus imp) {
     
    		// about...
    		if (arg.equals("about")) {
    			showAbout(); 
    			return DONE;
    		}
     
    		// else...
    		if (imp==null) return DONE;
     
    		// Configuration dialog.
    		GenericDialog gd = new GenericDialog("Parameters");
    		gd.addNumericField("Half-Window size",1,0);
    		gd.addNumericField("Gaussian sigma",1.4,1);
    		gd.addNumericField("Min Harris measure for corners",10,0);
    		gd.addNumericField("Min distance between corners",8,0);
     
    		int  halfwindow = 0;
    		double gaussiansigma = 0;
    		int minMeasure = 0;
    		int minDistance = 0;
     
    		while(true) {
    			gd.showDialog();
    			if ( gd.wasCanceled() )	return DONE;
     
    			halfwindow     = (int) gd.getNextNumber();
    			gaussiansigma  = (double) gd.getNextNumber();
    			minMeasure     = (int) gd.getNextNumber();
    			minDistance    = (int) gd.getNextNumber();
     
    			if (halfwindow<=0) continue;
    			if (gaussiansigma<=0) continue;
    			if (minMeasure<0) continue;
    			if (minDistance<0) continue;
    			break;
    		}
    		gd.dispose();
     
    		this.halfwindow = halfwindow;
    		this.gaussiansigma = gaussiansigma;
    		this.minMeasure = minMeasure;
    		this.minDistance = minDistance;
     
    		return PlugInFilter.DOES_8G;
    	}
     
    	public void run(ImageProcessor ip) {
     
    		// ImageProcessor -> ByteProcessor conversion
    		ByteProcessor bp = new ByteProcessor(ip.getWidth(),ip.getHeight());
    		for (int y = 0; y < ip.getHeight(); y++) {
    			for (int x = 0; x < ip.getWidth(); x++) {
    				bp.set(x,y,ip.getPixel(x,y));
    			}
    		}
     
    		// canny filter
    		ByteProcessor newbp = filter( bp, this.minMeasure, this.minDistance );
     
    		// ByteProcessor -> ImageProcessor conversion
    		ImageProcessor out = new ByteProcessor(ip.getWidth(),ip.getHeight());
    		for (int y = 0; y < ip.getHeight(); y++) {
    			for (int x = 0; x < ip.getWidth(); x++) {
    				out.set(x,y,newbp.get(x,y));
    			}
    		}
    		ImagePlus newImg = new ImagePlus("Canny Filter Result", out);
    		newImg.show();
     
    	}
     
    	// -------------------------------------------------------------------------
     
    	/**
             * Gaussian window function
             * 
             * @param x x coordinates
             * @param y y coordinates
             * @param sigma2 variance
             * @return value of the function
             */
    	private double gaussian(double x, double y, double sigma2) {
    		double t = (x*x+y*y)/(2*sigma2);
    		double u = 1.0/(2*Math.PI*sigma2);
    		double e = u*Math.exp( -t );
    		return e;
    	}
     
    	/**
             * compute harris measure for a pixel
             * 
             * @param c Image map
             * @param x x coord of the computation
             * @param y y coord of the computation
             * @return harris measure 
             */
    	private double harrisMeasure(ByteProcessor c, int x, int y) {
    		double m00=0, m01=0, m10=0, m11=0;
     
    		// Harris estimator
    		// ----------------
    		//
    		// k = det(A) - lambda * trace(A)^2
    		//
    		// Where A is the second-moment matrix 
    		//
    		//           | Lx²(x+dx,y+dy)    Lx.Ly(x+dx,y+dy) |
    		// A =  Sum  |                                    | * Gaussian(dx,dy)
    		//     dx,dy | Lx.Ly(x+dx,y+dy)  Ly²(x+dx,y+dy)   |
    		//
    		// and lambda = 0.06  (totaly empirical :-)
     
    		for(int dy=-halfwindow;dy<=halfwindow;dy++) {
    			for(int dx=-halfwindow;dx<=halfwindow;dx++) {
    				int xk = x + dx;
    				int yk = y + dy;
    				if (xk<0 || xk>=c.getWidth()) continue;
    				if (yk<0 || yk>=c.getHeight()) continue;
     
    				// gradient value
    				double[] g = gradient.getVector(c,xk,yk);
    				double gx = g[0];
    				double gy = g[1];
     
    				// gaussian window
    				double gw = gaussian(dx,dy,gaussiansigma);
     
    				// second-moment matrix elements
    				m00 += gx * gx * gw;
    				m01 += gx * gy * gw;
    				m10 = m01;
    				m11 += gy * gy * gw;
    			}
    		}
     
    		// Harris corner measure 
    		double harris = m00*m11 - m01*m10 - 0.06*(m00+m11)*(m00+m11);
     
    		// scaled down
    		return harris/(256*256);
    	}
     
    	/**
             * return the the measure at pixel (x,y) if the pixel is a spatial Maxima, else return -1
             * 
             * @param c original image 
             * @param x x coordinates of pixel
             * @param y y coordinates of pixel
             * @return the measure if the pixel is a spatial Maxima, else -1
             */
    	private double spatialMaximaofHarrisMeasure(ByteProcessor c, int x, int y) {
    		int n=8;
    		int[] dx = new int[] {-1,0,1,1,1,0,-1,-1};
    		int[] dy = new int[] {-1,-1,-1,0,1,1,1,0};
    		double w =  harrisMeasure(c,x,y);
    		for(int i=0;i<n;i++) {
    			double wk = harrisMeasure(c,x+dx[i],y+dy[i]);
    			if (wk>=w) return -1;
    		}
    		return w;
    	}
     
    	/**
             * Perfom Harris Corner Detection
             * 
             * @param c Image map
             * @param tilesize size of a tile 
             * @param nmbmax max number of corner to keep
             * @return filtered image map
             */
    	public ByteProcessor filter(ByteProcessor c, int minMeasure, int minDistance) {
    		int width = c.getWidth();
    		int height = c.getHeight();
     
    		// copy of the original image (at little darker)
    		ByteProcessor c2 = new ByteProcessor(width,height);
    		for (int y=0; y<height; y++)
    			for (int x=0; x<width; x++)
    				c2.set(x,y,(int)(c.get(x,y)*0.80));
     
    		// for each tile in the image
    		for (int y=0; y<height; y++) {
    			for (int x=0; x<width; x++) {
    				// harris measure
    				int h = (int)spatialMaximaofHarrisMeasure(c, x, y);
     
    				// add the corner to the list
    				if (h>=minMeasure) corners.add( new int[]{x,y,h} );
    			}
    		}
     
    		// remove corners to close to each other (keep the highest measure)
    		Iterator<int[]> iter = corners.iterator();
    		while(iter.hasNext()) {
    			int[] p = iter.next();
    			for(int[] n:corners) {
    				if (n==p) continue;
    				int dist = (int)Math.sqrt( (p[0]-n[0])*(p[0]-n[0])+(p[1]-n[1])*(p[1]-n[1]) );
    				if( dist>minDistance) continue;
    				if (n[2]<p[2]) continue;
    				iter.remove();
    				break;
    			}
    		}
     
    		// Display corners over the image (cross)
    		for (int[] p:corners) {
    			for (int dx=-2; dx<=2; dx++) {
    				if (p[0]+dx<0 || p[0]+dx>=width) continue;
    				c2.set(p[0]+dx,p[1],255);
    			}
    			for (int dy=-2; dy<=2; dy++) {
    				if (p[1]+dy<0 || p[1]+dy>=height) continue;
    				c2.set(p[0],p[1]+dy,255);
    			}
    			//System.out.println("corner found at: "+p[0]+","+p[1]+" ("+p[2]+")");
    		}		
     
    		return c2;
    	}
     
    	public class GradientVector {
     
    		int halfwindow = 1; // 3x3 kernel
    		double sigma2 = 1.4;
     
    		double[][] kernelGx = new double[2*halfwindow+1][2*halfwindow+1];
    		double[][] kernelGy = new double[2*halfwindow+1][2*halfwindow+1];
     
    		// Constructor
    		public GradientVector() {
    			for(int y=-halfwindow;y<=halfwindow;y++) {
    				for(int x=-halfwindow;x<=halfwindow;x++) {
    					kernelGx[halfwindow+y][halfwindow+x] = Gx(x, y);
    					kernelGy[halfwindow+y][halfwindow+x] = Gy(x, y);
    				}
    			}
    		}
     
    		// Kernel functions (gaussian 1st order partial derivatives)
    		private double Gx(int x, int y) {
    			double t = (x*x+y*y)/(2*sigma2);
    			double d2t = -x / sigma2;
    			double e = d2t * Math.exp( -t );
    			return e;
    		}
     
    		private double Gy(int x, int y) {
    			double t = (x*x+y*y)/(2*sigma2);
    			double d2t = -y / sigma2;
    			double e = d2t * Math.exp( -t );
    			return e;
    		}
     
    		// return the Gradient Vector for pixel(x,y) 
    		public double[] getVector(ByteProcessor c, int x, int y) {
    			double gx=0, gy=0;
    			for(int dy=-halfwindow;dy<=halfwindow;dy++) {
    				for(int dx=-halfwindow;dx<=halfwindow;dx++) {
    					int xk = x + dx;
    					int yk = y + dy;
    					double vk = c.getPixel(xk,yk); // <-- value of the pixel
    					gx += kernelGx[halfwindow-dy][halfwindow-dx] * vk;
    					gy += kernelGy[halfwindow-dy][halfwindow-dx] * vk;
    				}
    			}
     
    			double[] gradientVector = new double[] { gx, gy };
     
    			return gradientVector;
    		}	
    	}
    }

    Vous trouverez une version "stand-alone" de ce code au Post #14

    Et également une version sous forme de Plugin pour l'application de Millie ici -> HarrisDetectionPlugin.jar
    Bonjour Monsieur,
    Merci pour le code que je vais utiliser pour la detection des points d'interet
    Mais aprés la detection des points je dois bien sur determiner un descripteur de ces point (est ce que je dois fire un descripteur pour chaque point ou un et un seule descripteur pour touts les point)
    et sur quelles formules mathematiques dois je me baser pour determiner ce ou ces descripteur!!!
    Merci beaucoup pour votre aide

  3. #63
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par amira88 Voir le message
    Mais aprés la detection des points je dois bien sur determiner un descripteur de ces point (est ce que je dois fire un descripteur pour chaque point ou un et un seule descripteur pour touts les point)
    Un descripteur par point d'intérêt.

    et sur quelles formules mathematiques dois je me baser pour determiner ce ou ces descripteur!!!
    Des descripteurs il en existe plein : moments, SIFT, FAST, MPEG7, ...

    Ils ont chacun leurs propres particularités : généralement des invariances en rotation, échelle, luminance, ... et de la robustesse au bruit, discrétisation, ...
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  4. #64
    Membre du Club
    Inscrit en
    Juillet 2009
    Messages
    81
    Détails du profil
    Informations personnelles :
    Âge : 35

    Informations forums :
    Inscription : Juillet 2009
    Messages : 81
    Points : 65
    Points
    65
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Un descripteur par point d'intérêt.



    Des descripteurs il en existe plein : moments, SIFT, FAST, MPEG7, ...

    Ils ont chacun leurs propres particularités : généralement des invariances en rotation, échelle, luminance, ... et de la robustesse au bruit, discrétisation, ...
    Merci pour votre reponse treeeeeeees rapide ,mais moments, SIFT, FAST, MPEG7 ne sont pas des formules !!! donc comment les integrer avec votre code de Harris!
    Merci enrcore

  5. #65
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par amira88 Voir le message
    Merci pour votre reponse treeeeeeees rapide ,mais moments, SIFT, FAST, MPEG7 ne sont pas des formules !!! donc comment les integrer avec votre code de Harris!
    Merci enrcore
    Tous ces descripteurs se calculent a partir d'un voisinage du point d'intérêt.

    Ils convertissent donc un ensemble de N pixels (le voisinage) en un vecteur de K valeurs ( = la valeur du descripteur )

    La méthode de conversion n'est pas forcément une "simple" formule mathématique, mais peut nécessiter des transformations/calculs intermédiaires.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  6. #66
    Membre du Club
    Inscrit en
    Juillet 2009
    Messages
    81
    Détails du profil
    Informations personnelles :
    Âge : 35

    Informations forums :
    Inscription : Juillet 2009
    Messages : 81
    Points : 65
    Points
    65
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Tous ces descripteurs se calculent a partir d'un voisinage du point d'intérêt.

    Ils convertissent donc un ensemble de N pixels (le voisinage) en un vecteur de K valeurs ( = la valeur du descripteur )

    La méthode de conversion n'est pas forcément une "simple" formule mathématique, mais peut nécessiter des transformations/calculs intermédiaires.
    Merci,
    Mais ou pouvais-je trouver toute ces information :"des transformations/calculs intermédiaires" .
    est ce qui'il y a des cours!!

  7. #67
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par amira88 Voir le message
    Merci,
    Mais ou pouvais-je trouver toute ces information :"des transformations/calculs intermédiaires" .
    est ce qui'il y a des cours!!
    Des "cours" je ne sais pas. Ce sont plutôt des documents d'études/recherches universitaires. Tu peux faire une recherche google sur les mots clés "local image descriptor" pour avoir une idée de ce qui existe.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  8. #68
    Membre du Club
    Inscrit en
    Juillet 2009
    Messages
    81
    Détails du profil
    Informations personnelles :
    Âge : 35

    Informations forums :
    Inscription : Juillet 2009
    Messages : 81
    Points : 65
    Points
    65
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Des "cours" je ne sais pas. Ce sont plutôt des documents d'études/recherches universitaires. Tu peux faire une recherche google sur les mots clés "local image descriptor" pour avoir une idée de ce qui existe.
    Merci beaucoup pour votre aide je vais essayer la recherche sur google!!

  9. #69
    Membre averti
    Inscrit en
    Février 2006
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 707
    Points : 366
    Points
    366
    Par défaut
    Bonjour,

    Je ne trouve pas Harry.java et je voudrais le télécharger.

    Pouvez-vous me donner l'adresse de ce plug-in pour imageJ ?

    Merci d'avance

    Battant
    Battant

  10. #70
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par Battant Voir le message
    Bonjour,

    Je ne trouve pas Harry.java et je voudrais le télécharger.

    Pouvez-vous me donner l'adresse de ce plug-in pour imageJ ?

    Merci d'avance

    Battant
    Le code n'est pas dispo sous forme de fichier. Pour ImageJ, il suffit de prendre le code posté dans le message #1, et le coller dans un fichier vide qu'on sauvera sous le nom "Harris_.java"
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  11. #71
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 1
    Points : 1
    Points
    1
    Par défaut the step of key points matching
    Bonjour,
    En fait, je travail sur le recalage d’image médicale en java,
    Tout d’abord j’ai essayé avec SIFT mais j’ai pas pu l’appliquer en java, puis j’ai traveillé avec Harris et ça marche très bien pour la détection de points d’intérêt, alors maintenant je suis en train de travailler sur le descripteur pour faire le matching, mais j’arrive pas a le faire « ça fait 3 semaines», j’ai cherché bcp pour utiliser « moment » avec Harris pour le faire mais « in vain », est ce que vous pourrais m’aider SVP..

  12. #72
    Futur Membre du Club
    Inscrit en
    Avril 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 7
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Merci. Je n'ai pas vraiment de merite. Cet algo est largement connu, je n'ai fait que le réecrire en Java.

    En fait, a l'instar de millie, je fais un peu de menage dans mes archives de code. J'en profite pour remettre au propre et poster les algos usuels.
    stp est ce qu'il ya une version matlab du code java (détecteur de harris)??

  13. #73
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par noosa Voir le message
    stp est ce qu'il ya une version matlab du code java (détecteur de harris)??
    bilzzbenzbilz a posté une implémentation au post #28.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  14. #74
    Futur Membre du Club
    Inscrit en
    Avril 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 7
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    bilzzbenzbilz a posté une implémentation au post #28.
    oui deja je l'a essayé cette version, mais elle ne donne pas le résultat attendu,
    normalement je dois obtenir une image avec des croix qui indiquent les points d'intérêt de harris mais je trouve rien !!!!
    en plus j'ai essayé de changer l'image qu'il utilise 'cameraman.tif' , le code ne fonctionne plus, stp comment je peux m'en sortiiiir ????

  15. #75
    Futur Membre du Club
    Inscrit en
    Avril 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 7
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Le résultat sans doute pas, mais la vitesse surement...

    J'en profite pour poster une version "stand-alone" du filtre, qui précalcule les valeurs filtrés des derivées F*Lx², F*Ly² et F*Lxy pour accelerer le temps de traitement (au detriment de la mémoire).

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
     
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
     
     
    /**
     * Harris Corner Detector
     *              
     *  k = det(A) - k * trace(A)^2
     * 
     *  Where A is the second-moment matrix 
     * 
     *            | Lx²(x+dx,y+dy)    Lx.Ly(x+dx,y+dy) |
     *  A =  Sum  |                                    | * Gaussian(dx,dy)
     *      dx,dy | Lx.Ly(x+dx,y+dy)  Ly²(x+dx,y+dy)   |
     * 
     *  and k = a/(1+a)^2, 
     *  
     *  where "a" is the mininmum ratio between the two eigenvalues
     *  for a point to be considered as a corner.
     *  
     * @author Xavier Philippeau
     */
    public class HarrisFast  {
     
    	// corner class
    	class Corner {
    		int x,y; // corner position
    		float h; // harris measure
    		public Corner(int x, int y, float h) {
    			this.x=x; this.y=y; this.h=h;
    		}
    	}
     
    	// corners list
    	List<Corner> corners = new ArrayList<Corner>();
     
    	// image
    	private int[][] image;
    	int width,height;
     
    	// precomputed values of the derivatives
    	private float[][] Lx2,Ly2,Lxy;
     
    	/**
             *  Constructor
             */
    	public HarrisFast(int[][] image, int width, int height) {
    		this.image = image;
    		this.width = width;
    		this.height = height;
    	}
     
    	/**
             * Gaussian function
             */
    	private double gaussian(double x, double y, double sigma) {
    		double sigma2 = sigma*sigma;
    		double t = (x*x+y*y)/(2*sigma2);
    		double u = 1.0/(2*Math.PI*sigma2);
    		double e = u*Math.exp( -t );
    		return e;
    	}
     
    	/**
             * Sobel gradient 3x3
             */
    	private float[] sobel(int x, int y) {
    		int v00=0,v01=0,v02=0,v10=0,v12=0,v20=0,v21=0,v22=0;
     
    		int x0 = x-1, x1 = x, x2 = x+1;
    		int y0 = y-1, y1 = y, y2 = y+1;
    		if (x0<0) x0=0;
    		if (y0<0) y0=0;
    		if (x2>=width) x2=width-1;
    		if (y2>=height) y2=height-1;
     
    		v00=image[x0][y0]; v10=image[x1][y0]; v20=image[x2][y0];
    		v01=image[x0][y1];                    v21=image[x2][y1];
    		v02=image[x0][y2]; v12=image[x1][y2]; v22=image[x2][y2];
     
    		float sx = ((v20+2*v21+v22)-(v00+2*v01+v02))/(4*255f);
    		float sy = ((v02+2*v12+v22)-(v00+2*v10+v20))/(4*255f);
    		return new float[] {sx,sy};
    	}
     
     
    	/**
             * Compute the 3 arrays Ix, Iy and Ixy
             */
    	private void computeDerivatives(double sigma){
    		this.Lx2 = new float[width][height];
    		this.Ly2 = new float[width][height];
    		this.Lxy = new float[width][height];
     
    		// gradient values: Gx,Gy
    		float[][][] grad = new float[width][height][];
    		for (int y=0; y<height; y++)
    			for (int x=0; x<width; x++)
    				grad[x][y] = sobel(x,y);
     
    		// precompute the coefficients of the gaussian filter
    		int radius = (int)(2*sigma);
    		int window = 1+2*radius;
    		float[][] gaussian = new float[window][window];
    		for(int j=-radius;j<=radius;j++)
    			for(int i=-radius;i<=radius;i++)
    				gaussian[i+radius][j+radius]=(float)gaussian(i,j,sigma);
     
    		// Convolve gradient with gaussian filter:
    		//
    		// Ix2 = (F) * (Gx^2)
    		// Iy2 = (F) * (Gy^2)
    		// Ixy = (F) * (Gx.Gy)
    		//
    		for (int y=0; y<height; y++) {
    			for (int x=0; x<width; x++) {
     
    				for(int dy=-radius;dy<=radius;dy++) {
    					for(int dx=-radius;dx<=radius;dx++) {
    						int xk = x + dx;
    						int yk = y + dy;
    						if (xk<0 || xk>=width) continue;
    						if (yk<0 || yk>=height) continue;
     
    						// gaussian weight
    						double gw = gaussian[dx+radius][dy+radius];
     
    						// convolution
    						this.Lx2[x][y]+=gw*grad[xk][yk][0]*grad[xk][yk][0];
    						this.Ly2[x][y]+=gw*grad[xk][yk][1]*grad[xk][yk][1];
    						this.Lxy[x][y]+=gw*grad[xk][yk][0]*grad[xk][yk][1];
    					}
    				}
    			}
    		}
    	}
     
    	/**
             * compute harris measure for a pixel
             */
    	private float harrisMeasure(int x, int y, float k) {
    		// matrix elements (normalized)
    		float m00 = this.Lx2[x][y]; 
    		float m01 = this.Lxy[x][y];
    		float m10 = this.Lxy[x][y];
    		float m11 = this.Ly2[x][y];
     
    		// Harris corner measure = det(M)-k.trace(M)^2
    		return m00*m11 - m01*m10 - k*(m00+m11)*(m00+m11);
    	}
     
    	/**
             * return true if the measure at pixel (x,y) is a local spatial Maxima
             */
    	private boolean isSpatialMaxima(float[][] hmap, int x, int y) {
    		int n=8;
    		int[] dx = new int[] {-1,0,1,1,1,0,-1,-1};
    		int[] dy = new int[] {-1,-1,-1,0,1,1,1,0};
    		double w =  hmap[x][y];
    		for(int i=0;i<n;i++) {
    			double wk = hmap[x+dx[i]][y+dy[i]];
    			if (wk>=w) return false;
    		}
    		return true;
    	}
     
    	/**
             * compute the Harris measure for each pixel of the image
             */
    	private float[][] computeHarrisMap(double k) {
     
    		// Harris measure map
    		float[][] harrismap = new float[width][height];
     
    		// for each pixel in the image
    		for (int y=0; y<height; y++) {
    			for (int x=0; x<width; x++) {
    				// compute the harris measure
    				double h =  harrisMeasure(x,y,(float)k);
    				if (h<=0) continue;
    				// log scale
    				h = 255 * Math.log(1+h) / Math.log(1+255);
    				// store
    				harrismap[x][y]=(float)h;
    			}
    		}
     
    		return harrismap;
    	}
     
    	/**
             * Perfom the Harris Corner Detection
             * 
             * @param sigma gaussian filter parameter 
             * @param k parameter of the harris measure formula
             * @param minDistance minimum distance between corners
             * @return the orginal image marked with cross sign at each corner
             */
    	public int[][] filter(double sigma, double k, int minDistance) {
     
    		// precompute derivatives
    		computeDerivatives(sigma);
     
    		// Harris measure map
    		float[][] harrismap = computeHarrisMap(k);
     
    		// for each pixel in the harrismap 
    		for (int y=1; y<height-1; y++) {
    			for (int x=1; x<width-1; x++) {
    				// thresholding : harris measure > epsilon
    				float h = harrismap[x][y];
    				if (h<=1E-3) continue;
    				// keep only a local maxima
    				if (!isSpatialMaxima(harrismap, x, y)) continue;
    				// add the corner to the list
    				corners.add( new Corner(x,y,h) );
    			}
    		}
     
    		System.out.println(corners.size()+" potential corners found.");
     
    		// remove corners to close to each other (keep the highest measure)
    		Iterator<Corner> iter = corners.iterator();
    		while(iter.hasNext()) {
    			Corner p = iter.next();
    			for(Corner n:corners) {
    				if (n==p) continue;
    				int dist = (int)Math.sqrt( (p.x-n.x)*(p.x-n.x)+(p.y-n.y)*(p.y-n.y) );
    				if(dist>minDistance) continue;
    				if (n.h<p.h) continue;
    				iter.remove();
    				break;
    			}
    		}
     
    		// output
    		int[][] output =new int[width][height];
    		for (int y=0; y<height; y++)
    			for (int x=0; x<width; x++)
    				output[x][y]=(int)(image[x][y]*0.75); // original image (darker)
     
    		// for each corner
    		for (Corner p:corners) {
    			// add the cross sign over the image
    			for (int dt=-3; dt<=3; dt++) {
    				if (p.x+dt>=0 && p.x+dt<width ) output[p.x+dt][p.y]=255;
    				if (p.y+dt>=0 && p.y+dt<height) output[p.x][p.y+dt]=255;
    			}
    			System.out.println("corner found at: "+p.x+","+p.y+" ("+p.h+")");
    		}		
    		System.out.println(corners.size()+" corners found.");
     
    		return output;
    	}
    }

    Pour l'utiliser:
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int[][] input = ... // tableau 2D [x][y] contenant l'image en niveau de gris (0-255)
    int width     = ... // largeur de l'image
    int height    = ... // hauteur de l'image
     
    int sigma   = 1.2;  // parametre du filtre gaussien
    int k       = 0.06; // parametre de la formule de la mesure
    int spacing = 8;    // distance minimum entre 2 coins
     
    int[][] output = new HarrisFast(img,width,height).filter(sigma,k,spacing);
     
    // output[][] : image d'entrée avec les coins marqués par des croix
    bonjour,
    pour ce code, normalement int[][] input c'est le paramètre img??
    aussi, si j'ai une image comment je peux obtenir un tableau 2D [x][y] contenant l'image en niveau de gris à partir de mon image???
    une dernière question quelle est la différence entre harris et harrisfast ??

    merci pseudocode

  16. #76
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par noosa Voir le message
    bonjour,
    pour ce code, normalement int[][] input c'est le paramètre img??
    aussi, si j'ai une image comment je peux obtenir un tableau 2D [x][y] contenant l'image en niveau de gris à partir de mon image???
    Et bien tu crées un tableau de int[][] de la taille de l'image WidthxHeight, et dans chaque case tu mets la valeur d'intensité du pixel.

    une dernière question quelle est la différence entre harris et harrisfast ??
    Comme je l'ai dit poste #14 : HarrisFast est une version "stand-alone" du filtre (donc ce n'est pas un plugin ImageJ), qui précalcule les valeurs filtrés des derivées F*Lx², F*Ly² et F*Lxy pour accelerer le temps de traitement (au detriment de la mémoire).
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  17. #77
    Membre régulier
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 151
    Points : 92
    Points
    92
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    La détection se déroule en 3 étapes:

    1. Calcul de la mesure de Harris pour chaque pixel de l'image.
    2. Extraction des points qui ont une mesure supérieure au seuil ET qui sont des maximums locaux.
    3. Suppression des point qui sont trop proches les uns des autres: on garde le point qui a la plus grande mesure de Harris.
    Bonjour pseudocode,
    j'ai pas tester ton code car je travaille en matlab
    mais quand j'ai écrit mon code j'ai remarqué que le nombre de points détectés est élevé.. car il a détecté les points de bord et les coins!!
    donc je pense qu'il me reste l'étape 2 et 3

    est ce que tu peux m'expliquer d'avantage ces 2 dernières étapes?

  18. #78
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par azertyuio Voir le message
    Bonjour pseudocode,
    j'ai pas tester ton code car je travaille en matlab
    mais quand j'ai écrit mon code j'ai remarqué que le nombre de points détectés est élevé.. car il a détecté les points de bord et les coins!!
    Ce n'est pas normal. La mesure de Harris est élevée seulement si le pixel est sur un coin, et pas sur un bord.

    donc je pense qu'il me reste l'étape 2 et 3

    est ce que tu peux m'expliquer d'avantage ces 2 dernières étapes?
    Je ne vois pas ce que je peux expliquer de plus.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  19. #79
    Membre régulier
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 151
    Points : 92
    Points
    92
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    Ce n'est pas normal. La mesure de Harris est élevée seulement si le pixel est sur un coin, et pas sur un bord.
    oui oui je sais mais quand j'ai testé mon code sur une image contenant un carré, un triangle et un cercle,
    il me détecte les coins du carré ==> c bon
    mais les sommets du triangle avec quelques points sur les cotés
    et pour le cercle il me détecte presque tous les points du contour!!

    c'est le résultat de la matrice R = det(M)-k(Tr(M))²

    Citation Envoyé par pseudocode Voir le message
    Je ne vois pas ce que je peux expliquer de plus.
    je veux dire est ce que je dois appliquer un seuillage sur les valeur de R
    car d'après certains articles que j'ai lu, ils disent que
    si R>0 ==> coins
    si R<0 ==> contours
    si R petit ==> forme aplaties

    mais quand j'ai testé ça n'a pas changé grand chose..

    et quand j'ai affiché les valeurs de la matrice R, je trouve
    soit des valeurs positives très grandes (exemple 1.5478E+009)
    soit des valeurs négatives très grandes (exemple 1.5478E -009)
    soit des zéros !!

    car dans ton code j'ai trouvé :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
                                   double h =  harrisMeasure(x,y,(float)k);
    				if (h<=0) continue;
    				// log scale
    				h = 255 * Math.log(1+h) / Math.log(1+255);
    				// store
    				harrismap[x][y]=(float)h;
     
                         /////////////////////////////////////////////////////////////
     
     
                                     if (!isSpatialMaxima(harrismap, x, y)) continue;
    				// add the corner to the list
    				corners.add( new Corner(x,y,h) );
    et j'ai pas bien compris ces testes et leurs utilités !!

  20. #80
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par azertyuio Voir le message
    et quand j'ai affiché les valeurs de la matrice R, je trouve
    soit des valeurs positives très grandes (exemple 1.5478E+009)
    soit des valeurs négatives très grandes (exemple 1.5478E -009)
    soit des zéros !!
    Ce n'est pas étonnant. Si l'image n'est pas normalisées (c'est à dire si les valeurs des pixels varient entre 0 et 255), alors la valeur des gradients Lx et Ly varient entre -255 et +255.

    Les termes de la matrice de Harris (Lx², LxLy, Ly²) varient donc entre -255^2 et +255^2.

    Et la mesure de Harris "(Lx²*Ly²-LxLy*LyLx) - k*(Lx²+Ly²)^2" peut être de l'ordre de +/- 255^4 ~= 4E+9


    Normalement ca ne pose pas de problème tant qu'on utilise des float/double.


    car dans ton code j'ai trouvé (...) et j'ai pas bien compris ces testes et leurs utilités !!
    Ce changement d'échelle que j'effectue ne sert à rien. Je l'avais fait pour avoir des valeurs plus étalées lorsque j'affichais les valeurs de Harris sous forme de "carte colorée". Ca n'influence pas la détection, mais ca peut agir comme un seuil qui filtre les valeurs trop basses.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

Discussions similaires

  1. [image] Filtre Squelette pour ImageJ
    Par pseudocode dans le forum Contribuez
    Réponses: 47
    Dernier message: 12/08/2013, 11h41
  2. [Image] Filtre UnNoise pour ImageJ
    Par pseudocode dans le forum Contribuez
    Réponses: 37
    Dernier message: 07/03/2008, 17h23
  3. [Image] Filtre de Canny pour ImageJ
    Par pseudocode dans le forum Contribuez
    Réponses: 18
    Dernier message: 13/09/2007, 20h01
  4. [Image] Filtre UnNoise pour ImageJ
    Par pseudocode dans le forum Algorithmes et structures de données
    Réponses: 10
    Dernier message: 04/04/2007, 00h38
  5. Réponses: 20
    Dernier message: 19/12/2004, 19h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo