Rapide seuillage de l'image
Ce qui est une façon rapide et fiable de seuil images avec possibilité de brouillage et de non-uniforme de la luminosité?
Exemple (flou mais luminosité uniforme):
Parce que l'image n'est pas garanti pour avoir une luminosité uniforme, il n'est pas possible d'utiliser un seuil fixe. Un seuil adaptatif fonctionne pas mal, mais à cause de l'effet de flou, il crée des pauses et des distorsions dans les caractéristiques (ici, les caractéristiques importantes sont le Sudoku chiffres):
J'ai aussi essayé d'utiliser d'Égalisation d'Histogramme (à l'aide d'OpenCV est equalizeHist
fonction). Il augmente le contraste, sans réduire les différences de luminosité.
La meilleure solution que j'ai trouvé est de diviser l'image en son morphologiques de clôture (crédit à ce post) pour rendre la brillance uniforme, puis effectuer une renormalisation, puis d'utiliser un seuil fixe (à l'aide de l'algorithme d'Otsu de choisir le seuil optimal de niveau):
Voici le code à cet effet dans OpenCV pour Android:
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(19,19));
Mat closed = new Mat(); //closed will have type CV_32F
Imgproc.morphologyEx(image, closed, Imgproc.MORPH_CLOSE, kernel);
Core.divide(image, closed, closed, 1, CvType.CV_32F);
Core.normalize(closed, image, 0, 255, Core.NORM_MINMAX, CvType.CV_8U);
Imgproc.threshold(image, image, -1, 255, Imgproc.THRESH_BINARY_INV
+Imgproc.THRESH_OTSU);
Cela fonctionne très bien mais la commande de fermeture est très lent. La réduction de la taille de l'élément structurant augmente la vitesse, mais réduit la précision.
Edit: basé sur les contrôleurs de domaine de la suggestion, j'ai essayé à l'aide d'un filtre passe-haut. J'ai choisi le Laplacien de filtre, mais je m'attends à des résultats similaires avec Sobel et Scharr filtres. Le filtre capte le bruit haute fréquence dans les zones qui ne contiennent pas de caractéristiques, et souffre de distorsion similaire à l'adaptation du seuil en raison de l'effet de flou. elle prend également en tant que la clôture de l'opération. Voici un exemple avec un 15x15 filtre:
Edit 2: sur la Base des AruniRC réponse, j'ai utilisé Habile de détection de contours sur l'image avec les paramètres suggérés:
double mean = Core.mean(image).val[0];
Imgproc.Canny(image, image, 0.66*mean, 1.33*mean);
Je ne suis pas sûr de la façon de manière fiable automatiquement affiner les paramètres pour se connecter chiffres.
- Vous pourriez essayer de seuil sur un passe-haut à l'image filtrée, en supposant que le brigthness changement se produit dans les basses fréquences. Je ne sais pas, toutefois, à quelle vitesse ces filtrer les opérations sont sur un appareil mobile, et je pense que vous auriez besoin d'un assez grand noyau.
- Malheureusement, je ne pense pas que les filtres passe-haut sera travailler. Voir mon edit pour le post ci-dessus.
- Étant donné que les caractéristiques qui vous intéressent dans la couverture de plusieurs pixels, comment sur la réduction de l'image à une résolution inférieure en premier? Vous pouvez ensuite revenir en arrière et obtenir plus de détails à la résolution d'origine, à l'aide de votre bas-res de la version comme un masque.
- Pourriez-vous élaborer? Je ne vois pas comment réduire la résolution de l'aide.
- Avec une résolution inférieure, il y aurait moins de pixels à traiter, de sorte qu'il devrait prendre moins de temps.
- Oui, mais j'ai encore besoin de seuil les chiffres à haute résolution de sorte que je peux utiliser les chiffres de la reconnaissance. Quel est le but de seuillage à plus basse résolution de la première?
- Votre image de l'échantillon est 480x480, mais les chiffres sont encore très distinctes sur 120x120 résolution. L'effet de flou et le bruit est beaucoup moins perceptible.
- Réduire la résolution et l'utilisation de la petite image pour déterminer comment normilize la brigthness dans la zone correspondante dans la grande image, après la normalisation de procéder à filtre. Il devrait avoir plus de bruit que si vous ne la normalisation avec la grande image, mais il sera plus rapide. Nous espérons qu'avec le droit de seuil, il sera suffisant. C'est Juste une idée.
- N'est-ce pas la question, juste une question de faire une recherche Google et d'analyse comparative de quelques techniques?
- L'algorithme doit effectuer bien sur les images floues avec la variable de la luminosité, ce qui élimine la plupart des candidats. L'analyse comparative de la vitesse n'est pas le seul facteur. Avez-vous des suggestions?
Vous devez vous connecter pour publier un commentaire.
À l'aide de Vaughn Cato et Theraot suggestions, j'ai réduit l'image avant de le fermer, puis mis à l'échelle du clos de l'image jusqu'à la taille normale. J'ai aussi réduit la taille du noyau proportionnellement.
L'image ci-dessous montre les résultats side-by-side pour les 3 méthodes différentes:
Gauche - taille normale fermeture (432 pixels, taille du 19 noyau
Milieu de la moitié de la taille de la fermeture (216 pixels, taille 9 noyau
Droit - quart de la taille de la fermeture (108 pixels, taille 5 noyau
La qualité de l'image se détériore à mesure que la taille de l'image utilisée pour la fermeture devient plus petite, mais la détérioration n'est pas suffisamment important pour affecter la fonction des algorithmes de reconnaissance. La vitesse augmente un peu plus de 16 fois pour le quart de la taille de la fermeture, même avec le redimensionnement, ce qui suggère que l'heure de fermeture est à peu près proportionnelle au nombre de pixels dans l'image.
Des suggestions sur la façon d'améliorer encore cette idée (que ce soit en outre la réduction de la vitesse, ou la réduction de la détérioration de la qualité de l'image) sont les bienvenus.
Approche Alternative:
En supposant que votre intention est d'avoir les chiffres pour être clairement binarized ... à vous concentrer sur des composants à la place de l'ensemble de l'image.
Ici est assez facile d'approche:
Considérant chaque Savant bord, comme une composante connexe (c'est à dire utiliser le cvFindContours() ou de son C++ contrepartie, selon), on peut estimer que le premier plan et d'arrière-plan greylevels et d'atteindre un seuil.
Pour le dernier bit de jeter un oeil aux articles 2. et 3. de ce document. Sauter la plupart des non-essentiels pour la partie théorique, il ne devrait pas être trop difficile de le faire mis en œuvre dans OpenCV.
Espère que cela a aidé!
Edit 1:
Basé sur le Savant bord seuils voici une idée très approximative, en quantité juste suffisante pour affiner les valeurs. Le
high_threshold
contrôle la façon dont la force de l'arête doit être avant qu'il est détecté. Fondamentalement, un bord doit avoir gradient de grandeur plus grand quehigh_threshold
pour être détectée en premier lieu. Si ce n'est la première détection de bords.Maintenant, le
low_threshold
traite de la connexion à proximité des bords. Il contrôle la façon dont beaucoup de proximité déconnecté les bords peuvent être combinés en un seul bord. Pour avoir une meilleure idée, lire "à l'Étape 6" de cette page web. Essayez de définir une très petite low_threshold et voir comment les choses viennent à propos. Vous pourriez jeter que de 0,66*[valeur moyenne] chose si cela ne fonctionne pas sur ces images, c'est juste une règle de base de toute façon.low_threshold = 50, high_threshold = 150
. généralement low_threshold : high_threshold devrait être d'environ 1:3 par l'article original par Futé. la tripoter de partout! 🙂Nous utilisons Bradleys algorithme très similaires problème (pour le segment des lettres de l'arrière-plan, avec inégale de la lumière et de l'inégale de la couleur d'arrière-plan), il est décrit ici: http://people.scs.carleton.ca:8008/~roth/iit-publications-iti/docs/gerh-50002.pdf, C# code ici: http://code.google.com/p/aforge/source/browse/trunk/Sources/Imaging/Filters/Adaptive+Binarization/BradleyLocalThresholding.cs?r=1360. Il fonctionne sur partie intégrante de l'image, qui peut être calculée à l'aide de
integral
fonction de OpenCV. Il est très fiable et rapide, mais elle-même n'est pas mis en œuvre dans OpenCV, mais il est facile de port.Une autre option est adaptiveThreshold méthode dans openCV, mais nous n'avons pas l'essayer: http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#adaptivethreshold. La MOYENNE de la version est la même que bradleys, sauf qu'il utilise une constante de modifier la valeur moyenne au lieu d'un pourcentage, ce qui je pense est le meilleur.
Aussi, bon l'article est ici: https://dsp.stackexchange.com/a/2504
Vous pourriez essayer de travailler sur une tuile de base si vous savez que vous avez une bonne culture de la grille. Travail sur 9 sous-images plutôt que l'ensemble du pic va probablement conduire à plus de luminosité uniforme sur chaque sous-image. Si votre recadrage est parfait, vous pourriez même essayer d'aller de chacun des chiffres de la cellule individuellement; mais tout dépend de comment est la fiabilité de votre culture.
Ellipse de la forme est complexe à calculer, si on la compare à une forme plate.
Essayez de changer:
à:
pouvez accélérer votre solution avec un faible impact sur la précision.