如何使用 OpenCV 将偏导数高斯核应用于图像?
How to apply a partial derivative Gaussian kernel to an image with OpenCV?
我正在尝试重现一篇论文的结果,其中他们将图像与高斯核的水平偏导数进行卷积。我还没有找到用 OpenCV 实现这一目标的任何方法。那可能吗 ?
我是否必须获得高斯滤波器然后手动计算偏导数?
OpenCV 没有 built-in 函数来计算高斯偏导数。但是您可以使用 cv::getGaussianKernel
and cv::filter2D
来这样做。
例如:
cv::Mat kernel = cv::getGaussianKernel(3, 0.85, CV_32F);
kernel = kernel.reshape(1, 1);
cv::filter2D(img, img, CV_8U, kernel);
请注意 cv::getGaussianKernel
returns 列过滤器,因此您需要 reshape
使其水平。
正如@akarsakov 所说,OpenCV 没有为此提供内置函数。但是,我们仍然可以使用OpenCV的getGaussianKernel()
,然后应用一个因子来得到导数。
由于高斯 2D 内核是可分离的,该函数将简单地 return 您一个 1D 内核,并假设您将沿 x 轴应用 1D 滤波器,然后沿 y 轴应用 1D 滤波器,这比直接应用 2D 核要快。
因为你想要水平高斯导数,ref:
您可以简单地乘以 -x/sigma^2
内核的每个点。
import cv2
import numpy as np
import matplotlib.pyplot as plt
kernel_size = 13
sigma = 0.5
kernel = cv2.getGaussianKernel(kernel_size, sigma, cv2.CV_64F)
print(kernel)
gaussian_first_deriv_x = np.zeros_like(kernel)
assert(kernel_size % 2 == 1) # I assume you are using an odd kernel_size
half_kernel_size = int(kernel_size / 2)
for i in range(kernel_size):
x = - half_kernel_size + i
factor = - x/ (sigma**2)
gaussian_first_deriv_x[i] = kernel[i] * factor
print(gaussian_first_deriv_x)
plt.plot(kernel[:], 'b')
plt.plot(gaussian_first_deriv_x[:], 'r')
plt.show()
现在,您可以使用此内核进行卷积。
注意:如果您正在使用 Python,您也可以使用 from scipy import ndimage
中的函数 ndimage.gaussian_filter1d(data, sigma=1, order=1, mode='wrap')
。
OpenCV 默认使用以下内容:sigma = 0.3 * (kernel_size / 2.0 - 1) + 0.8
.
我正在尝试重现一篇论文的结果,其中他们将图像与高斯核的水平偏导数进行卷积。我还没有找到用 OpenCV 实现这一目标的任何方法。那可能吗 ?
我是否必须获得高斯滤波器然后手动计算偏导数?
OpenCV 没有 built-in 函数来计算高斯偏导数。但是您可以使用 cv::getGaussianKernel
and cv::filter2D
来这样做。
例如:
cv::Mat kernel = cv::getGaussianKernel(3, 0.85, CV_32F);
kernel = kernel.reshape(1, 1);
cv::filter2D(img, img, CV_8U, kernel);
请注意 cv::getGaussianKernel
returns 列过滤器,因此您需要 reshape
使其水平。
正如@akarsakov 所说,OpenCV 没有为此提供内置函数。但是,我们仍然可以使用OpenCV的getGaussianKernel()
,然后应用一个因子来得到导数。
由于高斯 2D 内核是可分离的,该函数将简单地 return 您一个 1D 内核,并假设您将沿 x 轴应用 1D 滤波器,然后沿 y 轴应用 1D 滤波器,这比直接应用 2D 核要快。
因为你想要水平高斯导数,ref:
您可以简单地乘以 -x/sigma^2
内核的每个点。
import cv2
import numpy as np
import matplotlib.pyplot as plt
kernel_size = 13
sigma = 0.5
kernel = cv2.getGaussianKernel(kernel_size, sigma, cv2.CV_64F)
print(kernel)
gaussian_first_deriv_x = np.zeros_like(kernel)
assert(kernel_size % 2 == 1) # I assume you are using an odd kernel_size
half_kernel_size = int(kernel_size / 2)
for i in range(kernel_size):
x = - half_kernel_size + i
factor = - x/ (sigma**2)
gaussian_first_deriv_x[i] = kernel[i] * factor
print(gaussian_first_deriv_x)
plt.plot(kernel[:], 'b')
plt.plot(gaussian_first_deriv_x[:], 'r')
plt.show()
现在,您可以使用此内核进行卷积。
注意:如果您正在使用 Python,您也可以使用 from scipy import ndimage
中的函数 ndimage.gaussian_filter1d(data, sigma=1, order=1, mode='wrap')
。
OpenCV 默认使用以下内容:sigma = 0.3 * (kernel_size / 2.0 - 1) + 0.8
.