Библиотека сайта rus-linux.net
ITK
Глава 9 из книги "Архитектура приложений с открытым исходным кодом", том 2.Оригинал: ITK
Авторы: Luis Ibanez, Brad King
Перевод: А.Панин
Фабрики
Одним из фундаментальных требований, предъявляемых во время проектирования к ITK, является возможность поддержки множества платформ. Это требование основывается на желании максимально расширить распространение тулкита путем реализации возможности его использования сообществом вне зависимости от предпочтительных платформ участников. В рамках проекта ITK был реализован шаблон проектирования фабрики (Factory design pattern) для решения задачи по поддержке фундаментальных различий множества аппаратных и программных платформ без ущерба совместимости решения с каждой из платформ.
Шаблон проектирования фабрик в ITK использует имена классов в качестве ключей для реестра конструкторов классов. Регистрация фабрик происходит в процессе работы приложения и может быть осуществлена путем простого размещения динамических библиотек в соответствующих директориях, где приложения на основе ITK производят их поиск при запуск. Эта возможность позволяет использовать существующий механизм для реализации модульной архитектуры очевидным и прозрачным образом. В результате упрощается процесс разработки расширяемых приложений для анализа изображений, удовлетворяющих требованиям предоставления постоянно расширяющегося набора функций анализа изображений.
Фабрики ввода/вывода
Механизм фабрик особенно важен при осуществлении операций ввода/вывода.
Обработка различий систем с помощью фасадовСообщество, занимающееся исследованием изображений, разработало очень большой набор форматов файлов для сохранения данных изображений. Многие из этих форматов проектировались и разрабатывались для специфических нужд и, следовательно, хорошо оптимизированы для хранения специфических типов изображений. В результате в сообществе постоянно разрабатываются и рекомендуются для использования новые форматы файлов изображений. Предсказывая эту ситуацию, команда разработчиков ITK спроектировала подходящую для простого расширения функций архитектуру ввода/вывода, в рамках которой достаточно просто регулярно добавлять поддержку все большего и большего набора форматов файлов.
Рисунок 9.8: Зависимости фабрик ввода/вывода
ImageIOFactory
, изображенным в верхнем левом углу Рисунка 9.8. Сами функции чтения и записи данных для различных форматов файлов изображений реализованы в рамках семейства классов ImageIO
, изображенного справа на Рисунке 9.8. Эти служебные классы предназначены для создания экземпляров по требованию в тот момент, когда пользователь осуществляет чтение или запись изображения. Эти служебные классы не раскрываются в рамках кода приложений. Вместо прямого обращения к этим классам приложения должны взаимодействовать с классами фасадов:
ImageFileReader
ImageFileWriter
reader->SetFileName("../image1.png"); reader->Update();
writer->SetFileName("../image2.jpg"); writer->Update();
В обоих случаях вызов метода Update()
приводит к запуску конвейера, с которым соединены рассматриваемые объекты ProcessObject
. И объект чтения, и объект записи данных ведут себя как дополнительный фильтр конвейера. В случае объекта для чтения данных вызов метода Update()
приводит к чтению соответствующего файла изображения и размещению данных в памяти. В случае объекта записи вызов метода Update()
приводит к выполнению операций конвейера, в результате чего объект записи получает входные данные, и, наконец, завершается записью изображения на диск в файл определенного формата.
std::string filename = this->GetFileNameFromGUI(); writer->SetFileName( filename ); writer->Update();
filename
будет представлено одной из следующих строк:
- image1.png
- image1.jpeg
- image1.tiff
- image1.dcm
- image1.mha
- image1.nii
- image1.nii.gz
причем расширения файлов указывают на различные форматы файлов в каждом случае.
Знайте тип пикселя
typedef itk::Image< signed short, 3 > MRImageType; typedef itk::ImageFileWriter< MRImageType > MRIWriterType; MRIWriterType::Pointer writer = MRIWriterType::New(); writer->Update();
Однако, существует ограничение того, насколько особенности форматов файлов изображений могут быть скрыты от разработчика приложений. Например, при чтении изображений из файлов форматов DICOM или RAW разработчику придется использовать дополнительные вызовы для точного указания характеристик имеющегося формата. Файлы формата DICOM наиболее часто встречаются в медицинских учреждениях, а файлы формата RAW все еще являются необходимым злом, предназначенным для обмена данными в процессе исследований.
Объединенные, но разделенные
Автономный характер каждой фабрики ввода/вывода и служебный класс ImageIO также были затронуты процессом разделения на модули. Обычно класс ImageIO зависит от специализированной библиотеки, предназначенной для работы со специфическим форматом файлов. Такими форматами, например, являются PNG, JPEG, TIFF и DICOM. В этих случаях сторонняя библиотека рассматривается как независимый модуль и специализированный код класса ImageIO, являющийся интерфейсом между кодом ITK и кодом сторонней библиотеки, также размещается в модуле. Таким образом, специфические приложения могут могут ограничить использование множества форматов файлов, которые не входят в сферу их применения и работать только с теми форматами файлов, которые окажутся полезными в ожидаемых сценариях применения данного приложения.
Как и в случае со стандартными фабриками, загрузка фабрик ввода/вывода может быть осуществлена в процессе работы приложения из динамических библиотек. Этот гибкий процесс загрузки фабрик упрощает использование специализированных самостоятельно разработанных форматов фалов без необходимости включения поддержки таких форматов файлов непосредственно в состав тулкита ITK. Загружаемые фабрики ввода/вывода были одним из наиболее успешных архитектурных решений проекта ITK. Они позволили достаточно просто разрешить сложную ситуацию без усложнения или запутывания кода. Не так давно подобная архитектура ввода/вывода была реализована для управления процессом чтения и записи файлов, содержащих пространственные преобразования в рамках семейства классов Transform
.
Продолжение статьи: Потоковая передача данных