Vous ne recherchez pas de bords (= bordures entre les zones étendues de gris haut et bas), vous recherchez des crêtes (lignes fines plus sombres ou plus claires que leur voisinage), de sorte que les filtres de bord ne sont peut-être pas idéaux: un filtre de bord sera vous donner deux flancs (un de chaque côté de la ligne) et une réponse faible au milieu de la ligne:
AJOUTER : Si vous avez été invité à expliquer plus clairement la différence entre un détecteur de bord et un détecteur de crête. Je m'excuse par avance si cette réponse est très longue.
Un détecteur de bord est (généralement) un premier opérateur dérivé: Si vous imaginez l'image d'entrée en tant que paysage 3D, un détecteur de bord mesure l'inclinaison de la pente en chaque point de ce paysage:
Si vous souhaitez détecter la bordure d'une région claire ou sombre étendue, c'est très bien. Mais pour les veines dans l'image du PO, cela vous donnera exactement la même chose: les contours gauche et droit de chaque veine:
Cela explique également le "motif de double ligne" dans les résultats du détecteur de bord Canny:
gxy
g(x,y)≈12x2∂2g∂x2+xy∂2g∂x∂y+12y2∂2g∂y2+x∂g∂x+y∂g∂y+g(0,0)
ou, sous forme de matrice:
g(x,y)≈12(xy).⎛⎝⎜∂2g∂x2∂2g∂x∂y∂2g∂x∂y∂2g∂y2⎞⎠⎟.(xy)+(xy).(∂g∂x∂g∂y)+g(0,0)
⎛⎝⎜∂2g∂x2∂2g∂x∂y∂2g∂x∂y∂2g∂y2⎞⎠⎟
λ1x2+λ2y2λ1λ2
Quel genre de formes cette approximation de fonction peut-elle avoir? En fait, pas tant que ça:
Pour détecter des crêtes, nous souhaitons trouver dans l'image des zones qui ressemblent à la dernière des parcelles ci-dessus. Nous recherchons donc des zones dans lesquelles la valeur propre principale de la Hesse est grande (par rapport à la valeur propre mineure). Le moyen le plus simple de détecter cela consiste simplement à calculer la valeur propre principale de chaque pixel - et c'est ce que fait le filtre de crête ci-dessous.
Un filtre à crête donnera probablement de meilleurs résultats. J'ai essayé Mathematica intégré RidgeFilter
(qui calcule la valeur propre majeure de la matrice de Hesse à chaque pixel) sur votre image:
Comme vous pouvez le constater, il n’ya qu’un seul pic pour chaque fine ligne sombre. Binarisation et squelettisation des rendements:
Après la taille du squelette et la suppression des petits composants (bruit) de l'image, j'obtiens ce dernier squelette:
Code Mathematica complet:
ridges = RidgeFilter[ColorNegate@src];
skeleton = SkeletonTransform[Binarize[ridges, 0.007]];
DeleteSmallComponents[Pruning[skeleton, 50], 50]
AJOUTER:
Je ne suis pas un expert de Matlab, je ne sais pas s'il possède un filtre d'arête intégré, mais je peux vous montrer comment le mettre en œuvre "à la main" (encore une fois, en utilisant Matematica). Comme je l'ai dit, le filtre de crête est la valeur propre principale de la matrice de Hesse. Je peux calculer cette valeur propre symboliquement dans Mathematica:
eigenvalue=Last[Eigenvalues[(HxxHxyHxyHyy)]]
12(Hxx+Hyy+H2xx+4H2xy−2HxxHyy+H2yy−−−−−−−−−−−−−−−−−−−−−−−√)
HxxHxyHyy