使用 accumarray 进行矢量化
Vectorization using accumarray
我想将 3D 表面的纹理 (CylCoors
300000x3) 投影到 2D 平面 (Image
380x360) 中。为此,我采用 Z (UniqueZ=unique(CylCoors(:,3))
) 和 Theta (UniqueTheta=unique(CylCoors(:,1))
) 中的每个唯一值并投影所有纹理值 (PointValues
300000x1 ) 两者相遇的地方是这样的:
Image=zeros(max(UniqueH),max(UniqueTheta)); %380x360
tic
HMat=bsxfun(@eq,CylCoors(:,3),UniqueH'); % 300000x380
ThetaMat=bsxfun(@eq,CylCoors(:,1),UniqueTheta'); %300000x360
for ii=1:length(UniqueH) % Sloooow and not nice :(
for jj=1:length(UniqueTheta)
Image(ii,jj)=sum(PointValues.*...
HMat(:,ii).*ThetaMat(:,jj))/...
sum(HMat(:,ii).*ThetaMat(:,jj));
end
end
toc
这是一个带有修剪变量的示例:
CylCoorsSample = [263.0000 184.2586 10.0000
264.0000 183.0417 10.0000
264.0000 182.1572 10.0000
82.0000 157.4746 11.0000
80.0000 158.2348 11.0000
86.0000 157.3507 11.0000
84.0000 157.7633 11.0000]
PointValuesSample = [0.4745
0.5098
0.5020
0.4784
0.4510
0.4431
0.5804]
UniqueTheta = [80
82
84
86
263
264]
UniqueH =[10
11]
ThetaMat = HMat =
0 0 0 0 1 0 1 0
0 0 0 0 0 1 1 0
0 0 0 0 0 1 1 0
0 1 0 0 0 0 0 1
1 0 0 0 0 0 0 1
0 0 0 1 0 0 0 1
0 0 1 0 0 0 0 1
Image = % size: length(UniqueH)xlength(UniqueTheta)
NaN NaN NaN NaN 0.4745 0.5059
0.4510 0.4784 0.5804 0.4431 NaN NaN
有没有办法使用 accumarray
向量化 for
循环?有些东西告诉我是这种情况,但我发现此函数的多维子索引非常混乱。
也欢迎任何其他矢量化解决方案(我假设使用 reshape
、bsxfun
和 sum
的智能组合),但我真的很想了解 accumarray
好一点。
鉴于:
CylCoorsSample = [263.0000 184.2586 10.0000
264.0000 183.0417 10.0000
264.0000 182.1572 10.0000
82.0000 157.4746 11.0000
80.0000 158.2348 11.0000
86.0000 157.3507 11.0000
84.0000 157.7633 11.0000]
PointValuesSample = [0.4745
0.5098
0.5020
0.4784
0.4510
0.4431
0.5804]
您可以按如下方式使用accumarray
(使用unique
的第三个输出生成所需的subs
输入):
[UniqueTheta, ~, subsTheta]=unique(CylCoorsSample(:,1))
[UniqueH,~,subsH]=unique(CylCoorsSample(:,3))
sz = [numel(UniqueH), numel(UniqueTheta)]
Image = accumarray([subsH, subsTheta], PointValuesSample, sz, @mean, NaN)
我想将 3D 表面的纹理 (CylCoors
300000x3) 投影到 2D 平面 (Image
380x360) 中。为此,我采用 Z (UniqueZ=unique(CylCoors(:,3))
) 和 Theta (UniqueTheta=unique(CylCoors(:,1))
) 中的每个唯一值并投影所有纹理值 (PointValues
300000x1 ) 两者相遇的地方是这样的:
Image=zeros(max(UniqueH),max(UniqueTheta)); %380x360
tic
HMat=bsxfun(@eq,CylCoors(:,3),UniqueH'); % 300000x380
ThetaMat=bsxfun(@eq,CylCoors(:,1),UniqueTheta'); %300000x360
for ii=1:length(UniqueH) % Sloooow and not nice :(
for jj=1:length(UniqueTheta)
Image(ii,jj)=sum(PointValues.*...
HMat(:,ii).*ThetaMat(:,jj))/...
sum(HMat(:,ii).*ThetaMat(:,jj));
end
end
toc
这是一个带有修剪变量的示例:
CylCoorsSample = [263.0000 184.2586 10.0000
264.0000 183.0417 10.0000
264.0000 182.1572 10.0000
82.0000 157.4746 11.0000
80.0000 158.2348 11.0000
86.0000 157.3507 11.0000
84.0000 157.7633 11.0000]
PointValuesSample = [0.4745
0.5098
0.5020
0.4784
0.4510
0.4431
0.5804]
UniqueTheta = [80
82
84
86
263
264]
UniqueH =[10
11]
ThetaMat = HMat =
0 0 0 0 1 0 1 0
0 0 0 0 0 1 1 0
0 0 0 0 0 1 1 0
0 1 0 0 0 0 0 1
1 0 0 0 0 0 0 1
0 0 0 1 0 0 0 1
0 0 1 0 0 0 0 1
Image = % size: length(UniqueH)xlength(UniqueTheta)
NaN NaN NaN NaN 0.4745 0.5059
0.4510 0.4784 0.5804 0.4431 NaN NaN
有没有办法使用 accumarray
向量化 for
循环?有些东西告诉我是这种情况,但我发现此函数的多维子索引非常混乱。
也欢迎任何其他矢量化解决方案(我假设使用 reshape
、bsxfun
和 sum
的智能组合),但我真的很想了解 accumarray
好一点。
鉴于:
CylCoorsSample = [263.0000 184.2586 10.0000
264.0000 183.0417 10.0000
264.0000 182.1572 10.0000
82.0000 157.4746 11.0000
80.0000 158.2348 11.0000
86.0000 157.3507 11.0000
84.0000 157.7633 11.0000]
PointValuesSample = [0.4745
0.5098
0.5020
0.4784
0.4510
0.4431
0.5804]
您可以按如下方式使用accumarray
(使用unique
的第三个输出生成所需的subs
输入):
[UniqueTheta, ~, subsTheta]=unique(CylCoorsSample(:,1))
[UniqueH,~,subsH]=unique(CylCoorsSample(:,3))
sz = [numel(UniqueH), numel(UniqueTheta)]
Image = accumarray([subsH, subsTheta], PointValuesSample, sz, @mean, NaN)