Image - détecte les bords à faible contraste

Aug 27 2020

J'ai une image avec des transitions à contraste élevé et faible.

J'ai besoin de détecter les bords sur l'image ci-dessus. J'ai besoin d'une image binaire. Je peux facilement détecter les bords noirs et bleus "foncés" avec l'opérateur Sobel et le seuillage.

Cependant, le bord entre le bleu "clair" et la couleur jaune "clair" est problématique.

Je commence avec une image lisse avec un filtre médian pour chaque canal pour éliminer le bruit.

Ce que j'ai déjà essayé pour détecter les bords:

  • Opérateur Sobel
  • Opérateur Canny
  • Laplace
  • espaces colorimétriques en niveaux de gris, RVB, HSV, LUV (avec des espaces multicanaux, les bords sont détectés dans chaque canal, puis combinés pour créer une image de bord finale)
  • Prétraitement de l'image RVB avec correction gamma (le problème avec le prétraitement est la compression de l'image. L'image source est JPG et si j'utilise le prétraitement, la détection des contours se termine souvent par une grille visible causée par des macroblocs JPG.)

Jusqu'à présent, Sobel sur RVB fonctionne mieux, mais la ligne à faible contraste est également à faible contraste.

Un seuillage supplémentaire supprime cette partie. Je considère tout ce qui est sous une certaine valeur de gris. Si j'utilise des valeurs de seuil élevées comme 250, le résultat pour un bord à faible contraste est meilleur mais les bords restants sont détruits. Je n'aime pas non plus les lacunes dans les bords à faible contraste.

Donc, si je change encore le seuil et dis que tout sauf le blanc est bord, j'ai des bords partout.

Avez-vous une autre idée de la façon de combiner la détection des contours à contraste faible et élevé afin que les contours soient autant que possible sans espaces et pas partout?

Remarque: pour le test, j'utilise principalement OpenCV et ce qui n'est pas disponible dans OpenCV, je programme moi-même

Réponses

3 YvesDaoust Sep 03 2020 at 15:04

IMO c'est à peine faisable, voire faisable du tout si vous voulez une solution automatisée.

Ici, j'ai utilisé la binarisation dans l'espace RVB, en attribuant à chaque pixel la couleur la plus proche parmi deux couleurs représentatives du bleu et du jaune. (J'ai choisi des pixels isolés, mais choisir une moyenne sur une région serait mieux.)

Peut-être qu'un classificateur k-means pourrait y parvenir?


Mettre à jour:

Voici ce qu'un classificateur k-means peut donner, avec 5 classes.

1 MarkSetchell Sep 03 2020 at 16:48

Tous les félicitations et tous les points à Yves, s'il vous plaît, pour avoir proposé une solution possible. Je m'amusais à expérimenter cela et j'avais envie de partager du code réel, autant pour ma propre référence future qu'autre chose. Je viens d'utiliser ImageMagick dans Terminal, mais vous pouvez faire la même chose en Python avec Wand .

Donc, pour obtenir une segmentation de clustering K-means avec 5 couleurs, vous pouvez faire:

magick edge.png -kmeans 5 result.png

Si vous voulez un échantillon des couleurs détectées en dessous, vous pouvez faire:

magick edge.png \( +clone -kmeans 5 -unique-colors -scale "%[width]x20\!" \) -background none -smush +10 result.png

Mots clés : Python, ImageMagick, baguette, traitement d'image, segmentation, k-means, clustering, swatch.