Как преобразовать промежуток времени (серию маскированных поверхностей) в двоичную матрицу в MATLAB? - PullRequest
1 голос
/ 27 марта 2019

Я изучаю иммунные клетки с помощью программного обеспечения Imaris для визуализации, которое позволяет маскировать поверхность клеток в эксперименте с промежутками времени и связывает каждую маскированную поверхность от одного временного интервала к другому, чтобы их можно было отслеживать. Я работаю с двумерными наборами данных, и для каждого временного кадра и каждого поверхностного объекта (ячейки) мне нужно извлечь несколько двумерных параметров (периметр, длина большой оси, площадь), чтобы я мог отслеживать изменение формы ячейки во времени. К сожалению, Imaris дает несколько 3D параметров (объем обнаруженных частиц и т. Д.), Но не 2D параметр. Imaris построен таким образом, что данные могут быть экспортированы в Matlab, и мне сказали, что можно использовать Matlab для извлечения этих 2D параметров.

Поэтому моя цель состоит в том, чтобы экспортировать мои маскированные 2D-поверхности (как временные ряды) в Matlab и извлечь упомянутые выше 2D-параметры.

С помощью команды поддержки Imaris я смог правильно связать Matlab и Imaris, импортировать мой набор данных, извлечь данные маски и преобразовать их в двоичную матрицу. Однако с предоставленным кодом это можно сделать только в течение одного таймфрейма (из 61). Тем не менее, мне удалось преобразовать этот временной интервал (одно изображение) в двоичную матрицу, и, в свою очередь, в двоичную матрицу в двоичное изображение, из которого я мог извлечь нужные мне параметры (используя функцию regionprops).

Моя проблема заключается в том, чтобы делать это со всеми временными рядами, что требует изменения исходного кода. Хотя я думаю, что добился определенного прогресса, я считаю, что застрял. Отсюда и этот вопрос.

Как вы увидите в коде ниже, я изменил «vindexT = 0», который выбрал только один таймфрейм, для «vIndexT = 0: vSizeT» (где vSizeT - максимальное количество таймфреймов, 61), которое я Считается, что побудит Matlab сделать одну и ту же операцию для всех временных периодов. Когда я помещаю оператор «end» сразу после кода, извлекающего данные маски из Imaris, я не получаю никакого сообщения об ошибке. Что, я надеюсь, означает, что все данные маски были правильно импортированы (но я не знаю, как это проверить). Однако, когда я запускаю следующую часть кода, которая должна преобразовать данные маски («vMask») в двоичную матрицу, я получаю сообщение об ошибке, которое вставил ниже.

В качестве альтернативы я попытался поместить оператор «конец» после кода, чтобы преобразовать маску в матрицу (вместо двух циклов у меня только один), но я получил то же сообщение об ошибке.

Вот исходный код, который мне отправили: этот позволил мне правильно обработать один таймфрейм:

%% %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 очень ограничены, я думаю, что, вероятно, ответ не за горами, но я просто не вижу этого.

Если вы думаете, что я просто ошибаюсь, и что, возможно, решение моей проблемы будет гораздо проще, ваше предложение также будет высоко оценено!

С наилучшими пожеланиями,

Florian

...