我的程序将原始的equiretectangular图像转换为方位角矫正投影。
这是通过在等映射图像(输入(上的投影图像(目标(上的每个像素来完成的。由于等值角图像上的位置通常是非数字的,因为投影(三角和其他功能(,投影图像的颜色值像素必须从源图像的颜色值中插值。
。 im_source
是一个3维矩阵,由(行,列,color_channel(排序,包含特定颜色通道的值
m_source_q
是一个2维矩阵,包含插值(查询(网格的行,因此对于1024*512原始图像和0.1像素的网格精度为0.1像素m_source_q
看起来像:
[1 1 1 1 .... 1
1.1 1.1 1.1 1.1 .... 1.1
1.2 1.2 1.2 1.2 ..... 1.2
...
512 512 512 512 .... 512]
n_source_q
同样包含查询列位置
[1 1.1 1.2 1.3 .... 1024
1 1.1 1.2 1.3 .... 1024
...
1 1.1 1.2 1.3 .... 1024]
p_er
是一个3-D矩阵。这是一个二维图,包含投影图像上每个像素的插值原始图像的分数坐标。因此,例如p_er(502, 262, 1) == 259.9
(原始图像中的对应行(;p_er(592, 252, 2) == 513.2
(原始图像中的相应列(。
imq
是一个3-D矩阵,包含每个颜色通道和每个网格位置的所有插值颜色值。imq
是通过插值获得的:
for idim=1:3
imq(:,:,idim) = interp2(n_source, m_source, imsource(:,:,idim), n_source_q, m_source_q, 'linear');
end;
请注意,idim
是颜色通道的索引(R:1,G:2,B:3(
imp_double
是一个3-D矩阵,其中包含每个投影图像像素的所有颜色通道的(双类/实数(颜色值。这只需转换为projection_image = uint8(imp_double)
。
最后一步是将投影像素映射到相应的插值颜色值:
for idim=1:3
imq_idim = imq(:,:,idim);
for m=1:Hp % Hp .. height of projection image
for n=1:Wp % Wp .. width of projection image
if isRealPixel(m,n)
imp_double(m,n,idim)=imq_idim(m_source_q==per(m,n,1) & n_source_q==per(m,n,2));
end;
end;
end;
end;
这确实有效,但是确实需要太长,我很确定这两个嵌套的for
循环是原因。
我的问题:如何通过逻辑索引或其他方法避免使用循环?
我尝试了
for idim=1:3
imp_double(:,:,idim) = imq_idim(m_source_q==per(:,:,1) & n_source_q==per(:,:,2));
end;
但是口译员抱怨矩阵的尺寸不匹配。显然,我必须告诉MATLAB关于哪些索引向量(您是如何称呼它?(应该应用功能,并且两个结肠不够。我是否需要矩阵m_source
和n_source
,它只是真实的源图像行,RSP。Col位置,为此目的?
返回矩阵A的返回索引,与矩阵B
中的项目匹配out = ismember(A,B);
在这种情况下,将具有A的形状,并且仅包含A和B中的项目。
部分解决方案
这假设imq_idim
与m_source.
相同,如果情况并非如此,并且per(:,:,1)
的大小与img_idim
相同,则可以翻转参数。
这也假定您要做的就是找到per(:,:,1)
中的任何m_source
值。如果您不尝试这样做,那么您还需要查看循环解决方案,因为那是当前发生的事情
for idim=1:3
imp_double(:,:,idim) = imq_idim(ismember(m_source_q,per(:,:,1)) & ....
ismember(n_source_q,per(:,:,2));
end;
维度不匹配
上面的代码在右侧是正确的,但不会在imp_double(:,:,idim) = ...
%
左侧
imp_double(:,:,idim)
要求的矩阵与IMP_Double的前两个维度相同。
右侧 imq_idim(ismember(m_source_q,per(:,:,1)) & ... ismember(n_source_q,per(:,:,2));
返回一个一维的可变大小向量(取决于我们获得多少匹配(。
解决方案
a(使右侧为矩阵imp_double(:,:,idim)
,但具有正确的值更改
% imp_double MUST BE PREALLOCATED
temp = imp_double(:,:,idim); % temp is a 2D matrix
temp(ismember(m_source_q,per(:,:,1)) & ....
ismember(n_source_q,per(:,:,2))) = ...
imq_idim(ismember(m_source_q,per(:,:,1)) & ....
ismember(n_source_q,per(:,:,2)));
imp_double(:,:,idim) == temp;
b(在imp_double
这将是与下面类似的简单解决方案。问题是,您不能用2D逻辑索引3D矩阵,然后是第三索引。此处的任何解决方案都会使用 a(冗余,但略复杂
% Doesn't work because can't index imp_double(mat,ind)
imp_double(ismember(m_source_q,per(:,:,1)) & ....
ismember(n_source_q,per(:,:,2)),...
idim)) = ...
imp_double(:,:,idim) = imq_idim(ismember(m_source_q,per(:,:,1)) & ....
ismember(n_source_q,per(:,:,2));