当前位置: 首页 > 知识库问答 >
问题:

如何在MATLAB中将延时(一系列遮罩曲面)转换为二进制矩阵?

张岳
2023-03-14

我用成像软件Imaris研究免疫细胞,该软件允许在延时实验中掩蔽细胞表面,并将每个掩蔽表面从一个时间帧链接到另一个时间帧,以便可以跟踪它们。我使用2D数据集,对于每个时间帧和每个曲面对象(单元),我需要提取几个2D参数(周长、长轴长度、面积),以便可以监视单元形状随时间的变化。不幸的是,Imaris提供了几个3D参数(检测到的粒子体积等),但没有2D参数。Imaris的构建是为了将数据导出到Matlab,我被告知应该可以使用Matlab提取这些2D参数。

因此,我的目标是将我的蒙面2D表面(作为时间序列)导出到Matlab,并提取上面提到的2D参数。

在Imaris支持团队的帮助下,我能够正确链接Matlab和Imaris,导入我的数据集,提取掩码数据,并将其转换为二进制矩阵。然而,使用提供的代码,这只能在一个时间框架内完成(总共61个)。尽管如此,我还是能够将这个时间框架(一个图像)转换为二进制矩阵,进而将二进制矩阵转换为二进制图像,从中我可以提取我需要的参数(使用区域道具函数)。

我的问题在于对整个时间序列执行此操作,这需要修改原始代码。虽然我认为我已经取得了一些进展,但我相信我被困住了。因此这个问题。

正如您在下面的代码中所看到的,我将只选择一个时间帧的“vindexT=0”修改为“for vindexT=0:vSizeT”(其中vSizeT是最大时间帧数,61),我认为这将促使Matlab对所有时间帧执行相同的操作。当我在代码从Imaris提取掩码数据之后放置“end”操作符时,我没有收到任何错误消息。我希望这意味着所有掩码数据都已正确导入(但我不知道如何验证)。然而,当我运行代码的下一部分将掩码数据(“vMask”)转换为二进制矩阵时,我得到了我粘贴在下面的错误消息。

或者,我尝试将“end”操作符放在代码之后,以将掩码转换为矩阵(而不是有两个循环,然后只有一个循环),但我收到了相同的错误消息。

这是我收到的原始代码:这一代码允许我正确处理一个时间段:

%% %Get a Copy of the Dataset
vImarisDataSet = vImarisApplication.GetDataSet.Clone;
%%
% Get Surpass Surfaces Object - Please ensure that it is selected in the
% Surpass Tree
vImarisObject = vImarisApplication.GetSurpassSelection;            

%% %Convert the Object into the correct Data Type
vImarisObject = vImarisApplication.GetFactory.ToSurfaces(vImarisObject);

%% % Get the data dimensions
vDataMin = [vImarisDataSet.GetExtendMinX, vImarisDataSet.GetExtendMinY, vImarisDataSet.GetExtendMinZ];
vDataMax = [vImarisDataSet.GetExtendMaxX, vImarisDataSet.GetExtendMaxY, vImarisDataSet.GetExtendMaxZ];
vDataSize = [vImarisDataSet.GetSizeX, vImarisDataSet.GetSizeY, vImarisDataSet.GetSizeZ];

%%
% Create a new channel where the result will be sent
vNumberOfChannels = vImarisDataSet.GetSizeC;
vImarisDataSet.SetSizeC(vNumberOfChannels + 1);
vImarisDataSet.SetChannelName(vNumberOfChannels,['Surface Mask ', char(vImarisObject.GetName)]);
vImarisDataSet.SetChannelColorRGBA(vNumberOfChannels, 255*256*256+255*256+255);
%% %Get the Size of the Time Dimension
vDataSize = [vDataSize, vImarisDataSet.GetSizeT];
%% % Here only the first time point is considered to show the principle
vIndexT = 0;

%% %extract the Mask Data from Imaris
 vMaskDataSet = vImarisObject.GetMask( ...
      vDataMin(1), vDataMin(2), vDataMin(3), ...
      vDataMax(1), vDataMax(2), vDataMax(3), ...
      vDataSize(1), vDataSize(2), vDataSize(3), vIndexT);

%% %Convert the Imaris data into an Matlab Matrix
vMask = GetDataVolume(vMaskDataSet, 0, 0);

以下是我为了导入和转换整个时间序列而尝试的:

%%
% Create a new channel where the result will be sent
vNumberOfChannels = vImarisDataSet.GetSizeC;
vImarisDataSet.SetSizeC(vNumberOfChannels + 1);
vImarisDataSet.SetChannelName(vNumberOfChannels,['Surface Mask ', char(vImarisObject.GetName)]);
vImarisDataSet.SetChannelColorRGBA(vNumberOfChannels, 255*256*256+255*256+255);
aSizeX = vImarisDataSet.GetSizeX;
aSizeY = vImarisDataSet.GetSizeY;
vSizeT = vImarisDataSet.GetSizeT;
%% %Get the Size of the Time Dimension
vDataSize = [vDataSize, vImarisDataSet.GetSizeT];

%% % Here only the first time point is considered to show the principle
vSizeT = vImarisDataSet.GetSizeT;
for vIndexT = 1:vSizeT-1
%% %extract the Mask Data from Imaris

vMaskDataSet = vImarisObject.GetMask( ...
      vDataMin(1), vDataMin(2), vDataMin(3), ...
      vDataMax(1), vDataMax(2), vDataMax(3), ...
      vDataSize(1), vDataSize(2), vDataSize(3), vIndexT);
end
%% %Convert the Imaris data into an Matlab Matrix
for vIndexT = 1:vSizeT-1
vMask = GetDataVolume(vMaskDataSet, 0, vIndexT);
end

这是我运行修改后的代码时遇到的错误:

Error using GetDataVolume (line 23)
Java exception occurred: 
Imaris.Error

    mType = "bpIllegalRangeException"

    mDescription = "Error in bpImageT<Element>::CopyFromChannel"

    mLocation = "bpIceDataSet::GetDataSubVolumeAs1DArrayBytes"

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)

    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)

    at java.lang.reflect.Constructor.newInstance(Unknown Source)

    at java.lang.Class.newInstance(Unknown Source)

    at IceInternal.BasicStream.createUserException(BasicStream.java:2779)

    at IceInternal.BasicStream.access$300(BasicStream.java:14)

    at IceInternal.BasicStream$EncapsDecoder10.throwException(BasicStream.java:3298)

    at IceInternal.BasicStream.throwException(BasicStream.java:2291)

    at IceInternal.OutgoingAsync.throwUserException(OutgoingAsync.java:399)

    at Imaris.IDataSetPrxHelper.end_GetDataSubVolumeAs1DArrayBytes(IDataSetPrxHelper.java:4248)

    at Imaris.IDataSetPrxHelper.GetDataSubVolumeAs1DArrayBytes(IDataSetPrxHelper.java:4078)

    at Imaris.IDataSetPrxHelper.GetDataSubVolumeAs1DArrayBytes(IDataSetPrxHelper.java:4065)


Error in TestMask (line 52)
vMask = GetDataVolume(vMaskDataSet, 0, vIndexT);

如果代码运行正确,我希望它将返回一个由61个二进制图像(时间帧)组成的时间序列。然后,我将从中提取每个时间帧中每个表面的2D统计数据。

我知道你们以前听过,但我对这个很陌生,我对Matlab的知识非常有限,我认为答案可能不远,但我就是看不到。

如果你认为我只是走错了路,而且我的问题可能有更容易的解决办法,你的建议也将不胜感激!

最美好的祝福,

弗洛里安

共有1个答案

喻子航
2023-03-14

您的方法是正确的。代码中的错误是您尝试访问GetMask()返回的vMaskDataSet中不存在的时间点。

i曲面。GetMask()方法返回一个IDataSet,该IDataSet只有一个时间点,与您选择的Vindex参数无关。

vMaskDataSet = vImarisObject.GetMask( ...  
  vDataMin(1), vDataMin(2), vDataMin(3), ...
  vDataMax(1), vDataMax(2), vDataMax(3), ...
  vDataSize(1), vDataSize(2), vDataSize(3), vIndexT);

您可以使用vMaskDataSet验证vMaskDataSet的时间点数。GetSizeT()

您必须调用vMask=GetDataVolume(vMaskDataSet,0,0[

 类似资料:
  • 在我的代码中,它不断给我错误: TypeError:描述符“blit”需要“pygame.Surface”对象,但收到了“pygame.Rect”。 帮助 这是我的代码: 顺便说一句:如果按下s键的部分我已经离开了相同的,直到我得到如果按下w键的部分工作。 提前谢谢。

  • 我有一个编码器BCH的输出矩阵(3,63),但这个矩阵是伽罗瓦域,我需要将这个伽罗瓦域转换为矩阵二进制,因为matlab将伽罗瓦域中的元素视为字符串,我需要将这些值视为二进制数。 我需要将代码列与000010进行比较,。。。对于开关情况或if,但代码矩阵行是伽罗瓦场格式。我的问题是,遵循matlab错误是开关表达式必须是标量或字符向量。

  • 问题内容: 我正在寻找一种简单的方法来在Swift中将二进制数转换为十进制数。例如,二进制的“ 10”变为十进制的“ 2”。 谢谢, 问题答案: 更新 为 斯威夫特2: 所有整数类型有 现在的方法,该方法根据给定的基数将字符串转换为整数: (先前的答案:) 您可以简单地使用BSD库函数,该函数根据给定的基数将字符串转换为数字:

  • 本文向大家介绍如何将八进制转换为二进制?,包括了如何将八进制转换为二进制?的使用技巧和注意事项,需要的朋友参考一下 八进制数是基数为8的数字系统之一,这意味着只有8个符号−0、1、2、3、4、5、6和7。而二进制数是数字系统、网络和计算机专业人员最熟悉的数字系统。基2只有2个符号−0和1,这些数字可以分别用off和on表示。 从八进制转换为二进制数制 将八进制数转换成二进制数有多种直接或间接的方法

  • 问题内容: 如何在Swift中将Int转换为UInt8?例。我想将数字22转换为0b00010110 问题答案: 您可以使用带有参数的初始化程序将十进制值转换为人类可读的二进制 表示形式 : 如果您愿意,也可以很容易地用任意数量的零填充它: 斯威夫特5

  • 将二进制补码转换为十进制最简单的方法是什么?例如,如果我通常将“1001”之类的字符串转换为十进制,则得到9。但我实际上想得到一个简单的-7。你们有什么建议?,