def filter_with_theta(image, theta, sigma=1., filter_size=9):
        """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
        """
        x = np.arange(-filter_size // 2 + 1, filter_size // 2 + 1)
        # 1D Gaussian
        g = np.array([np.exp(-(x**2) / (2 * sigma**2))])
        # first-derivative of 1D Gaussian
        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

        # np.cos(theta) * np.matmul(g.T, gp) + np.sin(theta) * np.matmul(gp.T, g)
        gt_filter = np.matmul(g.T, gp)
        gt_filter = np.cos(theta) * gt_filter + np.sin(theta) * gt_filter.T

        return output, gt_filter
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
        
examples/DynamicFilterNetwork/steering-filter.py