如何使用逻辑索引而不是用于映射插值图像值的循环



我的程序将原始的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_sourcen_source,它只是真实的源图像行,RSP。Col位置,为此目的?

返回矩阵A的返回索引,与矩阵B

中的项目匹配
out = ismember(A,B);

在这种情况下,将具有A的形状,并且仅包含A和B中的项目。

部分解决方案

这假设imq_idimm_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));

最新更新