Je voudrais reconnaître les limites d'un carrelage hexagonal sur une photo, comme dans l'image ci-dessous:
Il me semble qu'une approche standard sur une grille carrée consiste à détecter d'abord les coins (par exemple rusés) puis à extraire les lignes les plus longues via une transformation de Hough ou quelque chose de similaire.
Cela ne semble pas être une solution optimale avec le carrelage hexagonal, car la longueur des lignes extérieures est plus courte et il est difficile de les séparer des autres lignes.
Existe-t-il un algorithme pour résoudre ce problème? Ce serait particulièrement bien d'avoir une solution en opencv, mais je m'intéresse aussi aux idées générales.
mise à jour:
Avec python et opencv j'ai pu recevoir ce résultat:
Voici mon code:
import cv2
import numpy as np
imgOrig = "test1";
img = cv2.imread(imgOrig+".jpg");
lap = cv2.Laplacian(img, cv2.IPL_DEPTH_32F, ksize = 3)
imgray = cv2.cvtColor(lap,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
size = img.shape
m = np.zeros(size, dtype=np.uint8)
for i, cnt in enumerate(contours):
if cv2.contourArea(cnt) >= 1:
color = (255,255,255)
cv2.drawContours(m, cnt, -1, color, -1)
cv2.imwrite(str(imgOrig)+"contours.jpg", m);
Le laplacien de l'image ressemble à:
Je vais essayer d'optimiser les paramètres de cette approche et ensuite essayer d'interpoler les limites des quatre sections.
Réponses:
1ère approche:
Utilisez les méthodes de haartraining d'opencv selon ce didacticiel http://note.sonots.com/SciSoftware/haartraining.html - cela devrait donner les meilleurs résultats, mais je n'ai pas travaillé avec haartraining moi-même jusqu'à présent ...
2ème approche:
Je suggérerais d'utiliser des méthodes de "suivi sans marqueur" des tuiles individuelles du plateau. Vous pouvez également implémenter ceci en utilisant OpenCV.
Préparation
À cette fin, vous aurez besoin de quelques photos de chaque type de tuile. Prenez une photo de tous les types de tuiles (chacune comme une seule image), avec un arrière-plan homogène à partir d'une tuile vue de haut en bas au milieu de l'image.
Ensuite, utilisez un détecteur de fonctionnalités (OpenCV a plusieurs algorithmes pour cela, mais SIFT / SURF sont des algorithmes non libres; je suggérerais d'utiliser "FAST") pour trouver des points distinctifs dans les images.
Utilisez un descripteur de fonction pour décrire la fonction trouvée dans l'image (utilisez par exemple "BREF").
Détection
Vous pouvez maintenant détecter les tuiles d'une image en appliquant les mêmes algorithmes de détecteur / descripteur de caractéristiques à cette image. Lorsque vous avez acquis les fonctionnalités / descripteurs, vous pouvez appliquer le FlannBasedMatcher pour trouver les tuiles.
Voici un exemple de code / tutoriel d'OpenCV: http://docs.opencv.org/doc/tutorials/features2d/feature_homography/feature_homography.html#feature-homography
Remarques
La méthode Matcher ne vous donnera qu'une seule correspondance et aura peut-être des problèmes si plusieurs tuiles de ce type se trouvent sur le plateau. Vous pouvez contourner ce problème en masquant uniquement certaines parties de l'image d'entrée. Je suggère de le faire en utilisant les coordonnées en pixels des entités détectées. Si vous - en quelque sorte - détectez d'abord le contour et la taille des carreaux, vous pouvez approximativement estimer la position et la taille des carreaux sur l'image. Filtrez votre liste de fonctionnalités détectée (par exemple, uniquement les fonctionnalités dans un rayon de x pixels à partir du milieu attendu de la tuile) avant de les faire correspondre, puis utilisez la correspondance la plus forte. En conséquence, vous recevrez la position exacte de la tuile sur l'image (y compris son orientation). S'il est trop compliqué de détecter le contour de la carte, vous pouvez laisser l'utilisateur "pointer" sur les tuiles d'angle pour marquer manuellement le contour ...
Approche alternative
Vous pouvez également utiliser cette méthode pour rechercher n'importe quelle tuile par son contour. Dessinez un exemple d'image schématique en niveaux de gris d'une tuile (hexagone) sans aucune image dessus. Notez que les régions "sombres" et "claires" de cette image doivent être correctes dans le schéma, pas seulement quelques "lignes". Vous devrez probablement expérimenter cela. Vous pouvez essayer de faire la moyenne de plusieurs photographies de différentes tuiles pour générer une image "moyenne" d'une tuile. Assurez-vous que les coins sont à la même position (déplacez / redimensionnez les images en conséquence) et nettoyez l'image une fois terminé (les coins / bords clairs doivent être visibles) et ajustez un peu le contraste, si nécessaire.
la source
Je décrirai mon approche actuelle, qui est une combinaison de l'exploitation des règles du jeu, du traitement d'image et de la détection des fonctionnalités.
Règles de jeu pertinentes
La concrétisation
Au début, j'utilise la transformation de Hough pour extraire la position du plateau de jeu. L'image source ressemble à l'image finale en question, mais avec des lignes plus épaisses et j'ai filtré les limites plus petites. J'utilise uniquement la détection de lignes très longues (ordre de grandeur: environ 60% de la largeur / hauteur de l'image) et un très petit seuil pour la correspondance des lignes. Je regarde également les lignes des 40% extérieurs de l'image et je prends la médiane des lignes détectées en haut, en bas, à gauche et à droite. Le résultat est montré dans l'image ci-dessous:
Je n'ai besoin que d'une approximation approximative, donc c'est très bien. À partir de maintenant, je n'examine que l'image à l'intérieur des lignes de Houghline, plus un espace supplémentaire en raison de l'incertitude de la transformation de Hough.
Ensuite, j'utilise la détection des fonctionnalités, comme l'a proposé Stefan K. dans sa réponse, pour détecter les fonctionnalités dans l'image, qui ne peuvent pas être prises par les joueurs, à savoir les châteaux, les tuiles de localisation et les montagnes. J'utilise l'algorithme ORB dans opencv-python pour ce faire et BruteForce-Hamming-Matcher (je n'ai pas encore pu faire fonctionner FlannBased matcher). ORB est invariant à l'échelle et à la rotation. Afin de détecter plusieurs occurrences de mêmes caractéristiques (par exemple des châteaux), je divise l'image en plusieurs parties qui se chevauchent. Cela fonctionne bien car la longue résolution de l'image est suffisamment grande et la photo est prise directement par le haut (nécessite encore quelques tests). C'est aussi un peu lent. La détection de la tuile de localisation (taverne) est montrée comme exemple dans l'image ci-dessous
En ce moment, j'essaie de trouver l'homographieTransform pour extraire la position et l'orientation exactes des caractéristiques détectées.
J'espère pouvoir reconstruire la grille à partir de ces informations (position des montagnes, du château, de l'emplacement des tuiles et dans la plupart des cas de l'eau). Les expériences actuelles semblent prometteuses, bien que beaucoup de réglages fins et une préparation appropriée des images de fonctionnalité doivent être effectués.
la source