【问题标题】:Selection of data in a region of interest in a matrix (with Mathematica)选择矩阵中感兴趣区域的数据(使用 Mathematica)
【发布时间】:2011-07-15 05:29:07
【问题描述】:

我遇到了一个(mathematica 8.0.1.0-)我自己无法解决的问题。 我在矩阵中有测量数据,我想选择其中一些,然后将它们相加。

为了更好地解释我的问题,这里有一个简单的例子。数据可以由矩阵S产生:

S = Table[ -Sin[i/2] - Sin[j/2], {i,20}, {j,20}];

它们可以很好地绘制:

xmin = N[Min[S]]; 
xmax = N[Max[S]]; 
mycolorfun = Function[ Blend[{Blue,Cyan,Green,Yellow,Red},#] ];

MatrixPlot[S, PlotRange -> {All,All,All}, AspectRatio -> 1/1,
   ColorFunction -> (mycolorfun[ Rescale[ #1{xmin,xmax} ] ]&),
   ColorFunctionScaling -> False, MaxPlotPoints -> Automatic,
   FrameLabel -> {y,x} ]

那么应该会得到一张和这张类似的图片:

现在我想选择棕色绘制的多边形内的数据。这些数据应该在最后加起来。

我该怎么做? 好的,我可以使用矩形并通过选择/猜测良好的开始和结束索引来构建子矩阵。然后我只需要建立这个子矩阵的总和。但我更喜欢多边形(如果我们不争论与多边形线相交的矩阵值的小问题,则更准确)。如果我可以通过将多边形“绘制”到矩阵中直接选择我的感兴趣区域 (ROI),我会很高兴(不再费时选择/猜测矩阵索引)。
有人可以帮我解决我的问题吗?如果用mathematica 无法解决,是否有其他程序可以使用?

如果能得到一些帮助和提示,我会很高兴的!

【问题讨论】:

  • 请注意,代码块前面需要一个空行,所以我为您修复了它。我还稍微重新格式化了代码,并将链接隐藏在可点击文本后面以提高可读性。
  • 感谢您编辑我的问题!由于我是新来的,所以我自己编辑时遇到了一些问题。下次我会努力让它变得更好。
  • 没问题。你的新人在这里,布置你的问题/答案需要练习。
  • 感谢@belisarius 和@rcollyer 编辑我的文字。很高兴看到我的照片现在直接在我的帖子中。这样更容易理解!

标签: image-processing wolfram-mathematica


【解决方案1】:

如果手动以图形方式选择感兴趣的区域不成问题,那么您可以:

首先,从您的数据中创建一个图像,使用可视化,便于您之后手动选择:

S = Table[-Sin[i/50.] - Sin[j/50.], {i, 400}, {j, 400}];
img = ReliefImage@S

然后使用前端图形工具在您感兴趣的区域上绘制多边形(鼠标右键):

获取与您的多边形相对应的蒙版(再次,右键单击按钮):

最后,用掩码制作一个二值图像,并用它来恢复多边形内像素的总和:

Total[S*ImageData@mask, Infinity]

整个过程是这样的:

编辑:如果您想使用手绘轮廓来定义您感兴趣的区域,请使用手绘线工具而不是多边形。确保增加笔画的宽度,以便在绘制时容易关闭轮廓。您可以通过将 Stroke>Thickness 滑块向右移动来做到这一点。

看起来像这样:

然后使用函数FillingTransform填充手绘轮廓的内部来创建蒙版,并像以前一样继续:

【讨论】:

  • 天啊!这正是我一直在寻找的解决方案!非常感谢!我只是做了一些较小的修改。例如,我在 ReliefImage 中使用我自己的 ColorFunction(出于品味问题),我正在创建一个额外的矩阵来再次绘制我感兴趣的区域。我正在这样做: SROI=Mat​​rixForm[S*ImageData@mask];然后我将张量 SROI 减少为一个矩阵 SROImatrix=SROI[[1,All,All]][[All,All,1]];所以我可以很容易地使用 SROImatrix 来计算总和 (Total[SROImatrix,2]) 并绘制它。效果很好,我几乎不敢相信!
  • 好的,如果可以在感兴趣的区域上绘制一条手绘线而不仅仅是一个多边形,那也很棒。但目前我未能填充封闭的手绘线的内部。因为之后我可以调整多边形的顶点,所以我并不真正关心这个问题。大声笑,我很高兴有这样一个非常好的解决方案 :-) 再次感谢您的这篇有用的帖子!
  • @user842603 我已经编辑了我的答案以展示如何使用手绘轮廓。这应该回答你的问题。另外,能否请您在您的问题中添加标签 image-processing ?
  • @user, @Matthias 我已经添加了标签。我建议稍微改写一下这个问题,以便更清楚地表明需要图像处理答案;目前,它以“我在矩阵中有测量数据,我想选择其中一些然后将它们相加。”开始。
  • @Matthias 啊,这也比想象的容易(我不知道 FillingTransform)!也感谢您解决了这个问题。有了手绘轮廓的可能性,我现在的所有需求都得到了完美的满足。 @acl 感谢您将标签图像处理添加到我的问题中。我认为它适合我的问题,虽然我在写问题时没有想到这个关键词。
【解决方案2】:

也许是这样的:

upl = 20;
s = Table[-Sin[i/2] - Sin[j/2], {i, upl}, {j, upl}];

xmin = N[Min[s]]; xmax = N[Max[s]]; mycolorfun = 
Function[Blend[{Blue, Cyan, Green, Yellow, Red}, #]];

mp = MatrixPlot[s, PlotRange -> {All, All, All}, AspectRatio -> 1/1, 
ColorFunction -> (mycolorfun[Rescale[#1, {xmin, xmax}]] &), 
ColorFunctionScaling -> False, MaxPlotPoints -> Automatic, 
FrameLabel -> {"y", "x"}];
Manipulate[
{{x1, y1}, {x2, y2}} = 
 Floor /@ {{p1[[1]], upl - p1[[2]]}, {p2[[1]], upl - p2[[2]]}};
    mp,
{{p1, {1, 1}}, Locator}, {{p2, {19, 19}}, Locator}]

Dynamic[{{x1, y1}, {x2, y2}}]
Dynamic[N@s[[y2 ;; y1, x1 ;; x2]] // MatrixForm]

它会产生类似的东西 当您移动定位器时,矩阵的一部分会实时更新。

要改为创建多边形,只需添加更多定位器。选择矩阵的一部分会更加复杂,这取决于您希望输出的方式。

【讨论】:

  • 感谢 acl(我希望你喜欢德累斯顿;你也会说德语吗?)的详细回答。我尝试了您的建议,它甚至适用于我真正的大 (2048 x 2048) 矩阵。添加更多定位器很简单(您可以如此轻松地读出它们的坐标/索引真是太好了),但您是对的:选择我感兴趣的矩阵部分,然后真的更复杂。由于我已阅读您的答案,因此我正在考虑并尝试为两个以上的定位器(以及五边形和六边形等)找到解决方案,但直到现在我还没有一个好主意。
  • 我只能告诉你,我认为六边形应该总是足以让我将感兴趣的区域包围在我的矩阵中。作为输出,我可以想象我生成了一个新矩阵(由具有最小和最大索引的 6 个定位器中的 4 个(甚至更多)拉伸)。感兴趣区域之外的新矩阵部分可以用 0 填充。因此,如果我使用这个新矩阵,将正确计算事件的总和。但我真的不知道如何实现这一点。
  • @user 是的,如果选择多边形区域,提取相关元素并不是那么简单,使用它们可能也很麻烦。也许您可以在这里提出另一个单独且更具体的问题。 [顺便说一句,德累斯顿很好,谢谢:)]
  • 再次感谢您的回复和努力。你看过 Matthias Odisios 的建议吗?我没想到有这么好的方法可以解决我的问题。但我想我也会将您建议的某些部分用于其他一些问题。很高兴听到你喜欢德累斯顿,我也应该有一天去参观这座城市 ;-)
【解决方案3】:

如果我猜对了,你需要找到一个相似像素值的连通分量。

您可以使用图像处理功能:

首先Binarize 使用适当阈值的图像。然后使用MorphologicalComponents 来识别所有连接的区域。最后可以提取图片数据,使用Pick获取你感兴趣的组件对应的像素值。

编辑:以下是该概念的说明:

【讨论】:

  • 但是如果他想要自动选择,直接在原始矩阵上做不是更好吗?使用例如Position?
  • 感谢 Szabolcs 采用这种完全不同的方法。不幸的是,我目前无法上传包含真实测量数据的矩阵图之一。可以看出,如果我尝试您的解决方案,我会遇到麻烦。原因很简单:有几个区域具有相似的像素值。对于我的分析,我必须分别计算这些区域中的事件数量。很抱歉没有早点提到!
  • @user,查看MorphologicalComponents 的第二个示例,您会看到每个断开连接的区域都被单独处理。这意味着,您只需找到Binarize 的阈值,它将在您的数据中创建这些断开连接的区域。然后,使用MorphologicalComponents 为每个区域编号。
  • 再次感谢您的回复和努力。我想我会遵循 Matthias Odisios 的建议。不知何故,他将您的建议和 acls 的建议结合在一起,颇有成效。
  • @user 终于有时间添加示例计算了。
猜你喜欢
  • 2013-10-19
  • 1970-01-01
  • 2011-08-10
  • 2013-02-28
  • 2012-04-25
  • 2012-02-22
  • 2019-05-10
  • 2013-03-03
相关资源
最近更新 更多