Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
复制MATLAB';s`conv2()`使用傅里叶域卷积_Matlab_Image Processing_Fft_Convolution - Fatal编程技术网

复制MATLAB';s`conv2()`使用傅里叶域卷积

复制MATLAB';s`conv2()`使用傅里叶域卷积,matlab,image-processing,fft,convolution,Matlab,Image Processing,Fft,Convolution,我想拍摄两幅图像,并在Matlab中使用2D FFT将它们卷积在一起,而无需使用conv2函数。然而,我不确定矩阵应该如何正确填充和准备卷积 数学运算如下: A*B=C 在上面的例子中,*是卷积算子() 下面的Matlab程序显示了填充和不填充矩阵之间的区别。我怀疑不填充矩阵会导致循环卷积,但我希望执行线性卷积而不产生锯齿 如果我对两个矩阵进行填充,那么如何截断卷积的输出,使C与A和B的大小相同 A = rgb2gray(im2double(imread('1.png'))); % input

我想拍摄两幅图像,并在Matlab中使用2D FFT将它们卷积在一起,而无需使用
conv2
函数。然而,我不确定矩阵应该如何正确填充和准备卷积

数学运算如下:

A*B=C

在上面的例子中,*是卷积算子()

下面的Matlab程序显示了填充和不填充矩阵之间的区别。我怀疑不填充矩阵会导致循环卷积,但我希望执行线性卷积而不产生锯齿

如果我对两个矩阵进行填充,那么如何截断卷积的输出,使CAB的大小相同

A = rgb2gray(im2double(imread('1.png'))); % input A
B = rgb2gray(im2double(imread('2.png'))); % kernel B

figure;
imagesc(A); colormap gray;
title ('A')

figure;
imagesc(B); colormap gray;
title ('B')

[m,n] = size(A);
mm = 2*m - 1;
nn = 2*n - 1;

C = (ifft2(fft2(A,mm,nn).* fft2(B,mm,nn)));

figure;
imagesc(C); colormap gray;
title ('C with padding')

C0 = (ifft2(fft2(A).* fft2(B)));

figure;
imagesc(C0); colormap gray;
title ('C without padding')
以下是程序的输出:


如您所指出,如果不填充,结果将等价于循环卷积。对于线性卷积,在卷积2幅图像(2D信号)A*B时,完整输出的大小为
Ma+Mb-1 x Na+Nb-1
,其中
Ma x Na,Mb x Nb
图像A和B的大小分别为

填充到预期大小后,通过ifft2进行乘法和变换,可以保留结果图像的中心部分(通常对应于A和B中最大的一个)

现在,使用
conv2D

 % space-domain convolution result
 F = conv2(A,B,'same');
 figure; imshow(F,[]);

结果在视觉上是相同的,两者之间的总误差(由于四舍五入)为
e-10。

我创建了一个MATLAB函数,基本上是
conv2()
频域:

function[mO]=ImageConvFrequencyDomain(mI、mH、convShape)
% ----------------------------------------------------------------------------------------------- %
%[mO]=ImageConvFrequencyDomain(mI、mH、convShape)
%在频域中应用图像卷积。
%输入:
%-mI-输入图像。
%结构:矩阵。
%键入:“单通道”/“双通道”(单通道)。
%范围:(-inf,inf)。
%-mH-过滤内核。
%结构:矩阵。
%键入:'单'/'双'。
%范围:(-inf,inf)。
%-convShape-卷积形状。
%设置卷积形状。
%结构:标量。
%键入:'单'/'双'。
%范围:{1,2,3}。
%输出:
%-mI-输出图像。
%结构:矩阵(单通道)。
%键入:'单'/'双'。
%范围:(-inf,inf)。
%参考资料:
%   1.  MATLAB的“conv2()”-https://www.mathworks.com/help/matlab/ref/conv2.html.
%备注:
%   1.  A.
%待办事项:
%   1.  
%发行说明:
%-1.0.000 2021年4月29日Royi AvitalRoyiAvital@yahoo.com
%*第一版。
% ----------------------------------------------------------------------------------------------- %
CONV_SHAPE_FULL=1;
CONV_SHAPE_SAME=2;
CONV_SHAPE_VALID=3;
numRows=尺寸(mI,1);
numCols=大小(mI,2);
numRowsKernel=大小(mH,1);
numColsKernel=尺寸(mH,2);
开关(convShape)
箱子(箱型箱满)
numRowsFft=numRows+numRowsKernel-1;
numColsFft=numCols+numColsKernel-1;
firstRowIdx=1;
firstColIdx=1;
lastRowIdx=numRowsFft;
lastColdIdx=numColsFft;
外壳(转换形状相同)
numRowsFft=numRows+numRowsKernel;
numColsFft=numCols+numColsKernel;
firstRowIdx=ceil((numRowsKernel+1)/2);
firstColIdx=ceil((numColsKernel+1)/2);
lastRowIdx=firstRowIdx+numRows-1;
lastColdIdx=firstColIdx+numCols-1;
案例(CONV_SHAPE_有效)
numRowsFft=numRows;
numColsFft=numCols;
firstRowIdx=numRowsKernel;
firstColIdx=numColsKernel;
%转换时的内核被移位(即它的(0,0)是top)
%左边(不是中间)。
lastRowIdx=numRowsFft;
lastColdIdx=numColsFft;
结束
mO=ifft2(fft2(mI,NUMROWSFT,numColsFft)。*fft2(mH,NUMROWSFT,numColsFft),“对称”);
mO=mO(firstRowIdx:lastRowIdx,firstColIdx:lastColdIdx);
结束
它完全兼容并经过验证。

完整的代码可以在我的上找到。

这太棒了,gevang。谢谢你这么完整的回答!一个问题:既然卷积运算与相关性有关,我会对两个矩阵的2D相关性做同样的操作吗?
ifft2(fft2(M1,mm,nn).*fft2(fliplr(flipud(M2)),mm,nn)
是相关性的Matlab代码,然后我会以与上面的答案相同的方式保留图像的中心部分吗?此外,如果A和B是复矩阵,卷积(或相关性)会不会操作代码的工作方式完全相同?因为卷积(和傅里叶变换)是线性运算,并且是加法分布的,所以对于
A+Aj
形式的信号,等效性将保持不变,也就是说,在原始大小的图像的实部和虚部的组合之间,将有一个卷积和。您可以用上面的复杂矩阵替换A和B进行检查。如果两者都很复杂,请可视化输出的
abs()
,或者比较F和D部分的
real()
imag()
之间的差异。再次感谢gevang。是的,经过一些实验,我可以确认卷积码在Matlab中对
A+Aj
形式的信号有效。此外,使用Matlab
xcorr2<
 % space-domain convolution result
 F = conv2(A,B,'same');
 figure; imshow(F,[]);