- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
问题是频域的卷积原理我还不能完全理解。
我有一个 大小为 256x256 的图像
,我想将其与 3x3 高斯矩阵
进行卷积。它的系数是 (1/16, 1/8, 1/4
):
PlainImage<float> FourierRunner::getGaussMask(int sz)
{
PlainImage<float> G(3,3);
*G.at(0, 0) = 1.0/16; *G.at(0, 1) = 1.0/8; *G.at(0, 2) = 1.0/16;
*G.at(1, 0) = 1.0/8; *G.at(1, 1) = 1.0/4; *G.at(1, 2) = 1.0/8;
*G.at(2, 0) = 1.0/16; *G.at(2, 1) = 1.0/8; *G.at(2, 2) = 1.0/16;
return G;
}
为了获得图像和滤波器内核的 FFT,我对它们进行了零填充。 sz_common
代表扩展大小。图像和内核分别移动到 h
和 g
ComplexImage
的中心,因此它们在右、左、底部和顶。
sz_common >= sz+gsz-1
因为循环卷积属性:过滤器可以改变边界上不需要的图像值。 sz_common = sz
、sz_common = sz+gsz-1
或 sz_common = 2*sz
时才会有足够的结果>,在 IFFT 之后,我得到的卷积图像缩小了 2-3 倍! 为什么?
fft_in
是中心在
[sz/2;sz/2]
void FourierRunner::convolveImage(ComplexImage& fft_in)
{
int sz = 256; // equal to fft_in.width()
// Get original complex image (backward fft_in)
ComplexImage original_complex = fft_in;
fft2d_backward(fft_in, original_complex);
int gsz = 3;
PlainImage<float> filter = getGaussMask(gsz);
ComplexImage filter_complex = ComplexImage::fromFloat(filter);
int sz_common = pow2ceil(sz); // should be sz+gsz-1 ???
ComplexImage h = ComplexImage::zeros(sz_common,sz_common);
ComplexImage g = ComplexImage::zeros(sz_common,sz_common);
copyImageToCenter(h, original_complex);
copyImageToCenter(g, filter_complex);
LOOP_2D(sz_common, sz_common) g.setPoint(x, y, g.at(x, y)*256);
fft2d_forward(g, g);
fft2d_forward(h, h);
fft2d_fft_shift(g);
// CONVOLVE
LOOP_2D(sz_common,sz_common) h.setPoint(x, y, h.at(x, y)*g.at(x, y));
copyImageToCenter(fft_in, h);
fft2d_backward(fft_in, fft_in);
fft2d_fft_shift(fft_in);
// TEST DIFFERENCE BTW DOMAINS
PlainImage<float> frequency_res(sz,sz);
writeComplexToPlainImage(fft_in, frequency_res);
fft2d_forward(fft_in, fft_in);
}
我尝试在右侧和底部对图像进行零填充,以便将较小的图像复制到较大的图像的开头,但它也不起作用。
我在空间域中写了卷积来比较结果,频率模糊结果几乎与在空间域中相同(平均错误 btw 像素为 5),仅当 sz_common = sz
.
最佳答案
空间域中的卷积等同于傅里叶域中的乘法。
这是定义在各处的连续函数的真理。
然而在实践中,我们有离散信号和卷积核。
更需要温柔的呵护。
如果你有一个大小为 M x N 的图像和一个大小为 MM x NN 的内核,如果你对它们应用 DFT(FFT 是计算 DFT 的有效方法),你将获得大小为分别为 M x N 和 MM x NN。
此外,上面关于乘法等价的定理要求相同的频率相互相乘。
由于实际上内核比图像小得多,通常它会被零填充到图像的大小。
现在,通过应用 DFT,您将获得大小相同的 M x N 矩阵,并且能够将它们相乘。
然而,这相当于图像和内核之间的循环卷积。
要应用线性卷积,您应该使它们的大小均为 (M + MM - 1) x (N + NN - 1)。
通常,这是通过在图像上应用“复制”边界条件并对内核进行零填充。
享受...
附言您能否支持 SE 的新社区提案 - http://area51.stackexchange.com/proposals/86832/ .
我们需要更多人关注,赞成票少于 10 票的问题和更多问题要问。
谢谢。
关于c++ - 傅立叶域 : works, 中的图像高斯卷积,但不应该,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32678652/
我正在尝试构建不同(但每个同质)类型的可遍历项的多个交叉产品。所需的返回类型是元组的可遍历对象,其类型与输入可遍历对象中的类型相匹配。例如: List(1, 2, 3) cross Seq("a",
import java.util.Scanner; public class BooleanProduct { public static void main(String[] args) {
任务 - 数字的最大 K 积 时间限制:1 内存限制:64 M 给定一个整数序列 N(1 ≤ N ≤ 10 月,| A i | ≤ 2.10 9)和数量 K(1 ≤ K ≤ N)。找出乘积最大的 K
考虑一个大小为 48x16 的 float 矩阵 A 和一个大小为 1x48 的 float vector b。 请建议一种在常见桌面处理器 (i5/i7) 上尽可能快地计算 b×A 的方法。 背景。
假设我有一个 class Rectangle(object): def __init__(self, len
设 A 为 3x3 阶矩阵。判断矩阵A的 boolean 积可以组成多少个不同的矩阵。 这是我想出的: #include int main() { int matri
背景 生成随机权重列表后: sizes = [784,30,10] weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1],sizes[
我正在开发一个 python 项目并使用 numpy。我经常需要通过单位矩阵计算矩阵的克罗内克积。这些是我代码中的一个相当大的瓶颈,所以我想优化它们。我必须服用两种产品。第一个是: np.kron(n
有人可以提供一个例子说明如何使用 uBLAS 产品来乘法吗?或者,如果有更好的 C++ 矩阵库,您可以推荐我也欢迎。这正在变成一个令人头疼的问题。 这是我的代码: vector myVec(scala
我正在尝试开发一个Javascript程序,它会提示用户输入两个整数,然后显示这两个整数的和、乘积、差和商。现在它只显示总和。我实际上不知道乘法、减法和除法命令是否正在执行。这是 jsfiddle 的
如何使用 la4j 计算 vector (叉)积? vector 乘积为 接受两个 vector 并返回 vector 。 但是他们有scalar product , product of all e
在 C++ 中使用 Lapack 让我有点头疼。我发现为 fortran 定义的函数有点古怪,所以我尝试在 C++ 上创建一些函数,以便我更容易阅读正在发生的事情。 无论如何,我没有让矩阵 vecto
是否可以使用 Apple 的 Metal Performance Shaders 执行 Hadamard 产品?我看到可以使用 this 执行普通矩阵乘法,但我特别在寻找逐元素乘法,或者一种构造乘法的
我正在尝试使用 open mp 加速稀疏矩阵 vector 乘积,代码如下: void zAx(double * z, double * data, long * colind, long * row
有没有一种方法可以使用 cv::Mat OpenCV 中的数据结构? 我检查过 the documentation并且没有内置功能。但是我在尝试将标准矩阵乘法表达式 (*) 与 cv::Mat 类型的
我是一名优秀的程序员,十分优秀!