J'ai une image avec des lignes horizontales et verticales. En fait, cette image est 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. Quelqu'un sait-il comment faire cela ou suggère-t-il des idées pour commencer? Cette tâche est facile pour moi en tant que personne de trouver les rectangles visuels, mais je ne sais pas comment le décrire comme un 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 ligne horizontale et verticale, le problème est que ces lignes ne se rencontrent pas complètement dans les coins et parfois elles ne forment pas complètement un rectangle. Merci!
Opencv (traitement d'images et bibliothèque de vision par ordinateur écrits en c) a une implémentation pour la transformation de Hough (la simple transformation de Hough 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 coins tels que cornerHarris qui peuvent vous aider.
J'ai exécuté la démo houghlines fournie avec opencv et voici le résultat sur l'image que vous avez donnée (lignes détectées marquées en rouge):
(source: splintec.com )
Je crois que vous recherchez la transformation de Hough généralisée .
En vision par ordinateur, il existe un algorithme appelé Generalized Hough Transform qui peut peut-être résoudre votre problème. Il devrait y avoir du code open source ayant implémenté cet algorithme. Recherchez-le.
En supposant que c'est une image raisonnablement exempte de bruit (pas une vidéo d'un écran), alors l'un des algorithmes de remplissage simple devrait fonctionner. Vous devrez peut-être exécuter une dilatation/érosion sur l'image pour combler les lacunes.
La manière normale de trouver des lignes est une transformation de Hough (puis de trouver des lignes à angle droit). L'opencv est la manière la plus simple.
Jetez un oeil à cette question Détection d'objets OpenCV - Point central
Il existe plusieurs approches différentes à votre problème. J'utiliserais un traitement d'image morphologique comme celui-ci . Vous aurez la possibilité de définir "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 machine learning , qui est fondamentalement plus axée sur les données que sur la définition comme la précédente. 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).
Pour passer de l'image que vous avez avec les lignes horizontales et verticales presque touchantes aux seuls rectangles:
Avec un peu de chance, cela montrera d'abord les boîtes avec des lignes de graisse épaisses, laissant des artefacts de graisse épaisse sur toute l'image (après l'étape 3), puis après l'étape 5, tous les artefacts de graisse épaisse auront été supprimés, tandis que toutes les boîtes resteront . Vous devez modifier le nombre de répétitions à l'étape 3 pour de meilleurs résultats. Si vous êtes intéressé par la morphologie de l'image, c'est le livre d'un très bon cours d'introduction que j'ai suivi.
Échantillon: (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
itérer de gauche à droite jusqu'à ce que vous atteigniez un pixel de couleur, puis utilisez un algorithme de remplissage inondé modifié. plus d'informations sur l'algo fill flood @ wiki
une autre approche serait de trouver N'IMPORTE QUEL pixel coloré sur l'image puis aller avec
while(pixel under current is colored)
{
lowest pixel coordinate = pixel under current
current = pixel under
}
puis faites de même vers le haut. maintenant vous avez défini une seule ligne. puis utilisez les extrémités des lignes pour faire correspondre approximativement les lignes en rectangles. s'ils ne sont pas parfaits en pixels, vous pouvez faire une sorte de seuil.
Le remplissage d'inondation fonctionnerait, ou vous pourriez utiliser une modification d'un algorithme de suivi d'Edge.
ce que vous faites est de créer un tableau 2d (ou toute autre structure de données d2) - chaque ligne représente une ligne horizontale de pixels à l'écran et chaque colonne une ligne verticale
parcourir 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 et les lignes de recherche et stocker le pixel de début et de fin pour chacun (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 constituent un rectangle