我正在创建一个具有0.015截止频率的低通滤波器和相应的高通滤波器,如下所示:
auto getGaussianFilter(int32_t size) {
const auto sigmaf = 0.015f*size; // cutoff freq.
cv::Mat kernel = cv::Mat::zeros(size, size, CV_32FC1);
for (auto fy = -size/2; fy < size/2; ++fy)
for (auto fx = -size/2; fx < size/2; ++fx)
kernel.at<float>(fy + size/2, fx + size/2) = std::exp(-(fy*fy+fx*fx)/(2*sigmaf*sigmaf));
return kernel;
}
...
lowpassFilter = getGaussianFilter(256);
highpassFilter = 1 - lowpassFilter; ,这些应用于像下面的片段这样的图像。
std::vector<cv::Mat> planes { src, cv::Mat::zeros(src.size(), src.type()) };
std::vector<cv::Mat> fplanes { filter, filter };
cv::Mat complex, complexFilter;
cv::merge(planes, complex);
cv::merge(fplanes, complexFilter);
cv::dft(complex, complex, cv::DFT_COMPLEX_OUTPUT);
shift(complex); // swapping quadrants
cv::mulSpectrums(complex, complexFilter, complex, cv::DFT_ROWS);
shift(complex);
cv::idft(complex, complex, cv::DFT_SCALE | cv::DFT_REAL_OUTPUT); 输入图像为256×256,为对数尺度,并将低通滤波器应用于高通滤波输入图像的平方。
然后,我想要得到最终空闲结果的平方根,但是它包含负值;因此,出现了几个NaN值。
applyFilter(src, dst, highpassFilter);
cv::pow(dst, 2, dst);
applyFilter(dst, dst, lowpassFilter);
cv::sqrt(dst, dst); // NaN !为什么有负值,我如何处理它们才能取平方根呢?
编辑:添加shift代码
void shift(cv::Mat& src) {
src = src(cv::Rect(0, 0, src.cols & -2, src.rows & -2));
const auto cy = src.rows/2, cx = src.cols/2;
cv::Mat q0(src, cv::Rect(0, 0, cx, cy));
cv::Mat q1(src, cv::Rect(cx, 0, cx, cy));
cv::Mat q2(src, cv::Rect(0, cy, cx, cy));
cv::Mat q3(src, cv::Rect(cx, cy, cx, cy));
cv::Mat tmp;
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
} 发布于 2018-02-14 06:32:46
直到第三次或第四次读完你的代码我才明白.
std::vector<cv::Mat> fplanes { filter, filter };
cv::merge(fplanes, complexFilter);这里创建了一个复值滤波器,它不是共轭对称的。应用这个滤波器产生一个频谱,它不是共轭对称的,因此你得到了一个非实反变换。
你想要做的是拥有一个纯粹的真正的过滤器:
std::vector<cv::Mat> fplanes { filter, cv::Mat::zeros(filter(), filter()) };
cv::merge(fplanes, complexFilter);想想频域滤波器的大小和相位(而不是一个真实的和想象的成分)。幅值改变图像中每个频率分量的幅度,相移每个频率分量。通常(在非常特殊的情况下除外),你不想改变你的图像中的频率成分,因为它会搞乱你的图像。因此,将频域滤波器的相位保持在0.零相位意味着每个值都是非负的和真实的.
尽管如此,您的序列移动图像的频谱,应用滤波器,并移回:
cv::dft(complex, complex, cv::DFT_COMPLEX_OUTPUT);
shift(complex); // swapping quadrants
cv::mulSpectrums(complex, complexFilter, complex, cv::DFT_ROWS);
shift(complex);
cv::idft(complex, complex, cv::DFT_SCALE | cv::DFT_REAL_OUTPUT); 与简单地移动筛选器相同:
cv::dft(complex, complex, cv::DFT_COMPLEX_OUTPUT);
shift(complexFilter); // swapping quadrants
cv::mulSpectrums(complex, complexFilter, complex, 0);
cv::idft(complex, complex, cv::DFT_SCALE | cv::DFT_REAL_OUTPUT); 还请注意,我将cv::DFT_ROWS替换为0。根据文献资料,该标志表示每个图像行是一个独立的一维转换。我的猜测是,这只对CCS填充的矩阵有影响,但最好还是忽略它。
https://stackoverflow.com/questions/48683322
复制相似问题