首页 文章

如何使用逻辑索引而不是for循环来映射插值图像值?

提问于
浏览
1

我的程序将原始的equirectangular图像转换为方位角正投影 .

这是通过在投影图像(目的地)上定位等距矩形图像(输入)上的每个像素来完成的 . 由于投影(三角函数和其他函数),所以在等距矩形图像上的位置通常是非内部数字,投影图像像素的颜色值必须从源图像的颜色值内插 .

im_source 是一个三维矩阵,按(row,column,color_channel)排序,包含特定颜色通道的值

m_source_q 是一个二维矩阵,包含插值(查询)网格的行,因此对于1024 * 512的原始图像和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 是一个三维矩阵 . 它是一个二维 Map ,包含投影图像上每个像素的插值原始图像的分数坐标 . 所以例如 p_er(502, 262, 1) == 259.9 (原始图像中的相应行); p_er(592, 252, 2) == 513.2 (原始图像中的相应列) .

imq 是一个三维矩阵,包含每个颜色通道和每个网格位置的所有插值颜色值 . 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 是一个三维矩阵,包含每个投影图像像素的所有颜色通道的(双/实数)颜色值 . 这只会转换为 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循环?

我试过了

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 . 上校职位,为此目的?

1 回答

  • 0

    返回与矩阵B中的项匹配的矩阵A的索引

    out = ismember(A,B);
    

    在这种情况下,out将具有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) = ... %中正确传递到左侧

    Left-side

    imp_double(:,:,idim) 要求的矩阵与imp_double的前两个维度相同 .

    Right-side imq_idim(ismember(m_source_q,per(:,:,1)) & ... ismember(n_source_q,per(:,:,2)); 返回一维,可变大小的向量(取决于我们得到多少匹配) .

    Solution

    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逻辑后跟第3个索引来索引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));
    

相关问题