Pourquoi Sobel opérateur ressemble de cette façon?
Pour le calcul de la dérivée de l'image, l'opérateur Sobel se présente comme suit:
[-1 0 1]
[-2 0 2]
[-1 0 1]
Je ne comprends pas tout à fait 2 des choses à ce sujet,
1.Pourquoi le pixel central est 0? Ne puis-je pas simplement utiliser un opérateur comme ci-dessous,
[-1 1]
[-1 1]
[-1 1]
2.Pourquoi la rangée centrale est 2 fois les autres rangées?
J'ai googlé mes questions, je n'ai trouvé aucune réponse qui puisse me convaincre. S'il vous plaît aider moi.
3 réponses
En vision par ordinateur, il n'y a souvent pas de façon parfaite et universelle de faire quelque chose. Le plus souvent, nous essayons simplement un opérateur, voyons ses résultats et vérifions s'ils correspondent à nos besoins. C'est vrai aussi pour le calcul de gradient: l'opérateur Sobel est l'une des nombreuses façons de calculer un gradient d'image, ce qui a prouvé son utilité dans de nombreux cas d'utilisation.
En fait, l'opérateur de gradient plus simple auquel nous pourrions penser est encore plus simple que celui que vous suggérez ci-dessus:
[-1 1]
Malgré son simplicité, cet opérateur a un premier problème: quand vous l'utilisez, vous calculez le gradient entre deux positions et pas à une position. Si vous l'appliquez à 2 pixels (x,y)
et (x+1,y)
, avez-vous calculé le gradient de position (x,y)
ou (x+1,y)
? En fait, ce que vous avez calculé est le gradient à la position (x+0.5,y)
, et travailler avec des demi-pixels n'est pas très pratique. C'est pourquoi nous ajoutons un zéro au milieu:
[-1 0 1]
Appliquant le présent pixels (x-1,y)
, (x,y)
et (x+1,y)
sera clairement vous donner un dégradé pour le pixel central (x,y)
.
Celui-ci peut également être vu comme le produit de convolution de deux [-1 1]
filtres: [-1 1 0]
qui calcule le gradient de position (x-0.5,y)
, à la gauche du pixel, et [0 -1 1]
qui calcule la pente à droite du pixel.
Maintenant, ce filtre a encore un autre inconvénient: il est très sensible au bruit. C'est pourquoi nous décidons de ne pas l'appliquer sur une seule ligne de pixels, mais sur 3 lignes: cela permet d'obtenir un dégradé moyen sur ces 3 lignes, qui vont adoucir le bruit possible:
[-1 0 1]
[-1 0 1]
[-1 0 1]
Mais celui-ci a tendance à faire une moyenne un peu trop: lorsqu'il est appliqué à une ligne spécifique, nous perdons beaucoup de ce qui rend le détail de cette ligne spécifique. Pour résoudre ce problème, nous voulons donner un peu plus de poids à la rangée centrale, ce qui nous permettra de nous débarrasser du bruit possible en tenant compte de ce qui se passe dans les rangées précédente et suivante, tout en gardant la spécificité de cette rangée même. C'est ce qui donne le Sobel filtre:
[-1 0 1]
[-2 0 2]
[-1 0 1]
Altérer les coefficients peut conduire à d'autres opérateurs de gradient tels que L'opérateur Scharr, ce qui donne juste un peu plus de poids à la rangée centrale:
[-3 0 3 ]
[-10 0 10]
[-3 0 3 ]
Il y a aussi des raisons mathématiques à cela, telles que la séparabilité de ces filtres... mais je préfère le voir comme une découverte expérimentale qui s'est avérée avoir des propriétés mathématiques intéressantes, car l'expérience est à mon avis au cœur de la vision par ordinateur. Seulement votre imagination est la limite pour en créer de nouvelles, tant qu'elle correspond à vos besoins...
EDIT la vraie raison pour laquelle L'opérateur Sobel ressemble de cette façon peut être trouvé en lisant un article intéressant de Sobel lui-même . Mon la lecture rapide de cet article indique que L'idée de Sobel était d'obtenir un l'amélioration de l'estimation du gradient par la moyenne de l'horizontale, différences centrales verticales et diagonales. Maintenant, quand vous cassez le gradient en composants verticaux et horizontaux, la diagonale centrale les différences sont incluses dans les deux, tandis que le verticale et horizontale les différences centrales ne sont incluses que dans une seule. Deux éviter double compter les diagonales devrait donc avoir la moitié des poids de l' vertical et horizontal. Les poids réels de 1 et 2 sont juste pratique pour l'arithmétique à points fixes (et comprend en fait une échelle facteur 16).
Je suis d'accord avec @mbrenon surtout, mais il y a quelques points trop difficiles à faire dans un commentaire.
Tout d'abord dans la vision par ordinateur, le "le plus souvent, nous essayons juste un l'approche "opérateur" ne fait que perdre du temps et donne de mauvais résultats par rapport à ce qui aurait pu être réalisé. (Cela dit, j'aime expérimenter aussi.)
Il est vrai qu'une bonne raison d'utiliser [-1 0 1]
est qu'il Centre l'estimation dérivée au pixel. Mais une autre bonne raison est que c'est la formule différence centrale, et vous pouvez prouver mathématiquement qu'elle donne une erreur plus faible dans son estmate du dérivé vrai que [-1 1].
[1 2 1]
est utilisé pour filtrer le bruit comme mbrenon, ledit. La raison pour laquelle ces nombres particuliers fonctionnent bien est qu'ils sont une approximation D'un gaussien qui est leseul filtre qui n'introduit pas d'artefacts (bien que d'après L'article de Sobel, cela semble être une coïncidence). Maintenant, si vous voulez réduire le bruit et que vous trouvez une dérivée horizontale, vous voulez filtrer dans la direction verticale afin d'affecter le moins possible l'estimation dérivée. La convolution transpose([1 2 1])
avec [-1 0 1]
nous obtenons l'opérateur de Sobel. c'est à dire:
[1] [-1 0 1]
[2]*[-1 0 1] = [-2 0 2]
[1] [-1 0 1]
Pour une image 2D, vous avez besoin d'un masque. Dites que ce masque est:
[ a11 a12 a13;
a21 a22 a23;
a31 a32 a33 ]
Df_x (gradient le long de x) doit être produit à partir de Df_y (gradient le long de y) par une rotation de 90o, c'est-à-dire que le masque doit être:
[ a11 a12 a11;
a21 a22 a21;
a31 a32 a31 ]
Maintenant, si nous voulons soustraire le signal devant le pixel du milieu (c'est ce que la différenciation est en soustraction discrète), nous voulons allouer les mêmes poids aux deux côtés de la soustraction, c'est-à-dire que notre masque devient:
[ a11 a12 a11;
a21 a22 a21;
-a11 -a12 -a11 ]
Ensuite, la somme du poids devrait être nulle, car lorsque nous avoir une image lisse (par exemple tous les 255s) nous voulons avoir une réponse nulle, c'est-à-dire que nous obtenons:
[ a11 a12 a11;
a21 -2a21 a21;
-a31 -a12 -a31 ]
Dans le cas d'une image lisse, nous nous attendons à ce que la différenciation le long de L'axe des abscisses produise zéro, c'est-à-dire:
[ a11 a12 a11;
0 0 0;
-a31 -a12 -a31 ]
Enfin, si nous normalisons, nous obtenons:
[ 1 A 1;
0 0 0;
-1 -A -1 ]
Et vous pouvez définir A à tout ce que vous voulez expérimentalement. Un facteur de 2 donne le filtre Sobel d'origine.