Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Магистерская диссертация.pdf
Скачиваний:
63
Добавлен:
27.03.2015
Размер:
2.77 Mб
Скачать

3.Описание реализации программной системы

Врамках выполнения данной работы был разработан экспериментальный программный комплекс «Neocortex», решающий задачи сегментации, идентификации объектов по найденным сегментам их 3D-реконструкции. Комплекс был разработан на алгоритмическом языке С++ в среде визуального программирования Microsoft Visual Studio 2008 .NET. Для визуализации исходных данных, сегментов и реконструированных объектов использовался фреймворк Tao OpenGL 2.1 [64], а открытие и фильтрация изображений осуществлялась посредством библиотеки с открытым исходным кодом OpenCV 2.4 [65]. Кроме того, как было отмечено выше, реализация параллельных версий алгоритмов сегментации методом k-средних с использованием графических процессоров проводилась с помощью технологии OpenCL [66].

3.1. Основные классы, структуры и методы

Главными объектами, которые используются в рамках программной системы для решения поставленной задачи, являются данные компьютерной томографии или электронной микроскопии и сегменты этих данных. Поэтому при реализации программной системы основное внимание было уделено разработке классов и структур, обеспечивающих сегментацию исходных данных, а также хранение, представление, обработку исходных данных и найденных сегментов.

Перечислим классы, соответствующие данным объектам, а также наиболее важные поля и методы, реализованные в этих классах.

1.TLayer – структура для более удобной работы с отдельно взятыми слоями данных, включающая в себя информацию о значениях плотности вокселов в виде массива Density, а также размеры слоя и каждого воксела вдоль обеих осей (X и Y). Помимо конструкторов, позволяющих инициализировать новый слой данных, в рамках данной структуры реализованы методы доступа к массиву Density, а также функции, вычисляющие абсолютную разницу между двумя вокселами по плотности.

2.TVoxelSegments – набор индексов, характеризующих принадлежность каждого воксела к тому или иному 2Dили 3D-сегменту, в зависимости от рассматриваемого уровня иерархической структуры.

3.TVoxelsData – класс, инкапсулирующий в себе информацию о входных данных в виде массива целочисленных значений Density, аналогично структуре TLayer. Кроме этого он включает в себя такие поля, как размеры исходных данных и каждого воксела вдоль осей X, Y и Z, а также минимальное и максимальное значения плотности вокселов. Для того чтобы

34

иметь возможность рассматривать не все исходные данные, а только их часть, предусмотрена маска используемых вокселов IsVoxelUsed, а для выполнения разных операций над сегментами – массив объектов структуры TVoxelSegments.

Основными методами класса TVoxelsData, как и для структуры TLayer , являются методы, обеспечивающие работу с массивом Density. Помимо них, работать с данной структурой можно с помощью следующих функций:

bool Load(const char *pathToBinFile) – загрузка данных из файла в формате «.bin»;

TVoxelsData* GetSubData(size_t z_first, size_t z_last) – возвращает подмножество множества исходных данных, начинающееся и заканчивающееся слоями с индексами z_first и z_last соответственно;

TLayer GetLayer(size_t z) – извлекает слой данных с индексом z;

int FindConnectedRegions(size_t LayerIndex, cv::Vec2i SegmentIndex) – ищет связные области на слое с номером LayerIndex для сегмента, характеризующегося парой целых чисел SegmentIndex (первая компонента – индекс сегмента по диапазону значений плотности вокселов, а вторая – либо индекс сегмента по расстоянию между вокселами, либо -1, в зависимости от уровня иерархической структуры).

4.TSegment – структура хранения сегмента как набора описывающих его атрибутов. Помимо тех атрибутов сегмента, которые были приведены в разделе 2.6, данная структура включает в себя атрибуты цвета и прозрачности сегмента для его отображения, а также границы диапазона значений плотности принадлежащих ему вокселов. Для поддержания иерархической структуры сегментов используется поле NextLevelSegments – указатель на вектор сегментов следующего уровня иерархии.

5.TPath – обозначает последовательность индексов сегментов, соответствующих определённому идентифицированному объекту. Данная последовательность в общем случае представляет собой корневое дерево из 2 ветвей – подпоследовательностей индексов, соответствующих выполнению динамического процесса вперёд и назад.

6.KMeansMethod – базовый абстрактный шаблонный класс для всех алгоритмов, основанных на методе k-средних и реализованных при разработке программной системы. Данный класс параметризован типом центров тяжести, вычисляемых на каждой итерации метода (обозначим данный тип через T). Каждый класс, производный от класса KMeansMethod, реализует свои версии следующих функций:

T GetMean (size_t I) – возвращает центра тяжести сегмента с заданным индексом I;

T EmptyClusterValue () – значение, соответствующее пустому сегменту;

bool IsClusterNotEmpty (size_t I) – проверка I-ого сегмента на пустоту;

35

float GetVoxelDistance (size_t J, size_t K) – расстояние от воксела с индексом J до сегмента с индексом K (по плотности и/или координатам);

vector <vector <size_t> > GetClusters () – возвращает вектор непустых сегментов,

найденных соответствующим алгоритмом; каждый сегмент – вектор приведённых

индексов образующих его вокселов.

Классы, реализующие тот или иной алгоритм сегментации k-средних, образуют иерархию наследования, приведённую в Приложении Б. Их также можно разделить на несколько групп:

1.По типу искомых сегментов (сегменты по плотности, сегменты по геометрическому расстоянию между вокселами, или по совокупности этих признаков).

2.По ограничениям, накладываемым на сегментируемые исходные данные (диапазон значений плотности, представляющий интерес, либо маска вокселов, соответствующая

выделенной области).

Основные методы, реализованные как самостоятельные функции вне классов и структур хранения данных, предназначены для вычисления центра масс и атрибутов, как отдельно взятого сегмента, так и их совокупности. Каждый такой метод возвращает значение соответствующего атрибута или совокупность атрибутов, если их несколько.

Методы вычисления атрибутов сегментов можно разделить на 2 группы по их назначению:

1.Вычисление центра масс заданного сегмента (по плотности и/или координатам). Входными данными каждого метода является указатель на объект исходных данных TVoxelsData и сегмент, принадлежащий этим данным, в виде вектора приведённых индексов вокселов.

2.Вычисление других атрибутов сегментов.

Втаблице 2 приведены имена всех методов, входящих в указанные группы, а также назначение каждого из них.

Таблица 2. Методы вычисления характеристик сегментов

Имя метода

Назначение

 

 

GetMeanDensity

среднее значение плотности вокселов в сегменте

GetMeanCoords_2D, GetMeanCoords_3D

геометрические центры 2D- и 3D-сегмента

соответственно

 

GetMeanDensityCoords_2D,

среднее значение плотности и геометрический центр

GetMeanDensityCoords_3D

сегмента в совокупности

MinMaxDensityOfSegment_2D,

минимальное и максимальное значения плотности 2D-

CalcMinMaxDensityOfSegments_2D

сегмента и группы сегментов

DensityMeanDevOfSegment_2D,

среднее значение и среднеквадратическое отклонение

CalcDensityMeanDevOfSegments_2D

плотности 2D-сегмента и группы сегментов

36

Имя метода

Назначение

 

 

MeanDevXYOfSegment_2D,

среднее значение и среднеквадратическое отклонение

CalcMeanDevXYOfSegments_2D

координат X и Y для 2D-сегмента и группы сегментов

VolumeOfConnectedRegion_2D,

объём двумерной связной области и группы областей

CalcVolumesOfConnectedRegions_2D

в вокселах

Также в качестве отдельных функций оформлены следующие методы морфологической фильтрации сегментов:

MatMorphologyDilation – расширение;

MatMorphologyErosion – сужение;

MatMorphologyOpening – открытие;

MatMorphologyClosing – закрытие.

Каждый из перечисленных методов фильтрации принимает на вход следующие параметры:

-Data – исходные данные, включающие набор индексов 2D-сегментов для всех вокселов;

-Segments – набор, которому принадлежит рассматриваемый сегмент;

-LayerIndex – индекс слоя данных, на котором расположен 2D-сегмент;

-SegmentIndex – индекс обрабатываемого сегмента;

-ParentSegmentIndex – пара индексов, идентифицирующих родительский сегмент;

-SegmentType – тип сегмента (по плотности, по расстоянию, или по связности);

-Mask – структурный элемент (маска пикселов из окрестности, используемых для анализа);

-Iterations – количество итераций (последовательных применений фильтра к сегменту).

Для поиска соответствий между 2D-сегментами на соседних слоях по алгоритму, описанному в разделе 2.7, используется функция FindOptimalMatches(); каждое новое соответствие, порождаемое некоторым сегментом, вычисляет метод DynamicProcess, прототип которого имеет следующий вид:

DynamicProcess(int LayerIndex, int I, WHERE direction, TPath& path, vector <bool>* &IsSegmentUsed, TSegment& VirtualSegment),

где:

-LayerIndex – индекс начального слоя;

-I – индекс сегмента, являющегося началом нового соответствия;

-direction – направление развития динамического процесса (вперёд или назад);

-path – цепочка соответствий между 2D-сегментами;

-IsSegmentUsed – маска занятых и свободных для поиска сегментов;

37