# Gnral Dveloppement > Algorithme & Mathmatiques > Traitement d'images >  Implmenter sobel et calculer son gradient

## Goffer

Bonjour  tous, j'ai besoin d'un peu d'aide pour comprendre et finir mon bout de code.

Pas trs original, je souhaite implmenter l'algorithme de sobel (en vue d'une impl de canny edge par la suite...).

Je ne vois pas comment calculer la norme du gradient G = sqrt(Gx+Gy) avec les lments que j'ai dj :



```

```

Merci par avance pour l'aide !

Edit : Je pense que je me suis tromp sur ma comprhension de la norme du gradient donc je pouvais pas progresser. Je pense que j'ai rsolu mon problme et j'ai mis  jour mon code. Est-ce que vous pouvez me dire si j'ai bon ou pas ?

----------


## ToTo13

Bonjour,

est ce que le code du gradient de Sobel fonctionne correctement ?
As tu affich le rsultats sur des images ?

----------


## Goffer

Bonjour Toto,

Le code du sobel ne marche pas correctement, et je ne m'en suis aperu qu'aujourd'hui... (bon en mme temps j'ai pas pass les 7 derniers jours l-dessus ^^).

Voil l'image que cela m'affiche :


Uploaded with ImageShack.us


On peut voir que tous les contours ne sont pas dtects (marqu en blanc / gris) mais on peut aussi voir que les contours qui devraient tre dtects sont marqus en noir (le chapeau, l'paule et le bras).

Je pense que c'est en noir car la valeur dpasse 255 et je pense que c'est la fonction cvFilter2D qui fait ca. Je ne peux donc pas rajouter de condition pour qu'il me fixe correctement ma valeur... 

Mon nouveau soucis c'est que je n'arrive pas  implmenter une convolution 2D en C++.... et si quelqu'un a un algo simple  implmenter je suis preneur ! Il faut vraiment que j'avance sur mon projet et l je prends du retard ...

----------


## kmaniche

Pour la dtection de contours, le calcul du gradient n'est qu'une tape. Il te faut par la suite l'extraction des maximas locaux et le seuillage par hystrsis.

----------


## kmaniche

Pour la convolution :
Soit un masque de convolution Msk de 3x3 et l'image Im de taille H et W 

La convolution de l'image Im par le masque Msk consiste  faire balayer  le masque sur l'image, et pour chaque pixel central, remplacer sa valeur  par le somme du produit des pixels voisins avec le masque, ensuite  passer au balayage suivant.



```

```

----------


## Goffer

Salut Kmaniche et merci de ton aide,

J'ai implment ton pseudo-code, malheureusement l'image final est toute blanche (except les bords), tous les pixels ont une valeur suprieur  255.

Est-ce que tu pourrais me corriger stp ? Je m'en sors pas je me perds dans les indices, j'ai pas de vision de ce que je fais...

Merci pour l'aide 



```

```

ps : Le but c'est de dtecter des cercles par transform de Hough, donc j'en suis  l'tape CannyEdge  ::):

----------


## pseudocode

Dans les deux cas, le noyau n'est pas normalis. Les valeurs finales excdent donc souvent l'intervalle de valeurs des intensits.

----------


## Goffer

Tu entends quoi par normaliser le noyau ? Normaliser l'image avant de la passer  la moulinette ?

----------


## pseudocode

> Tu entends quoi par normaliser le noyau ? Normaliser l'image avant de la passer  la moulinette ?


Ton noyau Sobel a l'air d'tre



```

```

Ce qui fait que dans le cas extreme d'un fort gradient, par exemple un passage brutal du noir (0) au blanc (255)



```

```


on obtient la valeur finale de



```

```

c'est  dire 4*255 = 1020


=> pour normaliser le rsultat final il faut diviser le rsultat par 4

----------


## kmaniche

L'algorithme que je t'ai donn sert  faire une convolution entre une image et un masque. Pour le masque, c'est  toi de voir le quel est le plus adapt  ton cas.

Pour solbel, le masque est :


```

```

Ce qui revient  faire le calcul du gradient de ton image par le masque de Sobel.

Pour la partie programmatio, je te conseil qu'avant de te lancer dans l'criture du programme final, utilise un nouveau projet virge, o tu insre deux image et un bouton. cris ensuite le programme sans utiliser les pointeurs, et affiche le rsultat. Normalement tu devrais avoir une image en noir, et le gradient en nuances de blanc.

Bonne chance

----------


## kmaniche

Zut, une petite erreur d'algorithme. J'ai oubli de rinitialiser la variable sm par 0.

Reprend l'algorithme ci-dessus, j'ai corrig  ::oops::

----------


## Goffer

Bonjour  tous,

Merci de vos rponses j'ai pu m'en sortir et je suis presque  la fin de ma peine  :;): 

Je n'ai plus que deux problmes  rgler : 
Concernant la normalisation, pourquoi faut-il diviser le rsultat par 4 sachant qu'il y a 9 valeurs dans mon noyau ? Pourquoi c'est pas 9 ? J'ai mal compris cette partie

Enfin, mon algorithme pour l'hystrsis semble faux puisque mon image finale est blanche, voici le code :



```

```

En gros je regarde les alentours du pixel que si celui-ci n'est pas marqu comme fort. 
Pour regarder si mon pixel est connect avec un autre pixel, je regarde si les valeurs de ses voisins sont diffrentes de 0. Si au moins l'un d'eux a une valeur alors je conserve le pixel et le marque comme un bord.

----------


## kmaniche

Tu as lu et compris le rle d'un seuillage par hystrsis ?

Est-ce que tu as la dfinition ?

----------


## Goffer

Mon hystrsis c'est :

J'ai un threshold mini et un threshold maxi, 

Si mon pixel est en dessus du t_mini alors je met sa valeur  0
Si mon pixel est au dessus du t_maxi alors je met sa valeur  255
S'il est entre les deux, je regarde alors s'il est connect  d'autres pixels. Si oui, je le met  255 si non je le met  0.

Mon code au dessus c'est la dernire partie o je regarde les pixels connects lorsque ceux-ci sont entre t_min et t_maxi.

----------


## Goffer

En fait c'est dbile ce que j'ai fais, mon code est faux.

Celui que j'estime bon c'est :



```

```

Autre soucis, j'ai pas l'impression que ma recherche des maximas locaux fonctionne puisque j'ai toujours des bords assez gros...

Voici mon code complet :


```

```

J'ai mis en PJ l'image que cela me donne avec un t_min = 60 et un t_max = 200.

----------


## kmaniche

un threshold mini et un threshold maxi, 

Si mon pixel est en dessus du t_mini alors je met sa valeur  0
Si mon pixel est au dessus du t_maxi alors je met sa valeur  255
S'il est entre les deux, et au moins un des voisin soit > t_mini tu met 255, sinon 0



d'ailleurs, pourquoi 127.

et normalement tu devrais obtenir des contours fins :koi

----------


## Goffer

Dans la doc que j'ai, on distingue les deux tapes de thresholding et d'hystrsis et ils disent "si t'es entre t_mini et t_maxi alors tu le marques  gris", d'o le 127. Cependant on peut combiner les deux.

Est-ce que tu pourrais me rassurer et me dire si mon implmentation de l'hystrsis est bonne stp ?

Une ide d'o ca peut venir le fait que j'ai pas de contours fins ? Je comprends pas vraiment :/

----------


## kmaniche

D'autrs cooqrez, c'est faux !!

Pour la dtection de contours, les tapes sont :

1. Filtrage optimal.
2- Drivation (Calcul du gradient).
3. Calcul des maximums locaux.
4. Seuillage par Hystrsis.


Tu te rfre  quelle doc pour tes travaux ? Pour que je puisse voir !

----------


## Goffer

Voil la doc :

http://www.cvmt.dk/education/teachin...ny_09gr820.pdf

----------


## kmaniche

Je te renvoie vers la dfinition que j'ai dans ma doc (Coquerez) :



```

```

----------


## pseudocode

Il y a le meme genre de dfinition dans son documents.




> The Canny edge detection algorithm uses double thresholding.
> 
> Edge pixels stronger than the high threshold are marked as *strong*; 
> edge pixels weaker than the low threshold are *suppressed* and edge pixels between the two thresholds are marked as *weak*.

----------


## Goffer

Je pense que c'est moi qui est mal interprt la doc, j'ai revu cette partie hystrsis et ca donne :


```

```

Le rsultat est en pice-jointe avec un t_mini= 60 et un t_maxi = 200. Cependant je ne suis toujours pas satisfait de l'image finale, les bords sont plutt gros.

Est-ce que vous voyez une erreur dans mon implmentation des maxima locaux ?


```

```

A priori c'est le dernier point qu'il me reste  traiter avant de passer  la transform de hough (CHT). D'ailleurs en anticipation si vous avez de la bonne doc  me donner pour l'implmentation, ca me ferait gagner du temps dans mes recherches

----------


## pseudocode

attention a l'ordre des paramtres dans atan2()  :;):

----------


## kmaniche

Une image contour contient un fond noir avec des segments de contours en blanc, mais dans ton cas, il y a toujours le nvg 127 !!

D'autant plus, les contours sont pais, cel est du directement  la dtection des maximums locaux.

Il vaut revoir  mon avis

----------


## Goffer

J'ai beau cherch je comprends pas pourquoi ma suppression des non maxima ne fonctionnent pas...

Il y a trs peu de diffrences entre l'image produite par sobel et l'image produite par les maximas (cf PJ).

Je vois vraiment pas, j'ai vraiment besoin d'un coup de pouce.. SVP



```

```

----------


## kmaniche

Le problme c'est que : dans le calcul des maximas locaux que tu as fais, tu ne compare pas le module du gradient du point P considr, avec ces voisins M1 et M2 pris dans la direction du gradient.

Tu connais la condition pour que un point P de l'image soit un maximum local ?

----------


## Goffer

Pour un point P[x][y]
Pour les maximas locaux je regarde la direction du gradient.

Si le gradient est gal  0 alors je compare:
P[x+1][y] et P[x-1][y]  P[x][y]. S'ils sont plus grand  alors P[x][y] = 0 sinon P[x][y] garde sa valeur.

Si le gradient est gal  90 alors je compare:
P[x][y+1] et P[x][y-1]  P[x][y]. S'ils sont plus grand  alors P[x][y] = 0 sinon P[x][y] garde sa valeur.

Si le gradient est gal  45 alors je regarde :
P[x+1][y+1] et P[x-1][y-1]  P[x][y]. S'ils sont plus grand  alors P[x][y] = 0 sinon P[x][y] garde sa valeur.

Si le gradient est gal  135 alors je regarde :
P[x-1][y+1] et P[x+1][y-1]  P[x][y]. S'ils sont plus grand  alors P[x][y] = 0 sinon P[x][y] garde sa valeur.

que j'ai traduis par :


```

```

Ou alors c'est la direction des gradients qui est fausse mais j'ai pourtant pas l'impression d'avoir fait une erreur...

----------


## pseudocode

> Si le gradient est gal  0 alors je compare:
> P[x+1][y] et P[x-1][y]  P[x][y]. S'ils sont plus grand  alors P[x][y] = 0 sinon P[x][y] garde sa valeur.


Si L'UN DES DEUX est plus grand, alors P[x][y] n'est pas un extremum local.

----------


## kmaniche

Je te conseil de lire cet ouvrage : 




> J. P. COCQREZ et S. PHILIPP. "Analyse d'images: filtrage et  segmentation".  Enseignement de la physique. MASSON,  Paris, 1995.


Il explique bien : l'extraction des maximas locaux de la norme du gradient :




> Cette opration est effectue sur un voisinage de taille 3x3 de limage norme de gradients, le but est dextraire tous les pixels prsentant un maximum local dans la direction du gradient. Pour cela les images gradients obtenues aux tapes prcdentes sont utilises afin dobtenir une approximation de la direction du gradient.
> 
> Lalgorithme dextraction des maximas locaux consiste  comparer la norme du gradient au site M[i  j]  celle de ses deux voisins M1 et M2 situs dans la direction du gradient : Soient A limage de dpart, Ac et Ay les images des composantes verticales et horizontales du gradient. Soient Gr la norme du gradient au point M[i  j], Gr1 et Gr2 les normes du gradient correspondant aux points M1 et M2.
> 
> M est un maximum local si *Gr > Gr1 et Gr >= Gr2*


Commence  penser  un algorithme, d'aprs ce qui prcde, il est simple  ::lol::

----------


## Goffer

J'ai pu m'en sortir et effectivement je me suis embrouill dans la dtection des maximum, ce que j'avais fais tait dbile.

Voici l'image finale avec un threshold (20,80), vous en pensez quoi ?

----------


## kmaniche

Ce qui reste  parfaire.

j'imagine que soit tu as considr deux angle pour l'orientation du gradient, soit le seuillage par hystrsis est mal conu.

Comment t'as fais pour l'extraction des maximas local ?

----------


## Goffer

Pour le double threshold et hystrsis j'ai utilis :


```

```

Ce qui je l'espre correpond  :

Si la norme du gradient est suprieure au seuil haut,   c'est un point de contour sr, qu'on code par 1.Si la norme du gradient est infrieure au seuil bas, alors ce n'est pas un point de contour, qu'on code par 0.Si la norme du gradient est entre les deux, alors c'est un contour de fermeture, i.e un contour potentiel et qu'on  code par 2.  Ces contours sont transforms en contours srs s'ils sont adjacents  un  contour cod 1

----------


## kmaniche

Drapeau blanc  ::aie:: 


```

```

Je ne pas faire mieux  ::aie::

----------


## pseudocode

> Drapeau blanc 
> 
> 
> ```
> 
> ```
> 
> Je ne pas faire mieux


Pas mal... mais le seuillage par hystrsis dans Canny doit se propager : un point "strong" (255) change tous ses voisins weak (127) en strong (255). Et ces nouveaux point "strong" font de mme, et ainsi de suite...

----------


## Goffer

Bonjour et merci de ces rponses ^^

J'ai mis en parenthse la rfection de ces algos, je n'ai malheureusement plus de temps  moi, mon projet est  rendre dans 2 semaines et je dois raliser d'autres modules ...

----------

