Matlab 矢量化多重高斯计算
我正在尝试将我的一些代码矢量化,这些代码在图像上添加了许多高斯分布的强度。我目前为每个高斯循环函数“gaussIt2D”,该函数为单个2D高斯向量化:Matlab 矢量化多重高斯计算,matlab,vectorization,gaussian,Matlab,Vectorization,Gaussian,我正在尝试将我的一些代码矢量化,这些代码在图像上添加了许多高斯分布的强度。我目前为每个高斯循环函数“gaussIt2D”,该函数为单个2D高斯向量化: windowSize=10; imSize=[512,512]; %pointsR is an nx2 array of coordinates [x1,y1;x2,y2;...;xn,yn] pointsR=rand(100,2)*511+1; %sigmaR is the standard deviation of the gaussian
windowSize=10;
imSize=[512,512];
%pointsR is an nx2 array of coordinates [x1,y1;x2,y2;...;xn,yn]
pointsR=rand(100,2)*511+1;
%sigmaR is the standard deviation of the gaussian being created
sigmaR = 1;
outputImage=zeros(imSize);
for n=1:size(pointsR,1)
rangeX = floor(pointsR(n,1)-windowSize):ceil(pointsR(n,1)+ windowSize);
rangeX = rangeX(rangeX > 0 & rangeX <= imSize(1));
rangeY = floor(pointsR(n,2)-windowSize):ceil(pointsR(n,2)+windowSize);
rangeY = rangeY(rangeY > 0 & rangeY <= imSize(2));
outputImage(rangeX,rangeY) = outputImage(rangeX,rangeY)+gaussIt2D(rangeX(1),rangeX(end),rangeY(1),rangeY(end),[sigmaR,pointsR(n,1),pointsR(n,2)]);
end
function [result] = gaussIt2D(xInit,xFinal,yInit,yFinal,sigma,xCenter,yCenter)
%Returns gaussian intenisty values for the region defined by [xInit:xFinal,yInit:yFinal] using the gaussian properties sigma,centerX,centerY
[gridX,gridY]=ndgrid(xInit:xFinal,yInit:yFinal);
result=exp( -( (gridX-xCenter).^2 + (gridY-yCenter).^2 ) ./ (2*sigma.^2) );
end
然后我想按照以下形式创建网格和中心:
gridX = [1,2
1,2
2,3
2,3
3,4
3,4]
xCenters = [1.2,1.2
1.2,1.2
2.8,2.8
2.8,2.8
3.1,3.1
3.1,3.1]
然后,可以将其用于原始函数中使用的相同高斯方程中。然而,生成这些阵列让我很困惑。我现在得到的是:
function [result]=gaussIt2DVectorized(xInits,xFinals,yInits,yFinals,sigmas,xCenters,yCenters)
%Incomplete
%Returns gaussian intenisty values for the region defined by
%[xInit:xFinal,yInit:yFinal] using the values array:[sigma,centerX,centerY]
[gridX,gridY]=arrayfun('ndgrid',xInits:xFinals,yInits:yFinals);
xCenters = repelem(xCenters,numel(xInits(1):xFinals(1)), numel(yInits(1):yFinals(1)));
yCenters = repelem(yCenters,numel(xInits(1):xFinals(1)), numel(yInits(1):yFinals(1)));
result=exp( -( (gridX-xCenters).^2 + (gridY-yCenters).^2 ) ./ (2*sigmas^2) );
end
但这实际上并不起作用,而且我还预计在计算不同长度的范围(即xInit:xFinal)时会遇到困难
任何帮助、提示或替代方法都将受到欢迎
谢谢。由于您无法确定网格的大小是否相同,因此最好将其存储在单元阵列中,而不是将其堆叠在矩阵中。使用cells数组,您仍然可以运行计算,而无需使用cellfun循环 例如:
function [result] = gaussIt2D_better(xInits,xFinals,yInits,yFinals,sigmas,xCenters,yCenters)
[gridsX, gridsY] = arrayfun(@(x) ndgrid(xInits(x):xFinals(x), yInits(x):yFinals(x)),1:length(xInits),'UniformOutput',0);
f=@(gridX, gridY, xCenter, yCenter, sigma) exp( -( (gridX-xCenter).^2 + (gridY-yCenter).^2 ) ./ (2*sigma.^2) );
result=cellfun(f, gridsX, gridsY, num2cell(xCenters), num2cell(yCenters), num2cell(sigmas), 'UniformOutput',0);
end
请注意,在本例中,返回的值是一个与输入向量长度相同的单元格数组,每个数组对应一个结果。在上面的示例代码中。当您编写sdWindow*sigmaR时,这与WindowsSize相同吗?是的,这是正确的,我在原始代码中将此示例中的sdWindow*sigmaR更改为WindowsSize以使其更清晰。很明显我漏掉了一个,我会修正的。奇怪的是,虽然这是一个矢量化的方法,但它实际上比原来的gaussIt2D函数执行的时间更长。100000分,执行时间延长3%。虽然不需要太长时间,但我还是有点惊讶,因为它不再循环了。这是意料之中的。一般来说,虽然使用arrayfun和cellfun具有代码更短/更整洁的优势,但它不如循环有效。这是解决的问题。如果您关注性能,我建议使用循环。在这种情况下,矢量化并不能节省您的时间。当然,如果您知道所有网格的大小都相同,那么您实际上也可以通过将它们存储在3D矩阵中来利用矢量化来提高性能。但我仍然怀疑,在这种情况下,性能会比循环好得多。
function [result] = gaussIt2D_better(xInits,xFinals,yInits,yFinals,sigmas,xCenters,yCenters)
[gridsX, gridsY] = arrayfun(@(x) ndgrid(xInits(x):xFinals(x), yInits(x):yFinals(x)),1:length(xInits),'UniformOutput',0);
f=@(gridX, gridY, xCenter, yCenter, sigma) exp( -( (gridX-xCenter).^2 + (gridY-yCenter).^2 ) ./ (2*sigma.^2) );
result=cellfun(f, gridsX, gridsY, num2cell(xCenters), num2cell(yCenters), num2cell(sigmas), 'UniformOutput',0);
end