FFT sur l'image avec Python
J'ai un problème avec la FFT la mise en œuvre en Python. J'ai complètement étranges résultats.
Ok, donc, je veux ouvrir une image, d'obtenir la valeur de chaque pixel de RVB, puis-je utiliser de la fft sur elle, et de le convertir à nouveau l'image.
Mon étapes:
1) je suis à l'ouverture d'une image avec PIL bibliothèque en Python comme ce
from PIL import Image
im = Image.open("test.png")
2) je suis l'obtention de pixels
pixels = list(im.getdata())
3) je suis séparée de chaque pixel à r,g,b valeurs
for x in range(width):
for y in range(height):
r,g,b = pixels[x*width+y]
red[x][y] = r
green[x][y] = g
blue[x][y] = b
4). Supposons que j'ai un pixel (111,111,111). Et l'utilisation de la fft sur toutes les valeurs en rouge comme ça
red = np.fft.fft(red)
Et puis:
print (red[0][0], green[0][0], blue[0][0])
Mon résultat est:
(53866+0j) 111 111
C'est complètement faux je pense. Mon image est 64x64, et la FFT à partir de gimp est complètement différent. En fait, mon FFT me donner seulement des tableaux avec des valeurs énormes, c'est pourquoi mon image de sortie est noir.
Avez-vous une idée où est le problème?
[MODIFIER]
J'ai changé, comme l'a suggéré à
red= np.fft.fft2(red)
Et après que je l'échelle
scale = 1/(width*height)
red= abs(red* scale)
Et encore, je suis seul noir de l'image.
[EDIT2]
Ok, donc permet de prendre une image.
Supposer que je ne veux pas l'ouvrir et l'enregistrer comme image en niveaux de gris. Donc, je fais comme ça.
def getGray(pixel):
r,g,b = pixel
return (r+g+b)/3
im = Image.open("test.png")
im.load()
pixels = list(im.getdata())
width, height = im.size
for x in range(width):
for y in range(height):
greyscale[x][y] = getGray(pixels[x*width+y])
data = []
for x in range(width):
for y in range(height):
pix = greyscale[x][y]
data.append(pix)
img = Image.new("L", (width,height), "white")
img.putdata(data)
img.save('out.png')
Après cela, je suis de cette image , qui est ok. Alors maintenant, je veux faire de la fft sur mon image avant je vais l'enregistrer à nouveau, alors je fais comme ceci
scale = 1/(width*height)
greyscale = np.fft.fft2(greyscale)
greyscale = abs(greyscale * scale)
après le chargement. Après les enregistrer dans un fichier, j'ai . Donc, nous allons essayer maintenant de test ouvert.png avec gimp et utiliser le filtre FFT plugin. Je suis de cette image, ce qui est correct
Comment je peux gérer ça?
fft2
2d des transformées de fourier discrètes docs.scipy.org/doc/numpy/reference/generated/...Je pense que la question a un grand XY problème. S'il vous plaît dites-nous ce que vous êtes vraiment essayer de faire. Est-il un algorithme spécifique que vous souhaitez mettre en œuvre? Aussi, pouvez-vous nous montrer un exemple de l'image et de ce que Gimp est la FFT produit (qui est ce que vous voulez essayer et produire en Python)?
Pourriez-vous s'il vous plaît également partager le code qui enregistre vos résultant de la FFT en tant qu'image?
OriginalL'auteur Tatarinho | 2016-07-20
Vous devez vous connecter pour publier un commentaire.
Grande question. Je n'ai jamais entendu parler de cela, mais la Gimp Fourier plugin semble vraiment bien:
Cette idée de faire Gimp-style de la manipulation de la fréquence des données dans le domaine et la transformation de revenir à une image qui est très cool! Malgré des années de travail avec la Fft, je n'ai jamais pensé à faire cela. Au lieu de vous embêter avec Gimp plugins et C exécutables et de la laideur, on va le faire en Python!
Mise en garde. J'ai expérimenté avec un certain nombre de façons de le faire, essayer d'obtenir quelque chose de proche de la sortie de Gimp de Fourier de l'image (gris avec effet de moiré) à partir de l'entrée d'origine de l'image, mais je ne pouvais simplement pas. Le Gimp image semble être quelque peu symétrique autour de la moyenne de l'image, mais il n'est pas retourné verticalement ou horizontalement, ni est-il transpose-symétrique. Je m'attends à le plugin à l'aide d'un réel 2D FFT à transformer un H×l image dans un H×W tableau de valeurs réelles des données dans le domaine de fréquence, dans lequel cas il n'y aurait pas de symétrie (c'est juste la FFT complexe qui est conjugué-symétrique pour de vrai valeur des intrants tels que des images). J'ai donc renoncé à l'ingénierie inverse de ce que l'Gimp plugin est en train de faire et vu comment je le ferais à partir de zéro.
Le code. Très simple: lire une image, appliquer
scipy.fftpack.rfft
en deux dimensions pour obtenir la “fréquence-image, redimensionner à 0 à 255, et de les enregistrer.Notez comment cela est différent de l'autre des réponses! Pas grayscaling—2D réel-réel de la FFT se produit de façon indépendante sur l'ensemble des trois canaux. Pas
abs
nécessaire: le domaine fréquentiel de l'image peut légitimement avoir des valeurs négatives, et si vous les faire positif, vous ne pouvez pas récupérer votre image d'origine. (Également une fonctionnalité intéressante: pas de compromis sur la taille de l'image. La taille du tableau reste la même avant et après la FFT, si la largeur/hauteur est pair ou impair.)(De côté: FFT-amant geek note. Regarder la documentation
rfft
pour plus de détails, mais j'ai utilisé Scipy est FFTPACK module car sonrfft
entrelace composantes réelle et imaginaire d'un seul pixel comme deux adjacentes valeurs réelles, en garantissant que la sortie de la toute-la taille de l'image 2D (même vs bizarre, largeur vs hauteur) seront préservés. Ceci est en contraste avec Numpy estnumpy.fft.rfft2
qui, parce qu'elle renvoie à des données complexes de taillewidth/2+1
parheight/2+1
, vous oblige à composer avec une ligne/colonne et de traiter avec deinterleaving complexe-à-réel vous-même. Qui a besoin de tracas pour cette application.)Résultats. Donnée d'entrée nommé
test.png
:cet extrait produit la sortie suivante (global min/max ont été redimensionnés et quantifiée de 0 à 255):
Et rétrogrades:
Dans cette fréquence d'image, la DC (de 0 Hz à la fréquence) est en haut à gauche, et les fréquences de se déplacer plus élevé que vous allez à droite et en bas.
Maintenant, nous allons voir ce qui se passe lorsque vous manipulez cette image dans un couple des manières. Au lieu de cette image de test, nous allons utiliser un photo chat.
J'ai fait quelques images de masque dans Gimp que j'ai ensuite charger en Python et multiplier la fréquence-image pour voir quel est l'effet du masque sur l'image.
Voici le code:
Voici un filtre passe-bas masque sur la gauche et sur la droite, le résultat—cliquez pour voir la pleine résolution de l'image:
Dans le masque, noir = 0.0, blanc = 1.0. Si les fréquences les plus basses sont conservés ici (blanc), alors que le haut ceux qui sont bloqués (noir). Cela brouille l'image en atténuant les hautes fréquences. Filtres passe-bas sont utilisés dans tous les sens, y compris lors de la décime (“le sous-échantillonnage”) une image (bien qu'ils soient en forme beaucoup plus attentivement que moi dessin Gimp ).
Voici un filtre passe-bande, où les fréquences les plus basses (voir que peu de blanc dans le coin en haut à gauche?) fréquences et les hautes fréquences sont conservés, mais la médiocre-les fréquences sont bloqués. Assez bizarre!
Voici un filtre passe-haut, où le coin en haut à gauche qui a été laissé en blanc dans le haut du masque est biffée:
C'est la façon de détection des bords œuvres.
Postscript. Quelqu'un, faire une webapp à l'aide de cette technique qui permet de dessiner les masques et les appliquer à une image en temps réel!!!
Votre but est de reproduire le Gimp de Fourier du plugin de comportement? Je peux jeter un oeil au code source et essayer de comprendre ce qu'il fait—les exemples que vous nous avez montré aucun sens. Néanmoins, l'approche de mon code est très général, et les exemples montrent qu'il fonctionne bien, donc si vous avez juste besoin de la fonctionnalité similaire pour le plugin, le code fonctionne bien.
Quel système avez-vous que vous rencontrez des problèmes d'installation scipy?
Ce site web vous permettent de personnaliser les masques et les appliquer à une image. bigwww.l'epfl.ch/demo/ip/demos/03-FFT-le filtrage
il est maintenant plus à la bigwww.l'epfl.ch/demo/ip/demos/FFT-le filtrage - mais très cool, merci pour le partage du lien!
OriginalL'auteur Ahmed Fasih
Il y a plusieurs questions ici.
1) Manuel de conversion en niveaux de gris n'est pas bon. Utilisation
Image.open("test.png").convert('L')
2) il y a très probablement un problème avec types. Vous ne devriez pas passer
np.ndarray
defft2
à une image de PIL sans être sûr que leurs types sont compatibles.abs(np.fft.fft2(something))
vous renverra un tableau de typenp.float32
ou quelque chose comme cela, alors que l'image de PIL va recevoir quelque chose comme un tableau de typenp.uint8
.3) de mise à l'Échelle suggéré dans les commentaires des regards mauvais. Vous avez réellement besoin de vos valeurs afin de les adapter en 0..255 gamme.
Voici mon code qui répond à ces 3 points:
Je dois admettre que je n'ai pas réussi à obtenir des résultats identiques à la GIMP FFT plugin. Autant que je le vois il fait un peu de post-traitement. Mes résultats sont tous un peu très faible contraste désordre, et GIMP semble dépasser ce par le réglage du contraste et de la réduction de la non-information des chaînes (dans votre cas, toutes les chaines sauf les Rouges sont tout simplement vide). Reportez-vous à l'image:
OriginalL'auteur Vovanrock2002