Luca
Luca

Reputation: 10996

Gabor filters: large variance compared to the mean

I am trying to extract Gabor features from an input image. So, I have setup a series of Gabor filters with different parameters (frequency, angle and standard deviation) and I am convolving each of these filters with the input image and looking at the mean and variance of the output magnitude image. So, in python it would look something like:

import numpy as np
from scipy import ndimage as nd

# Here kernel is a given Gabor filter
def filter_image(self, image):
    filtered = np.zeros((len(self.kernels)*2,) + image.shape)        
    for k, kernel in enumerate(self.kernels):            
        filtered[k*2, :] = nd.convolve(image, np.real(kernel), mode='wrap')
        filtered[k*2+1, :] = nd.convolve(image, np.imag(kernel), mode='wrap')

return filtered

And now, I am looking at the mean and variance of the power image as:

def compute_features(self, image):
    features = np.zeros((len(self.kernels), 2))
    filtered = filter_image(image)
    for k in range(0, len(self.kernels)):
        power_image = np.sqrt(filtered[k*2]**2 + filtered[k*2+1]**2)
        features[k, 0] = filtered[k, :].mean()
        features[k, 1] = filtered[k, :].var()

return features

So, when I look at the mean and variance of the each of the filter responses, I notice that the variance is really high with respect to the mean. For example, I get values like (mean = 0.83, variance = 900). I wonder if this is something one sees often. Does this tell me that I do not really have any texture in the image? I am not sure how to interpret this.

I do apologize if this does not exactly belong on this forum. I did post this on crossvalidated as well.

Upvotes: 0

Views: 693

Answers (1)

amyrit
amyrit

Reputation: 485

You should have an idea about the texture of your image just by looking at them.

I suggest you have a look at the example given in scikit-image documentation. You'll be able to see typical results on texture images and to check your code.

I think there is a mistake in your code snippet: in your function filter_image, you are iterating over all the kernels, where you should be doing just one kernel convolution.

Besides this, you should check which type of image you use as input. In the skimage example, the image is first converted to float. The features are then all in [0, 1]. From your results, I suspect you're working with integers, which can yield very different values of mean and variance, though it give the same output after normalization. If I change the code in the skimage example and use the raw integer images, I get results more like yours than with floats. I computed the min/max/mean ratios of mean over variance:

print((ref_feats[:, :, 0] / ref_feats[:, :, 1]).min())
print((ref_feats[:, :, 0] / ref_feats[:, :, 1]).mean())
print((ref_feats[:, :, 0] / ref_feats[:, :, 1]).max())

(where ref_feats is a table of (mean, var) over the images and kernels) and got this:

0.00403515106897
1.67550281887
9.91940408151

Upvotes: 1

Related Questions