import matplotlib.pyplot as plt import numpy as np from scipy import ndimage as ndi from skimage.io import imread from skimage.util import img_as_float from skimage.filters import gabor_kernel def compute_feats(image, kernels): feats = np.zeros((len(kernels), 2), dtype=np.double) for k, kernel in enumerate(kernels): filtered = ndi.convolve(image, kernel, mode='wrap') feats[k, 0] = filtered.mean() feats[k, 1] = filtered.var() return feats def match(feats, ref_feats): min_error = np.inf min_i = None for i in range(ref_feats.shape[0]): error = np.sum((feats - ref_feats[i, :])**2) if error < min_error: min_error = error min_i = i return min_i sigma = 10 # 1 - 10 frequency = 0.35 # 0.05 - 0.35 kernels = [] for theta in range(4): theta = theta / 4. * np.pi kernel = np.real(gabor_kernel(frequency, theta=theta, n_stds=sigma)) kernels.append(kernel) shrink = (slice(0, None, 3), slice(0, None, 3)) disc = img_as_float(imread("discord-logo.png", as_gray=True))[shrink] feng = img_as_float(imread("Feng_wind.jpg", as_gray=True))[shrink] vazka = img_as_float(imread("vazka.png", as_gray=True))[shrink] image_names = ('Discord', 'Znak', 'Vážka') images = (disc, feng, vazka) # prepare reference features ref_feats = np.zeros((3, len(kernels), 2), dtype=np.double) ref_feats[0, :, :] = compute_feats(disc, kernels) ref_feats[1, :, :] = compute_feats(feng, kernels) ref_feats[2, :, :] = compute_feats(vazka, kernels) def power(image, kernel): # Normalize images for better comparison. image = (image - image.mean()) / image.std() return np.sqrt(ndi.convolve(image, np.real(kernel), mode='wrap')**2 + ndi.convolve(image, np.imag(kernel), mode='wrap')**2) # Plot a selection of the filter bank kernels and their responses. results = [] kernel_params = [] for theta in range(0, 10): theta = theta / np.pi kernel = gabor_kernel(frequency, theta=theta) params = f"Θ={18*(theta*np.pi):.0f}°" kernel_params.append(params) # Save kernel and the power image for each image results.append((kernel, [power(img, kernel) for img in images])) fig, axes = plt.subplots(nrows=len(results)+1, ncols=len(image_names)+1, figsize=(4, 9)) plt.gray() fig.suptitle(f'Gaborovy filtry\n pro λ={frequency}, ϕ={0}, σ={sigma} a γ={1}.', fontsize=12) axes[0][0].axis('off') # Plot original images for label, img, ax in zip(image_names, images, axes[0][1:]): ax.imshow(img) ax.set_title(label, fontsize=9) ax.axis('off') for label, (kernel, powers), ax_row in zip(kernel_params, results, axes[1:]): # Plot Gabor kernel ax = ax_row[0] ax.imshow(np.real(kernel)) ax.set_ylabel(label, fontsize=7) ax.set_xticks([]) ax.set_yticks([]) # Plot Gabor responses with the contrast normalized for each filter vmin = np.min(powers) vmax = np.max(powers) for patch, ax in zip(powers, ax_row[1:]): ax.imshow(patch, vmin=vmin, vmax=vmax) ax.axis('off') plt.show()