Ладно, как мы к этому пришли? 😄
Начнем с того, что я Frontend Engineer, а когда-то мой путь в АйТи начинался с QA Engineer. И вот одним из первых проектов, где я работал, была медтех компания в РФ, которая занимается цифровизацией рабочего пространства патоморфологов.
Патоморфолог — это врач, который исследует ткани и клетки, чтобы по их изменениям диагностировать различные заболевания. В том числе он играет очень важную роль в диагностике онкологических заболеваний. Там, конечно, все немного сложнее, но для понимания этой статьи такого определения нам хватит.
Дальше для удобства буду называть его просто врачом.
Небольшой дисклеймер: я не врач, а статья в первую очередь про технологии и мой опыт работы с цифровой патоморфологией. Медицинскую часть я местами намеренно упрощаю, чтобы не перегружать текст, поэтому где-то могу упустить нюансы или допустить неточность.
Я несколько лет провёл внутри этой предметной области и успел посмотреть на неё с разных сторон. Вообще, у меня есть идея написать 3 статьи, зафиксировать свой опыт и поделиться им.
Первая – эта, где я в общих чертах расскажу, что это вообще такое и как всё работает. Вторая будет технической, с подробным разбором фронтенда – интерфейса веб-приложения, который работает у вас в браузере, если кто не знает. А в третьей хочу разобрать архитектуру такого приложения целиком.
Замахнулся я конечно, но даже этой статьи будет достаточно, если она выйдет 😄
О чем речь
Уверен, что сейчас все еще непонятно, о чем статья)) Так что, разбираемся!
Допустим, у пациента нашли подозрительное образование. Дальше, чтобы понять, что это вообще такое, ему делают биопсию (берут небольшой кусочек ткани для исследования). Этот образец проходит несколько этапов подготовки в лаборатории: из него делают очень тонкий срез, окрашивают и помещают на небольшое предметное стекло.

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

WSI
На выходе получается цифровая версия всего стекла под названием WSI (Whole Slide Image). Разрешение у такого изображения может исчисляться гигапикселями, а размер файла – гигабайтами.
Сканер снимает стекло в максимальном разрешении, например 40×. Из него создаются уменьшенные версии того же изображения – 20×, 10×, 5×.
Условно, на 5× можно посмотреть на всё стекло, а на 40× – отдельные клетки и мелкие детали ткани.
В итоге, получается пирамида изображений: 5× → 10× → 20× → 40×.

Сканеры
Такие сканеры производят разные компании: Leica, Hamamatsu, 3DHISTECH, Philips и другие. И исторически так сложилось, что единого формата для цифрового стекла, которым пользовались бы вообще все, нет.
У разных производителей появились свои форматы: например, .svs у Leica/Aperio, .ndpi у Hamamatsu, .mrxs у 3DHISTECH и другие.
У разных расширений внутри может отличаться структура изображения, метаданные, уровни увеличения, способ хранения отдельных частей изображения и куча других деталей.
Поэтому если мы хотим сделать приложение, которое умеет работать со стеклами с разных сканеров, нам нужно каким-то образом всё это многообразие форматов поддерживать.
Но, независимо от производителя, у нас появляется цифровое изображение всего стекла, которое можно хранить, передавать и открывать на компьютере.
Почему браузер?
Конечно, цифровые стекла можно просматривать и в обычных десктопных приложениях. Но браузер вытесняет их по абсолютному удобству.
Врачу достаточно зайти на сайт и авторизоваться. Не нужно обновлять никакие приложения.
Плюс это сильно упрощает удаленную работу и консультации. Также ему не нужно хранить, передавать само стекло или скачивать WSI размером в несколько гигабайт.
Как WSI работает в браузере
Как я писал выше, один WSI может весить несколько гигабайт и иметь разрешение в несколько гигапикселей. Загружать такое изображение целиком каждый раз, когда врач открывает стекло, долго и бессмысленно.
Тайлы
Чтобы не грузить все изображение целиком, оно делится на небольшие кусочки – тайлы (tiles).
Это можно представить, как огромное стекло разрезанное на тысячи маленьких квадратных изображений.
По такому же принципу работают онлайн-карты. Когда вы открываете Google Maps, браузер загружает только небольшие участки карты вокруг того места, которое вы сейчас смотрите. Поэтому при плохом интернете иногда можно увидеть, как отдельные квадратики карты не успели загрузиться и на их месте какое-то время остаётся пустая область. Эти квадратики и есть тайлы.

Тайлы тоже могут быть разного размера. Например, одну и ту же область изображения можно представить как один тайл 512×512 пикселей или как четыре тайла по 256×256.
Чем меньше тайлы, тем точнее приложение может загружать только нужные участки изображения, но при этом увеличивается количество запросов. Более крупные тайлы уменьшают количество запросов, но иногда заставляют загружать больше данных, чем реально нужно.
Viewer (Вьювер)
Часть приложения, в которой врач смотрит цифровое стекло: перемещается по нему, приближает и отдаляет нужные участки, называется вьювером.
Область стекла, которую пользователь видит сейчас на экране, называется viewport. Вьювер знает, что сейчас видит пользователь, поэтому загружает только тайлы, которые попадают в эту область.
Передвинулись вправо – загрузились новые тайлы справа. Приблизили изображение – вьювер переключился на более детальный уровень WSI и загрузил тайлы уже оттуда. Отдалили – переключился обратно на уровень с меньшим разрешением.
Уже загруженные тайлы можно какое-то время хранить в кеше. Поэтому, если врач вернётся на участок, который только что смотрел, часть данных не придётся снова загружать с сервера.
В итоге врач просто перемещается по огромному изображению и приближает нужные участки, а браузер под капотом постоянно определяет нужный уровень WSI, загружает подходящие тайлы и отрисовывает их на экране.
Я сделал небольшое демо вьювера для экспериментов с производительностью. Можно посмотреть тут.
В демо можно перемещаться по стеклу, менять увеличение, создавать и измерять аннотации, сравнивать несколько стекол одновременно и включать тестовые AI-оверлеи. Ещё там есть небольшой отчёт и несколько инструментов для тестирования производительности.
В демо используются небольшие тестовые стекла размером в несколько десятков мегабайт, поэтому их детализация сильно ниже, чем у полноценных WSI. Это сделано специально, чтобы не хранить на сервере лишнее.

Работа врача во вьювере
Вьювер может иметь огромный функционал. Тут разберу самые частые возможности. Но в реальной работе всё зависит от компании, страны и конкретного продукта, так как по сути вокруг вьювера строится целая платформа.
Навигация и просмотр
Самое очевидное, врач может просматривать стекло также, как он это делал бы с микроскопом. Можно зумить, перемещаться, поворачивать, измерять линейкой.
Ну и с этим конечно идет весь вспомогательный интерфейс: текущий зум, масштаб, горячие клавиши и тд.
Аннотации и измерения
Поверх самого изображения врач может отмечать интересующие его клетки или участки ткани с помощью аннотаций.
Это может быть обычная точка, прямоугольник, круг, полигон или нарисованная вручную область. Аннотации можно подписывать.
Также во вьювере есть линейка. Можно провести линию между двумя точками и получить реальное расстояние в микронах или миллиметрах.

Аннотации хранятся отдельно от самого изображения в виде координат и показываются поверх него. Для их хранения часто используют GeoJSON, который хорошо подходит для описания точек, линий и полигонов.
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[
[120, 80],
[240, 80],
[260, 180],
[140, 200],
[120, 80]
]]
},
"properties": {
"name": "Tumor"
}
}Здесь coordinates описывают форму аннотации, а в properties можно хранить дополнительную информацию — например название или тип.
Несколько стекол
Часто у одного случая может быть несколько стекол (разные срезы, окраски). Врачу нужно быстро переключаться между ними, а иногда и смотреть несколько стекол одновременно.
Например, можно открыть два изображения рядом и сравнивать одну и ту же область ткани. Причём их можно автоматически сопоставить и синхронизировать. Но тут уже используются алгоритмы регистрации изображений и методы машинного обучения.

AI
Ну раз мы уже затронули тему ИИ.
Обычный флоу: модель получает стекло, анализирует его и возвращает результаты, которые можно показать врачу прямо поверх WSI. Тоже, как и для аннотаций, можно использовать GeoJSON.
Результатом могут быть найденные клетки, выделенные области ткани, сегментация или тепловая карта, показывающая участки, на которые стоит обратить внимание.
Например, модель может найти десятки тысяч клеток, а вьювер отобразит каждую из них поверх стекла.
А когда таких результатов становится несколько десятков или сотен тысяч, начинается уже отдельное веселье с производительностью браузера 😄

Совместная работа
Цифровое стекло также позволяет нескольким врачам работать с одним исследованием одновременно. Например, один врач может открыть нужную область ткани, а второй – видеть его перемещения, аннотации и изменения практически в реальном времени. Похожая механика есть в Miro и Figma, если вы знакомы с этими инструментами.
По сути, что-то вроде мультиплеера: несколько пользователей находятся в одном исследовании и могут вместе смотреть стекло, обсуждать интересующие участки и проводить удалённые консультации.
Кстати, один из кейсов – обучение, когда один врач может показывать и рассказывать что-то десяткам или даже сотням других. Вебинар, короче 😄
Отчёт и заключение
В конечном итоге врач после просмотра стекла и исследования материалов должен сформировать медзаключение.
В самом простом виде весь процесс можно представить примерно так:
Кейс → стекла → просмотр → аннотации и измерения → AI → заключение
Что находится за всем этим?
Ну наконец, мы открыли исследование, посмотрели стекла, сделали аннотации, запустили AI и сформировали заключение.
Но, вьювер – это только одна из частей всей системы. До того как стекло вообще появится в браузере, его нужно отсканировать, загрузить на сервер, обработать, где-то хранить и потом быстро отдавать пользователю.

Вокруг этого уже появляется куча других вещей: база данных с исследованиями и пациентами, очереди для обработки больших файлов и также их конвертация (помним про разные форматы), хранение аннотаций, AI-сервисы, отчёты, авторизация, разграничение доступа и интеграции с другими медицинскими системами.
Например, после загрузки WSI размером в несколько гигабайт системе нужно прочитать его метаданные, подготовить изображение для просмотра, сохранить информацию о стекле в базе и только после этого сделать его доступным врачу.
И всё это должно работать с тысячами исследований и огромным количеством данных, должно быть безопасным (медицинские данные одни из самых чувствительных данных) и отказоустойчивым.
Итог
В этой статье мне хотелось скорее показать, что вообще представляет собой цифровая патоморфология и как выглядит работа с ней со стороны врача.
А дальше хочется уже закопаться в техническую часть. Во второй статье отдельно разберу фронтенд: как рендерить огромные WSI, работать с десятками и сотнями тысяч аннотаций, не убивать браузер и держать 60 FPS (а то и 120), а также расскажу про интересные баги и особенности.
Ну а в третьей попробую разобрать всю систему целиком – от загрузки стекла до хранения, обработки, нагрузки, AI и интеграций.
Если, конечно, я до них доберусь 😄