【问题标题】:How to use logical indexing instead of for loops for mapping interpolated image values?如何使用逻辑索引而不是 for 循环来映射插值图像值?
【发布时间】:2017-11-27 08:06:57
【问题描述】:

我的程序将原始等距矩形图像转换为方位角正交投影。

这是通过在 equirectangular 图像(输入)上定位投影图像(目标)上的每个像素来完成的。由于投影(三角函数和其他函数)的原因,等距矩形图像上的位置通常是非整数,因此必须根据源图像的颜色值对投影图像像素的颜色值进行插值。

im_source 是一个 3 维矩阵,按 (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 是一个 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 循环?

我试过了

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 位置,为了那个目的?

【问题讨论】:

  • 澄清一下,你能在你的解决方案中执行m_source_q==per(:,:,1) & n_source_q==per(:,:,2)吗?
  • 不,这不起作用,错误是:Error using == Matrix dimensions must agree.
  • 例如,如果你尝试,for idim=1:3; temp = m_source_q==per(:,:,1) & n_source_q==per(:,:,2); end; 你会得到那个错误?
  • m_source_q 是 2D,您将其与 3D 矩阵进行比较。试试squeeze。例如m_source_q==squeeze(per(:,:,1)) & n_source_q==squeeze(per(:,:,2))。顺便说一句,我不知道您要做什么,只是指出可能的尺寸不匹配。哦,我看到n_source_q 是一维的。好吧,我必须阅读更多内容,但请记住尺寸
  • @BrendanFrick 是的,我遇到了同样的错误。

标签: matlab dictionary image-processing matrix vectorization


【解决方案1】:

返回与矩阵 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) = ...% 中不会正确传递到左侧

左侧

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 逻辑后跟第 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));

【讨论】:

  • ismember 真的很像我需要的功能!非常感谢你。我尝试了imp_double(:,:,idim) = imq_idim(ismember(per(:,:,1) , m_source_q) & ismember(per(:,:,2) , n_source_q));,它给了我一个Subscripted assignment dimension mismatch.,但我认为这可能是由我没有捕捉到的复杂的非实数引起的。我必须先过滤掉非实数值。
  • 没有。这实际上是另一个问题。左手和右手参数不匹配。我将添加修复程序
猜你喜欢
  • 2012-09-11
  • 1970-01-01
  • 2019-09-10
  • 1970-01-01
  • 2015-10-24
  • 2018-08-17
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
相关资源
最近更新 更多