8
votes

Un moyen simple de vérifier si une image bitmap est floue

Je cherche un moyen simple "très" de vérifier si une image bitmap est floue. Je n'ai pas besoin d'algorithme précis et compliqué qui implique une FFT, une ondelette, etc. Une seule idée très simple, même si ce n'est pas précis.

J'ai pensé calculer la distance d'euclidienne moyenne entre pixels (x, y) et pixel (x + 1, y) en considérant leurs composants RVB, puis en utilisant un seuil, mais cela fonctionne très mal. Toute autre idée?


3 commentaires

Vous pouvez peut-être utiliser la variance moyenne d'une fenêtre coulissante pour obtenir une idée approximative de la quantité de contenu haute fréquence que vous avez. Convertir en premier à la Greyscale. Les réponses à Cette question ont beaucoup plus d'options.


Duplicaté possible de est là un moyen de détecter si Une image est floue?


J'ai essayé cela ça marche Medium.com/better-programming / ...


3 Réponses :


1
votes

Calculez la moyenne L1-Distance des pixels adjacents: xxx

puis la distance de L2 moyenne: xxx

puis le rapport N2 / (N1 * N1) est une mesure de flou. Ceci est pour les images en niveaux de gris, pour la couleur que vous le faites pour chaque canal séparément.


2 commentaires

Merci @pentadecagon. Vous suggérez-vous de convertir l'image en niveaux de gris ou de répéter la tâche ci-dessus pour chaque canal, puis d'agréger les résultats en quelque sorte?


Bonjour @pentadecagon, pouvez-vous fournir le code exact pour brouiller l'image. Merci beaucoup.



3
votes

Je suppose que, philosophiquement parler, toutes les images naturelles sont floues ... comment floue et à quelle quantité est quelque chose qui dépend de votre application. De manière générale, la flammes ou la netteté des images peuvent être mesurées de différentes manières. Comme une première tentative facile, je vérifierais l'énergie de l'image , définie comme la sommation normalisée des valeurs de pixels carrés: xxx

Vous pouvez Appliquez un filtre LE LAPLACIAN DE GAUSSIEN (LOG) pour détecter les zones "énergiques" de l'image, puis vérifier l'énergie. L'image floue doit montrer une énergie considérablement inférieure.

Voir un exemple dans matlab à l'aide d'une image typique de niveaux de gris:
c'est l'image d'origine Ceci est l'image d'origine C'est l'image floue, floue de bruit gaussien C'est l'image floue, floue de bruit gaussien c'est l'image du journal de l'original C'est l'image du journal de l'original et ceci est l'image du journal du flou unique Ceci est l'image du journal de l'image floue

Si vous comprenez simplement l'énergie du Deux images de journal que vous obtenez: xxx

qui est une énorme quantité de différence ...
Ensuite, vous devez simplement choisir un seuil pour juger quelle quantité d'énergie est bonne pour votre application ...


6 commentaires

L'image d'origine a beaucoup de bruit granulaire éliminé par votre filtre gaussien. Une vraie photo contiendrait toujours la même quantité de bruit, même si elle était mal ciblée.


@squaMishOSSifrage Je suis fortement en désaccord avec votre opinion. À ma compréhension, il n'ya aucun moyen que vous ayez une image floue (ou de manière incorrecte) et que vous soyez assez «granuleux» suffisamment pour obtenir une énergie élevée ...


Laissez-moi essayer d'expliquer, alors. Regardez le fond de votre image d'origine dans la région au-dessus du chapeau. L'image est clairement bruyante ici, même si elle est déjà incitée. Cela reflète le granularité du film sur lequel cette photo a été prise. D'autre part, les photographies prises sur des caméras numériques sont affectées par Current sombre et < Un href = "http://fr.wikipedia.org/wiki/thermal_noise" rel = "Nofollow Noreferrer"> bruit thermique . Dans les deux cas, ce bruit aura un effet significatif sur l'énergie moyenne de l'image.


@sQuaMishOSSifrage Je peux comprendre cela, mais mon argument était que cette "granularité" ne contribuera pas de manière significative à une augmentation de l'énergie. J'ai testé la méthode que j'ai proposée avec diverses images, aussi les images de votre exemple et mon approche tient toujours.


@sQuaMishOSSifrage ... Continuer ... J'ai également mis en œuvre votre méthode à Matlab, ce qui est beaucoup plus facile et qui l'a essayé à l'aide de l'image entière et non seulement des échantillons sur une grille. Les résultats obtenus par les deux approches sont cohérents. Mais, clairement, mon approche sera plus lente que la vôtre, qui utilise des opérations plus simples et pourrait sûrement devenir encore plus rapide si votre grille devient plus simple (suffisamment pour représenter toujours l'image).


J'ai utilisé l'approche de Sepdek avec un succès limité. Le frottement vient avec "Il suffit de sélectionner un seuil". La sélection de ce seuil nécessite que le problème soit lié plus qu'il ne l'est généralement.



17
votes

Ne calculez pas la moyenne différences entre les pixels adjacents.

Même lorsqu'une photo est parfaitement mise au point, il peut toujours contenir de grandes zones de couleur uniforme, comme le ciel par exemple. Celles-ci appellent la différence moyenne et masquer les détails dont vous êtes intéressé. Ce que vous voulez vraiment trouver, c'est la valeur maximum .

Aussi, pour accélérer les choses, je ne me soucierais pas de vérifier chaque pixel dans l'image. Vous devriez obtenir des résultats raisonnables en consultant une grille de lignes horizontales et verticales espacées, disons, 10 pixels à part.

Voici les résultats de certains tests avec les fonctions GD GD de PHP à l'aide d'une image de Wikimedia Commons ( Bokeh_ipomea.jpg ). Les valeurs NETTRESSES sont simplement les valeurs de différence de pixels maximales en pourcentage de 255 (je n'ai que l'air dans le canal vert; vous devriez probablement convertir en Greyscale en premier). Les chiffres ci-dessous montrent combien de temps il a fallu pour traiter l'image.

gros plan de fleur ipomea, netteté calculée comme 71,0%

la même image avec une légère flou, la netteté est réduite à 36,1%

identique image avec flou sévère; la netteté est maintenant de 17,6%

Si vous les voulez, voici les images source que j'ai utilisées:

  • Original
  • légèrement floue
  • floue

    MISE À JOUR:

    Il y a un problème avec cet algorithme en ce sens qu'il repose sur l'image ayant un niveau de contraste assez élevé ainsi que sur des bords ciblés tranchants. Il peut être amélioré en trouvant la différence maximale de pixels ( maxdiff ) et en trouvant la gamme globale de valeurs de pixels dans une petite zone centrée sur cet emplacement ( gamme ). La netteté est ensuite calculée comme suit:

    netteté = ( maxDiff / ( décalage + plage )) * (1.0 + offset / 255) * 100%

    décalse est un paramètre qui réduit les effets de très petits bords afin que le bruit de fond n'affecte pas de manière significative les résultats. (J'ai utilisé une valeur de 15.)

    Cela produit des résultats assez bons. N'importe quoi avec une netteté de moins de 40% est probablement pas parti. Voici quelques exemples (les emplacements de la différence de pixel maximum et les zones de recherche locales 9 × 9 sont également présentées pour référence):

    (source)

    (source)

    (source)

    (source)

    Les résultats ne sont toujours pas parfaits, cependant. Les sujets qui sont intrinsèquement floustrions entraîneront toujours une valeur de netteté faible:

    (source)

    bokeh effets peut produire des arêtes vives à partir de sources de lumière de la lumière, même quand elles sont complètement sorties de la mise au point:

    (source)

    Vous avez commenté que vous souhaitez pouvoir rejeter les photos soumises par l'utilisateur qui ne sont pas au point. Étant donné que cette technique n'est pas parfaite, je vous suggère de notifier l'utilisateur si une image apparaît floue au lieu de le rejeter complètement.


13 commentaires

Merci @ Squeamish-Ossifrage pour votre réponse, mais pourriez-vous me fournir des détails supplémentaires? Je voudrais mettre en œuvre votre méthode mais ce n'est pas clair pour moi comment ça fonctionne exactement. Calculez-vous la distance de couleur entre un pixel et son voisin pour chaque pixel, puis sélectionnez le maxium? Est-ce correct? Si tel est le cas, supposons que votre image contienne deux pixels adjacents un blanc et un noir. Cela donnera la distance maximale de 255 et une netteté de 100%. Est-ce correct?


Cela fonctionne sûrement et est simple si nécessaire. Seule préoccupation est l'heure. Choisissez une grille clairsemée pour les résultats rapides.


Cela fonctionne bien, mais malheureusement, il est utile lorsque vous avez plusieurs instances de la même image et que vous souhaitez déterminer lequel d'entre eux est le meilleur (en termes de netteté). Mon problème est différent. En fait, j'ai une seule instance d'une image et je tiens à déterminer sa qualité (en termes de netteté) et de le rejeter s'il est flou ...


@ user2923045 J'ai mis à jour ma réponse; S'il vous plaît, jetez un oeil.


@sQuaMishOSSifrage Merci pour cette réponse détaillée. Malheureusement, la liaison de Pastebin a expiré. Pouvez-vous s'il vous plaît le partager à nouveau, ce sera vraiment utile.


@ arvind.mohan Aucun problème. (Remarque: J'aurais peut-être modifié le code légèrement, mais cela devrait toujours fonctionner. Incapable de tester pour le moment.)


@sQuaMishOSSifrage J'étais vraiment inquiet si cette théorie fonctionnera pour mes images, où il n'y a que des couleurs noires et blanches sont utilisées.


@ arvind.mohan Si vous voulez dire des images de Greyscale, cela devrait bien fonctionner. Si vos images sont simplement noires et blanches (c'est-à-dire 1 bit par pixel), alors cela ne fonctionnera pas du tout. Je vous suggère de l'essayer pour vous-même.


@squeamishOSSifrage link Pastebin.com/5360KCFQ ne fonctionne pas. Pouvez-vous s'il vous plaît partager votre code à nouveau?


Hé, merci pour l'effort que vous avez assuré de répondre à cette question. Une chose n'est pas claire pour moi. Dans votre réponse, vous avez placé la formule pour calculer la netteté sous la netteté (maxDiff / (compensation + plage)) * (1,0 + décalage / 255) * 100% et dans le code Pastebin, il est indiqué < Code> $ nette = ($ maxDiff / (15 + $ maxv - $ Minv)) * 27000/255; où 15 serait le décalage mais 27000 est nulle part près du résultat de 1.0 + 15/255 . Pouvez-vous clarifier sur la manière dont vous êtes venu à cette formule et qui est celui qui a conduit aux résultats que vous avez postés ci-dessus?


@floriankrueger Désolé, je n'ai pas bien expliqué ça. La valeur a été choisie pour produire une valeur de 0.0 lorsque $ maxv- $ minv == 0 et 100.0 quand $ maxv- $ minv == 255 .


@ R3Mainer Pouvez-vous partager le nom du code / de l'application Avez-vous pu trouver la netteté dans différentes régions de l'image?


@ Polarbear10 Il est toujours là: Pastebin.com/8HC1Sure