Comment puis-je filtrer passe-bas en réduisant uniquement les données de pointe?

16

J'ai une image 2D, que je souhaite filtrer passe-bas, avec ces contraintes / mesures de qualité:

  1. Je ne peux pas "ajouter" de lumière à l'image, donc chaque pixel du résultat doit être <= le pixel correspondant dans l'entrée.
  2. La fréquence de coupure passe-bas doit être un paramètre, pour expérimenter avec
  3. L'application répétée de ce filtre ne devrait pas modifier le résultat de manière significative.
  4. Le temps qu'il faut pour exécuter cet algorithme (5 minutes pour une image 5MPix semble raisonnable)
  5. Minimiser la quantité de lumière qui est filtrée.

Voici quelques approches que j'ai essayées, ainsi que leurs lacunes:

  1. Filtre gaussien comme d'habitude, puis tirez le résultat vers le bas pour respecter la contrainte 1. Cela correspond très bien aux 3 premiers points, mais réduit beaucoup plus de lumière que nécessaire.

  2. Montage des paraboles "vers le haut" à travers les points "bas" et des paraboles "vers le bas" entre elles pour lisser. Cela fonctionne très bien en 1D, mais l'appliquer d'abord horizontalement, puis verticalement produit de mauvais résultats en 2D. Cela prend beaucoup plus de temps, mais pas trop longtemps pour mon application. Cependant, l'application répétée de ce filtre changera radicalement le résultat. Si l'entrée (1D) est une parabole "descendante" parfaite (qui ne doit pas du tout être filtrée), elle sera remplacée par 2 paraboles "ascendantes" situées au début / fin.

  3. Utiliser une autre forme de fonctions "basiques" 2D et une résolution linéaire pour trouver les paramètres optimaux. C'est une idée seulement actuellement, non encore implémentée / testée.

Mon domaine d'expérience dans le traitement du signal étant presque exclusivement le traitement d'images, j'espère donc trouver des alternatives à ce problème avec la contribution d'experts actifs dans d'autres domaines du traitement du signal.

mise à jour 2011/08/18

Sur la base des réactions actuelles, j'ai décidé de rendre les choses un peu plus claires en ajoutant des graphiques d'une entrée typique et les résultats des 3 approches que j'ai décrites à l'origine + les suggestions que j'ai reçues jusqu'à présent. Pour une comparaison facile, j'ai utilisé uniquement le filtrage 1D dans ces exemples.

Des données d'entrée: Des données d'entrée

Filtre gaussien + abaisser pour se conformer à l'exigence (1).
Vous pouvez voir que le réduire entraîne des réductions de lumière inutiles sur le côté droit. filtré gaussien

Paraboles
En ce qui me concerne, c'est à peu près excellent, malheureusement cela ne se traduit pas parfaitement en 2D en appliquant d'abord horizontal, puis vertical. Dans ce cas, vous voyez également que je peux évaluer les paraboles ajustées en résolution à virgule flottante, ce qui est un petit avantage, mais pas absolument nécessaire. raccord parabole

Érosion en niveaux de gris
Sur la base de la suggestion de rwong, j'ai essayé l'érosion en niveaux de gris. J'ai utilisé un élément structurant avec la même forme parabolique que mes paraboles "ajustées". Le résultat est presque exactement le même, donc cela semble prometteur. Cependant, il y a encore quelques problèmes: 1. Mon élément structurant n'était pas "assez grand" (même s'il faisait déjà 801 pixels de large) 1. Je n'ai que des paraboles "vers le haut", pas de "paraboles vers le bas pour faciliter la transition d'une parabole au suivant. érosion en niveaux de gris

Filtrage médian
Seulement inclus pour être complet, ce n'est pas vraiment ce que je veux. filtre médian

données brutes
J'ai collé les données d'entrée brutes + les diverses commandes python sur pastebin, afin que vous puissiez également expérimenter avec les mêmes données.
http://pastebin.com/ASnJ9M0p

Pieter-Jan Busschaert
la source
1
Pouvez-vous expliquer un peu plus les restrictions 1 et 5? Ils semblent (à première vue) contradictoires.
Peter K.
Je comprends probablement mal ce que vous entendez par "cet algorithme", mais 5 minutes pour 5 MP semblent beaucoup pour appliquer un filtre passe-bas.
bjoernz

Réponses:

8

Il existe en effet une version 2D pour votre tentative n ° 2 - elle est similaire en théorie, mais elle ne peut pas être décomposée en deux opérations 1D. Veuillez lire le "Filtrage morphologique en niveaux de gris 2D". Il est plus rapide que l'ajustement de courbe.

Le filtrage médian peut également être utile si vous essayez de supprimer les taches. Une forme plus avancée de filtrage médian est le "filtrage ordinal".

Dans tous les cas, l'exigence n ° 1 peut être satisfaite trivialement en prenant le minimum pixel par pixel entre la sortie et l'entrée. C'est un critère de qualité important, mais cela ne limitera pas le choix des algorithmes.


Le filtrage gaussien (et un certain nombre d'autres filtres utiles) peut être décomposé (d'abord des opérations 2D à 1D, puis via la transformée de Fourier), mais il existe de nombreuses autres techniques de traitement d'image utiles qui ne sont pas décomposables, ce qui les rend lentes mais ne diminue pas. leur utilité.

rwong
la source
Salut, merci pour le pointeur sur le filtrage morphologique en niveaux de gris. La description sur wikipedia semble intéressante et je vais enquêter là-dessus. Cependant, dans votre lien vers la documentation OpenCV, je ne vois que des filtres morphologiques normaux, pas des filtres en niveaux de gris. Je vais certainement vérifier cette option et vous informer des résultats. Merci.
Pieter-Jan Busschaert
6
Est-ce que la suggestion de rwong d'un filtrage médian aide du tout? Expliquer un peu plus ce que vous essayez de réaliser en présentant un exemple simple des données et un exemple "faux" de ce que vous voulez retirer pourrait aider.
Peter K.
J'ai mis à jour ma question avec des exemples de données + les résultats de diverses suggestions. J'espère que les choses sont plus claires maintenant.
Pieter-Jan Busschaert
2

Je suggère d'utiliser une spline de lissage.

Voici comment vous pouvez le faire en utilisant Matlab avec la fonction de lissage de spline robuste SMOOTHN de Matlab File Exchange (qui contient le code source complet, afin que vous puissiez le réimplémenter ailleurs si nécessaire). Notez qu'il fonctionne également avec des données à n dimensions:

%# - get inputlist from pastebin

%# - smoothen data. Lower factor means less smooth
smoothingFactor = 1000;
smoothData = smoothn(inputlist,smoothingFactor);

%# - shift down
smoothData = smoothData - max(inputlist-smoothData);

%# - show results
plot(inputlist,'b'),hold on,plot(smoothData,'r')

entrez la description de l'image ici

Jonas
la source
Merci pour votre suggestion, je vais enquêter. D'après votre graphique, il semblerait que j'ai besoin d'un facteur de lissage beaucoup plus élevé que votre exemple. Le bord raide autour de x = 700 n'est pas supprimé et sera clairement visible. De plus, le relief initial de x = [0, 400] n'est pas supprimé du tout. Ne pensez-vous pas que cela aura le même problème que toute autre approche (filtre passe-bas + déplacer vers le bas)? Vous pouvez voir le décalage global entre les deux graphiques, qui augmentera probablement même lorsque j'utiliserai un facteur de lissage plus élevé.
Pieter-Jan Busschaert
@ Pieter-JanBusschaert: Oh, je pensais que le premier pic vous était en quelque sorte utile. Quoi qu'il en soit, tous les filtres passe-bas + descente auront des problèmes avec la montée abrupte à ~ 650: Ils rendront cette partie plus plate, et donc la courbe doit être beaucoup baissée. Le filtre médian suivi d'une spline de lissage aide un peu.
Jonas