Précédent   Forum du club des développeurs et IT Pro > Autres langages > Algorithmes > Contribuez
Contribuez Proposez vos articles, cours, tutoriels, FAQ, sources, etc.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Actualité déjà publiée
 
Outils de la discussion
Publicité
'
Vieux 29/06/2009, 09h38   #61
pseudocode
Rédacteur/Modérateur
 
Avatar de pseudocode
 
Homme Xavier Philippeau
Architecte système
Inscription : décembre 2006
Messages : 9 837
Détails du profil
Informations personnelles :
Nom : Homme Xavier Philippeau
Âge : 40
Localisation : France, Hérault (Languedoc Roussillon)

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

Informations forums :
Inscription : décembre 2006
Messages : 9 837
Points : 16 517
Points : 16 517
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.

Citation:
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.
pseudocode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/12/2009, 09h33   #62
amira88
Nouveau Membre du Club
 
Inscription : juillet 2009
Messages : 81
Détails du profil
Informations personnelles :
Âge : 25

Informations forums :
Inscription : juillet 2009
Messages : 81
Points : 32
Points : 32
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 :
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
amira88 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/12/2009, 09h44   #63
pseudocode
Rédacteur/Modérateur
 
Avatar de pseudocode
 
Homme Xavier Philippeau
Architecte système
Inscription : décembre 2006
Messages : 9 837
Détails du profil
Informations personnelles :
Nom : Homme Xavier Philippeau
Âge : 40
Localisation : France, Hérault (Languedoc Roussillon)

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

Informations forums :
Inscription : décembre 2006
Messages : 9 837
Points : 16 517
Points : 16 517
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.

Citation:
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.
pseudocode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/12/2009, 09h49   #64
amira88
Nouveau Membre du Club
 
Inscription : juillet 2009
Messages : 81
Détails du profil
Informations personnelles :
Âge : 25

Informations forums :
Inscription : juillet 2009
Messages : 81
Points : 32
Points : 32
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
amira88 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/12/2009, 10h16   #65
pseudocode
Rédacteur/Modérateur
 
Avatar de pseudocode
 
Homme Xavier Philippeau
Architecte système
Inscription : décembre 2006
Messages : 9 837
Détails du profil
Informations personnelles :
Nom : Homme Xavier Philippeau
Âge : 40
Localisation : France, Hérault (Languedoc Roussillon)

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

Informations forums :
Inscription : décembre 2006
Messages : 9 837
Points : 16 517
Points : 16 517
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.
pseudocode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/12/2009, 10h20   #66
amira88
Nouveau Membre du Club
 
Inscription : juillet 2009
Messages : 81
Détails du profil
Informations personnelles :
Âge : 25

Informations forums :
Inscription : juillet 2009
Messages : 81
Points : 32
Points : 32
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!!
amira88 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/12/2009, 10h31   #67
pseudocode
Rédacteur/Modérateur
 
Avatar de pseudocode
 
Homme Xavier Philippeau
Architecte système
Inscription : décembre 2006
Messages : 9 837
Détails du profil
Informations personnelles :
Nom : Homme Xavier Philippeau
Âge : 40
Localisation : France, Hérault (Languedoc Roussillon)

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

Informations forums :
Inscription : décembre 2006
Messages : 9 837
Points : 16 517
Points : 16 517
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.
pseudocode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/12/2009, 20h53   #68
amira88
Nouveau Membre du Club
 
Inscription : juillet 2009
Messages : 81
Détails du profil
Informations personnelles :
Âge : 25

Informations forums :
Inscription : juillet 2009
Messages : 81
Points : 32
Points : 32
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!!
amira88 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/03/2010, 12h00   #69
Battant
Nouveau Membre du Club
 
Inscription : février 2006
Messages : 166
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 166
Points : 25
Points : 25
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 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/03/2010, 20h13   #70
pseudocode
Rédacteur/Modérateur
 
Avatar de pseudocode
 
Homme Xavier Philippeau
Architecte système
Inscription : décembre 2006
Messages : 9 837
Détails du profil
Informations personnelles :
Nom : Homme Xavier Philippeau
Âge : 40
Localisation : France, Hérault (Languedoc Roussillon)

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

Informations forums :
Inscription : décembre 2006
Messages : 9 837
Points : 16 517
Points : 16 517
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.
pseudocode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/03/2010, 09h54   #71
rkassab
Invité de passage
 
Rami KASSAB
Inscription : février 2010
Messages : 1
Détails du profil
Informations personnelles :
Nom : Rami KASSAB

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..
rkassab est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/07/2010, 21h33   #72
noosa
Invité régulier
 
noosa ingénieur
Inscription : avril 2010
Messages : 7
Détails du profil
Informations personnelles :
Nom : noosa ingénieur

Informations forums :
Inscription : avril 2010
Messages : 7
Points : 7
Points : 7
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)??
noosa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2010, 09h31   #73
pseudocode
Rédacteur/Modérateur
 
Avatar de pseudocode
 
Homme Xavier Philippeau
Architecte système
Inscription : décembre 2006
Messages : 9 837
Détails du profil
Informations personnelles :
Nom : Homme Xavier Philippeau
Âge : 40
Localisation : France, Hérault (Languedoc Roussillon)

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

Informations forums :
Inscription : décembre 2006
Messages : 9 837
Points : 16 517
Points : 16 517
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.
pseudocode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2010, 12h22   #74
noosa
Invité régulier
 
noosa ingénieur
Inscription : avril 2010
Messages : 7
Détails du profil
Informations personnelles :
Nom : noosa ingénieur

Informations forums :
Inscription : avril 2010
Messages : 7
Points : 7
Points : 7
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 ????
noosa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/07/2010, 11h16   #75
noosa
Invité régulier
 
noosa ingénieur
Inscription : avril 2010
Messages : 7
Détails du profil
Informations personnelles :
Nom : noosa ingénieur

Informations forums :
Inscription : avril 2010
Messages : 7
Points : 7
Points : 7
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 :
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 :
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
noosa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/07/2010, 19h36   #76
pseudocode
Rédacteur/Modérateur
 
Avatar de pseudocode
 
Homme Xavier Philippeau
Architecte système
Inscription : décembre 2006
Messages : 9 837
Détails du profil
Informations personnelles :
Nom : Homme Xavier Philippeau
Âge : 40
Localisation : France, Hérault (Languedoc Roussillon)

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

Informations forums :
Inscription : décembre 2006
Messages : 9 837
Points : 16 517
Points : 16 517
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.

Citation:
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.
pseudocode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 12h43   #77
azertyuio
Membre du Club
 
Femme
Étudiant
Inscription : mars 2009
Messages : 151
Détails du profil
Informations personnelles :
Sexe : Femme

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : mars 2009
Messages : 151
Points : 60
Points : 60
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?
azertyuio est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 14h16   #78
pseudocode
Rédacteur/Modérateur
 
Avatar de pseudocode
 
Homme Xavier Philippeau
Architecte système
Inscription : décembre 2006
Messages : 9 837
Détails du profil
Informations personnelles :
Nom : Homme Xavier Philippeau
Âge : 40
Localisation : France, Hérault (Languedoc Roussillon)

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

Informations forums :
Inscription : décembre 2006
Messages : 9 837
Points : 16 517
Points : 16 517
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.

Citation:
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.
pseudocode est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 12h00   #79
azertyuio
Membre du Club
 
Femme
Étudiant
Inscription : mars 2009
Messages : 151
Détails du profil
Informations personnelles :
Sexe : Femme

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : mars 2009
Messages : 151
Points : 60
Points : 60
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 :
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 !!
azertyuio est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 14h35   #80
pseudocode
Rédacteur/Modérateur
 
Avatar de pseudocode
 
Homme Xavier Philippeau
Architecte système
Inscription : décembre 2006
Messages : 9 837
Détails du profil
Informations personnelles :
Nom : Homme Xavier Philippeau
Âge : 40
Localisation : France, Hérault (Languedoc Roussillon)

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

Informations forums :
Inscription : décembre 2006
Messages : 9 837
Points : 16 517
Points : 16 517
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.


Citation:
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.
pseudocode est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Actualité déjà publiée
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 19h26.


 
 
 
 
Partenaires

Hébergement Web