Сегментация изображения. Muthukrishnan R, Radha M. — Алгоритмы выделения контуров для сегментации изображений

Вайбер на компьютер 01.08.2019
Вайбер на компьютер
1

Рассматриваются математические методы сегментации изображений стандарта Dicom. Разрабатываются математические методы сегментации изображений стандарта Dicom для задач распознавания медицинских изображений. Диагностика заболеваний зависит от квалификации исследователя и требует от него визуально проводить сегментацию, а математические методы по обработке растровых изображений являются инструментом для данной диагностики. Обработка полученных аппаратным обеспечением медицинских изображений без предварительной обработки графических данных в большинстве случаев дает неверные результаты. Выполнялись процедуры выделения контуров объектов методом Canny и дополнительными алгоритмами обработки растровых изображений. Результаты исследований позволяют вычислить необходимые для дальнейшего лечения пациента морфометрические, геометрические и гистограммные свойства образований в организме человека и обеспечить эффективное медицинское лечение. Разработанные принципы компьютерного автоматизированного анализа медицинских изображений эффективно используются для оперативных задач медицинской диагностики специализированного онкологического учреждения, так и в учебных целях.

распознавание образов

сегментация объектов интереса

медицинские изображения

1. Власов А.В., Цапко И.В. Модификация алгоритма Канни применительно к обработке рентгенографических изображений // Вестник науки Сибири. – 2013. – № 4(10). – С. 120–127.

2. Гонзалес Р., Вудс Р. Цифровая обработка изображений. – М.: Техносфера, 2006. – С. 1072.

3. Кулябичев Ю.П., Пивторацкая С.В. Структурный подход к выбору признаков в системах распознавания образов // Естественные и технические науки. – 2011. – № 4. – С. 420–423.

4. Никитин О.Р., Пасечник А.С. Оконтуривание и сегментация в задачах автоматизированной диагностики патологий // Методы и устройства передачи и обработки информации. – 2009. – № 11. – С. 300–309.

5. Canny J. A Computational approach to edge detection // IEEE Transactions on pattern analysis and machine intelligence. – 1986. – № 6. – P.679–698.

6. DICOM – Mode of access: http://iachel.ru/ zob23tai-staihroe/ DICOM

7. Doronicheva A.V., Sokolov A.A., Savin S.Z. Using Sobel operator for automatic edge detection in medical images // Journal of Mathematics and System Science. – 2014. – Vol. 4, № 4 – P. 257–260.

8. Jähne B., Scharr H., Körkel S. Principles of filter design // Handbook of Computer Vision and Applications. Academic Press. – 1999. – 584 p.

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

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

Цель исследования . Разрабатываются математические методы сегментации изображений стандарта Dicom для задач распознавания медицинских изображений. Диагностика заболеваний зависит от квалификации исследователя и требует от него визуально проводить сегментацию, а математические методы по обработке растровых изображений являются инструментом для данной диагностики. Обработка полученных аппаратным обеспечением медицинских изображений без предварительной обработки графических данных в большинстве случаев дает неверные результаты. Это связано с тем, что изначально изображения получены неудовлетворительного качества.

Материал и методы исследования

В качестве материала исследований используются компьютерные томограммы пациентов специализированного клинического учреждения. Прежде чем анализировать реальные графические данные, необходимо изображение подготовить или произвести предобработку. Этот этап решает задачу улучшения визуального качества медицинских изображений. Полезно разделить весь процесс обработки изображений на две большие категории: методы, в которых как входными данными, так и выходными являются изображения; методы, где входные данные - изображения, а в результате работы выходными данными выступают признаки и атрибуты, выявленные на базе входных данных. Этот алгоритм не предполагает, что к изображению используется каждый из вышеприведенных процессов. Регистрация данных - первый из процессов, отраженный на рис. 1.

Рис. 1. Основные стадии цифровой обработки графических данных

Регистрация может быть достаточно простой, как в примере, когда исходное изображение является цифровым. Обычно этап регистрации изображения предполагает предварительную обработку данных, к примеру, увеличение масштаба изображения. Улучшение изображения входит в число наиболее простых и впечатляющих направлений предварительной обработки. Как правило, за методами улучшения информативности изображений определена задача поиска плохо различимых пикселей или увеличения контрастности на исходном изображении . Одним из часто используемых методов улучшения информативности изображений является усиление контраста изображения, так как усиливаются границы объекта интереса. Нужно учесть, что улучшение качества изображения - это в определенной степени субъективная задача в обработке изображений. Восстановление изображений - это задача также относится к повышению визуального качества данных. Методы восстановления изображений опираются на математические и вероятностные модели деформации графических данных. Обработку изображений как этап следует отделять от понятия обработки изображения как всего процесса изменений изображения и получения некоторых данных. Сегментация или процесс выделения объектов интереса делит изображение на составляющие объекты или части. Автоматизированное выделение объектов интереса является в определенной степени сложной задачей цифровой обработки изображений. Слишком детализированная сегментация делает процесс обработки изображения затруднительным, если необходимо выделить объекты интереса. Но некорректная или недостаточно детализированная сегментация в большинстве задач приводит к ошибкам на заключительном этапе обработки изображений. Представление и описание графических данных, как правило, следуют за этапом выделения объектов интереса на изображении, на выходе которого в большинстве случаев имеются необработанные пиксели, образующие границы области или формируют все пиксели областей. При таких вариантах требуется преобразование данных в вид, доступный для компьютерного анализа. Распознавание образов является процессом, который определяет к какому-либо объекту идентификатор (например, «лучевая кость») на основании его описаний . Определим взаимосвязь базы знаний с модулями обработки изображений. База знаний (то есть информация о проблемной области) некоторым образом зашифрована внутри самой системы обработки изображений. Это знание может быть достаточно простым, как, например, детальное указание объектов изображения, где должна находиться зона интереса. Такое знание дает возможность ограничения области поиска. База знаний управляет работой каждого модуля обработки и их взаимодействием, что отражено на рис. 1 стрелками, направленными в две стороны между модулями и базой знаний. Сохранение и печать результатов часто также требует использования специальных методов обработки изображений. Недостаток этих этапов обработки изображения в системе обработки медицинских изображений заключается в том, то, что ошибки, созданные на первых этапах обработки, к примеру при вводе или выделения объектов интереса на изображении, могут привести к невозможности корректной классификации. Обработка данных производится строго последовательно, и в большинстве случаев отсутствует возможность возвращения на предыдущие этапы обработки, даже если ранее были получены некорректные результаты . Методы на этапе предварительной обработки достаточно разнообразны - выделение объектов интереса, их масштабирование, цветовая коррекция, корректировка пространственного разрешения, изменение контрастности и т.п. Одно из приоритетных действий на этапе предварительной обработки изображения - это корректировка контрастности и яркости. При использовании соответствующих масок возможно объединить два этапа (фильтрация и предварительная обработка) для увеличения скорости анализа данных. Заключительный результат анализа изображений в большинстве случаев определен уровнем качества сегментации, а степень детализации объектов интереса зависит от конкретной поставленной задачи . По этой причине не разработан отдельный метод или алгоритм, подходящий для решения всех задач выделения объектов интереса. Оконтуривание областей предназначено для выделения на изображениях объектов с заданными свойствами. Данные объекты, как правило, соответствуют объектам или их частям, которые маркируют диагносты. Итогом оконтуривания является бинарное или иерархическое (мультифазное) изображение, где каждый уровень изображения соответствует определенному классу выделенных объектов. Сегментация - это сложный этап в обработке и анализе медицинских данных биологических тканей, поскольку необходимо оконтуривать области, которые соответствуют разным объектам или структурам на гистологических уровнях: клеткам, органоидам, артефактам и т.д. Это объясняется высокой вариабельностью их параметров, низким уровнем контрастности анализируемых изображений и сложной геометрической взаимосвязью объектов. В большинстве случаях для получения максимально эффективного результата необходимо последовательно использовать разные методы сегментации объектов интереса на изображении. К примеру, для определения границ объекта интереса применяется метод морфологического градиента, после которого для областей, которые подходят незначительным перепадам характеристик яркости, проводится пороговая сегментация . Для обработки изображений, у которых несвязанные однородные участки различны по средней яркости, был выбран метод сегментации Canny, исследования проводятся на клиническом примере. При распознавании реальных клинических изображений моделирование плохо применимо. Большое значение имеет практический опыт и экспертные заключения об итоге анализа изображений. Для тестового изображения выбран снимок компьютерной томографии, где в явном виде присутствует объект интереса, представленный на рис. 2.

Рис. 2. Снимок компьютерной томографии с объектом интереса

Для реализации сегментирования используем метод Canny . Такой подход устойчив к шуму и демонстрирует в большинстве случаев лучшие результаты по отношению к другим методам. Метод Canny включает в себя четыре этапа:

1) предобработка - размытие изображения (производим уменьшение дисперсии аддитивного шума);

2) проведение дифференцирования размытого изображения и последующее вычисление значений градиента по направлениям x и y;

3) реализация не максимального подавления на изображении;

4) пороговая обработка изображения .

На первом этапе алгоритма Canny происходит сглаживание изображения с помощью маски фильтром Гаусса. Уравнение распределения Гаусса в N измерениях имеет вид

или в частном случае для двух измерений

(2)

где r - это радиус размытия, r 2 = u 2 + v 2 ; σ - стандартное отклонение распределения Гаусса.

Если используем 2 измерения, то эта формула задает поверхность концентрических окружностей, имеющих распределение Гаусса от центральной точки. Пиксели с распределением, отличным от нуля, используются для задания матрицы свертки, применяемого к исходному изображению. Значение каждого пикселя становится средневзвешенным для окрестности. Начальное значение пикселя принимает максимальный вес (имеет максимальное Гауссово значение), а соседние пиксели принимают минимальные веса, в зависимости от расстояния до них . Теоретически распределение в каждой точке изображения должно быть ненулевым, что следует расчету весовых коэффициентов для каждого пикселя изображения. Но практически при расчёте дискретного приближения функции Гаусса не учитываются пиксели на расстоянии > 3σ, поскольку оно достаточно мало. Таким образом, программе, обрабатывающей изображение, необходимо рассчитать матрицу ×, чтобы дать гарантию достаточной точности приближения распределения Гаусса .

Результаты исследования и их обсуждение

Результат работы фильтра Гаусса при данных равных 5 для размера маски гаусса и 1,9 значении параметра σ - стандартного отклонения распределения Гаусса, представлен на рис. 3. Следующим шагом осуществляется поиск градиента области интереса при помощи свертки сглаженного изображения с производной от функции Гаусса в вертикальном и горизонтальном направлениях вектора.

Применим оператор Собеля для решения данной задачи . Процесс базируется на простом перемещении маски фильтра от пикселя к пикселю изображения. В каждом пикселе (x, y) отклик фильтра вычисляется с предварительно определённых связей. В результате происходит первоначальное выделение краев. Следующим шагом происходит сравнение каждого пикселя с его соседями вдоль направления градиента и вычисляется локальный максимум. Информация о направлении градиента необходима для того, чтобы удалять пиксели рядом с границей, не разрывая саму границу вблизи локальных максимумов градиента, которое значит, что пикселями границ определяются точки, в которых достигается локальный максимум градиента в направлении вектора градиента. Такой подход позволяет существенно снизить обнаружение ложных краев и обеспечивает толщину границы объекта в один пиксель, что эмпирически подтверждается программной реализацией алгоритма сегментирования среза брюшной полости на снимке компьютерной томографии, представленного ниже на рис. 4.

Следующий шаг - использование порога, для определения нахождения границы в каждом заданном пикселе изображения. Чем меньше порог, тем больше границ будет находиться в объекте интереса, но тем более результат будет восприимчив к шуму, и оконтуривать лишние данные изображения. Высокий порог может проигнорировать слабые края области или получит границу несколькими областями. Оконтуривание границ применяет два порога фильтрации: если значение пикселя выше верхней границы - он принимает максимальное значение (граница считается достоверной), если ниже - пиксель подавляется, точки со значением, попадающим в диапазон между порогов, принимают фиксированное среднее значение. Пиксель присоединяется к группе, если он соприкасается с ней по одному из восьми направлений. Среди достоинств метода Canny можно считать то, что при обработке изображения осуществляется адаптация к особенностям сегментирования. Это достигается через ввод двухуровневого порога отсечения избыточных данных. Определяются два уровня порога, верхний - p high и нижний - p low , где p high > p low . Значения пикселей выше значения p high обозначаются как соответствующие границе (рис. 5).

Рис. 3. Применение фильтра Гаусса на компьютерной томограмме с объектом интереса

Рис. 4. Подавления не-максимумов на сегментируемом изображении

Рис. 5. Применение алгоритма сегментации Canny c разными значениями уровней порога

Практика показывает, что имеется некоторый интервал на шкале уровней порога чувствительности, при котором значение площади объекта интереса фактически неизменимое, но при этом существует определенный пороговый уровень, после которого отмечается «срыв» метода оконтуривания и итог выделения областей интереса становится неопределенным . Этот недостаток алгоритма, который можно компенсировать объединением алгоритма Canny с преобразованием Хафа для поиска окружностей. Сочетание алгоритмов позволяет максимально четко выделять объекты исследования, а также устранять разрывы в контурах .

Выводы

Таким образом, решена задача формулирования типовых характеристик патологических объектов на медицинских изображениях, что даст возможность в дальнейшем проводить оперативный анализ данных по конкретным патологиям. Важными параметрами для определения оценки качества сегментации являются вероятности ложной тревоги и пропуска - отказа. Эти параметры определяют применение автоматизации метода анализа. Сегментация при решении задачи классификации и распознавания объектов на изображениях является одной из первостепенных. Достаточно хорошо исследованы и применяются методы оконтуривания, базирующиея на сегментировании границ областей - Sobel, Canny, Prewit, Laplassian. Такой подход определен тем, что концентрация внимания человека при анализе изображений фокусируется зачастую на границах между более или менее однородными по яркости зонами. Исходя из этого, контуры часто выполняют задачу основы определения различных характеристик для интерпретирования изображений и объектов на них. Основная задача алгоритмов сегментирования зон интересов - это построение бинарного изображения, которое содержит замкнутые структурные области данных на изображении. Относительно к медицинским изображениям данными областями выступают границы органов, вены, МКЦ, а также опухоли. Разработанные принципы компьютерного автоматизированного анализа медицинских изображений эффективно используются как для оперативных задач медицинской диагностики специализированного онкологического учреждения, так и в учебных целях.

Исследовано при поддержке программы «Дальний Восток», грант № 15-I-4-014o.

Рецензенты:

Косых Н.Э., д.м.н., профессор, главный научный сотрудник, ФГБУН «Вычислительный центр» ДВО РАН, г. Хабаровск;

Левкова Е.А., д.м.н., профессор, ГОУ ВПО «Дальневосточный государственный университет путей сообщения», г. Хабаровск.

Библиографическая ссылка

Дороничева А.В., Савин С.З. МЕТОД СЕГМЕНТАЦИИ МЕДИЦИНСКИХ ИЗОБРАЖЕНИЙ // Фундаментальные исследования. – 2015. – № 5-2. – С. 294-298;
URL: http://fundamental-research.ru/ru/article/view?id=38210 (дата обращения: 06.04.2019). Предлагаем вашему вниманию журналы, издающиеся в издательстве «Академия Естествознания» Одной из основных задач обработки и анализа изображений является сегментация, т.е. разделение изображения на области, для которых выполняется определенный критерий однородности, например, выделение на изображении областей приблизительно одинаковой яркости. Понятие области изображения используется для определения связной группы элементов изображения, имеющих определенный общий признак (свойство).
Один из основных и простых способов - это построение сегментации с помощью порога. Порог - это признак (свойство), которое помогает разделить искомый сигнал на классы. Операция порогового разделения заключается в сопоставлении значения яркости каждого пикселя изображения с заданным значением порога.
Бинаризация

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

Пороговая обработка изображения может проводиться разными способами.

Бинаризация с нижним порогом
Бинаризация с нижним порогом
Бинаризация с нижним порогом является наиболее простой операцией, в которой используется только одно значение порога:

Все значения вместо критерия становятся 1, в данном случае 255 (белый) и все значения(амплитуды) пикселей, которые больше порога t - 0 (черный).

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

Бинаризация с двойным ограничением
Для выделения областей, в которых значения яркости пикселей может меняться в известном диапазоне, вводится бинаризация с двойным ограничением (t 1
Так же возможны другие вариации с порогами, где пропускается только часть данных (средне полосовой фильтр).

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

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

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

Локальная пороговая обработка
Метод Отса
Метод использует гистограмму распределения значений яркости пикселей растрового изображения. Строится гистограмма по значениям p i =n i /N, где N – это общее кол-во пикселей на изображении, n i – это кол-во пикселей с уровнем яркости i. Диапазон яркостей делится на два класса с помощью порогового значения уровня яркости k,k - целое значение от 0 до L. Каждому классу соответствуют относительные частоты ω 0 ω 1:

Средние уровни для каждого из двух классов изображения:
Далее вычисляется максимальное значение оценки качества разделения изображения на две части:
где (σ кл)2=ω 0 ω 1 (μ 1 -μ 0) 2 , – межклассовая дисперсия, а (σ общ) 2 – это общая дисперсия для всего изображения целиком.

Определение порога на основе градиента яркости изображения
Предположим, что анализируемое изображение можно разделить на два класса – объекты и фон. Алгоритм вычисления порогового значения состоит из следующих 2 шагов:
1. Определяется модуль градиента яркости для каждого пикселя
изображения

2. Вычисление порога:
Итого
Что нашел с радостью выложил вам, в дальнейшем, если получится и будет время, постараюсь реализовать часть алгоритмов. Это лишь малая часть всего, что сегодня существует, но я рад поделится и этим.
Спасибо за внимание.

Этим летом мне посчастливилось попасть на летнюю стажировку в компанию Itseez . Мне было предложено исследовать современные методы, которые позволили бы выделить местоположения объектов на изображении. В основном такие методы опираются на сегментацию, поэтому я начала свою работу со знакомства с этой областью компьютерного зрения.
Сегментация изображения - это разбиение изображения на множество покрывающих его областей. Сегментация применяется во многих областях, например, в производстве для индикации дефектов при сборке деталей, в медицине для первичной обработки снимков, также для составления карт местности по снимкам со спутников. Для тех, кому интересно разобраться, как работают такие алгоритмы, добро пожаловать под кат. Мы рассмотрим несколько методов из библиотеки компьютерного зрения OpenCV .

Алгоритм сегментации по водоразделам (WaterShed)


Алгоритм работает с изображением как с функцией от двух переменных f=I(x,y) , где x,y – координаты пикселя:


Значением функции может быть интенсивность или модуль градиента. Для наибольшего контраста можно взять градиент от изображения. Если по оси OZ откладывать абсолютное значение градиента, то в местах перепада интенсивности образуются хребты, а в однородных регионах – равнины. После нахождения минимумов функции f , идет процесс заполнения “водой”, который начинается с глобального минимума. Как только уровень воды достигает значения очередного локального минимума, начинается его заполнение водой. Когда два региона начинают сливаться, строится перегородка, чтобы предотвратить объединение областей . Вода продолжит подниматься до тех пор, пока регионы не будут отделяться только искусственно построенными перегородками (рис.1).




Рис.1. Иллюстрация процесса заполнения водой

Такой алгоритм может быть полезным, если на изображении небольшое число локальных минимумов, в случае же их большого количества возникает избыточное разбиение на сегменты. Например, если непосредственно применить алгоритм к рис. 2, получим много мелких деталей рис. 3.


Рис. 2. Исходное изображение


Рис. 3. Изображение после сегментации алгоритмом WaterShed

Как справиться с мелкими деталями?

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


Рис. 4. Изображение с маркерами


Рис. 5. Изображение после сегментации алгоритмом WaterShed с использованием маркеров

Если требуется действовать автоматически без вмешательства пользователя, то можно использовать, например, функцию findContours() для выделения маркеров, но тут тоже для лучшей сегментации мелкие контуры следует исключить рис. 6., например, убирая их по порогу по длине контура. Или перед выделением контуров использовать эрозию с дилатацией, чтобы убрать мелкие детали.


Рис. 6. В качестве маркеров использовались контуры, имеющие длину выше определенного порога


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

Mat image = imread("coins.jpg", CV_LOAD_IMAGE_COLOR); // выделим контуры Mat imageGray, imageBin; cvtColor(image, imageGray, CV_BGR2GRAY); threshold(imageGray, imageBin, 100, 255, THRESH_BINARY); std::vector > contours; std::vector hierarchy; findContours(imageBin, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); Mat markers(image.size(), CV_32SC1); markers = Scalar::all(0); int compCount = 0; for(int idx = 0; idx >= 0; idx = hierarchy, compCount++) { drawContours(markers, contours, idx, Scalar::all(compCount+1), -1, 8, hierarchy, INT_MAX); } std::vector colorTab(compCount); for(int i = 0; i < compCount; i++) { colorTab[i] = Vec3b(rand()&255, rand()&255, rand()&255); } watershed(image, markers); Mat wshed(markers.size(), CV_8UC3); for(int i = 0; i < markers.rows; i++) { for(int j = 0; j < markers.cols; j++) { int index = markers.at(i, j); if(index == -1) wshed.at(i, j) = Vec3b(0, 0, 0); else if (index == 0) wshed.at(i, j) = Vec3b(255, 255, 255); else wshed.at(i, j) = colorTab; } } imshow("watershed transform", wshed); waitKey(0);

Алгоритм сегментации MeanShift

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


Например, в качестве координат в пространстве признаков можно выбрать координаты пикселя (x, y) и компоненты RGB пикселя. Изобразив пиксели в пространстве признаков, можно заметить сгущения в определенных местах.

Рис. 7. (a) Пиксели в двухмерном пространстве признаков. (b) Пиксели, пришедшие в один локальный максимум, окрашены в один цвет. (с) - функция плотности, максимумы соответствуют местам наибольшей концентрации пикселей. Рисунок взят из статьи .

Чтобы легче было описывать сгущения точек, вводится функция плотности :
– вектор признаков i -ого пикселя, d - количество признаков, N - число пикселей, h - параметр, отвечающий за гладкость, - ядро. Максимумы функции расположены в точках сгущения пикселей изображения в пространстве признаков. Пиксели, принадлежащие одному локальному максимуму, объединяются в один сегмент. Получается, чтобы найти к какому из центров сгущения относится пиксель, надо шагать по градиенту для нахождения ближайшего локального максимума.

Оценка градиента от функции плотности

Для оценки градиента функции плотности можно использовать вектор среднего сдвига
В качестве ядра в OpenCV используется ядро Епанечникова :


- это объем d -мерной сферы c единичным радиусом.


означает, что сумма идет не по всем пикселям, а только по тем, которые попали в сферу радиусом h с центром в точке, куда указывает вектор в пространстве признаков . Это вводится специально, чтобы уменьшить количество вычислений. - объем d -мерной сферы с радиусом h, Можно отдельно задавать радиус для пространственных координат и отдельно радиус в пространстве цветов. - число пикселей, попавших в сферу. Величину можно рассматривать как оценку значения в области .


Поэтому, чтобы шагать по градиенту, достаточно вычислить значение - вектора среднего сдвига. Следует помнить, что при выборе другого ядра вектор среднего сдвига будет выглядеть иначе.


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

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

Пример кода для запуска алгоритма:

Mat image = imread("strawberry.jpg", CV_LOAD_IMAGE_COLOR); Mat imageSegment; int spatialRadius = 35; int colorRadius = 60; int pyramidLevels = 3; pyrMeanShiftFiltering(image, imageSegment, spatialRadius, colorRadius, pyramidLevels); imshow("MeanShift", imageSegment); waitKey(0);
Результат:


Рис. 8. Исходное изображение


Рис. 9. После сегментации алгоритмом MeanShift

Алгоритм сегментации FloodFill

С помощью FloodFill (заливка или метод «наводнения») можно выделить однородные по цвету регионы. Для этого нужно выбрать начальный пиксель и задать интервал изменения цвета соседних пикселей относительно исходного. Интервал может быть и несимметричным. Алгоритм будет объединять пиксели в один сегмент (заливая их одним цветом), если они попадают в указанный диапазон. На выходе будет сегмент, залитый определенным цветом, и его площадь в пикселях.

Такой алгоритм может быть полезен для заливки области со слабыми перепадами цвета однородным фоном. Одним из вариантов использования FloodFill может быть выявление поврежденных краев объекта. Например, если, заливая однородные области определенным цветом, алгоритм заполнит и соседние регионы, то значит нарушена целостность границы между этими областями. Ниже на изображении можно заметить, что целостность границ заливаемых областей сохраняется:

Рис. 10, 11. Исходное изображение и результат после заливки нескольких областей

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


Рис. 12, 13. Иллюстрация работы FloodFill при нарушение целостности границы между заливаемыми областями

Пример кода для запуска алгоритма:

Mat image = imread("cherry.jpg", CV_LOAD_IMAGE_COLOR); Point startPoint; startPoint.x = image.cols / 2; startPoint.y = image.rows / 2; Scalar loDiff(20, 20, 255); Scalar upDiff(5, 5, 255); Scalar fillColor(0, 0, 255); int neighbors = 8; Rect domain; int area = floodFill(image, startPoint, fillColor, &domain, loDiff, upDiff, neighbors); rectangle(image, domain, Scalar(255, 0, 0)); imshow("floodFill segmentation", image); waitKey(0);
В переменную area запишется количество “залитых" пикселей.
Результат:


Алгоритм сегментации GrabCut

Это интерактивный алгоритм выделения объекта, разрабатывался как более удобная альтернатива магнитному лассо (чтобы выделить объект, пользователю требовалось обвести его контур с помощью мыши). Для работы алгоритма достаточно заключить объект вместе с частью фона в прямоугольник (grab). Сегментирование объекта произойдет автоматически (cut).


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


Рассмотрим идею алгоритма. За основу взят алгоритм интерактивной сегментации GraphCut, где пользователю надо поставить маркеры на фон и на объект. Изображение рассматривается как массив . Z - значения интенсивности пикселей, N -общее число пикселей. Для отделения объекта от фона алгоритм определяет значения элементов массива прозрачности , причем может принимать два значения, если = 0 , значит пиксель принадлежит фону, если= 1 , то объекту. Внутренний параметр содержит гистограмму распределения интенсивности переднего плана и гистограмму фона:
.
Задача сегментации - найти неизвестные . Рассматривается функция энергии:

Причем минимум энергии соответствует наилучшей сегментации.


V (a, z) - слагаемое отвечает за связь между пикселями. Сумма идет по всем парам пикселей, которые являются соседями, dis(m,n) - евклидово расстояние. отвечает за участие пар пикселей в сумме, если a n = a m , то эта пара не будет учитываться.
- отвечает за качество сегментации, т.е. разделение объекта от фона.

Найдя глобальный минимум функции энергии E , получим массив прозрачности . Для минимизации функции энергии, изображение описывается как граф и ищется минимальный разрез графа. В отличие от GraphCut в алгоритме GrabCut пиксели рассматриваются в RGB пространстве, поэтому для описания цветовой статистики используют смесь гауссиан (Gaussian Mixture Model - GMM). Работу алгоритма GrabCut можно посмотреть, запустив сэмпл OpenCV

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

В этом случае изображение обрабатывается по пикселям и преобразование каждого пикселя входного изображения в выходное определяется из соотношения:

где - параметр обработки, называемый порогом, и - уровни выходной яркости. Обработка по пикселям, положение которых на изображении не играет никакой роли, называется точечной . Уровни и играют роль меток. По ним определяют, к какому типу отнести данную точку: к H0 или к H1. Или говорят, что H0 состоит из фоновых точек, а H1 из точек интереса . Как правило, уровни и соответствуют уровням белого и черного. Будем называть классы H1 (он же класс интереса) классом объекта, а класс H0 классом фона.

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

где - количество уровней, а - классы изображения. В таком случае для каждого из классов должен быть задан соответствующий порог, который бы отделял эти классы между собой. Бинарные изображения легче хранить и обрабатывать, чем изображения, в которых имеется много уровней яркости .

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

где - изображение, а - некоторая характеристика точки изображения, например, средняя яркость в окрестности с центром в этой точке.

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

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

Сегментация изображений с U-Net на практике

Введение

В этом блог посте мы посмотрим как Unet работает, как реализовать его, и какие данные нужны для его обучения. Для этого мы будем рассматривать:

  1. как источник для вдохновения.
  2. Pytorch как инструмент для реализации нашей задумки.
  3. Kaggle соревнования как место где мы можем опробовать наши гипотезы на реальных данных.

Мы не будем следовать на 100% за статьей, но мы постараемся реализовать ее суть, адаптировать под наши нужды.

Презентация проблемы

В этой задаче нам дано изображение машины и его бинарная маска(локализующая положение машины на изображении). Мы хотим создать модель, которая будет будет способна отделять изображение машины от фона с попиксельной точностью более 99%.

Для понимания того что мы хотим, gif изображение ниже:

Изображение слева - это исходное изображение, справа - маска, которая будет применяться на изображение. Мы будем использовать Unet нейронную сеть, которая будет учиться автоматически создавать маску.

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

Структура кода

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

Код

Мы будем итеративно проходить через код в main.py и через статью. Не волнуйтесь о деталях, спрятанных в других файлах проекта: нужные мы продемонстрируем по мере необходимости.

Давайте начнем с начала :

def main (): # Hyperparameters input_img_resize = (572 , 572 ) # The resize size of the input images of the neural net output_img_resize = (388 , 388 ) # The resize size of the output images of the neural net batch_size = 3 epochs = 50 threshold = 0. 5 validation_size = 0. 2 sample_size = None # -- Optional parameters threads = cpu_count() use_cuda = torch.cuda.is_available() script_dir = os.path.dirname(os.path.abspath(__file__ )) # Training callbacks tb_viz_cb = TensorboardVisualizerCallback(os.path.join(script_dir,"../logs/tb_viz" )) tb_logs_cb = TensorboardLoggerCallback(os.path.join(script_dir,"../logs/tb_logs" )) model_saver_cb = ModelSaverCallback(os.path.join(script_dir,"../output/models/model_" + helpers.get_model_timestamp()), verbose= True )

В первом разделе вы определяете свои гиперпараметры, их можете настроить по своему усмотрению, например в зависимости от вашей памяти GPU. Optimal parametes определяют некоторые полезные параметры и callbacks . TensorboardVisualizerCallback - это класс, который будет сохранять предсказания в tensorboard в каждую эпоху тренировочного процесса, TensorboardLoggerCallback сохранит значения функций потерь и попиксельную «точность» в tensorboard . И наконец ModelSaverCallback сохранит вашу модель после завершения обучения.

# Download the datasets ds_fetcher = DatasetFetcher () ds_fetcher. download_dataset()

Этот раздел автоматически загружает и извлекает набор данных из Kaggle. Обратите внимание, что для успешной работы этого участка кода вам необходимо иметь учетную запись Kaggle с логином и паролем, которые должны быть помещены в переменные окружения KAGGLE_USER и KAGGLE_PASSWD перед запуском скрипта. Также требуется принять правила конкурса, перед загрузкой данных. Это можно сделать на вкладке загрузки данных конкурса

# Get the path to the files for the neural net X_train, y_train, X_valid, y_valid = ds_fetcher.get_train_files(sample_size= sample_size, validation_size= validation_size) full_x_test = ds_fetcher.get_test_files(sample_size) # Testing callbacks pred_saver_cb = PredictionsSaverCallback(os.path.join (script_dir,"../output/submit.csv.gz" ), origin_img_size, threshold)

Эта строка определяет callback функцию для теста (или предсказания). Она будет сохранять предсказания в файле gzip каждый раз, когда будет произведена новая партия предсказания. Таким образом, предсказания не будут сохранятся в памяти, так как они очень большие по размеру.

После окончания процесса предсказания вы можете отправить полученный файл submit.csv.gz из выходной папки в Kaggle.

# -- Define our neural net architecture # The original paper has 1 input channel, in our case we have 3 (RGB ) net = unet_origin. UNetOriginal ((3 , *img_resize)) classifier = nn. classifier. CarvanaClassifier (net, epochs) optimizer = optim. SGD (net. parameters() , lr= 0.01 , momentum= 0.99 ) train_ds = TrainImageDataset (X_train , y_train, input_img_resize, output_img_resize, X_transform = aug. augment_img) train_loader = DataLoader (train_ds, batch_size, sampler= RandomSampler (train_ds), num_workers= threads, pin_memory= use_cuda) valid_ds = TrainImageDataset (X_valid , y_valid, input_img_resize, output_img_resize, threshold= threshold) valid_loader = DataLoader (valid_ds, batch_size, sampler= SequentialSampler (valid_ds), num_workers= threads, pin_memory= use_cuda)

print ("Training on {} samples and validating on {} samples " . format(len(train_loader. dataset), len(valid_loader. dataset))) # Train the classifier classifier. train(train_loader, valid_loader, epochs, callbacks= )

test_ds = TestImageDataset (full_x_test, img_resize) test_loader = DataLoader (test_ds, batch_size, sampler= SequentialSampler (test_ds), num_workers= threads, pin_memory= use_cuda) # Predict & save classifier. predict(test_loader, callbacks= ) pred_saver_cb. close_saver()

Наконец, мы делаем то же самое, что и выше, но для прогона предсказания. Мы вызываем наш pred_saver_cb.close_saver() , чтобы очистить и закрыть файл, который содержит предсказания.

Реализация архитектуры нейронной сети

Статья Unet представляет подход для сегментации медицинских изображений. Однако оказывается этот подход также можно использовать и для других задач сегментации. В том числе и для той, над которой мы сейчас будем работать.

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

Задача оригинальной статьи отличается от нашей, нам нужно будет адаптировать некоторые части соответственно нашим потребностям.

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

  1. BatchNorm.
  2. Мощные GPU.

Первое был изобретено всего за 3 месяца до Unet , и вероятно слишком рано, чтобы авторы Unet добавили его в свою статью.

На сегодняшний день BatchNorm используется практически везде. Вы можете избавиться от него в коде, если хотите оценить статью на 100%, но вы можете не дожить до момента, когда сеть сойдется.

Что касается графических процессоров, в статье говорится:

To minimize the overhead and make maximum use of the GPU memory, we favor large input tiles over a large batch size and hence reduce the batch to a single image

Они использовали GPU с 6 ГБ RAM, но в настоящее время у GPU больше памяти, для размещения изображений в одном batch’e. Текущий batch равный трем, работает для графического процессора в GPU с 8 гб RAM. Если у вас нет такой видеокарты, попробуйте уменьшить batch до 2 или 1.

Что касается методов augmentations (то есть искажения исходного изображения по какому либо паттерну), рассматриваемых в статье, мы будем использовать отличные от описываемых в статье, поскольку наши изображения сильно отличаются от биомедицинских изображений.

Теперь давайте начнем с самого начала, проектируя архитектуру нейронной сети:

Вот как выглядит Unet. Вы можете найти эквивалентную реализацию Pytorch в модуле nn.unet_origin.py.

Все классы в этом файле имеют как минимум 2 метода:

  • __init__() где мы будем инициализировать наши уровни нейронной сети;
  • forward() который является методом, называемым, когда нейронная сеть получает вход.

Давайте рассмотрим детали реализации:

  • ConvBnRelu - это блок, содержащий операции Conv2D, BatchNorm и Relu. Вместо того, чтобы набирать их 3 для каждого стека кодировщика (группа операций вниз) и стеков декодера (группа операций вверх), мы группируем их в этот объект и повторно используем его по мере необходимости.
  • StackEncoder инкапсулирует весь «стек» операций вниз, включая операции ConvBnRelu и MaxPool , как показано ниже:



Мы отслеживаем вывод последней операции ConvBnRelu в x_trace и возвращаем ее, потому что мы будем конкатенировать этот вывод с помощью стеков декодера.

  • StackDecoder - это то же самое, что и StackEncoder, но для операций декодирования, окруженных ниже красным:



Обратите внимание, что он учитывает операцию обрезки / конкатенации (окруженную оранжевым), передавая в down_tensor, который является не чем иным, как тензором x_trace, возвращаемым нашим StackEncoder .

  • UNetOriginal - это место, где происходит волшебство. Это наша нейронная сеть, которая будет собирать все маленькие кирпичики, представленные выше. Методы init и forward действительно сложны, они добавляют кучу StackEncoder , центральной части и под конец несколько StackDecoder . Затем мы получаем вывод StackDecoder , добавляем к нему свертку 1x1 в соответствии со статьей, но вместо того, чтобы определять два фильтра в качестве вывода, мы определяем только 1, который фактически будет нашим прогнозом маски в оттенках серого. Далее мы «сжимаем» наш вывод, чтобы удалить размер канала (всего 1, поэтому нам не нужно его хранить).

Если вы хотите понять больше деталей каждого блока, поместите контрольную точку отладки в метод forward каждого класса, чтобы подробно просмотреть объекты. Вы также можете распечатать форму ваших тензоров вывода между слоями, выполнив печать (x.size() ).

Тренировка нейронной сети

  1. Функция потерь

Теперь к реальному миру. Согласно статье:

The energy function is computed by a pixel-wise soft-max over the final feature map combined with the cross-entropy loss function.

Дело в том, что в нашем случае мы хотим использовать dice coefficient как функцию потерь вместо того, что они называют «энергетической функцией», так как это показатель, используемый в соревновании Kaggle , который определяется:

X является нашим предсказанием и Y - правильно размеченной маской на текущем объекте. |X| означает мощность множества X (количество элементов в этом множестве) и ∩ для пересечения между X и Y .

Код для dice coefficient можно найти в nn.losses.SoftDiceLoss .

class SoftDiceLoss (nn.Module): def __init__(self, weight= None, size_average= True): super (SoftDiceLoss, self).__init__() def forward(self, logits, targets): smooth = 1 num = targets.size (0 ) probs = F.sigmoid(logits) m1 = probs.view(num, - 1 ) m2 = targets.view(num, - 1 ) intersection = (m1 * m2) score = 2 . * (intersection.sum(1 ) + smooth) / (m1.sum(1 ) + m2.sum(1 ) + smooth) score = 1 - score.sum() / num return score

Причина, по которой пересечение реализуется как умножение, и мощность в виде sum() по axis 1 (сумма из трех каналов) заключается в том, что предсказания и цель являются one-hot encoded векторами.

Например, предположим, что предсказание на пикселе (0, 0) равно 0,567, а цель равна 1, получаем 0,567 * 1 = 0,567. Если цель равна 0, мы получаем 0 в этой позиции пикселя.

Мы также использовали плавный коэффициент 1 для обратного распространения. Если предсказание является жестким порогом, равным 0 и 1, трудно обратно распространять dice loss .

Затем мы сравним dice loss с кросс-энтропией, чтобы получить нашу функцию полной потери, которую вы можете найти в методе _criterion из nn.Classifier.CarvanaClassifier . Согласно оригинальной статье они также используют weight map в функции потери кросс-энтропии, чтобы придать некоторым пикселям большее ошибки во время тренировки. В нашем случае нам не нужна такая вещь, поэтому мы просто используем кросс-энтропию без какого-либо weight map.

2. Оптимизатор

Поскольку мы имеем дело не с биомедицинскими изображениями, мы будем использовать наши собственные augmentations . Код можно найти в img.augmentation.augment_img . Там мы выполняем случайное смещение, поворот, переворот и масштабирование.

Тренировка нейронной сети

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

Для этого вам нужно запустить Tensorboard в папке logs с помощью команды:

Tensorboard --logdir=./logs

Пример того, что вы сможете увидеть в Tensorboard после эпохи 1:



Рекомендуем почитать

Наверх