Question Comment classer les nombres flous avec openCV


Je voudrais capturer le nombre de ce genre de photo.

enter image description here

J'ai essayé la correspondance multi-échelle à partir du lien suivant.

http://www.pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/

Tout ce que je veux savoir, c'est le chiffre rouge. Mais le problème est que le chiffre rouge est flou pour le modèle de reconnaissance / correspondance openCV. Y aurait-il un autre moyen possible de détecter ce numéro rouge sur le fond noir?


21
2018-06-05 18:52


origine


Réponses:


Classification des chiffres

Vous avez précisé dans les commentaires que vous avez déjà isolé la partie numérotée de la pré-détection de l'image. Je vais donc commencer par cette hypothèse.

Vous pouvez peut-être approcher les effets de perspective et le «flou» du nombre en le traitant comme un numéro écrit à la main. Dans ce cas, il existe un célèbre ensemble de données de chiffres manuscrits pour la formation à la classification appelée mnist.

Yann LeCun a énuméré l'état de l'art sur cet ensemble de données ici ensemble de données manuscrit mnist.

À l'extrémité du spectre, les réseaux neuronaux convolutionnels produisent taux d'erreur outrageusement bas (fractions d'erreur de 1%). Pour une solution plus simple, les voisins les plus proches utilisant le redressement, la suppression du bruit, le flou et le décalage de 2 pixels ont généré environ 1% d’erreur et sont beaucoup plus rapides à mettre en œuvre. Python opencv a une implémentation. Les réseaux de neurones et les machines à vecteurs de support avec redressement ont également des taux de performance assez impressionnants.

Notez que les réseaux convolutionnels ne vous permettent pas de choisir vos propres caractéristiques, de sorte que les informations importantes sur les différences de couleur peuvent être utilisées pour réduire la zone d’intérêt. D'autres approches, dans lesquelles vous définissez votre espace, peuvent incorporer plus précisément la différence de couleur connue.

Python prend en charge de nombreuses techniques d’apprentissage automatique dans le formidable package sklearn - voici des exemples de sklearn appliqués à mnist. Si vous cherchez une explication tutorée de l'apprentissage automatique en python, Le tutoriel de sklearn est très verbeux

À partir du lien sklearn: Classifying mnist

Ce sont les types d'éléments que vous essayez de classer si vous apprenez en utilisant cette approche. Pour souligner à quel point il est facile de commencer à former certains de ces classificateurs basés sur l'apprentissage automatique, voici une section abrégée du code exemple dans le package sklearn lié:

digits = datasets.load_digits() # built-in to sklearn!
data = digits.images.reshape((len(digits.images), -1))

# Create a classifier: a support vector classifier
classifier = svm.SVC(gamma=0.001)

# We learn the digits on the first half of the digits
classifier.fit(data[:n_samples / 2], digits.target[:n_samples / 2])

Si vous êtes connecté à openCv (peut-être parce que vous souhaitez transférer vers un système en temps réel), opencv3 / python a aussi un tutoriel sur ce sujet précis! Leur démo utilise le plus proche voisin (répertorié dans la page LeCun), mais ils ont également avoir svms et les nombreux autres outils de sklearn. Leur page ocr utilisant les SVM utilise le redressement, ce qui peut être utile avec l'effet de perspective dans votre problème:

Deskewed digit


METTRE À JOUR: J'ai utilisé l’approche skimage décrite ci-dessus sur votre image, fortement recadrée, et correctement classé. UNE lot plus de tests seraient nécessaires pour voir si cela est pratique dans la pratique

enter image description here

^^ Cette minuscule image est la culture 8x8 de l'image que vous avez intégrée à votre question. mnist est des images 8x8. C'est pourquoi il s'entraîne en moins d'une seconde avec des arguments par défaut dans skimage.

Je l'ai converti au format correct en le mettant à l'échelle de la gamme mniste en utilisant

number = scipy.misc.imread("cropped_image.png")
datum  =  (number[:,:,0]*15).astype(int).reshape((64,))
classifier.predict(datum) # returns 8

Je n'ai rien changé d'autre de l'exemple; Ici, je n'utilise que le premier canal pour la classification, et aucun calcul de fonctionnalité intelligente. J'ai regardé vers moi. vous devrez l’ajuster pour atteindre la plage cible ou (idéalement) fournir votre propre jeu de formation et de test


Détection d'objets

Si vous n'avez pas isolé le nombre dans l'image, vous aurez besoin d'un détecteur d'objet. L'espace de la littérature sur ce problème est gigantesque et je ne vais pas commencer ce lapin (google Viola et Jones, peut-être?) Ce blog couvre les bases d'un détecteur "à fenêtre coulissante" en python. Adrian Rosebrock semble même avoir contribué à SO, et cette page contient de bons exemples de détecteurs d’objets basés sur des opencv et des pythons, qui sont assez tutorisés (en fait, vous n’avez pas réalisé).

En bref, classer les fenêtres sur l'image et choisir la fenêtre de confiance la plus élevée. La réduction de l'espace de recherche avec une région d'intérêt entraînera bien sûr des améliorations considérables dans tous les domaines de la performance.


19
2018-06-05 19:28



Vous pouvez utiliser plusieurs choses à votre avantage:

  • Le numéro est dans la lunette rectangulaire noire et une couleur
  • Le nombre semble être un affichage de type LCD segmenté, si bien qu'il n'y a qu'un nombre fini de segments qui sont activés ou désactivés.

Je vous suggère donc:

  • Calibrer votre appareil photo et prétraiter l'image pour supprimer la distorsion de l'objectif
  • Rectifiez le rectangle d'affichage:
    • Détecte le rectangle d'affichage en utilisant soit l'intersection de hough lignes, ou détection de bord suivie par la détection de contour et puis sélectionnez les contours les plus grands et les plus carrés
    • utilisation GetPerspectiveTransform pour obtenir la transformation entre les coordonnées de l'image et un rectangle idéal, transformez l'image d'entrée en utilisant WarpPerspective
  • Diviser l'image en canaux R, G et B et travailler r - avg(g, b), c'est un peu dépendant de l'éclairage mais devrait donner quelque chose comme ceci:

    cleaned up number image

  • Ensuite, essayez de rechercher un motif sur cette image, ou peut-être re-segmentez l'image et essayez de trouver quels segments d'affichage sont allumés ou parcourez un package OCR.

2
2018-06-08 13:53