web-dev-qa-db-fra.com

Filtre passe-haut pour le traitement d'images en python à l'aide de scipy/numpy

J'étudie actuellement le traitement d'image. Dans Scipy, je sais qu’il existe un filtre médian dans Scipy.signal. Quelqu'un peut-il me dire s'il existe un filtre similaire au filtre passe-haut?

Je vous remercie

17
Hold_My_Anger

"Filtre passe-haut" est un terme très générique. Il existe un nombre infini de "filtres passe-haut" différents qui font des choses très différentes (par exemple, un filtre de détection de bord, comme mentionné précédemment, est techniquement un filtre passe-haut (la plupart sont en fait une bande passante), mais a un effet très différent de ce que vous avait en tête.)

Quoi qu’il en soit, en vous basant sur la plupart des questions que vous avez posées, vous devriez probablement regarder dans scipy.ndimage au lieu de scipy.filter, surtout si vous envisagez de travailler avec de grandes images (ndimage peut effectuer des opérations en amont). -place, conservant la mémoire). 

Comme exemple de base, montrant différentes façons de faire les choses:

import matplotlib.pyplot as plt
import numpy as np
from scipy import ndimage
import Image

def plot(data, title):
    plot.i += 1
    plt.subplot(2,2,plot.i)
    plt.imshow(data)
    plt.gray()
    plt.title(title)
plot.i = 0

# Load the data...
im = Image.open('lena.png')
data = np.array(im, dtype=float)
plot(data, 'Original')

# A very simple and very narrow highpass filter
kernel = np.array([[-1, -1, -1],
                   [-1,  8, -1],
                   [-1, -1, -1]])
highpass_3x3 = ndimage.convolve(data, kernel)
plot(highpass_3x3, 'Simple 3x3 Highpass')

# A slightly "wider", but sill very simple highpass filter 
kernel = np.array([[-1, -1, -1, -1, -1],
                   [-1,  1,  2,  1, -1],
                   [-1,  2,  4,  2, -1],
                   [-1,  1,  2,  1, -1],
                   [-1, -1, -1, -1, -1]])
highpass_5x5 = ndimage.convolve(data, kernel)
plot(highpass_5x5, 'Simple 5x5 Highpass')

# Another way of making a highpass filter is to simply subtract a lowpass
# filtered image from the original. Here, we'll use a simple gaussian filter
# to "blur" (i.e. a lowpass filter) the original.
lowpass = ndimage.gaussian_filter(data, 3)
gauss_highpass = data - lowpass
plot(gauss_highpass, r'Gaussian Highpass, $\sigma = 3 pixels$')

plt.show()

enter image description here

43
Joe Kington

Un filtre passe-haut simple est:

-1 -1 -1
-1  8 -1
-1 -1 -1

L'opérateur Sobel est un autre exemple simple.

Dans le traitement d'images, ces types de filtres sont souvent appelés "Détecteurs de bords" - la page Wikipedia était OK pour la dernière fois que j'ai vérifié.

4
Martin Thompson

scipy.filter contient un grand nombre de filtres génériques. Quelque chose comme la classe iirfilter peut être configuré pour produire les filtres passe-haut numériques ou analogiques typiques de Chebyshev ou de Buttworth.

1
talonmies

Voici comment nous pouvons concevoir un HPF avec scipy fftpack

from skimage.io import imread
import matplotlib.pyplot as plt
import scipy.fftpack as fp

im = np.mean(imread('../images/lena.jpg'), axis=2) # assuming an RGB image
plt.figure(figsize=(10,10))
plt.imshow(im, cmap=plt.cm.gray)
plt.axis('off')
plt.show()

Image d'origine

 enter image description here

F1 = fftpack.fft2((im).astype(float))
F2 = fftpack.fftshift(F1)
plt.figure(figsize=(10,10))
plt.imshow( (20*np.log10( 0.1 + F2)).astype(int), cmap=plt.cm.gray)
plt.show()

Spectre de fréquence avec FFT

 enter image description here

(w, h) = im.shape
half_w, half_h = int(w/2), int(h/2)

# high pass filter
n = 25
F2[half_w-n:half_w+n+1,half_h-n:half_h+n+1] = 0 # select all but the first 50x50 (low) frequencies
plt.figure(figsize=(10,10))
plt.imshow( (20*np.log10( 0.1 + F2)).astype(int))
plt.show()

Bloque les basses fréquences du spectre

 enter image description here

im1 = fp.ifft2(fftpack.ifftshift(F2)).real
plt.figure(figsize=(10,10))
plt.imshow(im1, cmap='gray')
plt.axis('off')
plt.show()

Image de sortie après application du HPF

 enter image description here

1
Sandipan Dey

Vous pouvez utiliser un filtre gaussien car il donne beaucoup plus de netteté qu'un filtre HPF pur. Pour utiliser un filtre HPF simple, vous pouvez utiliser le code suivant

import numpy as np
import cv2
from scipy import ndimage

class HPF(object):
    def __init__(self, kernel, image):
        self.kernel = np.array(kernel)
        self.image = image

    def process(self):
        return ndimage.convolve(self.image, self.kernel)


if __== "__main__":
    #enter ur image location
    image = cv2.imread("images/test2.jpg", 0)
    kernel3x3 = [[-1,-1,-1],[-1,8,-1],[-1,-1,-1]]
    kernel5x5 = [[-1, -1, -1, -1, -1],
    [-1, 1, 2, 1, -1],
    [-1, 2, 4, 2, -1],
    [-1, 1, 2, 1, -1],
    [-1, -1, -1, -1, -1]]

    hpf1 = HPF(kernel3x3, image)
    hpfimage1 = hpf1.process()
    hpf2 = HPF(kernel5x5, image)
    hpfimage2 = hpf2.process()
    cv2.imshow("3x3",hpfimage1)
    cv2.imshow("5x5",hpfimage2)
    cv2.waitKey()
    cv2.destroyAllWindows()

Pour utiliser le filtre gaussien, ajoutez simplement le flou gaussien à votre image.

blurred = cv2.GaussianBlur(image, (11, 11), 0)

Puis moins de l'image originale

g_hpf = image - blurred

Code original tiré de: Netteté de l'image par filtre passe-haut à l'aide de Python et OpenCV

0
Mohd Shibli