Question

J'ai une image avec des lignes horizontales et verticales. En fait, cette image représente le site Web de la BBC converti en lignes horizontales et verticales. Mon problème est que je veux pouvoir trouver tous les rectangles dans l'image. Je veux écrire un programme informatique pour trouver tous les rectangles. Est-ce que quelqu'un sait comment faire cela ou suggère des idées sur la façon de commencer? Il est facile pour moi, en tant que personne, de trouver les rectangles visuels, mais je ne sais pas comment le décrire en tant que programme.

L'image est le site Web de la BBC ici http://www.bbc.co.uk/

Mise à jour, j’ai écrit le code qui convertit l’image du site Web de la BBC en lignes horizontales et verticales. Le problème est que ces lignes ne se rencontrent pas complètement aux angles et qu’elles ne forment parfois pas complètement un rectangle. Merci!

Était-ce utile?

La solution

Opencv (la bibliothèque de traitement d'images et de vision par ordinateur écrite en c) est implémentée pour hough transform ( la transformation hough simple trouve des lignes dans une image, tandis que la généralisée trouve des objets plus complexes), ce qui pourrait être un bon début. Pour les rectangles qui ont des coins fermés, il existe également des détecteurs de coin tels que cornerHarris qui peuvent aider.

J'ai lancé la démonstration houghlines fournie avec opencv et voici le résultat sur l'image que vous avez donnée (lignes détectées en rouge): alt text
(source: splintec.com )

Autres conseils

Je pense que vous recherchez la transformation de Hough généralisée .

Dans le domaine de la vision par ordinateur, il existe un algorithme appelé Hough Transform généralisé qui peut peut-être résoudre votre problème. . Il devrait y avoir du code source ouvert ayant implémenté cet algorithme. Il suffit de chercher.

En supposant qu’il s’agisse d’une image raisonnablement exempte de bruit (et non d’une vidéo sur un écran), l’un des algorithmes simples de fond d’écran devrait fonctionner. Vous devrez peut-être exécuter un dilatage / érosion sur l'image pour combler les espaces vides.

La méthode normale pour trouver des lignes est une transformation de Hough (puis rechercher des lignes à angle droit) L'openv est le moyen le plus simple.

Regardez cette question Détection d'objet OpenCV - Point central

Il existe plusieurs approches différentes à votre problème. J'utiliserais un traitement d'images morphologiques comme celui-ci . Vous aurez la possibilité de définir le " rectangle " même quelque chose qui n'est pas "exactement fermé" (où l'algorithme de remplissage échouera).

Une autre possibilité pourrait être d'utiliser une approche d'apprentissage automatique , qui est fondamentalement plus basée sur les données. entraîné que par définition comme le précédent. Vous devrez donner à votre algorithme plusieurs "exemples". de ce qu'est un rectangle, et il finira par apprendre (avec un biais et un taux d'erreur) .

itérez de gauche à droite jusqu'à atteindre un pixel de couleur, puis utilisez l'algorithme de remplissage par inondation modifié. plus d'informations sur le remplissage du wiki @ wiki

une autre approche serait de rechercher N'IMPORTE QUEL pixel coloré sur l'image, puis d'aller avec

while(pixel under current is colored)
{
  lowest pixel coordinate = pixel under current
  current = pixel under
}

alors faites la même chose vers le haut. maintenant vous avez défini une seule ligne. utilisez ensuite les extrémités des lignes pour faire correspondre approximativement les lignes à des rectangles. s’ils ne sont pas parfaits en pixels, vous pouvez effectuer une sorte de seuillage.

L'inondation fonctionnerait ou vous pourriez utiliser une modification d'un algorithme de suivi des contours.

Ce que vous faites est: créer un tableau 2D (ou toute autre structure de données d2) - chaque ligne représente une ligne de pixel horizontale à l'écran, et chaque colonne une ligne verticale

parcourez tous les pixels, de gauche à droite, et chaque fois que vous en trouvez un de couleur, ajoutez ses coordonnées au tableau

parcourir le tableau, rechercher des lignes et stocker les pixels de début et de fin pour chacune (structure de données différente)

sachant que le début de chaque ligne est son pixel gauche / haut, vous pouvez facilement vérifier si 4 lignes comportent un rectangle

Pour obtenir de l'image que vous avez avec les lignes horizontales et verticales presque jointives aux rectangles uniquement:

  1. Convertir en binaire (c'est-à-dire toutes les lignes sont blancs, le reste est noir)
  2. Effectuez une dilatation binaire (ici vous créez chaque pixel qui touche pixel blanc dans l'image source ou est un pixel blanc dans l'image source blanc.Le toucher est uniquement droit (chaque pixel "touche" ainsi les pixels à gauche, à droite, au-dessus et au-dessous), on l'appelle "connecté en 4". ;
  3. répétez l'étape 3 plusieurs fois si les espaces entre les extrémités sont plus larges que 2 pixels de large, mais pas trop souvent!
  4. Effectuez une opération squelette (ici, vous faites en sorte que chaque pixel de l'image de sortie soit noir s'il s'agit d'un pixel blanc de l'image source qui touche au moins un pixel noir et que les pixels blancs qu'elle touche (dans l'image source) se touchent tous mutuellement. Encore une fois, toucher défini avec une connexion 4. Voir l'exemple ci-dessous.
  5. Répétez l'étape 4 jusqu'à ce que l'image ne change pas après une répétition (tous les pixels blancs sont des fins de ligne ou des connecteurs)

Ceci affichera, avec un peu de chance, d’abord les cases avec des lignes épaisses, laissant des artefacts épais sur toute l’image (après l’étape 3), puis après l’étape 5, tous les artefacts épais auront été supprimés. toutes les cases restent. Vous devez modifier le nombre de répétitions à l'étape 3 pour obtenir de meilleurs résultats. Si vous êtes intéressé par la morphologie des images, c'est le livre de un très bon cours d'initiation que j'ai suivi.

Exemple: (0 = noir, 1 = blanc, les pixels au centre de chaque bloc 3x3 sont pris en compte, entrée à gauche, sortie à droite)

011 => 011    
011 => 001  all other white pixels touch, so eliminate      
011 => 011    

010 => 010    
010 => 010  top pixel would become disconnected, so leave      
010 => 010    

010 => 010    
010 => 000  touches only one white pixel, so remove     
000 => 000    

010 => 010    
111 => 111  does not touch black pixels, leave    
010 => 010    

010 => 010    
011 => 011  other pixels do not touch. so leave    
000 => 000    
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top