我想在确定正确的填充尺寸后创建一个高斯高通滤波器(例如,如果图像宽度和高度是10X10,那么应该是20X20)。
我有Matlab代码,我试图在OpenCV中移植,但我很难正确移植它。我的Matlab代码如下所示:
f1_seg = imread('thumb1-small-test.jpg');
Iori = f1_seg;
% Iori = imresize(Iori, 0.2);
%Convert to grayscale
I = Iori;
if length(size(I)) == 3
I = rgb2gray(Iori);
end
%
%Determine good padding for Fourier transform
PQ = paddedsize(size(I));
I = double(I);
%Create a Gaussian Highpass filter 5% the width of the Fourier transform
D0 = 0.05*PQ(1);
H = hpfilter('gaussian', PQ(1), PQ(2), D0);
% Calculate the discrete Fourier transform of the image.
F=fft2(double(I),size(H,1),size(H,2));
% Apply the highpass filter to the Fourier spectrum of the image
HPFS_I = H.*F;
我知道如何在OpenCV中使用DFT,我能够生成其图像,但我不知道如何创建高斯滤波器。请指导我如何创建高通高斯滤波器,如上所示?
答案 0 :(得分:8)
我相信您遇到的问题是OpenCV提供的高斯滤波器是在空间(时间)域中创建的,但您希望滤波器位于频域中。 Here是关于频域中高通和低通滤波之间差异的好文章。
一旦您对频域滤波的工作原理有了充分的了解,就可以尝试在频域中创建高斯滤波器。 Here是关于在频域中创建一些不同(包括高斯)滤波器的好讲座。
如果您仍然遇到困难,稍后我会尝试用示例更新我的帖子!
编辑: 这是我写的关于实现高斯高通滤波器的简短示例(基于我指出的讲座):
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
double pixelDistance(double u, double v)
{
return cv::sqrt(u*u + v*v);
}
double gaussianCoeff(double u, double v, double d0)
{
double d = pixelDistance(u, v);
return 1.0 - cv::exp((-d*d) / (2*d0*d0));
}
cv::Mat createGaussianHighPassFilter(cv::Size size, double cutoffInPixels)
{
Mat ghpf(size, CV_64F);
cv::Point center(size.width / 2, size.height / 2);
for(int u = 0; u < ghpf.rows; u++)
{
for(int v = 0; v < ghpf.cols; v++)
{
ghpf.at<double>(u, v) = gaussianCoeff(u - center.y, v - center.x, cutoffInPixels);
}
}
return ghpf;
}
int main(int /*argc*/, char** /*argv*/)
{
Mat ghpf = createGaussianHighPassFilter(Size(128, 128), 16.0);
imshow("ghpf", ghpf);
waitKey();
return 0;
}
这绝对不是一个优化的过滤器生成器,但我试图保持简单直接以便于理解:)无论如何,此代码显示以下过滤器:
注意:此滤波器不是FFT移位的(即,当DC放置在中心而不是左上角时,此滤波器有效)。有关如何在OpenCV中执行FFT移位的信息,请参见OpenCV dft.cpp示例(特别是第62-74行)。
享受!