【发布时间】:2018-02-08 10:32:30
【问题描述】:
我正在创建一个截止频率为 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;
,这些应用于像下面的sn-p这样的图像。
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);
输入图像为 256x256 且采用对数刻度,低通滤波器应用于高通滤波输入图像的平方。
然后我想取最终 idft 的结果的平方根, 但它包含负值;因此,出现了几个 NaN 值。
applyFilter(src, dst, highpassFilter);
cv::pow(dst, 2, dst);
applyFilter(dst, dst, lowpassFilter);
cv::sqrt(dst, dst); // NaN !
为什么会有负值,我该如何处理它们才能取平方根?
EDIT:添加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);
}
【问题讨论】:
-
如果输入没有负值,应用高斯滤波器不会引入负值。所以我们要么是在谈论你的代码中的一个错误(检查中间值!),要么是由于数值不准确而低于 0 的值(你是否在寻找那些负值?它们有多大?)。在后一种情况下,只需在 0 处剪辑(将负值设置为 0)。
-
还要检查您的过滤是否正确。您发送到
idft的图像complex实际上是对称的吗?shift函数是否就地工作? -
负值不小,所以我认为数值不准确不是原因。此外,正方形不能包含负值,移动象限的方式与官方示例相同,并且我检查了过滤器不包含负值,并且每个过滤通过归一化和 cv::imshow 看起来都是正确的。 .
-
当我运行没有过滤的简单相互转换时,只有非常小的负值,如
-1e-5,这可能是由于您所说的数值不准确。所以过滤可能不正确;但是,过滤器的值范围从 0 到 1,我所要做的只是逐元素乘法,所以到目前为止我不知道.. -
啊,没有
DFT_REAL_OUTPUT的最终complex的大小看起来是一个理想的输出。然而,我很困惑。cv::idft和DFT_REAL_OUTPUT的结果不是经过适当变换的实矩阵吗?
标签: c++ image opencv image-processing imagefilter