En utilisant Opencv, comment détecter une boîte dans l'image tout en éliminant les objets imprimés à l'intérieur de la boîte ?

StackOverflow https://stackoverflow.com//questions/25082372

Question

J'essaie de développer une application de tri de boîtes dans Qt et en utilisant opencv.Je veux mesurer la largeur et la longueur de la boîte.

Input Image

Comme le montre l'image ci-dessus, je souhaite détecter uniquement les lignes les plus extérieures (c.-à-d.bords de la boîte), ce qui me donnera la largeur et la longueur de la boîte, quel que soit ce qui est imprimé à l'intérieur de la boîte.

Ce que j'ai essayé :

  1. J'ai d'abord essayé d'utiliser Findcontours() et le contour sélectionné avec une zone maximale, mais le contour du bord extérieur n'est pas inclus (cassé quelque part dans la sortie astucieuse) plusieurs fois et n'est donc pas détecté comme un contour.

  2. Bien que la transformation de ligne me donne trop de lignes, je ne sais pas comment obtenir seulement quatre lignes qui m'intéressent.

  3. J'ai essayé mon algorithme comme,

    Convertir l'image en échelle de gris.

    Prenez une colonne d'image, comparez chaque pixel avec le pixel successif suivant de cette colonne, si la différence de valeur est supérieure à un certain seuil (disons 100) auquel ce pixel appartient au bord, stockez-le donc dans un tableau.Faites ceci pour toutes les colonnes et cela donnera la ligne supérieure de la boîte parallèle à l'axe des x.

    Suivez la même procédure, mais à partir de la dernière colonne et de la dernière ligne (c.-à-d.de bas en haut), cela donnera une ligne inférieure parallèle à l’axe x.

    Trouvez également des lignes parallèles à l’axe y.J'ai maintenant quatre tableaux de points, un pour chaque côté.

Maintenant, cela me donne de bons résultats si la boîte est placée de telle manière que ses côtés soient exactement parallèles aux axes X et Y.Si la boîte est placée même légèrement orientée dans une certaine direction, cela me donne des lignes diagonales qui sont évidentes, comme le montre l'image ci-dessous.

Wrong Output

Comme le montre l'image ci-dessous, j'ai supprimé les 10 premiers et les 10 derniers points des quatre tableaux de points (qui sont responsables du dessin des lignes diagonales) et j'ai dessiné les lignes, ce qui ne fonctionnera pas lorsque la boîte est davantage inclinée et les mesures seront également erronées. .

enter image description here

Maintenant ma question est,

Existe-t-il un moyen plus simple dans opencv d'obtenir uniquement les bords extérieurs (rectangle) de la boîte et d'y obtenir les dimensions, en ignorant tout ce qui est imprimé sur la boîte et orienté dans n'importe quelle direction ?

Je ne demande pas nécessairement de corriger/améliorer mon algorithme, mais toute suggestion à ce sujet est également la bienvenue.Désolé pour un si gros post.

Était-ce utile?

La solution

Je suggérerais les étapes suivantes:

1:Créez une image de masque en utilisant cv::inRange() (Documentation) pour sélectionner la couleur d’arrière-plan.Utilisez ensuite cv::not() pour inverser ce masque.Cela vous donnera uniquement la boîte.

2 :Si vous n'êtes pas préoccupé par les effets d'ombre et de profondeur rendant votre mesure inexacte, vous pouvez immédiatement essayer d'utiliser cv::findContours() encore.Vous sélectionnez le plus grand contour et le stockez cv::rotatedRect.

3 :Ce cv::rotatedRect vous donnera un rotatedRect.size qui définit la largeur et la hauteur de votre boîte en pixels

Autres conseils

Étant donné que la boîte est placée sur un arrière-plan contrasté, vous devriez pouvoir utiliser le seuillage Otsu.

  • seuiller l'image (utiliser la méthode Otsu)
  • filtrer tous les pixels parasites qui se trouvent en dehors de la région de la boîte (espérons que vous n'obtiendrez pas beaucoup de ces pixels et que vous pourrez facilement les supprimer avec un filtre médian ou morphologique)
  • trouver des contours
  • combinez tous les points de contour et obtenez leur coque convexe (l'idée ici est de trouver la région convexe qui délimite tous ces contours dans la région de la boîte quelle que soit leur connectivité)
  • appliquez une approximation de polygone (approxPolyDP) à cette coque convexe et vérifiez si vous obtenez un quadrilatère
  • s'il n'y a pas de distorsion de perspective, vous devriez obtenir un rectangle, sinon vous devrez le corriger
  • si vous obtenez un rectangle, vous avez ses dimensions.Vous pouvez également trouver le rectangle d'aire minimale (minAreaRect) de la coque convexe, qui devrait directement vous donner un RotatedRect
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top