'Implements a steerable Gaussian filter.
This function can be used to evaluate the first
directional derivative of an image, using the
method outlined in
W. T. Freeman and E. H. Adelson, "The Design
and Use of Steerable Filters", IEEE PAMI, 1991.
It evaluates the directional derivative of the input
image I, oriented at THETA degrees with respect to the
image rows. The standard deviation of the Gaussian kernel
is given by SIGMA (assumed to be equal to unity by default).
Args:
image: any input image (only one channel)
theta: orientation of filter [0, 2 * pi]
sigma (float, optional): standard derivation of Gaussian
filter_size (int, optional): filter support
Returns:
filtered image and the filter'

@staticmethod
def filter_with_theta(image, theta, sigma=1.0, filter_size=9):

    x = np.arange((((- filter_size) // 2) + 1), ((filter_size // 2) + 1))
    g = np.array([np.exp(((- (x ** 2)) / (2 * (sigma ** 2))))])
    gp = np.array([((- (x / sigma)) * np.exp(((- (x ** 2)) / (2 * (sigma ** 2)))))])
    ix = convolve2d(image, (- gp), mode='same', boundary='fill', fillvalue=0)
    ix = convolve2d(ix, g.T, mode='same', boundary='fill', fillvalue=0)
    iy = convolve2d(image, g, mode='same', boundary='fill', fillvalue=0)
    iy = convolve2d(iy, (- gp.T), mode='same', boundary='fill', fillvalue=0)
    output = ((np.cos(theta) * ix) + (np.sin(theta) * iy))
    gt_filter = np.matmul(g.T, gp)
    gt_filter = ((np.cos(theta) * gt_filter) + (np.sin(theta) * gt_filter.T))
    return (output, gt_filter)
