我使用以下代码创建了一个Gabor过滤器:
Mat gabor(double sigma, double theta) {
int nstds = 3;
int kernel_size = nstds * sigma * 2 - 1;
if(!kernel_size % 2) {
kernel_size++;
}
int hks = (kernel_size - 1) / 2;
theta = theta * CV_PI / 180;
sigma = sigma;
double x_theta;
double y_theta;
double gamma = 1;
double del_phi = 0.8;
double v = sqrt(2 * log(2)) * ((pow(2, del_phi) + 1) / (pow(2, del_phi) - 1));
double psi = -exp(-0.5 * pow(v, 2));
double fs = (1 / (CV_PI * sigma)) * sqrt(0.5 * log(2)) * ((pow(2, del_phi) + 1) / (pow(2, del_phi) - 1));
double lambda = 1 / fs;
double p = gamma / (2 * CV_PI * pow(sigma, 2));
Mat kernel(kernel_size, kernel_size, CV_32F);
for(int y = -hks; y <= hks; y++) {
for(int x = -hks; x <= hks; x++) {
x_theta = x * cos(theta) + y * sin(theta);
y_theta = -x * sin(theta) + y * cos(theta);
kernel.at<float>(hks+y, hks+x) =
(float)
exp(-0.5 * (pow(x_theta, 2.0) + pow(y_theta, 2.0)) / pow(sigma, 2.0)) *
cos(2.0 * CV_PI * x_theta / lambda + psi);
}
}
return kernel;
}
上面的代码创建了一个Gabor内核,它与我在Matlab中创建的内核相同。我将Gabor过滤器与Matlab中的conv2
函数和OpenCV中的filter2D
一起应用。我理解filter2D
不是严格的卷积,但是当我翻转内核并更改锚点等时,没有任何帮助。 Matlab输出看起来不错,但OpenCV输出看起来很糟糕。为什么呢?
Matlab(好):
OpenCV(差):
我正在使用filter2D(preproc, filtered, CV_64FC1, kernel);
来生成OpenCV输出。为什么OpenCV看起来像斑马条纹,Matlab看起来像我想要的?同样,内核Mat值完全相同(我将OpenCV内核移植到Matlab中并进行比较,它们的相似度为99.99%)。
Matlab代码:
img = imread('preproc.jpg');
gamma = 1;
delta_phi = 0.8;
v = sqrt(2 .* log(2)) .* ((2 .^ delta_phi + 1) ./ (2 .^ delta_phi - 1));
psi = -exp(-0.5 .* v .^ 2);
sigma = 6;
fs = (1 ./ sigma) .* (1 ./ pi) .* sqrt(log(2) ./ 2) .* ((2 .^ delta_phi + 1) ./ (2 .^ delta_phi - 1));
lambda = 1 ./ fs;
thetas = linspace(0,pi,8);
theta = thetas(2);
Gsk = gabor_filter(sigma,theta,lambda,psi,gamma);
Fsk = conv2(double(img), Gsk, 'same');
Gsk
是gabor内核,它再次与我的OpenCV代码中创建的内核相同。