Je travaille sur un projet où des franges sont projetées sur un sujet et une photo est prise. La tâche consiste à trouver les lignes centrales des franges, qui représentent, mathématiquement, la courbe d'intersection 3D entre le plan de la frange et la surface du sujet.
La photo est au format PNG (RVB), et les tentatives précédentes utilisaient des niveaux de gris puis des seuils de différence pour obtenir une photographie en noir et blanc "semblable à un zèbre", à partir de laquelle il était facile de trouver le milieu de chaque colonne de pixels de chaque frange. Le problème est que, par seuillage et également en prenant la hauteur moyenne d'une colonne de pixels discrets, nous avons une perte de précision et une quantification, ce qui n'est pas du tout souhaité.
Mon impression, en regardant les images, est que les traits d'axe pourraient être plus continus (plus de points) et plus lisses (non quantifiés) s'ils étaient détectés directement à partir de l'image sans seuil (RVB ou niveaux de gris), par une méthode de balayage statistique (quelques inondations / convolution itérative, peu importe).
Voici un exemple d'image réel:
Toute suggestion serait très appréciée!
la source
Réponses:
Je suggère les étapes suivantes:
x
, trouvez le centre pondéré (par intensité de pixel) dans lay
direction.y
valeurs pour éliminer le bruit.(x,y)
points en ajustant une sorte de courbe. Cet article pourrait vous aider. Vous pouvez également adapter un polynôme de haut niveau, bien que ce soit pire à mon avis.Voici un code Matlab qui montre les étapes 1, 2 et 4. J'ai ignoré la sélection de seuil automatique. Au lieu de cela, j'ai choisi le manuel
th=40
:Voici les courbes que l'on trouve en trouvant la moyenne pondérée par colonne:
Ce sont les courbes après ajustement d'un polynôme:
Voici le code:
la source
double
. À propos des résultats dans la moitié inférieure, je dois vérifier, il pourrait s'agir d'un bug logicielJe n'utiliserais pas l'image RVB. Les images en couleur sont généralement réalisées en plaçant un "filtre Bayer" sur le capteur de la caméra, ce qui réduit généralement la résolution que vous pouvez obtenir.
Si vous utilisez l'image en niveaux de gris, je pense que les étapes que vous avez décrites (binariser l'image "zèbre", trouver la ligne médiane) sont un bon début. Enfin, je voudrais
la source
Voici encore une solution alternative à votre problème en modélisant votre question comme un «problème d'optimisation de chemin». Bien qu'elle soit plus compliquée que la simple solution de binarisation et d'ajustement de courbe, elle est plus robuste dans la pratique.
Du niveau très élevé, nous devons considérer cette image comme un graphique, où
chaque pixel d'image est un nœud sur ce graphique
chaque nœud est connecté à d'autres nœuds, appelés voisins, et cette définition de connexion est souvent référée à la topologie de ce graphique.
chaque nœud a un poids (fonctionnalité, coût, énergie, ou ce que vous voulez appeler), reflétant la probabilité que ce nœud soit dans une ligne centrale optimale que nous recherchons.
Tant que nous pouvons modéliser cette probabilité, votre problème de trouver `` les lignes centrales des franges '' devient le problème de trouver des chemins locaux optimaux sur le graphique , qui peuvent être résolus efficacement par programmation dynamique, par exemple l'algorithme de Viterbi.
Voici quelques avantages d'adopter cette approche:
tous vos résultats seront continus (contrairement à la méthode de seuil qui pourrait casser une ligne centrale en morceaux)
beaucoup de libertés pour construire un tel graphique, vous pouvez sélectionner différentes fonctionnalités et la topologie du graphique.
vos résultats sont optimaux dans le sens d'optimisations de chemin
votre solution sera plus robuste contre le bruit, car tant que le bruit est réparti également entre tous les pixels, ces chemins optimaux restent stables.
Voici une courte démonstration de l'idée ci-dessus. Comme je n'utilise aucune connaissance préalable pour spécifier les nœuds de début et de fin possibles, je décode simplement wrt chaque nœud de départ possible.
Pour les terminaisons floues, cela est dû au fait que nous recherchons des chemins optimaux pour tous les nœuds de terminaison possibles. Par conséquent, bien que pour certains nœuds situés dans des zones sombres, le chemin en surbrillance reste son optimal local.
Pour le chemin flou, vous pouvez soit le lisser après l'avoir trouvé, soit utiliser des fonctions lissées au lieu de l'intensité brute.
Il est possible de restaurer des chemins partiels en modifiant les nœuds de début et de fin.
Il ne sera pas difficile d'élaguer ces chemins optimaux locaux indésirables. Parce que nous avons les probabilités de tous les chemins après le décodage viterbi, et vous pouvez utiliser diverses connaissances antérieures (par exemple, nous voyons qu'il est vrai que nous n'avons besoin que d'un chemin optimal pour ceux qui partagent la même source.)
Pour plus de détails, vous pouvez vous référer au document.
Voici un court morceau de code python utilisé pour créer le graphique ci-dessus.
la source
J'ai pensé que je devrais poster ma réponse car elle est un peu différente des autres approches. J'ai essayé cela dans Matlab.
Un inconvénient que je vois ici est que cette approche ne fonctionnera pas bien pour certaines orientations des rayures. Dans ce cas, nous devons corriger son orientation et appliquer cette procédure.
Voici le code Matlab:
Par exemple, si vous prenez la colonne centrale de l'image, son profil devrait ressembler à ceci: (en bleu est le profil. En vert sont les maxima locaux)
Et l'image contenant les maxima locaux pour toutes les colonnes ressemble à ceci:
Voici les composants connectés (bien que certaines bandes soient cassées, la plupart d'entre elles ont une région continue):
la source