【发布时间】:2014-12-10 17:55:57
【问题描述】:
我仍在学习 matlab,并且正在尝试了解矢量化。我认为我的问题的根源是我不明白如何引用不同的矩阵等。我希望这个问题的答案能帮助我理解。
FI = imread(ForegroundImageName);
BI = imread(BackgroundImageName);
refRows =size(FI,1);
refCols =size(FI,2);
refChan =size(FI,3);
CommonRGB = mode(mode(FI));
BI = imresize(BI, [refRows refCols]);
swappedPixels = 0;
for row=1:refRows
for col=1:refCols
if(FI(row,col,:)==CommonRGB)
FI(row,col,:)=BI(row,col,:);
swappedPixels = swappedPixels + 1;
end
end
end
这个问题的背景是,如果前景像素与最常见的颜色匹配,我将用背景像素替换前景像素。 CommonRGB 是一个 1x1x3 矩阵,因为 mode(mode(FI)) 会吐出它。这些图像是 3D 彩色 RGB 图像。我选择这个作为我的问题的一个简单例子。这个 for 循环执行我想要它做的事情并且似乎工作。只是运行for循环需要很长时间。我执行mode(mode(FI)) 是运行上述for 循环所需时间的一小部分,我尝试自己实现mode(mode(FI)),与上面的像素交换相比,它变得相当复杂。创建直方图时我遇到了类似的问题。我希望你能帮助我更多地了解 matlab 并将我的编程知识扩展到这门语言中。我知道如果我说我想对整个矩阵执行这些操作会更容易,所以如果我们对其进行矢量化,我会假设我们不需要 refRows、refCols 和 refChan 变量在这种情况下.
我的一次失败尝试
if(FI(:,:,:)==CommonRGB)
FI(:,:,:)=BI(:,:,:);
swappedPixels = swappedPixels + 1;
end
从目前的答案来看,他们已经展示了向量化逻辑的方法。我得到的结论是,任何其他不涉及长 for 循环的方法都将比像我所做的那样使用大型 for 循环快得多。即使这意味着创建额外的数组并执行额外的过程,例如创建掩码数组并多次运行图片。据我所知,问题的根源在于 matlab 的 JIT Just In Time 编译器必须在 for 循环的每次迭代中重新解析命令。这种对for循环的解析和处理才是速度问题的真正根源。如果 matlab 可以“看到” for 循环并提前计划,那么它会运行得更快。因此,我对原始代码无能为力,我只需将 row 和 col 替换为其他内容并删除两个 for 循环。我将不得不设计其他不使用大 for 循环的方法。只有这样它才能以合理的速度运行。这告诉我,matlab 是一种真正的前端脚本语言,因为使用 for 循环运行脚本同样会遭受不利的性能下降。因此,我不确定如何将此问题标记为已回答、未回答或投票支持其他答案。因为如果我改变 for 循环内的逻辑,那么我将不得不改变我实现加速的方式。
所以,除非有人能告诉我如何用 1:refRows 之类的其他东西替换 for 循环中的变量 row 和 col,使用 parfor,使用简单的东西,只更改 for 循环内的代码并删除 for循环,或者可以只写一个答案来验证上面的段落,那么我现在不知道该怎么做。
正如@Divakar 所说,“你说得对,这里没有明确的矢量化技术来插入循环参数并从中获得矢量化解决方案。如果你有一个循环而不是这两个嵌套循环在循环情况下,您可以使用逻辑索引获得更直接的即插即用矢量化解决方案。但是,是的,矢量化在大多数情况下无法推广,需要根据具体情况进行处理。祝你好运矢量化探索!- Divakar"
话虽如此,我想帮助其他人,向他们展示我做了什么来应用我从这个问题中学到的东西。似乎我已经弄清楚了我认为的算法,尽管我仍然不确定我使用光阈值选择常见色调的第 3 阶段是否有效。当光阈值升高时,我没有看到它选择不同的色调。我只是看到第 3 阶段始终选择与第 2 阶段不同的色调。直到今天我才意识到这一点。对问题本身并不重要,但下面对问题很重要,因为我提到了 for 循环方法,然后实现了矢量化方法。在第 2-3 阶段比在第 1 阶段更是如此,我不需要做太多的改变。 ...好吧,它并没有让我粘贴那么多信息,所以我会尝试另一种方法。
My PDF of my lab report with code and pictures 我知道 mode(mode(FI)) 不正确,但我仍然很好奇第 2 阶段如何获得与第 3 阶段不同的色调。我认为第 2 阶段是正确的,我一次逐个像素地比较以验证第 2 阶段是否相同作为第 3 阶段,但 mode(FI(:)) 应该是正确的。如果您发现任何问题,请告诉我。我理解了大部分矢量化,除了使用掩码作为索引的工作原理。我知道他们称之为逻辑索引,但我猜只有 1 表示它将使用它,而零表示它不会查看该值。
【问题讨论】:
-
哇!这么多答案,但还是有点复杂。我试图理解答案并决定哪个是最好的。我真的很喜欢@Divakar,他展示了一张加速图。似乎没有一种简洁的方法可以将 for 循环参数直接插入到 for 循环内的内容中。它也引起了我的注意,虽然它不是这个问题的重点,但 mode(mode(FI)) 可能不是找到最常见颜色的正确方法,因为它按列进行,然后找到结果模式。根据颜色的比例,它可能不正确。
-
@KalenBrown 你是对的,这里没有明确的矢量化技术来插入循环参数并从中获得矢量化解决方案。如果您有一个循环而不是这两个嵌套循环的情况,您可以使用逻辑索引获得更直接的即插即用矢量化解决方案。但是,是的,矢量化在大多数情况下不能一概而论,需要根据具体情况进行处理。祝矢量化探索顺利!
-
很高兴看到矢量化代码最终出现在链接的实验室报告中!将这个 Stackoverflow 问题和/或答案(包含在 pdf 中的矢量化代码)链接到 pdf 的参考文献中不公平吗?
-
@Divakar 在参考资料部分(不在底部)我做。 stackoverflow.com/q/27407712/3988126
-
甜蜜!我现在明白了,我很抱歉,因为我之前粗略地看了一眼就错过了。顺便说一句,这看起来像是一个很好的介绍和彻底的文档,再看一遍,干得好!
标签: matlab image-processing for-loop vectorization logical-operators