44172

Разработка программных средств оцифровки электрокардиограмм

Дипломная

Информатика, кибернетика и программирование

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

Русский

2015-01-19

6.19 MB

30 чел.

Разработка программных средств оцифровки электрокардиограмм


Оглавление

Введение 3

1. Постановка задачи 5

2. Необходимые сведения об электрокардиограммах 7

        2.1. Проводящая система сердца 7

        2. 2. Теоретические основы ЭКГ 8

        2.3. Отведения на ЭКГ 9

        2.4. Сведения о кривой ЭКГ 11

3. Реализация приложения 14

      3.1. Устранение дефектов сканирования 15

      3.2. Выделение графика ЭКГ и сетки 19

      3.3. Первичная обработка 23

      3.4. Обработка последующих изображений 26

      3. 5. Выделение ROI 28

      3.6. Анализ графика ЭКГ 30

Заключение 48

Приложение 49

Литература 53


Ямковой Д.А., бакалаврская работа: РАЗРАБОТКА ПРОГРАММНЫХ СРЕДСТВ ОЦИФРОВКИ ЭЛЕКТРОКАРДИОГРАММ стр.53, рис. 19, библ. 11 назв., приложений 1.

Ключевые слова: ЭЛЕКТРОКАРДИОГРАММА, ЭКГ, РАСПОЗНАВАНИЕ КРИВОЙ НА ОТСКАНИРОВАННОЙ ЛЕНТЕ ЭКГ, АНАЛИЗ КРИВОЙ ЭКГ, АВТОМАТИЧЕСКАЯ РАСШИФРОВКА ЭКГ.

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

Новизна данной программы заключается, прежде всего, в том, что она позволяет работать со сделанными на бумаге ЭКГ.


Введение

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

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

Запись электрической активности сердца проводится с помощью электрокардиографа и обычно записывается на бумаге. Но развитие современных технологий привело к тому, что появились полностью электронные приборы позволяющие сохранять ЭКГ на цифровом носителе. Однако в России такие технологии введены далеко не везде. И даже там, где они введены, остается проблема, что делать с множеством, сделанных на бумаге, ЭКГ. Приложение, с помощью которого можно было бы оцифровать большое количество скопившихся бумажных ЭКГ, выделить из них график кривой ЭКГ, и в дальнейшем хранить эти оцифрованные данные, создав электронную историю болезни, в которую могут передаваться все данные о проведенных и проводимых записях ЭКГ, помогло бы привести все эти записи к единому стандарту (а именно, к цифровому, на данный же момент, после введения полностью электронной кардиографии часть записей по некоторым пациентам хранится в бумажном виде, а часть в цифровом), значительно упростило бы труд и повысило бы эффективность работы врачей кардиологов. Также, если бы данное приложение проводило бы еще и первичную обработку ЭКГ, то таким образом можно было бы сэкономить часть времени врача кардиолога и исключить ошибки анализа происходящие из-за человеческого фактора. Именно созданию такого приложения посвящена данная дипломная работа.

Стоит отметить, что подобные приложения разрабатываются (или уже разработаны, хотя в России кроме презентаций никакой информации о работающем приложении или хотя бы видеоролика с записью работы такового приложения найти не удалось) как за границей, так и в России. Новизна данной дипломной работы заключается, прежде всего, в том, что с помощью написанного приложения можно оцифровывать бумажные ЭКГ, которых в российских поликлиниках накопилось достаточно много (а в некоторых поликлиниках до сих пор делают запись ЭКГ только в бумажном виде). Перевод бумажных ЭКГ в электронный вид позволит привести все записи ЭКГ к одному стандарту – электронному и в перспективе создать единую базу с полной историей болезни по каждому пациенту.

  1.  Постановка задачи

Прежде всего, данная программа, которую мы назвали ECGStudio, должна уметь работать с отсканированными изображениями ленты ЭКГ. В данной дипломной работе мы будем рассматривать ЭКГ, записанные в одном стандарте (см. раздел “Приложение”). Под словом работать подразумевается выделение графика ЭКГ и сетки. При сегментации отсканированных изображений возникают проблемы, например, такие как устранение дефектов сканирования (потертости, изгибы, пыль). Также  из-за плохого качества записи некоторые участки графика ЭКГ могут быть плохо прорисованы. Подробнее о том, как решались эти проблемы, будет написано в разделах “Устранение дефектов сканирования”, “Выделение графика ЭКГ и сетки”.

После  распознавания графика ЭКГ начинается следующий этап – анализ кривой ЭКГ, а именно выделение зубцов, сегментов и интервалов, о значении которых подробнее будет написано в разделе  “ Сведения о графике ЭКГ”. Анализ проходит на основе знаний вида кривых ЭКГ при нормальном функционировании сердца. Форма этих кривых может варьировать в определенных пределах. В связи с этим непременным условием правильного толкования ЭКГ при различных видах сердечной патологии является умение распознавать нормальную электрокардиографическую кривую во всех ее разновидностях. Также очень важно провести анализ сетки ЭКГ для нахождения одного милливольта, подробнее об этом будет изложено в разделе “Первичная обработка”.

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

После анализа кривой и выделения зубцов необходимо провести первичную расшифровку ЭКГ, а именно:

  •  Проверить правильность регистрации ЭКГ
  •  Оценить регулярность сердечных сокращений
  •  Подсчитать частоты сердечных сокращений (ЧСС)
  •  Определить источник возбуждения
  •  Проанализировать амплитуды и длительности некоторых интервалов и зубцов

Подробная информация обо всех этих операциях (кроме пункта “Определить источник возбуждения”, так его реализация выходит за рамки данной дипломной работы), а также об их реализации, будет в разделе “Подробная информация о выбранном участке ЭКГ”.

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

2. Необходимые сведения об электрокардиограммах

2.1. Проводящая система сердца

Сердце обладает автоматизмом - способностью самостоятельно сокращаться через определенные промежутки времени. Это становится возможным благодаря возникновению электрических импульсов в самом сердце. Импульсы возникают и проводятся по сердцу с помощью, так называемой, проводящей системы сердца. Рассмотрим компоненты проводящей системы сердца (Рис. 2.1.):

1) Синусно-предсердный узел или просто синусовый узел (SA) - источник возникновения электрических импульсов в норме. Именно здесь импульсы возникают и отсюда распространяются по сердцу.

2) Предсердно-желудочковый узел или атриовентрикулярный узел (AV) является фильтром для импульсов из предсердий. В AV-узле самая низкая скорость распространения электрических импульсов во всей проводящей системе сердца. Задержка импульса в AV-узле составляет около 0.08 с, она необходима, чтобы предсердия успели сократиться раньше и перекачать кровь в желудочки.

3) Пучок Гиса (или предсердно-желудочковый пучок) не имеет четкой границы с AV-узлом, проходит в межжелудочковой перегородке и имеет длину 2 см, после чего делится на левую и правую ножки соответственно к левому и правому желудочку.

4) Волокна Пуркинье связывают конечные разветвления ножек и ветвей пучка Гиса с сократительным миокардом желудочков.

Рис. 2.1. Проводящая система сердца.

2. 2. Теоретические основы ЭКГ

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

ЭКГ записываются  с помощью электрокардиографа, который фиксирует суммарную электрическую активность сердца, а если точнее - разность электрических потенциалов (напряжение) между 2 точками.

В состоянии покоя клетки миокарда (мышечный средний слой сердца, составляющий основную часть его массы) заряжены изнутри отрицательно, а снаружи положительно, при этом на ЭКГ-ленте фиксируется прямая линия (изолиния). Когда в проводящей системе сердца возникает и распространяется электрический импульс (возбуждение), клеточные мембраны переходят из состояния покоя в возбужденное состояние, меняя полярность на противоположную (процесс называется деполяризацией). При этом изнутри мембрана становится положительной, а снаружи - отрицательной из-за открытия ряда ионных каналов и взаимного перемещения ионов K+ и Na+ (калия и натрия) из клетки в клетку. После деполяризации через определенное время клетки переходят в состояние покоя, восстанавливая свою исходную полярность (изнутри минус, снаружи плюс), этот процесс называется реполяризацией.

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

2.3. Отведения на ЭКГ

Как было написано выше, электрокардиограф регистрирует напряжение (или разность электрических потенциалов) между 2 точками. Разность электрических потенциалов, снятую каким-то определенным способом, будем называть отведением. Существует двенадцать видов отведений, и они отличаются друг от друга способом измерения напряжения.

Стандартная ЭКГ записывается в 12 отведениях:

  •  3 стандартных (I, II, III)
  •  3 усиленных от конечностей (aVR, aVL, aVF)
  •  6 грудных (V1, V2, V3, V4, V5, V6)

1) Стандартные отведения (предложены Эйнтховеном в 1913 году):

  •  I - два электрода ставятся между левой рукой и правой рукой
  •  II - два электрода ставятся между левой ногой и правой рукой
  •  III - два электрода ставятся между левой ногой и левой рукой

Также еще один электрод накладывается на правую ногу, но показания с него не регистрируются - он используется только для заземления пациента.

2) Усиленные отведения от конечностей (предложены Гольдбергером в 1942 году):

  •  aVR - усиленное отведение от правой руки (сокращение от augmented voltage right - усиленный потенциал справа).
  •  aVL - усиленное отведение от левой руки (left - левый)
  •  aVF - усиленное отведение от левой ноги (foot - нога).

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

3) Грудные отведения (предложены Вильсоном в 1934 году) записываются между грудным электродом и объединенным электродом от всех 3 конечностей. Всего таких отведений 6 штук: V1, V2, V3, V4, V5, V6.

Точки расположения грудного электрода находятся последовательно по переднебоковой поверхности грудной клетки от средней линии тела к левой руке (Рис. 2.2.).

Рис.2.2. Точки расположения грудного электрода в отведениях V1, V2, V3, V4, V5, V6.

2.4. Сведения о кривой ЭКГ

Любая ЭКГ состоит из зубцов, сегментов и интервалов (Рис. 2.3.).

1)Зубцы.

Зубцы - это выпуклости и вогнутости на электрокардиограмме. На ЭКГ выделяют следующие зубцы:

  •  P (сокращение предсердий)
  •  Q, R, S (все 3 зубца характеризуют сокращение желудочков – систола)
  •  T (расслабление желудочков - диастола)
  •  U (непостоянный зубец, регистрируется редко, его мы рассматривать не будем)

2)Сегменты.

Сегментом на ЭКГ называют отрезок прямой линии (изолинии) между двумя соседними зубцами. Наибольшее значение имеют сегменты P-Q и S-T. Например, сегмент P-Q образуется по причине задержки проведения возбуждения в предсердно-желудочковом AV- узле.

3)Интервалы.

Интервал состоит из зубца (комплекса зубцов) и сегмента. Самыми важными являются интервалы P-Q и Q-T.

Также на Рис. 2.3. изображены все параметры сетки, которые будут нам необходимы при анализе ЭКГ, а именно, величина одного милливольта в миллиметрах (10 мм) или в количестве маленьких квадратов (10 штук), соотношение время – количество маленьких квадратов для разных скоростей движения при записи ЭКГ (при скорости 25 мм/с каждая маленькая клеточка равна 0.04 c, а при скорости 50 мм/с - 0.02 с).

Рис. 2.3. Зубцы, сегменты и интервалы на ЭКГ.

3. Реализация приложения

В качестве среды разработки приложения была выбрана Microsoft Visual Studio 2010, так как она обеспечивает все необходимые для работы средства. Графический интерфейс программы разработан с помощью технологии Windows Forms, а само приложение написано на языке C#.

Так как нам предстоит работать с изображениями, то логично было бы использовать для этого уже имеющуюся библиотеку. В качестве такой библиотеки была выбрана OpenCV (версии 2.4.0) (англ. Open Source Computer Vision Library, библиотека компьютерного зрения с открытым исходным кодом) - библиотека алгоритмов компьютерного зрения, обработки изображений и численных алгоритмов общего назначения с открытым кодом; реализована на C/C++, также разрабатывается для Python, Java, Ruby, Matlab, Lua и других языков. Может свободно использоваться в академических и коммерческих целях.

Из-за того, что данная библиотека реализована для C\C++, нам пришлось воспользоваться обёрткой библиотеки или wrapper’ом (wrapper является промежуточным слоем между прикладной программой и другой библиотекой. Целью написания обёртки библиотеки может быть обеспечение работоспособности библиотеки в каком-либо языке, в котором прямой вызов функций этой библиотеки затруднителен или невозможен).

Для работы с OpenCV на C# существует несколько библиотек-обёрток:

  •  EmguCv
  •  OpenCvDotNet
  •  OpenCvSharp

Мы выбрали OpenCvSharp (версии 2.4), так на сайте этого wrapper’а есть достаточно много хороших и понятных примеров программ, а также есть удобная документация в формате .html.

3.1. Устранение дефектов сканирования

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

  •  Аналоговый шум (например, грязь, пыль, царапины, изгибы)
  •  Цифровой шум (шумы, возникающие при сканировании)

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

  •  Адаптивная фильтрация
  •  Медианная фильтрация
  •  Математическая морфология
  •  Размытие по Гауссу
  •  Методы на основе дискретного вейвлет-преобразования
  •  Фильтры Винера

Из всех этих методов для обработки двумерных сигналов (изображений) с целью снижения уровня шума чаще всего используется Фильтр Гаусса (Gaussian filter). Также он является достаточно простым в реализации.

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

Фильтр Гаусса использует нормальное распределение (или Гауссово распределение) для вычисления ядра преобразования, применяемого для каждого пикселя изображения. Ядро - матрица n x n, где n - нечетное число (n≥3). Как мы уже сказали, ядро Гаусса G строится с помощью нормального распределения, а именно: G(x,y) (рассмотрим для примера двумерный случай) = 12πσ2e-x2+y22σ2, где - стандартное отклонение распределения Гаусса (оно и задает степень размытия), G(x,y) – элемент в x-ой строке, y-м столбце ядра G, нумерация x,y идет от центрального элемента матрицы G. Чтобы стало понятно, разберем пример построения ядра Гаусса при n=5, =1:

G=G(-2,-2)G(-2,-1)G(-2,0)G(-2,1)G(-2,2)G(-1,-2)G(-1,-1)G(-1,0)G(-1,1)G(-1,2)G(0,-2)G(0,-1)G(0,0)G(0,1)G(0,2)G(1,-2)G(1,-1)G(1,0)G(1,1)G(1,2)G(2,-2)G(2,-1)G(2,0)G(2,1)G(2,2),

где, например G-1,2=12πe-(-1)2+222. Из формулы G(x,y) = 12πσ2e-x2+y22σ2 можно видеть, что матрица G – симметрична относительно главной и побочной диагонали, поэтому при реализации фильтра Гаусса необязательно считать все G(x,y).

Теперь, когда у нас есть ядро фильтра Гаусса, давайте посмотрим, как применить его к изображению. К каждому пикселю изображения матрица ядра фильтра Гаусса прикладывается так, чтобы центр матрицы совпал с этим пикселем (Рис. 3.1.).

Рис. 3.1. Применение ядра фильтра Гаусса к изображению (пример при n=5).

Новое значение пикселя P13, к которому приложили матрицу ядра, высчитывается с помощью «умножения» (или свертки) матриц:

P13=G-2,-2G-2,-1G-2,0G-2,1G-2,2G-1,-2G-1,-1G-1,0G-1,1G-1,2G0,-2G0,-1G0,0G0,1G0,2G1,-2G1,-1G1,0G1,1G1,2G2,-2G2,-1G2,0G2,1G2,2×

×P1P2P3P4P5P6P7P8P9P10P11P12P13P14P15P16P17P18P19P20P21P22P23P24P25 = G-2,-2*P1+ G-2,-1*P2+ G-2,0 * P3+G-2,1*P4++ G2,-1* P22+G2,0*P23+ G2,1 * P24+ G2,2*P25. Таким образом, значение каждого пикселя становится средне взвешенным для окрестности.

В случае если пиксель, к которому мы прикладываем ядро, лежит на границе (Рис. 3.2.), мы не можем явно применять фильтр Гаусса. Необходимо создать временное изображение с размерами (width + n/2*2, height + n/2*2), где n – размер ядра, width - ширина исходного изображения, height -  высота исходного изображения. В центр временного изображения копируется исходное изображение, а края заполняются его крайними пикселям. Фильтр Гаусса применяется к промежуточному буферу, а потом из него извлекается результат (Рис. 3.3.)

Рис. 3.2. Проблема применения ядра фильтра Гаусса к граничным пикселям изображения (пример при n=3).

Рис. 3.3. Применение ядра фильтра Гаусса к граничным пикселям изображению (пример при n=5).

Фильтр Гаусса имеет сложность O(height * width * n * n), где width - ширина исходного изображения, height -  высота исходного изображения, n – размер ядра фильтра.

Для реализации фильтра Гаусса была использована стандартная функция из библиотеки OpenCV - Smooth(image, SmoothType.Gaussian, n, sigma), где image – изображение, к которому хотим применить фильтр, SmoothType.Gaussian показывает, что мы используем сглаживание по Гауссу, n – размерность ядра Гаусса, sigma - стандартное отклонение распределения Гаусса. При выделении сетки будет использоваться функция Smooth с параметрами n=3, sigma=3, а при выделении графика ЭКГ с параметрами n=5, sigma=5 (подробнее об этом в следующем разделе); все параметры подобранны экспериментально.

3.2. Выделение графика ЭКГ и сетки

Чтобы отделить график ЭКГ, а также сетку от фона, мы используем один из самых простых и интуитивно понятных методов сегментации изображения -  пороговое преобразование. Чтобы успешно применять пороговое преобразование необходимо перевести исходную картинку в градации серого. Такая шкала передаёт 256 оттенков (градаций) серого цвета, или яркости (значение 0 представляет черный цвет, а значение 255 - белый)

3.2.1. Выделение графика ЭКГ

Перед выделением графика необходимо сгладить изображение с помощью фильтра Гаусса, точнее, с помощью функции Smooth с параметрами, описанными в конце раздела ”Устранение дефектов сканирования”, после этого можно приступать к сегментации. Для того чтобы выделить график ЭКГ, мы разделим изображение на две части с помощью глобального порога Т. А именно, каждый пиксель отмечается как относящийся к графику или к фону, в зависимости от того, превышает ли яркость этого пикселя значение порога Т или нет. В предположении, что график ЭКГ представляет самый темный участок (регистрации ЭКГ проходит с помощью нанесения регистратором чернил на бумагу), а фон – самый яркий (белая бумага), подберем порог Т так, чтобы все пиксели с яркостью Т отмечались черным цветом (0), а все пиксели с яркостью > Т – белым цветом(255) (Рис. 3.4.). Выбор порога Т происходил экспериментально и для данного типа электрокардиограмм Т равен 150. Для других типов также можно будет подобрать свой порог Т.

Пороговое преобразование при выделении графика ЭКГ реализовано с помощью функции Threshold (image, threshold, max_value, ThresholdType.Binary) из библиотеки OpenCV, где image – изображение, над которым проводим пороговое преобразование, threshold – порог, max_value – величина, которой отмечаются все пиксели с яркостью большей threshold (в нашем случае max_value = 255, т.е. белый цвет), а ThresholdType.Binary – тип порогового преобразования, описанный нами выше.

Рис. 3.4. В окне window0 представлен результат применения порогового преобразования для выделения графика ЭКГ.

3.2.2. Выделение сетки

Также как и при выделении графика, при выделении сетки необходимо сначала сгладить изображение с параметрами, приведенными в конце раздела ”Устранение дефектов сканирования” и дальше уже начинать сегментацию. При выделении сетки воспользоваться сегментацией с помощью глобального порога не получится, так как сетка ярче, чем график ЭКГ, но темнее чем белый фон. Решение этой проблемы напрашивается само собой - будем выбирать те пиксели изображения, которые лежат в заданном интервале значений. Все пиксели с яркостью ≥ нижней границы и < верхней границы отмечаются белым цветом (255), а все пиксели, не попавшие в этот интервал – черным цветом (0) (Рис. 3.5.). Выбор верхней и нижней границы также как и при выделении графика ЭКГ проводился экспериментально и для данного типа кардиограмм нижняя граница равна 190 , а верхняя - 220.

Рис. 3.5. В окне window0 представлен результат применения порогового преобразования для выделения сетки.

Пороговое преобразование при выделении сетки реализовано с помощью функции InRangeS(inf, sup, image) из библиотеки OpenCV, где inf - нижняя, а sup – верхняя границы для описанного выше метода, image - изображение, над которым проводим пороговое преобразование.

3.3. Первичная обработка

Предполагается, что в программу сначала должен поступать скан ЭКГ-ленты с калибровочным сигналом (Рис. 3.6.) (под первичной обработкой будет пониматься обработка скана ленты с калибровочным сигналом, из этого понятно, что первичная обработка будет происходить только один раз за сеанс работы с лентой ЭКГ) или так называемым контрольным милливольтом (без калибровочного сигнала запись ЭКГ считается неправильной). В разделе “Нахождение одного милливольта” мы объясним, зачем все это нужно.

Рис. 3.6. Часть ЭКГ ленты с калибровочным сигналом

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

3.3.1. Нахождение одного милливольта

Как мы уже знаем 1 милливольт это 10 мм на ленте ЭКГ (или 10 маленьких квадратов) на ленте ЭКГ. Будем находить его так: 1)Найдем начало сетки сверху, 2)Проведем сглаживание по Гауссу, а затем пороговое преобразование исходного изображения (уже переведенного в градации серого) с нижней границей равной 180 и верхней границе равной 197 для выделения более “толстых” линий сетки (как в разделе “Выделение сетки”), 3)От этой точки отступим вниз и возьмем достаточно малый кусок изображения (так как для выделения одного милливольта вся сетка не нужна), 4)Пользуясь тем, что более толстые линии ограничивают область из 5 маленьких квадратов, размер которой составляет 5 мм, находим расстояние в пикселях между этими линиями, 5)Умножаем его на 2 и кладем в глобальную переменную onemV. Таким образом, мы получим величину одного милливольта в пикселях.

Теперь можно объяснить, почему сначала должен поступать скан с калибровочным сигналом. В начале записи подается стандартное напряжение в 1 милливольт, которое должно отобразить на ленте отклонение в 10 мм (назовем его “эталонный” милливольт), в норме, по крайней мере, в одном из стандартных или усиленных отведений от конечностей, амплитуда должна превышать 5 мм, а в грудных отведениях - 8 мм. Если амплитуда ниже, это называется сниженный вольтаж ЭКГ, который бывает при некоторых патологических состояниях. Таким образом, сравнивая “эталонное” значение одного милливольта (которое мы уже нашли) с калибровочным сигналом, мы можем выдать сообщение о наличии/отсутствии патологии в зависимости от соотношения этих величин.

3.3.2. Поиск нулей

Также, по скану ЭКГ-ленты с калибровочным сигналом определяются позиции нулевого милливольта во всех трех кривых ЭКГ. Это делается так: 1)Берем кусок исходного изображения той же высоты, но длины в три раза меньшей (опять же как и в предыдущем разделе все изображение нам не понадобится), 2)Проводим пороговое преобразование этого изображения (уже переведенного в градации серого) с помощью глобального порога Т равного 170, как в разделе “Выделение графика ЭКГ” (Рис. 3.7), 3)Проходим циклом  сверху вниз выделенный кусок и смотрим, если попадается белый (255) пиксель, то идем дальше, если черный (0) пиксель, то сохраняем его позицию в переменную локальную tempV1 и выходим из цикла; в новом цикле идем пока текущий пиксель - черный, если попадается белый, то выходим из цикла и сохраняем в локальную переменную tempV2 позицию последнего встретившегося черного пикселя; в итоге первая сверху нулевая позиция zeropos1 будет равна tempV1+tempV22, 4)Аналогично находим остальные две нулевые позиции zeropos2 и zeropos3 (переменные zeropos1, zeropos2, zeropos3 - глобальные), отличие будет лишь в том, что для каждой следующей нулевой позиции, мы запускаем цикл от предыдущей.

Рис. 3.7. Пороговое преобразование куска исходного изображения с помощью глобального порога Т равного 170.

3.4. Обработка последующих изображений

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

Изначально это проблема была частично решена с помощью приведения всех изображений к одному стандарту размеров с помощью функции масштабирования изображений Cv.Resize(image, resizeimage, Interpolation.NearestNeighbor) из библиотеки OpenCV, где image - исходное изображение, resizeimage - изображение для сохранения результата, Interpolation.NearestNeighbor - метод интерполяции при масштабировании. Но при изменении размеров может пострадать детализация изображения, что в дальнейшем скажется при анализе графика и сетки. Даже если убрать из виду ухудшение качества изображения, есть и другие более важные недостатки, например, нам бы снова пришлось находить величину одного милливольта, а также, было бы непонятно, как находить нулевые позиции на новом изображении.

Поэтому был выбран другой способ решения данной проблемы, а именно с помощью глобальной переменно coeff отвечающей за соотношение размеров “значащих” частей (под словом “значащая часть” подразумевается та часть изображения, на которой напечатана сетка и нарисован график) отсканированных изображений. Этот метод основан на том, чтобы получать соотношение величины значащей части ЭКГ текущего изображения с величиной значащей части ЭКГ с калибровочным сигналом (это соотношение будет храниться в глобальной переменной coeff) и домножать характеристики (один милливольт, нулевые позиции) изображения с калибровочным сигналом на этот коэффициент. Под домножением в случае получения нового 1 милливольта подразумевается обычное умножение 1 милливольта из ленты ЭКГ с калибровочным сигналом на coeff. В случае же нахождения новых нулевых позиций на coeff умножается не сама величина нулевой позиции, а следующие величины. Рассмотрим код, с помощью которого вычисляются новые нулевые позиции:

currentzeropos1 = (int)(coeff * (zeropos1 - upfirst));

currentzeropos2 = (int)(coeff * (zeropos2 - zeropos1));

currentzeropos3 = (int)(coeff * (zeropos3 - zeropos2));

где upfirst – начало (сверху) значащей части ЭКГ в изображении с калибровочным сигналом, и zeropos1, zeropos2, zeropos3 - соответствующие нулевые позиции в этом же изображении. Таким образом, мы можем получать в текущем изображении значения одного милливольта и все нулевые позиции простым умножением характеристик ЭКГ с калибровочным сигналом на соответствующий коэффициент.

3. 5. Выделение ROI

Функция выделения интересующей пользователя области (Region of interest или сокращенно ROI) на скане ЭКГ-ленты реализована с помощью двух щелчков левой кнопки мыши. Точку, выделенную пользователем и ближайшую к левому верхнему углу, положим в глобальную переменную pointbegin, которая понадобится нам в разделе “Отображение графика ЭКГ с выделенными зубцами”. Область между двумя точками, выбранными пользователем выделяется цветом с помощью вычитанием из пикселей ROI на исходном изображении константы равной 100 (Рис. 3.8.). При выделении другого ROI эта же константа добавляется к пикселям “старого” ROI на исходной картинке, тем самым убирая на изображении выделенное цветом “старое” ROI. Далее в глобальную переменную ROItmp кладем ROI из исходного изображения, сглаживаем ROItmp (как в разделе “Устранение дефектов сканирования”), проводим над ним пороговое преобразование с глобальным порогом Т равным 150 (как в разделе “Выделение графика ЭКГ) и отправляем ROItmp на дальнейший анализ.

Рис. 3.8. Выделение ROI.

3.6. Анализ графика ЭКГ

После того, как пользователь выбрал ROI, он переходит в одну из четырех вкладок, в каждой из которых по три поля для одной из трех кривых ЭКГ на ленте. В сумме получается двенадцать полей, т.е. каждое поле соответствует одному из двенадцати отведений (Рис. 3.9.).

Рис. 3.9. Одна из четырех вкладок с тремя полями для графиков ЭКГ.

После того, как пользователь выберет одну из четырех вкладок и одно из трех полей в этой вкладке, он должен нажать кнопку “Добавить”, после чего появится форма, где нужно будет выбрать номер отведения (Рис. 3.10.).

Рис. 3.10. Выбор номера отведения.

После нажатия кнопки “Ок” начинается обработка выделенной части графика ЭКГ.

3.6.1. Получение графика в виде массива точек  

После того, как пользователь выбрал ROI, ввел номер отведения и нажал кнопку “Ок” в процедуре ECGAnalysis с одним параметром nomerotved (номер отведения выбранной области) типа int , происходит обработка изображения хранящегося в глобальной переменной ROItmp. Сначала необходимо получить массив, состоящий из точек графика ЭКГ. Для этого помимо выделения графика необходимо сделать его “утончение” (Рис. 3.11.), так как в ROItmp график может быть шириной в несколько пикселей. Заведем массив y1[] длины равной ширине ROItmp. “Утончение” происходит подобно тому, как мы выделяли график ЭКГ в разделе “Поиск нулей”, а именно, заведем внешний цикл по локальной переменной x, проходящий картинку в ширину, а вложенный цикл по локальной переменной y, который будет проходить изображение в высоту, начиная снизу (снизу мы начинаем потому, что на некоторых ЭКГ сверху графика иногда есть необходимые подписи, сделанные врачом; проходя циклом снизу и находя точки графика ЭКГ, мы выходим из цикла, тем самым пропуская обработку всего, что находится выше графика); внутри вложенного цикла будет проходить проверка, если текущий пиксель - белый (255), то идем дальше, если же черный (0), то сохраняем позицию этого пикселя в локальную переменную temp1, заводим новый цикл и идем вверх по изображению, пока текущий пиксель черный, если нам попадается белый пиксель, то сохраняем позицию последнего черного пикселя в локальную переменную temp2, кладем в y1[x] значение temp1+temp22 и выходим из вложенного цикла с помощью оператора break. Пройдя таким образом все изображение ROItmp, мы получим “утонченный” массив точек y1[] графика ЭКГ.

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

Рис. 3.11. “Утончение” графика ЭКГ.

3.6.2. Добавление недостающих точек

После получения массива точек ЭКГ может оказаться, что некоторые точки графика не будут выделены из ROItmp, например, из-за потертости или плохого качества записи ЭКГ. Так как порог Т в разделе “Выделение графика ЭКГ” подобран достаточно хорошо, то таких точек будет немного. Недостающие точки  можно получить путем соединения прямой линией  соседних выделенных точек, между которыми есть какое-то количество пропущенных точек.

3.6.3. Вычисление среднего значения графика и производной по трем узлам

Для дальнейшего анализа нам потребуется посчитать среднее значение графика ЭКГ, а также первую производную. Среднее значение посчитаем по формуле:

(i=0Width-1y1i  )/Width,

где  Width – ширина изображения ROItmp, и положим его в локальную переменную matozh.

Первую производную будем считать приближено по трем узлам с помощью схемы:

y1[ i-1] = -3*y1i-1+4*y1i-y1[i+1]2h,

в каждой точке массива y1[] (за исключением точек i=0 и i=Width-1, в этих точках положим в качестве значения производной 0). Для значений производной в каждой точке заведем массив dif3[] той же размерности, что и y1[].

3.6.4. Поиск зубцов P, Q, R, S, T

Самым важным моментом анализа графика ЭКГ будет выделение его зубцов. Для хранения найденного зубца заведем структуру:

public struct zub

       {

           public int x;

           public int y;

           public string type;

       }

где в x будет храниться горизонтальная координата зубца, в y будет y1[x] – соответствующая вертикальная координата, а в type будет информация о том, какой это зубец. Все найденные зубцы будем помещать в очередь zubci:

Queue zubci = new Queue();

Для выделения зубцов заводим внешний цикл по локальной переменной ind, проходящий массив y1[]. Сначала планируется выделять зубец R, а затем уже от него искать все остальные зубцы. Заметим, что приведенный ниже алгоритм характерен для поиска зубцов в отведениях I, II, III, aVF, aVL, V4, V5, V6. После описания алгоритма для этих отведений, мы путем небольших изменений текущего алгоритма сможем получить новый, находящий зубцы во всех двенадцати отведениях.

3.6.4.1. Выделение зубца R

Зубец R можно найти, зная, что он имеет самую большую амплитуду. Первое, что приходит в голову, это запустить цикл по массиву y1[] и если какое-то его значение равно Max(y1[]), то это и будет зубец R. Такой метод будет работать, только если в ROI, выбранном пользователем, один зубец R.На самом же деле, зубцов R в выбранном участке может быть несколько, причем, амплитуда одного зубца может отличаться от амплитуд других зубцов. Поэтому необходимо модифицировать предложенный метод поиска зубца R.А именно, внутри цикла по ind будем проверять условие: если y1ind-Max(y1[]) меньше какого-то заданного значения и эта точка является локальным максимумом, т.е. y1[ind]  y1[ind + j], где j = -2, 2 (такую область мы выбрали экспериментально). Чаще всего зубец R представлен несколькими пикселями с одинаковыми значениями y1[], тогда зубцом R будем считать средний (по горизонтальной координате) из этих пикселей. Таким образом, мы находим зубец R  и помещаем его в очередь zubci.

3.6.4.2. Выделение зубца Q

Зубец Q предшествует зубцу R и ищется довольно просто. От левой границы зубца R мы идем в обратную сторону (справа налево) и проверяем условие: если y1[ i-1] < y1[i], то идем дальше назад, если же условие не выполняется то текущий зубец - Q зубец, помещаем его в очередь zubci.

3.6.4.3. Выделение зубца P

Как мы знаем, зубец P находится перед зубцом Q и представляет собой локальный максимум, из этого следует, что его можно найти так: заводим цикл по i от зубца Q и идем в обратную сторону пока dif3[i]    0, если вышли из цикла, то в i будет лежать горизонтальная координата зубца P. Но такой метод не очень эффективный и иногда может дать неверный результат, например при небольших отклонениях (не более одного пикселя) участка изолинии. Зная, что зубец достаточно пологий, и его пик состоит из не менее трех пикселей, мы должны отличать такие случайные отклонения в не более чем один пиксель, немного изменив предложенный в начале раздела метод путем небольшого корректировки условия в проходе цикла: dif3[i] 0 || dif3[i - 1] != 0. Так как зубец P состоит из нескольких пикселей с одинаковыми значениями y1[], то подобно тому, как мы делали в случае нахождения зубца R, зубцом P будем считать средний (по горизонтальной координате) из этих пикселей. Итак, мы находим зубец P  и помещаем его в очередь zubci.

3.6.4.4. Выделение зубца S

Выделение зубца S происходит проходом слева направо от правой границы выделенного зубца R с условием, что y1[i] < y1[ i+1], если вышли из цикла значит текущий зубец - зубец S. Однако подобно тому, как это было с зубцом R и P, зубец S может состоять из нескольких пикселей с одинаковыми значениями y1[], эта проблема решается как в разделах “Выделение зубца R”, “Выделение зубца P. После выделения зубца, помещаем его в очередь zubci.

Также для последующих измерений необходимо выделить правую границу зубца S. Это можно сделать, зная, что после пика зубца S, график ЭКГ возрастает до какого-то значения, а потом стабилизируется и совершает малые колебания около некоторой константы. Так вот момент перехода от возрастания к константе и будет правой границей зубца S. Чтобы найти этот момент необходимо от правой границы пика зубца S идти слева направо и проверять условие: dif3[i] < 0 || dif3[i + 1] < 0, вторая часть условия нужна для того, чтобы обойти случаи, когда при возрастании график может стать константой (такие участки могут быть длиной не более 2-ух пикселей). После нахождения правой границы зубца S, помещаем эту границу в очередь zubci.

3.6.4.5. Выделение зубца T

Алгоритм нахождения зубца T очень похож на алгоритм нахождения зубца P, зубец T также как и зубец P представляет собой локальный максимум. Алгоритм, описанный в разделе “Выделение зубца P”, полностью повторяется с отличием лишь в том, что циклом по i от правой границы зубца S мы идем слева направо и проверяем условие dif3[i] ≥ 0 || dif3[i - 1] != 0, если вышли из цикла, то в i будет лежать горизонтальная координата зубца T. Также как и в случае с зубцом P, зубец T может состоять из нескольких пикселей с одинаковыми значениями y1[], эта проблема решается также как и в разделе “ Выделение зубца P”. Опять же помещаем найденный зубец в очередь zubci.

Как уже отмечалось, приведенный выше алгоритм находит зубцы в отведениях I, II, III, aVF, aVL, V4, V5, V6. Как видно из Рис. 3 и Рис. 4 (раздел “Приложение”), кривые в отведениях V1, V2, V3, aVR представляют из себя те же кривые, что и в остальных отведениях, только повернутые на 180 градусов. Таким образом, если в приведенном выше алгоритме поиска зубцов все знаки сравнения в условиях прохода цикла поменять на противоположные, то мы получим алгоритм анализа зубцов и для V1, V2, V3, aVR отведений.

3.6.5. Отображение графика ЭКГ с выделенными зубцами

После того как мы выделил график ЭКГ и зубцы, нам необходимо вывести результат. Сначала необходимо будет отрисовать график с зубцами в изображении tmp1 (глобальная переменная), а затем уже вывести это изображение в выбранное пользователем одно из двенадцати полей с помощью PictureBoxIpl.

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

Рис. 3.12. ROI выбранное пользователем.

Рис. 3.13. ROI выбранное пользователем.

Проблему такого стандарта будем решать нижеописанным способом. Для начала найдем ближайшее к нашему графику положение нулевого милливольта (в дальнейшем просто нулевое положение). Как раз здесь и понадобится matozh, вычисленное нами в разделе “Вычисление среднего значения графика и производной по трем узлам”. Для вычисления ближайшего нулевого положения нам нужно сравнить три расстояния: matozh+pointbegin-zeropos1, matozh+pointbegin-zeropos2, matozh+pointbegin-zeropos3, где pointbegin – значение, которое мы вычислили в разделе “Выделение ROI”. Нетрудно видеть, что взяв минимум из этих трех значений и взяв соответствующую этому минимому нулевую позицию zeroposi, где i = 1,2,3, мы получим ближайшее к нашему графику нулевое положение, которое мы положим локальную переменную currentzeropos, чтобы в дальнейшем ей воспользоваться.

После нахождения ближайшей нулевой позиции мы уже можем описать сам стандарт  отображения. Так как нам известен размер одного милливольта в пикселях, и мы знаем, что отклонение графика ЭКГ от нулевого значения милливольта обычно не превышает двух с небольшим милливольт, то мы можем создать новое изображение в переменой tmp1 размера 5 * onemV (такой размер берется “прозапас”, onemV – величина одного милливольта в текущем изображении) с нулевой позицией посередине, что будет гарантировать то, что график будет находиться в пределах этого изображения. Теперь необходимо сдвинуть график ЭКГ и найденные зубцы так, чтобы они оказались в том же положении относительно середины нового изображения размером tmp1, в каком они находятся в исходном изображении относительно своей нулевой позиции. Сдвиг кривой ЭКГ происходит с помощью кода:

for (int x = 0; x < ROItmp.Width; x++)

{

y1[x] = y1[x] – (currentzeropos – pointbegin – (int)(onemV * 2.5));

}

а зубцы сдвигаются по аналогии с предыдущим кодом:

for (int x = 0; x < zubci.Count; x++)

{

_zub = (zub)zubci.Dequeue();

_zub.y = _zub.y - (currentzeropos - pointbegin - (int) (onemV * 2.5));

zubci.Enqueue(_zub);

}

где _zub – вспомогательная переменная типа zub, введенного нами в разделе “ Поиск зубцов P, Q, R, S, T”.

Теперь мы готовы рисовать график ЭКГ в изображении tmp1, но сперва необходимо сохранить массив графика ЭКГ, а также  выделенные зубцы для последующей работы с ними. Для этого мы заведем структуру:

public struct partoofECG

       {

           public int singlemV;

           public Queue graphECG;

           public Queue tooth;

       }

где поле singlemV - единичный милливольт для текущего изображения, поле graphECG – очередь, состоящая из элементов массива y1[], а поле tooth – очередь, состоящая из элементов очереди zubci. В начале работы приложения заводится двенадцать глобальных переменных partofECGi (где i = 1,12) типа partofECG для каждого из двенадцати отведений, а соответственно и для каждого из 12 полей.

Эти двенадцать переменных мы и будем использовать для хранения графика ЭКГ и зубцов. Сохранение происходит по следующему коду:

partofECGi.graphECG = new Queue();

for (int x = 0; x < ROItmp.Width; x++)

{

partofECGi.graphECG.Enqueue(y1[x]);

}

partofECGi.tooth = new Queue();

partofECGi.tooth = zubci;

if (up == 0)

{

partofECGi.singlemV = onemV;

}

else

{

partofECGi.singlemV = onemVnew;

}

break;

где partofECGi –переменная, в которой i = nomerotved.

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

CvSize size1;

size1 = new CvSize(ROItmp.Width, onemV * 5);

tmp1 = new IplImage(size1, BitDepth.U8, 3);

CvScalar white;

white.Val0 = 255;

white.Val1 = 255;

white.Val2 = 255;

white.Val3 = 0;

tmp1.Set(white);

После этого мы уже можем рисовать график и зубцы с помощью следующего кода:

//Отрисовка графика ЭКГ

for (i = 0; i < ROItmp.Width - 1; i++)

tmp1.Line(i, y1[i], i + 1, y1[i + 1], CvColor.Red, 2, LineType.AntiAlias, 0);

//Отрисовка зубцов

foreach (zub zubec in zubci)

{

tmp1.DrawMarker(zubec.x, zubec.y, CvColor.Black, MarkerStyle.CircleLine, 4, LineType.AntiAlias, 2);

}

По завершении всего выше перечисленного изображение tmp1 выведется в одно из двенадцати полей выбранное пользователем (Рис. 3.14.).

Рис. 3.14. Вывод проанализированного графика ЭКГ в выбранное пользователем поле.

Как мы видим на Рис. 3.14. после отрисовки графика ЭКГ и его зубцов слева от поля появилась информация от номере отведения и некоторые дополнительные инструменты, такие как возможность убрать выбранный график из поля, а также возможность нарисовать позицию нулевого милливольта и сетку (Рис. 3.15.), причем независимо друг от друга. Также снизу поля появилась кнопка “Подробнее”, о которой будет написано в следующем разделе.

Рис. 3.15. Отрисовка позиции нулевого милливольта и сетки.

3.6.6.Подробная информация о выбранном участке ЭКГ.

После нажатия кнопки “Подробнее”, о которой упоминалось в предыдущем разделе, появляется новое окно (Рис. 3.16), в котором уже более детально изображен график (и также, как и в предыдущем окне, снизу есть дополнительные опции отрисовки нуля и сетки), и справа от этого окна есть информация о выбранной кривой ЭКГ, полезная для постановки диагноза. Рассмотрим, какая именно информация присутствует.

Начнем разбор сверху вниз. Первой идет информации о частоте сердечных сокращений  (ЧСС). На ЭКГ – ленте, как мы уже знаем, напечатаны большие квадраты, каждый из которых включает в себя 25 маленьких квадратиков (5 по вертикали и 5 по горизонтали). Для быстрого подсчета ЧСС при правильном ритме (о том, что такое правильный ритм, будет рассказано далее) считают число больших квадратов между двумя соседними зубцами R - R:

  •  При скорости ленты 50 мм/с: ЧСС = 600 / (число больших квадратов).
  •  При скорости ленты 25 мм/с: ЧСС = 300 / (число больших квадратов).

На Рис. 3.16. интервал R-R равен примерно 9.6 больших клеточек, что при скорости 50 мм/с дает 600 / 9.6 = 62.5 уд./мин. При неправильном же ритме (о том, что такое неправильный ритм, будет рассказано опять же позже) обычно считают максимальную и минимальную ЧСС согласно длительности самого маленького и самого большого интервала R-R соответственно.

Далее идет информация о R - R интервалах. А именно о длительности максимального, минимального и среднего интервалах, а также соответствующие им частоты сердечных сокращений. Регулярность ритма оценивается по интервалам R-R. Если R - зубцы находятся на равном расстоянии друг от друга, то ритм называется регулярным, или правильным, иначе же - нерегулярный, что значит, что имеет место какая-то патология. Допускается разброс длительности отдельных интервалов R-R не более ± 10% от средней их длительности. Информация о том, правильный ли ритм или нет, выводится ниже таблицы с RR интервалами. Также вместе с ней расположена информация о правильности регистрации ЭКГ, суть которой состоит в том, чтобы сравнить величину калибровочного милливольта и “эталонного” милливольта (о том, как находиться и как сравниваются эти величины, было написано в разделе “Нахождение одного милливольта”).

Ниже в отдельной панели идет информация о длительности каждого из комплексов QRS и амплитуде каждого из зубцов R. Стоит сказать, что все эти замеры происходят из знания вычисленной нами длины (в пикселях) одного милливольта (раздел “Нахождение одного милливольта”) и что все эти вычисленные амплитуды и длительности впоследствии сравниваются врачом с нормальными значениями, и по итогам этих сравнений может быть поставлен диагноз.

Рис. 3.16. Подробная информация о выбранном участке ЭКГ.

Заключение

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

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

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

Приложение

В приложении приведены сканы ЭКГ, сделанной на скорости 50 мм/с.

Рис. 1. Скан ЭКГ с калибровочным милливольтом и отведениями I, II, III.

Рис. 2. Скан ЭКГ с отведениями V4, V5, V6.

Рис. 3. Скан ЭКГ c отведениями aVR, aVL, aVF.

Рис. 4. Скан ЭКГ c отведениями V1, V2, V3, V4, V5, V6.


Литература

  1.  Гонсалес Р., Вудс Р. Цифровая обработка изображений. Издательство "Техносфера", 2005 г.
  2.  Дэвид Форсайт, Жан Понс Компьютерное зрение. Современный подход. -М.: “Вильямс”, 2004 г.
  3.  Иванов Д. В., Хропов А. А., Кузьмин Е. П., Карпов А. С., Лемпицкий В. С. Алгоритмические основы растровой графики. Издательство Бином, 2007 г.
  4.  Мурашко В.В., Струтынский А.В.  Электрокардиография. Издательство “МЕДпресс-информ”, 2007 г.
  5.  Библиотека MSDN //  Практические советы, справочная документация, примеры кодов, технические статьи для разработчиков, использующих средства, продукты, технологии и службы корпорации Майкрософт. URL:  http://msdn.microsoft.com/ru-ru/library .
  6.  RoboCraft  blog // сообщество/коллективный блог людей, занимающихся робототехники, электроникой и программированием.
    URL: http://robocraft.ru/blog/computervision .
  7.  OpenCV documentation.
    URL:
    http://opencv.org .
  8.  Opencvsharp documentation and samples.
    URL:
    http://code.google.com/p/opencvsharp .
  9.  Хабрахабр // Коллективный блог для публикации новостей и аналитических статей, связанных с информационными технологиями.
    URL: http://habrahabr.ru .
  10.   Wikipedia // Свободная электронная энциклопедия.
    URL: http://en.wikipedia.org/wiki/Main_Page .
  11.   CyberForum // Форум начинающих и профессиональных программистов.
    URL: http://www.cyberforum.ru .


 

А также другие работы, которые могут Вас заинтересовать

43525. Социальные конфликты современной России 162.5 KB
  Социальная неоднородность общества, различие в уровне доходов, власти, престиже и т.д. нередко приводят к конфликтам. Конфликты являются неотъемлемой частью общественной жизни. Это обуславливает пристальное внимание социологов к исследованию конфликтов.
43526. Многомерная модель базы данных и ее реализация на основе Microsoft SQL Server 479.5 KB
  Поэтому не удивительно то внимание которое сегодня уделяется средствам реализации и концепциям построения информационных систем ориентированных на аналитическую обработку данных. И в первую очередь это касается систем управления базами данных основанными на многомерном подходе МСУБД. Требования к средствам реализации систем оперативной и аналитической обработки данных.
43527. Организация отдыха детей и молодежи: технологии, опыт, проблемы 246.5 KB
  Правильно организованный отдых детей и молодежи обеспечит их разностороннее развитие и формирование личности, духовное, патриотическое, нравственное воспитание, укрепление здоровья, оздоровление организма и восстановление работоспособности. В современной России возникла проблема, касающаяся организации досуга и отдыха детей и молодежи
43528. Анализ и прогнозирование финансового состояния предприятия ООО «Зеркало-инфо» 455 KB
  Объектом исследования курсовой работы является ООО Зеркалоинфо предмет исследования – финансовое состояние предприятия. Цель курсовой работы – исследование финансового состояния предприятия ООО Зеркалоинфо выявление основных проблем финансовой деятельности. В первой главе работы проводится анализ финансового состояния предприятия.
43529. Анализ и прогнозирование финансового состояния предприятия СООО «Эмир Моторс» 467 KB
  Объектом исследования курсовой работы является СООО Эмир Моторс предмет исследования – финансовое состояние предприятия. Цель курсовой работы – исследование финансового состояния предприятия СООО Эмир Моторс выявление основных проблем финансовой деятельности. В первой главе работы проводится анализ финансового состояния предприятия.
43530. Расчет балки и ее характеристик 3.86 MB
  Для указанных схем определить собственные частоты и формы колебаний. Проверить ортогональность собственных форм колебаний. Определить амплитуды вынужденных колебаний под действием силы P(t) = P0cosΩt, приложенной в точке А. Построить эпюру динамических изгибающих моментов при частоте Ω = (γ/mδ)1/2
43531. Системный анализ информационной системы управления бюджетом на предприятии 12.42 MB
  А1 Масштаб предприятия одно здание 100 служащих. А2 Масштаб предприятия четыре филиала в пределах города 500 служащих. А3 Масштаб предприятия один филиал в пределах города и четыре филиала в области 1000 служащих. А4 Масштаб предприятия семь офисов в семи регионах РФ 500 служащих.
43532. Становление системы хореографического образования А.Я.Вагановой 82.91 KB
  Стремясь подчеркнуть особенности русской балетной школы, Ваганова в своей книге нередко сопоставляет ее с французской и итальянской школами. Эти понятия нельзя связывать с современным зарубежным балетом, хотя в отдельных случаях описанные Вагановой приемы еще бытуют в хореографической практике.
43533. Проектирование автоматизированного участка цеха по производству сотового заполнителя 649 KB
  Характеристика изделий получаемых в данном технологическом процессе Технические характеристики сот Краткая характеристика линии для производства непрерывного сотового заполнителя Характеристика склада