Перейти к содержимому
Главная страница

CellProfiler: сегментация и измерение клеток на микроскопических изображениях

CellProfiler

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

Варианты загрузок
  • Обычная обработка фотографий
  • Цвет, экспозиция и кадрирование
  • Не заменяет научные вычисления
CellProfiler
  • Нужна настройка сегментации под данные
  • Нет инструментов художественной ретуши
  • Большие данные требовательны к памяти

Содержание:

Что именно делает CellProfiler

Основная единица работы в CellProfiler — pipeline, то есть последовательность модулей. Каждый модуль получает изображения, объекты или измерения от предыдущих шагов и передаёт результат дальше. Типичный конвейер начинается с четырёх входных модулей Images, Metadata, NamesAndTypes и Groups, после чего добавляются коррекция освещения, фильтрация, сегментация, измерения и экспорт. Такой подход важен не только ради удобства интерфейса: настройки каждого шага сохраняются в явном виде, поэтому один и тот же набор правил можно прогнать по сотням или тысячам полей зрения.

CellProfiler не является редактором фотографий в обычном смысле. Здесь нет задачи «сделать картинку красивее», вручную подрисовать область или подготовить коллаж. Даже когда программа создаёт производное изображение — например, маску, сглаженную копию, изображение с контурами или карту скорректированной освещённости, — это промежуточные данные для анализа либо материал для контроля качества. Главный продукт работы — измеряемые объекты и численные признаки, связанные с исходными файлами и метаданными эксперимента.

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

Установка и начало работы

Официальные сборки CellProfiler 4.2.8 доступны для Windows 10/11 и macOS 13+, а для Linux предлагается Flatpak; исходный код открыт, основной проект распространяется по лицензии BSD 3-Clause. На практике это означает, что лаборатория может использовать готовую сборку на рабочем компьютере, а при необходимости автоматизации или развёртывания в вычислительной среде работать с исходниками и командным запуском. Версия важна прежде всего для совместимости pipeline, плагинов, поддерживаемых форматов и поведения отдельных модулей, поэтому проект лучше сохранять вместе с указанием использованной версии программы.

После первого запуска в главном окне уже присутствуют четыре входных модуля: Images, Metadata, NamesAndTypes и Groups. Это не готовый анализ, а каркас проекта. Слева находится список модулей, справа — настройки выделенного шага, внизу — управление тестовым режимом и запуском анализа. Для знакомства полезно открыть примерный pipeline, похожий на собственные изображения, но затем пройти его модуль за модулем и понять, какие имена каналов, размеры объектов и правила порога в нём заложены.

Главное окно CellProfiler 4.2.5 со входными модулями Images, Metadata, NamesAndTypes и Groups

Проект CellProfiler и pipeline — разные сущности. Project с расширением .cpproj хранит не только набор модулей, но и список файлов проекта и часть связанной информации. Pipeline с расширением .cppipe удобнее для переноса самого алгоритма: его можно импортировать в другой проект и заново подать изображения. Поэтому для воспроизводимости разумно сохранять и проект для конкретного запуска, и экспортированный pipeline как переносимую спецификацию обработки.

Для нового анализа используйте File > New Project, затем добавьте изображения и настройте входные модули. Готовый pipeline импортируется через File > Import > Pipeline From File либо перетаскиванием .cppipe в панель Pipeline Modules. Проект сохраняется через File > Save Project или Save Project As, а pipeline — через File > Export > Pipeline. Папку результатов задавайте отдельно от исходных изображений: это снижает риск смешивания исходных файлов, временных масок и таблиц.

Главное окно и логика интерфейса

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

Кнопка с плюсом в блоке Adjust modules открывает список категорий. Модули можно добавлять, удалять, дублировать и перемещать. Те же операции доступны через Edit: Move Selected Modules Up/Down, Delete Selected Modules, Duplicate Selected Modules, Disable/Enable Module и Add Module. В сложном pipeline дублирование удобно для однотипных измерений разных каналов, но перед запуском полезно переименовывать промежуточные изображения и объекты так, чтобы по имени было понятно их происхождение: OrigDNA, DNA_Corrected, Nuclei, Cells, Cytoplasm понятнее, чем цепочка Image1, Image2 и Objects1.

Справа каждый модуль показывает собственные параметры. Маленькие кнопки со знаком вопроса открывают справку для конкретной настройки. Это особенно ценно в IdentifyPrimaryObjects, Threshold, CorrectIlluminationCalculate и измерительных модулях: одинаково звучащие варианты порога или сглаживания могут принципиально менять смысл результата. Интерфейс позволяет построить pipeline без программирования, но не отменяет необходимости понимать биологическое и математическое значение параметров.

Глаз рядом с модулем управляет показом его display window во время теста или анализа. Если открыть все окна на длинном pipeline, графический вывод может заметно замедлить работу и создать десятки окон. В меню Windows есть команды Show All Windows On Run и Hide All Windows On Run; для массового запуска обычно оставляют отображение только у нескольких контрольных модулей либо скрывают все окна после настройки.

Импорт изображений: модуль Images

Images формирует список файлов, с которыми будет работать проект. Самый прямой способ — перетащить файлы или папку в центральную область. Можно также вызвать контекстное меню и выбрать Browse For Images или Browse For Image Folder. В списке отображаются пути и содержимое каталогов, а двойной щелчок по файлу открывает изображение для просмотра. Удаление пункта из списка не удаляет файл с диска: команда Remove From File List меняет только проект.

CellProfiler с загруженным стартовым pipeline, списком изображений и открытым микроскопическим кадром

Не стоит бездумно добавлять целую экспериментальную папку, если в ней лежат превью, маски, старые результаты, таблицы и служебные изображения. В Images есть фильтрация списка файлов; она должна пропускать только те элементы, которые реально относятся к анализу. Это особенно важно, когда NamesAndTypes затем собирает изображения в многоканальные наборы: случайный TIFF с похожим именем может нарушить соответствие каналов или создать лишний image set.

CellProfiler читает множество научных форматов через Bio-Formats, поэтому в проектах встречаются TIFF/OME-TIFF, PNG и форматы производителей микроскопов. Для измерений предпочтительны форматы без потерь. JPEG может быть пригоден для визуальных задач, но компрессия изменяет значения пикселей и создаёт блоковые артефакты; если вы собираетесь измерять интенсивность, текстуру или слабые границы, исходные несжатые либо lossless-файлы надёжнее.

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

Metadata: извлечение условий эксперимента

Metadata связывает изображение с экспериментальными признаками: номером планшета, лункой, полем, каналом, временем, обработкой и другими метками. Источником могут быть имя файла, имя папки, заголовок изображения или внешняя CSV-таблица. Самый распространённый вариант — регулярное выражение с именованными группами, которое извлекает части систематического имени файла. Например, из строки с кодом лунки, site и channel можно получить отдельные значения Well, Site и ChannelNumber.

После настройки нажмите Update и посмотрите таблицу извлечённых полей. Проверка нескольких первых строк недостаточна: возьмите файлы из начала, середины и конца серии, разные лунки и разные каналы. Если регулярное выражение слишком широкое, оно может совпадать и с нежелательными файлами; если слишком узкое — часть серии останется без ключевого metadata. Отсутствие метаданных потом проявится в NamesAndTypes как неполные наборы или неверный порядок.

Модуль Metadata с извлечением метаданных из имени файла регулярным выражением

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

Метаданные затем доступны не только для группировки. Их можно включать в имена экспортируемых файлов, добавлять в object-level CSV, использовать для разбиения результатов по группам и сохранять рядом с измерениями. Это превращает набор изображений в структурированный эксперимент: таблица после анализа содержит не абстрактные строки, а измерения, к которым можно присоединить биологическое условие.

NamesAndTypes: как собрать каналы в image set

NamesAndTypes присваивает данным смысловые имена и определяет тип изображения. Для многоканальной съёмки удобен режим Images matching rules: каждое правило выбирает нужные файлы по имени или metadata и присваивает им имя, например OrigDNA, OrigActin, OrigTubulin. Все последующие модули обращаются уже к этим именам, а не к путям. Поэтому здесь закладывается «система координат» всего pipeline.

Настроенный NamesAndTypes с правилами сопоставления каналов DNA, Actin и Tubulin

Для каждого входа задаётся Select the image type. Большинство сегментационных и измерительных модулей ожидают grayscale image. Если на входе RGB, а нужно анализировать отдельный красный или зелёный канал, лучше явно разделить цветовое изображение модулем ColorToGray. NamesAndTypes также умеет загружать label image как Objects, когда у вас уже есть готовая сегментационная маска с целочисленными метками объектов.

Параметр Set intensity range from критически важен для количественной флуоресценции. CellProfiler обычно представляет интенсивности в диапазоне 0–1, нормируя их относительно выбранного максимума. Если двум сериям назначить разные правила диапазона или неверно интерпретировать битность, абсолютные численные значения становятся несопоставимыми. Поэтому настройку интенсивности документируйте и не меняйте между экспериментальными группами без причины.

В нижней таблице NamesAndTypes можно проверить итоговое сопоставление: какие файлы попали в один image set и какие имена им назначены. Если наборов меньше ожидаемого, ищите слишком строгий фильтр. Если больше — возможно, один канал не участвует в matching или в имени файла отсутствует ключевой metadata. Проверять эту таблицу лучше до добавления сложной сегментации: исправление входов потом автоматически устраняет десятки последующих «аномалий».

Groups: независимые серии, планшеты и временные ряды

Groups нужен не каждому pipeline. Если каждый image set анализируется полностью независимо, группировку можно выключить. Она становится существенной, когда операция должна видеть последовательность связанных кадров или отдельный экспериментальный блок: time-lapse, несколько планшетов, партии изображений для общей коррекции освещения, серии Z-срезов или наборы, по которым экспорт должен выполняться раздельно.

Группы строятся по metadata. Например, для нескольких временных рядов можно группировать по Plate, Well и Site, оставляя Time как переменную внутри группы. TrackObjects тогда не перепутает последнюю клетку одного поля с первой клеткой другого. Для коррекции освещения по планшету можно группировать по Plate, чтобы функция освещения вычислялась отдельно для каждого планшета, а не усредняла неодинаковые условия съёмки.

Ошибку группировки трудно заметить визуально на одном кадре, поэтому проверяйте порядок image set. Если параметр времени сортируется как текст, строки 1, 10, 11, 2 могут идти не в хронологическом порядке; числовой тип metadata устраняет такую проблему. При трекинге это принципиально: алгоритм предполагает последовательное движение по кадрам.

Как строить pipeline без хаотической настройки

Надёжный порядок разработки — сначала входы, затем один репрезентативный image set, затем сегментация, измерения и только после этого массовый запуск. Не начинайте с десятков модулей. Добавьте минимальный путь: Images → Metadata → NamesAndTypes → IdentifyPrimaryObjects → одно нужное измерение → ExportToSpreadsheet. Добейтесь правильной сегментации на нескольких разных изображениях, после чего усложняйте цепочку.

Модули добавляются кнопкой «+» в Adjust modules либо через Edit > Add Module. В окне выбора слева находятся категории, справа — конкретные модули. Для задач анализа клеток чаще всего используются Image Processing, Object Processing, Measurement и File Processing. Порядок можно менять стрелками, перетаскиванием или командами Edit. Если требуется сравнить две настройки одного шага, проще Duplicate Selected Modules и дать выходам разные имена, чем постоянно переписывать значения.

Название выходного изображения или объекта выбирайте как технический идентификатор. Оно должно быть коротким, но содержательным: DNA_Smooth, NucleiRaw, NucleiFiltered, CellMask. Избегайте пробелов и двусмысленных слов, если pipeline будет использоваться в headless-режиме и внешних скриптах. При большом числе каналов полезно придерживаться шаблона «биологический канал + стадия обработки».

Многие модули образуют пары. CorrectIlluminationCalculate создаёт функцию освещения, CorrectIlluminationApply применяет её. ConvertObjectsToImage превращает объектные метки в изображение, SaveImages сохраняет выбранный результат. MeasureObjectSizeShape вычисляет признаки, FilterObjects может затем использовать их как критерий. RelateObjects назначает родительские и дочерние связи, после чего экспорт содержит дополнительные relationship-измерения. Планируя pipeline, думайте не о списке кнопок, а о типах данных между шагами.

Test Mode: главный инструмент настройки

Перед массовым Analyze Images включайте Test > Start Test Mode. В тестовом режиме у модулей появляются элементы пошагового выполнения, а внизу — Run, Step, Next Image Set и выход из режима. Step выполняет следующий модуль; Run идёт до следующей паузы или конца pipeline. Можно вернуться к уже выполненному шагу, изменить параметр и повторить вычисление без запуска всего проекта.

Меню Test в CellProfiler с командой Start Test Mode и модулем ColorToGray

Команды Test > Next Image Set, Random Image Set и Choose Image Set позволяют проверять pipeline не только на первом удачном поле. Это обязательная часть разработки. Выберите изображения с низкой и высокой плотностью клеток, слабой и сильной флуоресценцией, краевыми объектами, разным фоном и артефактами. Параметр, который идеально работает на одном «красивом» кадре, часто разваливается на экстремальных случаях.

Активный Test Mode в CellProfiler с кнопками Run, Step и управлением выполнением модуля

В display window модулей используйте масштабирование и панорамирование. В IdentifyPrimaryObjects смотрите не только на число объектов, но и на контуры, отброшенные элементы и разделение кластеров. В MeasureObjectSizeShape окно показывает агрегированные характеристики по изображению, поэтому для проверки отдельных объектов лучше использовать DisplayDataOnImage либо экспортировать таблицу на небольшой тестовой серии.

Когда pipeline стабилен, выключите ненужные display windows и выйдите из Test Mode. Полноценный Analyze Images обрабатывает все image set. Тестовый режим предназначен для настройки, а не для получения окончательной статистики: он позволяет прыгать между изображениями и повторять отдельные шаги, поэтому последовательность выполнений не эквивалентна обычному массовому запуску.

Подготовка изображения перед сегментацией

Хорошая сегментация начинается не с перебора порогов, а с корректного входного сигнала. Если объект тёмный на светлом фоне, его можно инвертировать через ImageMath, поскольку многие схемы IdentifyPrimaryObjects рассчитаны на светлые объекты на тёмном фоне. RGB-изображение разделяется ColorToGray. Неровный фон исправляется коррекцией освещения. Шум иногда полезно снизить Smooth, GaussianFilter или ReduceNoise, но чрезмерное сглаживание сливает близкие структуры и смещает границы.

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

Threshold может создавать бинарное изображение отдельно от Identify-модулей. Это удобно, когда нужно получить простой foreground/background, измерить площадь занятой области или передать бинарный результат в Watershed. Доступны глобальные и адаптивные стратегии, различные методы порогования и корректирующий коэффициент. Адаптивный порог полезен при пространственно меняющемся фоне, но размер окна должен быть крупнее локальных объектов и достаточно мал, чтобы следовать неоднородности освещения.

Коррекция неоднородного освещения

CorrectIlluminationCalculate строит функцию освещения, которая описывает плавное пространственное изменение фона или чувствительности по полю зрения. В режиме Regular функция основана на интенсивности пикселей и обычно применяется делением; Background оценивает фон между объектами и чаще сочетается с вычитанием. Затем CorrectIlluminationApply создаёт скорректированное изображение через Divide или Subtract.

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

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

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

IdentifyPrimaryObjects: сегментация ядер и других первичных объектов

IdentifyPrimaryObjects предназначен для объектов, которые можно найти по одному grayscale-каналу без опоры на уже известный объект. Классический пример — ядра, окрашенные ДНК-красителем. В простом режиме достаточно указать входное изображение, имя выходных объектов и Typical diameter of objects. При включении advanced settings доступны стратегия и метод threshold, параметры сглаживания, способы разъединения слипшихся объектов, границы порога и правила обработки объектов на краю.

Typical diameter задаётся в пикселях и влияет не только на фильтрацию по размеру, но и на некоторые параметры declumping. Не переносите диапазон из чужого pipeline без пересчёта масштаба. Ядро диаметром 25 пикселей в одном микроскопе после изменения объектива, биннинга или ресайза может занимать совершенно другое число пикселей. Сначала измерьте несколько объектов инструментом длины в display window или по известному pixel size.

Порог отвечает за отделение foreground от background. Global использует единый критерий на изображение; Adaptive рассчитывает локальные пороги и лучше переносит градиент фона. Otsu подходит для многих флуоресцентных данных, но не является универсальной кнопкой. Если распределения интенсивностей сильно перекрываются, слабые объекты могут исчезнуть, а шум — стать объектами. Threshold correction factor позволяет систематически сделать порог строже или мягче, но изменение коэффициента должно проверяться на разных условиях.

После threshold начинается declumping — разделение соприкасающихся объектов. CellProfiler может искать центры по Shape или Intensity и проводить разделительные линии различными методами. Если локальных максимумов слишком много, один объект дробится на части; если их мало — соседние ядра сливаются. Размер сглаживания и минимальное расстояние между максимумами следует согласовывать с размером объекта. Хороший результат — не максимальное число сегментов, а биологически правдоподобные границы на репрезентативной выборке.

Display window IdentifyPrimaryObjects обычно показывает исходное изображение, цветную label image, контуры на исходном канале и таблицу параметров. Цвета меток произвольны и нужны, чтобы различать соседние объекты. Контуры полезнее для контроля: видно, где алгоритм отрезает края, сливает пары и принимает мусор за ядро. Объекты, отброшенные по размеру или из-за касания границы, также можно оценивать визуально.

Как оценивать качество порога и declumping

Сегментация должна быть устойчивой не только по среднему полю, но и по краям распределения. Сформируйте небольшой набор контрольных изображений: минимальная плотность, максимальная плотность, слабый сигнал, яркий сигнал, сильный фон, фокус хуже среднего. В Test Mode переходите между ними через Random Image Set или Choose Image Set. После каждой правки спрашивайте, какой класс ошибок уменьшился и какой вырос.

Если адаптивный порог улучшает тёмные участки, но съедает часть ярких ядер, проверьте размер локального окна и коррекцию порога. Если Shape-declumping лучше разделяет плотные скопления, но режет вытянутые ядра, возможно, интенсивностные максимумы дадут более биологичный центр. Универсального сочетания нет: параметры зависят от морфологии, окраски и разрешения.

Не подгоняйте pipeline под число клеток, которое «должно» получиться. Такая обратная подстройка легко скрывает систематические ошибки. Сначала создайте визуальную контрольную выборку и оцените типичные false positive, false negative, merge и split. Для критических задач можно вручную разметить небольшое число полей и сравнить count, Dice/IoU или другие метрики во внешнем инструменте.

Разница между глобальным и локальным порогом хорошо видна на контурных наложениях: одна и та же область может быть включена или исключена без явной ошибки интерфейса. Поэтому сохранять только конечную CSV недостаточно. Для аудита стоит сохранить примеры overlay или label masks, особенно если pipeline используется в публикации или между лабораториями.

IdentifySecondaryObjects и IdentifyTertiaryObjects

IdentifySecondaryObjects строит объект вокруг уже найденного первичного объекта. Типичная схема: ядро является primary object, а клетка — secondary object. На вход подаётся изображение, по которому видна граница клетки, и набор ядер. Алгоритм расширяет область от каждого ядра и определяет границы по интенсивности или геометрическому правилу. В результате каждой клетке соответствует максимум один исходный primary object.

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

Если клеточная граница вообще не видна, можно определять вторичный объект на фиксированном расстоянии от ядра. Это не «настоящая клетка», а аналитическая область вокруг ядра. Такой ROI может быть оправдан, например, для локального фонового измерения, но его нельзя интерпретировать как площадь клетки. Имя объекта должно отражать смысл, например PerinuclearRing, а не Cells.

IdentifyTertiaryObjects формирует объект из разности двух уже известных наборов. Классический пример — Cytoplasm = Cells минус Nuclei. Это удобно для транслокационных анализов: измерить среднюю интенсивность маркера отдельно в ядре и цитоплазме, затем вычислить отношение. Если исходные ядра или клетки сегментированы неправильно, третичный объект автоматически наследует ошибку, поэтому сначала проверяйте оба родительских набора.

Контраст display window и контроль границ

Слабое отображение не означает слабый сигнал в данных. В окнах результатов можно менять визуальную нормализацию через меню Subplots и Adjust Contrast, не изменяя само аналитическое изображение. Это полезно, когда клеточная граница есть, но на линейном показе почти не видна. Логарифмическая нормализация может сделать слабые структуры заметнее для контроля контуров.

Важно различать «настройку display» и «обработку изображения». Изменение контраста в окне просмотра предназначено для визуализации и не становится частью pipeline. Если нужно реально усилить или преобразовать сигнал перед segmentation, добавляйте явный модуль ImageMath, RescaleIntensity, EnhanceOrSuppressFeatures или другой подходящий шаг. Так обработка остаётся воспроизводимой.

При оценке secondary objects увеличивайте проблемные участки: места контакта трёх-четырёх клеток, края кадра, области со слабым цитоплазматическим сигналом. Контур, который выглядит приемлемо на полном кадре, при увеличении может проходить через ядро соседней клетки или захватывать большой фон. Такие ошибки особенно сильно искажают площадь, mean intensity и texture.

Watershed и объёмные данные

IdentifyPrimaryObjects в актуальной документации ориентирован на 2D; для объёмной сегментации следует использовать Watershed и модули, поддерживающие 3D. В NamesAndTypes для объёмных данных включается Process as 3D и задаётся относительный pixel spacing по X, Y и Z. Это важно, потому что Z-шаг часто отличается от размера пикселя в плоскости, а алгоритмы расстояния без учёта анизотропии будут искажать форму.

3D-pipeline требует более строгого контроля памяти. Объём из сотен плоскостей, несколько каналов и промежуточные массивы быстро занимают гигабайты. Начинайте с небольшого volume, отключайте ненужные display windows, сохраняйте только необходимые промежуточные данные. Если задача допускает 2D-анализ отдельных проекций, он дешевле вычислительно, но это другой биологический вопрос: проекция теряет глубинную информацию и может сливать объекты.

Watershed полезен и в 2D как самостоятельный объектный модуль, когда вы заранее подготовили marker image, binary mask или distance map. Такой путь даёт больше контроля, чем один монолитный Identify-модуль: можно отдельно посмотреть каждый промежуточный образ и понять, где появилась ошибка. Цена — более длинный pipeline и больше параметров, которые нужно документировать.

Постобработка объектов

После сегментации объектный набор часто очищают. FilterObjects удаляет объекты по уже рассчитанным признакам — площади, форме, интенсивности, текстуре и другим измерениям. Важно: прошедшие фильтр элементы образуют новый object set и не наследуют автоматически все старые measurements. Если вы хотите получить окончательные признаки именно для очищенного набора, разместите нужные Measure-модули после FilterObjects.

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

RelateObjects связывает дочерние элементы с родительскими. Например, сегментированные ядерные фокусы можно назначить ядрам, а затем получить Children_Count и агрегировать измерения дочерних объектов. Это мощнее простого подсчёта пятен на изображении: одна строка таблицы для каждого ядра может содержать число фокусов и их средние характеристики.

ClassifyObjects классифицирует объекты по измерениям либо модели, а SplitOrMergeObjects, MaskObjects, CombineObjects и ResizeObjects помогают перестроить label sets. Такие модули полезны, но их стоит добавлять только когда есть конкретная аналитическая причина. Каждый дополнительный шаг усложняет интерпретацию: в итоговой таблице необходимо понимать, какой набор объектов измерялся и как он был получен.

MeasureObjectSizeShape: площадь и морфология

MeasureObjectSizeShape вычисляет площадь, периметр и широкий набор дескрипторов формы для каждого объекта. Для 2D-клеток особенно часто используют Area, Perimeter, Eccentricity, Solidity, Extent, MajorAxisLength, MinorAxisLength и FormFactor. Конкретный набор доступных признаков зависит от версии и размерности, но общий принцип один: метрики вычисляются из label mask, а не из визуальной яркости изображения.

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

Не путайте display агрегаты и per-object data. Окно MeasureObjectSizeShape показывает сводные значения по текущему изображению, тогда как каждая клетка получает собственную строку при экспорте. Чтобы увидеть индивидуальный Area или Eccentricity непосредственно на кадре, используйте DisplayDataOnImage либо изучите CSV после короткого тестового запуска.

Морфологические показатели чувствительны к качеству маски. Небольшая ошибка границы иногда почти не меняет count, но заметно влияет на Perimeter, Solidity и texture. Если научный вывод основан на форме, сегментацию нужно валидировать строже, чем для простого подсчёта объектов.

MeasureObjectIntensity: количественная флуоресценция

MeasureObjectIntensity берёт один или несколько grayscale-каналов и измеряет их внутри выбранных объектов. Среди типичных выходов — IntegratedIntensity, MeanIntensity, StdIntensity, MaxIntensity, MinIntensity, квартильные характеристики и координаты центра интенсивности. Если указать несколько images и несколько object sets, модуль создаёт измерения для всех выбранных комбинаций, поэтому при большом pipeline лучше разделять логические группы на несколько модулей и не генерировать лишние пары.

MeanIntensity отвечает на вопрос о среднем уровне сигнала в объекте, IntegratedIntensity суммирует все пиксели и поэтому зависит от площади. Для растущей клетки integrated signal может увеличиться даже при той же средней концентрации маркера. Выбор метрики должен следовать биологической гипотезе, а не удобству столбца в таблице.

Интенсивности микроскопии обычно рассматриваются в условных единицах. Между днями съёмки, настройками экспозиции и приборами абсолютная шкала может меняться. CellProfiler корректно считает то, что записано в пикселях, но не выполняет биологическую нормализацию автоматически. Контроль экспозиции, фон, flat-field correction и downstream normalization — отдельные части дизайна эксперимента.

Если вы измеряете ядерную транслокацию, получите Nuclei и Cytoplasm, измерьте MeanIntensity маркера в обоих наборах и затем вычислите отношение во внешнем анализе либо CalculateMath, если структура pipeline это позволяет. Важно экспортировать идентификаторы родителей, чтобы строки ядра и клетки можно было сопоставить.

Распределение интенсивности, гранулярность и текстура

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

MeasureGranularity анализирует характерный размер ярких структур после последовательных морфологических преобразований. Он полезен для гранул, везикул и других точечных паттернов, когда количество отдельных объектов трудно сегментировать напрямую. Параметры масштаба должны соответствовать размеру структуры; сравнивать granularity при разных разрешениях без пересчёта нельзя.

MeasureTexture вычисляет текстурные признаки, в том числе Haralick features по матрице совместной встречаемости уровней серого. Scale задаёт расстояние между сравниваемыми пикселями: маленький scale чувствителен к мелкой текстуре, большой — к крупным паттернам. Модуль может также вычислять Gabor-признаки, которые чувствительны к полосчатой структуре и ориентации.

Texture особенно легко «раздувает» число столбцов. Несколько каналов × несколько object sets × несколько scales × направления дают сотни features. Не экспортируйте их автоматически «на всякий случай», если downstream-анализ не умеет работать с высокой размерностью и мультиколлинеарностью. Для морфологического профилирования широкий feature set оправдан, но там обычно предусмотрены нормализация, контроль качества и отбор признаков.

Соседи, колокализация и пространственные отношения

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

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

Для анализа пятен внутри клеток часто лучше сначала сегментировать puncta как отдельные child objects, затем RelateObjects назначить их ядрам или клеткам. Так можно получить count, площадь, интенсивность каждого фокуса и суммарные признаки по родителю. Простое измерение общей текстуры отвечает на другой вопрос и не заменяет объектный анализ.

Качество изображения и флаги

Высокопроизводительный анализ почти всегда нуждается в image-level QC. Фокус, насыщение, чрезвычайно яркий фон, пустая лунка и артефакты могут сделать отдельный кадр несопоставимым с остальными. MeasureImageQuality и другие image-level измерения дают признаки, по которым можно находить такие случаи, а FlagImage — отмечать изображения или группы, не соответствующие критериям.

QC лучше строить как отдельный слой pipeline. Сначала измерьте показатель, затем сохраните его в выходной таблице и сформулируйте порог на основе контрольных данных. Не скрывайте проблемные изображения автоматически до того, как увидите распределение: слишком строгий threshold может систематически исключить биологически интересное состояние, например клетки с действительно необычной морфологией.

В больших скринингах полезно сохранять несколько контрольных визуализаций на plate или condition: overlay ядер и клеток, изображение после illumination correction, примеры high/low QC. Полная ручная проверка тысяч полей невозможна, но стратифицированная выборка помогает обнаружить систематический сбой pipeline.

Экспорт таблиц через ExportToSpreadsheet

ExportToSpreadsheet сохраняет measurements в разделённые текстовые файлы, обычно CSV. Можно экспортировать все признаки либо выбрать нужные. Для каждого object set создаётся таблица с per-object rows, отдельно могут сохраняться image-level, experiment-level и object relationships. Это один из самых прозрачных способов передать результат в R, Python, Excel или систему статистической обработки.

Имена столбцов CellProfiler кодируют смысл. Общая схема включает тип объекта или Image, категорию, конкретный признак и параметры, например имя канала и scale. Столбец вида Intensity_MeanIntensity_DNA относится к среднему интенсивностному признаку в канале DNA, а AreaShape_Area не требует имени канала, потому что вычисляется по геометрии маски.

Если Metadata настроен, добавьте metadata columns в object data. Тогда каждая клетка будет не только иметь ObjectNumber и measurements, но и Plate, Well, Site, Treatment или другие экспериментальные ключи. Это существенно упрощает downstream join: не нужно восстанавливать условие из имени файла регулярным выражением второй раз.

Опция Overwrite without warning удобна для headless и кластерного запуска, но опасна при интерактивной настройке: можно перезаписать прошлый результат той же папки. Для воспроизводимости лучше создавать отдельный output directory для каждого запуска или включать идентификатор experiment/run в путь.

ExportToDatabase и CellProfiler Analyst

ExportToDatabase предназначен для ситуаций, где CSV становится неудобным из-за объёма или требуется дальнейшая работа в CellProfiler Analyst. База лучше масштабируется для миллионов строк и поддерживает связи между изображениями, объектами и measurements. При подготовке CPA проект должен содержать необходимые пути к изображениям, ключи и свойства; если изменить структуру файлов после экспорта, просмотр изображений может перестать работать.

CellProfiler Analyst — отдельное приложение. Не следует приписывать его Classifier, Plate Viewer или Image Gallery самому CellProfiler. CellProfiler извлекает объекты и признаки; Analyst использует эти данные для интерактивного просмотра, классификации и анализа. В статье или протоколе указывайте обе программы, если workflow действительно разделён между ними.

Для обычного эксперимента с десятками тысяч клеток CSV часто достаточно. База данных оправдана, когда нужно хранить очень большие наборы per-cell features, связывать их с изображениями и многократно выполнять запросы. Формат следует выбирать на этапе проектирования, потому что переход после длительного анализа может потребовать повторного запуска Export-модулей.

SaveImages: когда сохранять промежуточные изображения

CellProfiler по умолчанию не сохраняет каждое изображение, созданное внутри pipeline. Для этого нужен SaveImages. Модуль может сохранить обработанное изображение, маску, cropping, objects или последовательность кадров. Это полезно для QC, передачи масок в другой инструмент, создания reference images и архивирования ключевых промежуточных стадий.

Не ставьте SaveImages после каждого модуля в большом проекте: объём диска быстро возрастёт, а запись на диск станет узким местом. Определите минимальный набор: например, corrected channel, label mask и overlay для небольшой доли изображений. Если downstream-модель требует отдельные кропы объектов, используйте SaveCroppedObjects и заранее оцените количество файлов.

При сохранении label masks выбирайте формат, способный вместить нужное число меток и не искажать значения. Для 16-bit TIFF поддерживается соответствующая глубина, а 12-bit сохранение не поддерживается. Цветная картинка с контурами удобна человеку, но для повторного анализа нужна именно целочисленная label image либо объектные данные.

Практический сценарий: ядра, клетки и цитоплазма в трёх каналах

Рассмотрим типичный набор: DNA, actin и protein-of-interest. Имена файлов содержат Well, Site и Channel. Задача — получить по каждой клетке площадь ядра и клетки, среднюю интенсивность белка в ядре и цитоплазме и число объектов на поле. Такой pipeline удобно строить по следующей схеме.

  1. В Images добавьте только исходные изображения нужного эксперимента и проверьте, что служебные файлы исключены.
  2. В Metadata извлеките Plate, Well, Site и Channel из имени либо присоедините CSV с Treatment.
  3. В NamesAndTypes назначьте каналы OrigDNA, OrigActin и OrigProtein и сопоставьте их по Plate/Well/Site.
  4. При необходимости скорректируйте освещение отдельно для каждого канала через CorrectIlluminationCalculate и CorrectIlluminationApply.
  5. IdentifyPrimaryObjects: сегментируйте Nuclei по DNA, настройте размер, threshold и declumping в Test Mode.
  6. IdentifySecondaryObjects: постройте Cells по actin, используя Nuclei как seeds.
  7. IdentifyTertiaryObjects: создайте Cytoplasm как разность Cells и Nuclei.
  8. MeasureObjectSizeShape: измерьте Nuclei и Cells.
  9. MeasureObjectIntensity: измерьте OrigProtein или корректированный protein channel в Nuclei и Cytoplasm.
  10. ExportToSpreadsheet: экспортируйте object tables и metadata; при необходимости SaveImages сохранит контрольный overlay.

После настройки не запускайте сразу весь plate. Выберите несколько wells с разными условиями и по два-три sites из каждого. Посмотрите, не меняется ли характер background между условиями, не насыщен ли signal и одинаково ли сегментируются клетки разных фенотипов. Если обработка сама зависит от фенотипа — например, крупные клетки систематически отбрасываются диапазоном diameter — результат будет смещён.

Для ratio nucleus/cytoplasm учитывайте, что маленькая cytoplasm region может давать нестабильное среднее, особенно если Cell и Nucleus почти совпадают. Добавьте фильтр по минимальной площади Cytoplasm либо анализируйте такие клетки отдельно. Не удаляйте их без записи причины: QC-правило должно быть воспроизводимым.

Практический сценарий: подсчёт пятен внутри ядра

Если нужно посчитать ядерные foci, сначала сегментируйте Nuclei по стабильному DNA-каналу. Затем подготовьте spot channel: вычитание плавного фона или EnhanceOrSuppressFeatures может повысить локальный контраст, но параметры должны соответствовать размеру foci. Второй IdentifyPrimaryObjects создаёт объектный набор Spots на обработанном канале.

Чтобы пятна вне ядер не попадали в анализ, используйте MaskObjects или MaskImage с ядерной маской до сегментации. После этого RelateObjects назначит Spots родительским Nuclei. В таблице появится число дочерних объектов на ядро; дополнительно MeasureObjectIntensity и MeasureObjectSizeShape дадут яркость и площадь каждого spot.

Проблема такого анализа — слипшиеся пятна и насыщение. Если два foci сливаются в один яркий объект, count уменьшается, а area и integrated intensity растут. Поэтому при валидации смотрите одновременно на Count и distribution размера. Если размер расплывается к крупным значениям в условиях с сильным сигналом, возможно, declumping требует настройки.

Практический сценарий: brightfield, phase contrast и DIC

CellProfiler лучше всего чувствует себя на изображениях, где foreground хорошо отделяется по интенсивности. В brightfield, phase contrast и DIC границы объектов часто состоят из светлых и тёмных ореолов, а внутри клетки контраст неоднороден. Прямой IdentifyPrimaryObjects может давать нестабильный результат. Документация рекомендует предварительную обработку, включая EnhanceOrSuppressFeatures с подходящими настройками, а для сложных случаев — использование внешней pixel classification, например ilastik.

Практическая стратегия: сначала получить probability map «cell/background» в ilastik, затем загрузить её в CellProfiler как отдельное изображение и threshold/Watershed превратить в objects. Так машинное обучение решает сложную задачу выделения пикселей, а CellProfiler берёт на себя object-level измерения, метаданные и массовую обработку.

Если применяется нейросетевая сегментация Cellpose или StarDist через плагины и внешние модули, фиксируйте версию модели, параметры диаметра и среду. Результат такой цепочки воспроизводим только при сохранении не одного .cppipe, но и зависимостей плагина и модели.

Практический сценарий: многолунковый скрининг

В 96- или 384-well plate объём файлов быстро становится главным организационным риском. Metadata должен однозначно кодировать Plate, Well, Site и Channel. Treatment лучше хранить во внешней таблице plate map, чтобы не зашивать биологические условия в имя файла. NamesAndTypes объединяет каналы одного site, Groups при необходимости разделяет plate или другие серии.

Коррекцию освещения обычно рассчитывают по большому числу полей, потому что она должна отражать оптику, а не отдельную клетку. Если разные plates снимались в разные дни или на разных настройках, безопаснее строить illumination function внутри соответствующей группы. Затем image-level QC позволяет выявить пустые поля, расфокус и аномальный фон до анализа phenotype.

При экспорте добавляйте metadata в object tables. Downstream aggregation выполняйте отдельно: сначала нормализуйте per-cell features, затем рассчитывайте summary по Well и Treatment. CellProfiler может давать image-level агрегаты, но статистический дизайн скрининга — включая репликаты, plate effects и контрольные лунки — должен задаваться осознанно.

Time-lapse и TrackObjects

TrackObjects связывает объекты между последовательными кадрами, поддерживая уникальный идентификатор траектории. До него должен стоять сегментационный модуль, создающий объекты на каждом кадре. Metadata и Groups обязаны корректно разделять разные фильмы и сортировать время. Ошибка в порядке кадров делает любой трекинг бессмысленным.

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

Перед полным запуском проверьте несколько траекторий вручную: быстро движущиеся объекты, деления, контакты и области высокой плотности. Сохраняйте TrackObjects measurements вместе с исходным ObjectNumber и metadata timepoint, чтобы downstream-скрипт мог восстановить временную последовательность.

Плагины и интеграция с внешними инструментами

CellProfiler имеет механизм внешних модулей. Официальный репозиторий CellProfiler-plugins содержит экспериментальные и community-модули, включая интеграции с современными алгоритмами. Установка плагина не равна установке обычной кнопки: некоторым модулям нужны дополнительные Python-зависимости, которые должны попасть в окружение приложения.

Путь к папке плагинов задаётся в Preferences. После добавления модуля проверьте, что он загружается без ошибки и появляется в Add Module. Если plugin требует пакет, установка в системный Python может не помочь, потому что готовая сборка CellProfiler использует собственное окружение. Документация плагина обычно указывает, куда ставить requirements.

Интеграция с Fiji/ImageJ полезна, когда конкретный фильтр или макрос доступен там, но итоговый pipeline должен оставаться воспроизводимым. RunImageJMacro и аналогичные механизмы зависят от версии и конфигурации. Если такой модуль является критическим, архивируйте макрос рядом с .cppipe и описывайте ожидаемую версию Fiji.

Связка с ilastik часто строится через probability maps: ilastik обучает pixel classifier по пользовательским штрихам и экспортирует вероятности, CellProfiler преобразует их в объекты и измеряет признаки. Это хороший пример разделения ролей: интерактивное обучение там, где классический threshold слаб, и прозрачный массовый object analysis в CellProfiler.

Производительность и память

Скорость CellProfiler зависит не только от числа изображений. На неё влияют размер каждого кадра, bit depth, число каналов, количество промежуточных images, число объектов, texture scales, Gabor features, 3D, display windows, чтение с сетевого диска и запись большого числа файлов. Поэтому невозможно честно дать универсальное время «на тысячу снимков» без данных о pipeline и оборудовании.

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

Сетевое хранилище может ограничивать скорость сильнее CPU. Тысячи маленьких TIFF и CSV создают большой I/O overhead. Для тестирования удобно скопировать небольшой subset локально и сравнить поведение. При переносе на кластер пути к входным и выходным папкам должны быть корректно преобразованы, что поддерживает CreateBatchFiles.

При out-of-memory сначала уменьшите масштаб задачи: меньше image sets, меньший volume, меньше одновременно хранимых промежуточных изображений. Для 3D и очень больших снимков учитывайте, что CellProfiler не является специализированным multiscale whole-slide viewer с автоматическим tile/chunk processing. Если исходник огромен, предварительное разбиение или инструмент вроде QuPath может быть практичнее.

Batch processing и CreateBatchFiles

CreateBatchFiles ставится ближе к концу pipeline и готовит файлы для разделения набора на независимые задачи на вычислительном кластере. Модуль умеет преобразовывать корневые пути, если локальная машина видит данные как Windows-диск, а cluster — как Unix-путь. Это не делает кластер из одного компьютера: необходима внешняя система запуска jobs.

До batch processing pipeline должен быть полностью отлажен на representative subset. Запуск сотен задач с неправильным threshold просто быстрее создаст неправильный результат. Кроме того, все узлы должны иметь доступ к одинаковым исходным данным, output storage и зависимостям плагинов.

Для headless выполнения избегайте настроек, требующих диалогов подтверждения, например «не перезаписывать без вопроса». Логи и exit status нужно сохранять, чтобы различать успешно завершённые и упавшие batches. После распределённого запуска проверяйте число output rows и ожидаемое число image sets: отсутствие ошибки в scheduler ещё не гарантирует полноту результата.

Воспроизводимость: project, pipeline и provenance

.cppipe сохраняет последовательность модулей и параметры, но не является полным научным протоколом. Для воспроизводимости также нужны версия CellProfiler, версия плагинов, сведения о модели, если применялась ML-сегментация, описание исходных каналов, bit depth, масштаб пикселя и правила metadata. Если изменение сделано после предварительного запуска, фиксируйте номер ревизии pipeline.

Проект .cpproj полезен, потому что хранит список файлов, но абсолютные пути могут не работать на другом компьютере. Переносимый процесс строят так: данные организованы по предсказуемой структуре, Metadata извлекает ключи из имени/папки, а .cppipe не зависит от конкретного локального диска. При открытии на новой машине входы заменяются, после чего NamesAndTypes должен собрать те же image sets.

Сохраняйте контрольные изображения и небольшой benchmark dataset. Когда обновляется версия CellProfiler или plugin, прогоните этот subset и сравните count, masks и ключевые measurements. Это обнаруживает изменения поведения раньше, чем они попадут в большой эксперимент.

Типичные ошибки и способы их исправления

Каналы не объединяются в один image set

Симптом: NamesAndTypes показывает меньше наборов, появляются missing image или лишние строки. Причина почти всегда в правилах matching или metadata. Проверьте одинаковы ли Plate, Well, Site для каналов одного поля, не содержит ли один файл другой формат номера лунки, правильно ли извлекается Channel. Нажмите Update и сравните таблицу на нескольких примерах.

IdentifyPrimaryObjects находит слишком много мусора

Сначала исключите техническую причину: неверный канал, неправильная intensity range, JPEG-артефакты, сильный uneven background. Затем попробуйте более строгий threshold, корректировку освещения, минимальный diameter или preprocessing. Не используйте только фильтр по площади, если мелкий мусор систематически влияет на threshold всей сцены.

Соседние ядра постоянно сливаются

Проверьте declumping method и расстояние между локальными максимумами. Если nuclei имеют яркие центры, Intensity может давать лучшие seeds; если интенсивность однородна, Shape иногда стабильнее. Слишком сильное smoothing уничтожает седловины между объектами. Слишком большой minimum distance подавляет второй максимум и оставляет слипшийся объект.

Одно ядро делится на несколько объектов

Это противоположная проблема: локальных максимумов слишком много. Увеличьте сглаживание для declumping или minimum distance, проверьте, нет ли ярких внутренних пятен. Если ядра имеют естественно неоднородную интенсивность, Shape может быть устойчивее Intensity.

Secondary objects захватывают соседние клетки

Посмотрите канал границ и сравните Propagation с Watershed. Если цитоплазматический сигнал слаб, алгоритм вынужден опираться на distance. Возможно, нужен preprocessing или другая окраска. Нельзя исправить отсутствие информации одним параметром regularization: иногда корректный вывод — анализировать perinuclear regions, а не полные клетки.

После FilterObjects пропали нужные measurements

Отфильтрованный object set считается новым набором. Переместите или продублируйте MeasureObjectSizeShape, MeasureObjectIntensity и другие нужные модули после FilterObjects. Старые measurements относятся к исходным объектам и не должны автоматически считаться характеристиками нового набора.

CSV содержит слишком много столбцов

Отключите Export all measurement types и выберите только признаки, нужные анализу, либо сократите upstream Measure-модули. Особенно быстро растут texture features при нескольких scales и каналах. Сначала определите гипотезу и downstream model, потом формируйте feature set.

Результаты интенсивности отличаются между сериями без биологической причины

Проверьте экспозицию микроскопа, saturation, illumination correction и Set intensity range from. Убедитесь, что один набор не был преобразован RescaleIntensity иначе. Если acquisition settings различаются, CellProfiler не может автоматически сделать абсолютные интенсивности сопоставимыми.

Pipeline работает в Test Mode, но падает на полном запуске

Причина может находиться в редком image set: отсутствующий канал, необычный размер, пустое изображение, слишком много объектов, несовпадающая metadata. Используйте лог, найдите номер image set и откройте его через Test > Choose Image Set. Затем добавьте правило, которое корректно обрабатывает этот класс данных, либо явно исключите повреждённый файл.

Анализ резко замедляется

Проверьте, не включены ли display windows для всех модулей, не добавлен ли тяжёлый MeasureTexture/Gabor, не сохраняются ли тысячи crops, не читаются ли данные по медленной сети. Для 3D оцените объём в памяти. Оптимизация должна быть измеримой: отключайте по одному фактору на небольшом subset и сравнивайте время.

Сравнение с аналогами

CellProfiler относится к научному количественному анализу изображений, поэтому сравнение с обычным фоторедактором полезно только для понимания границы задач. ФотоМАСТЕР рассчитан на обработку фотографий: цветокоррекцию, ретушь портретов, удаление объектов, замену и размытие фона, фильтры и локальные кисти. Он удобнее, если результатом должна быть визуально исправленная фотография. CellProfiler, наоборот, строит pipeline, сегментирует биологические объекты и экспортирует численные measurements. Использовать ФотоМАСТЕР для подсчёта ядер или CellProfiler для портретной ретуши — неправильный выбор класса инструмента.

Программа Основная задача Сильная сторона Ключевое ограничение относительно CellProfiler
CellProfiler Массовый анализ биологических изображений Модульные pipeline, object-level measurements, metadata Сегментацию нужно настраивать под данные
ФотоМАСТЕР Редактирование обычных фотографий Ретушь, фон, эффекты, цветокоррекция Не предназначен для научной сегментации и per-cell таблиц
Fiji/ImageJ Универсальная научная обработка изображений Огромная экосистема плагинов, макросы, ручные и интерактивные инструменты Для сложного batch workflow часто нужны макросы или скрипты
QuPath Цифровая патология и большие изображения тканей Whole-slide viewing, аннотации, клеточная детекция и spatial analysis Менее ориентирован на произвольные модульные high-content pipelines
ilastik Интерактивная ML-сегментация и классификация Pixel Classification с обучением по штрихам и live feedback Вероятностные карты часто требуют дальнейшего object analysis

Fiji/ImageJ — ближайший универсальный сосед. В нём доступны сегментация, tracking, deconvolution, registration и множество плагинов. Для единичной научной картинки или необычной операции Fiji часто быстрее: можно открыть изображение, применить команду, вручную поправить ROI и записать macro. CellProfiler выигрывает, когда workflow естественно описывается как повторяемая последовательность модулей с image sets, metadata, объектами и табличными measurements.

QuPath предпочтителен для whole-slide pathology и больших tissue images. Он совмещает просмотр огромных слайдов, аннотации областей, клеточную детекцию и пространственный анализ. CellProfiler лучше подходит для классического high-content microscopy, где много сравнительно небольших полей зрения и набор каналов повторяется. Огромный WSI без предварительного tiling — не естественный формат для CellProfiler.

ilastik закрывает другую слабость классических pipeline: когда foreground нельзя надёжно отделить фиксированным threshold, пользователь рисует примеры классов, а Random Forest строит pixel probabilities. После обучения ilastik умеет batch/headless prediction. Однако semantic segmentation ещё не равна таблице клеток. Поэтому практичная связка — ilastik для probability maps, CellProfiler для Watershed/objects, relationships и measurements.

Когда CellProfiler подходит лучше всего

Выбирайте CellProfiler, если у вас повторяющаяся серия микроскопических изображений с понятной схемой каналов и нужно получить количественные признаки объектов по одинаковым правилам. Особенно органичны задачи «найти → измерить → экспортировать»: ядра и клетки, organelles, colonies, spots, ткани небольшого поля, time-lapse objects и морфологическое профилирование.

Программа хорошо подходит лабораториям, где биолог должен менять параметры без написания кода, но workflow всё равно должен быть прозрачным. Каждый модуль виден в pipeline, а каждое output имя можно проследить до источника. Это облегчает совместную работу: специалист по анализу может подготовить .cppipe, а экспериментатор — применить его к стандартно названным данным.

CellProfiler особенно полезен, если downstream анализ уже построен вокруг CSV/SQL и per-cell features. Тогда сегментация — только первый этап, а истинная ценность — тысячи измерений, которые можно нормализовать, агрегировать и моделировать статистически.

Когда лучше выбрать другой инструмент

Для ручной ретуши, замены фона, портретов и художественных эффектов нужен фоторедактор, а не CellProfiler. Для огромных whole-slide pathology images с аннотациями и просмотром на разных масштабах логичнее QuPath. Для сложной интерактивной pixel classification — ilastik. Для нестандартной операции, которая уже реализована как Fiji plugin или легко записывается macro, Fiji может быть короче и удобнее.

Если анализ строится вокруг современной нейросети и весь объектный pipeline уже есть в Python, добавлять CellProfiler только ради графического интерфейса не всегда рационально. Но он остаётся полезным как оболочка для metadata, batch, QC и измерений, если эти части иначе пришлось бы писать самостоятельно.

Ограничение памяти и отсутствие полноценной multiscale tiling архитектуры тоже важно. CellProfiler способен на крупные batch-наборы за счёт обработки image sets и кластерного запуска, но один гигантский многогигапиксельный кадр — иной тип задачи, чем миллион небольших полей зрения.

Как проверить готовый pipeline перед большим экспериментом

Перед запуском выполните технический чек-лист. В Images должно быть ожидаемое число файлов. Metadata — без пустых ключевых полей. NamesAndTypes — ожидаемое число image sets, каждый с правильными каналами. Groups — число групп и порядок кадров. Output folder — отдельный и доступный для записи. Все модули — без красных ошибок.

В Test Mode пройдите минимум пять-десять разнообразных image sets. Для сегментации посмотрите контуры при большом увеличении, не только count. Для intensity проверьте, что выбран правильный канал и объект. Для filtering убедитесь, что критерий действительно удаляет артефакты, а не биологический подтип. Для export сделайте короткий обычный Analyze Images на маленьком subset и откройте CSV.

После запуска полной серии сравните число обработанных image sets с ожидаемым, размер каждой таблицы — с ожидаемым числом объектов, а распределение базовых признаков — с pilot run. Скачок Count или MeanIntensity может указывать как на биологию, так и на техническую проблему; контрольные wells и QC позволяют различить эти варианты.

Практические принципы настройки без переобучения на одном кадре

Главная ловушка визуального pipeline — бесконечная подстройка под конкретное изображение. Чтобы избежать этого, заранее разделите данные хотя бы мысленно на development и validation subset. На первой группе настраивайте parameters, на второй только оценивайте результат. Если validation плох, возвращайтесь к настройке, но не используйте все изображения по очереди как «пример для исправления».

Пороговые значения, размер объектов и фильтры должны иметь физический или эмпирический смысл. Диапазон diameter берётся из реального размера клетки и pixel size; минимальная Area — из распределения артефактов; intensity cutoff — из control population. Чем меньше произвольных чисел, тем легче объяснить pipeline и перенести на новый эксперимент.

Для batch-эксперимента проверяйте стабильность не только визуально, но и статистически. Постройте распределение Count, Area, MeanIntensity по plate/site. Резкие полосы по position могут показать illumination issue; один plate с другим distribution — изменение acquisition; высокая доля объектов на границе — неверное поле или crop. CellProfiler создаёт признаки, но визуализация распределений обычно выполняется downstream.

Что важно знать о форматах и значениях пикселей

Микроскопические данные могут быть 8-, 12-, 16-битными, float и многоканальными. CellProfiler часто нормирует значения внутри 0–1 для вычислений, основываясь на intensity range, указанном в NamesAndTypes. Поэтому число 0,5 внутри pipeline не означает «128 в 8-bit» во всех ситуациях без знания исходной шкалы и настроек.

Формат файла и формат изображения — не одно и то же. TIFF может содержать одну плоскость, stack, несколько каналов и OME metadata; Bio-Formats решает чтение, но matching между каналами остаётся вашей задачей. Если производитель микроскопа пишет нестандартный контейнер, сначала проверьте один файл через viewer и таблицы metadata.

Конвертация научного исходника в JPEG перед анализом почти всегда плохая идея. Потери меняют значения интенсивности и мелкую текстуру. Если нужно уменьшить объём, используйте lossless compression в поддерживаемом формате либо сохраняйте оригинал и отдельные preview для просмотра.

Маски, label images и перенос сегментации

CellProfiler различает бинарную маску и label image. В бинарной маске foreground обычно имеет одно значение; отдельные объекты ещё нужно разделить connected components или Watershed. В label image каждому объекту присвоено собственное целое число. NamesAndTypes может загружать такие данные как Objects, что позволяет измерять внешнюю сегментацию без повторного Identify.

При импорте label images убедитесь, что background = 0, объекты имеют целочисленные labels и размер точно совпадает с исходным изображением. Маска, сохранённая после resize или crop без аналогичной обработки raw channel, приведёт к пространственному сдвигу measurements.

При экспорте масок для другой программы лучше сохранять label data и отдельную визуальную overlay. Цветная картинка приятна для контроля, но цвета labels могут быть случайными и не являются идентификаторами объектов. Для машинного анализа нужен исходный label matrix.

Расширенные измерения и high-content profiling

В морфологическом профилировании один объект описывается сотнями признаков: геометрия, intensity разных каналов, texture на нескольких scales, granularity, radial distribution, neighbors. CellProfiler исторически хорошо подходит для такого извлечения признаков, но pipeline должен быть согласован с downstream normalization. Сырые features разных масштабов нельзя напрямую складывать в модель.

Часть признаков может быть почти константной, сильно коррелированной или чувствительной к batch effects. После экспорта обычно выполняют feature selection, robust scaling, plate normalization и контроль репликатов. Это уже не задача CellProfiler как такового. Он предоставляет воспроизводимое измерение; качество биологического профиля определяется всей цепочкой.

Если один channel используется только для сегментации, не обязательно измерять на нём все texture features. Разделение «channels for segmentation» и «channels for phenotype» уменьшает размер данных и число технических корреляций. То же относится к объектам: если Cytoplasm нужен только для ratio, не обязательно вычислять по нему весь набор shape metrics.

Разбор нескольких полезных модулей обработки

Align

Align сдвигает изображения по X/Y, чтобы каналы лучше совпадали. Это полезно при небольшом chromatic shift между каналами. Модуль не выполняет сложное nonrigid warping или rotation, поэтому большие геометрические искажения требуют другого инструмента. После align сегментацию и измерения делайте на соответствующих выходных images.

Crop и MaskImage

Crop физически ограничивает область изображения, MaskImage сохраняет геометрию кадра, но исключает masked pixels из дальнейших операций. Для планшета mask может убрать тёмный край лунки до illumination correction. Для анализа ROI маска помогает не считать объекты вне биологической области.

EnhanceOrSuppressFeatures

Модуль подчёркивает структуры определённого типа и масштаба. Его используют для точек, линий, текстур и некоторых brightfield/DIC задач. Параметр размера должен соответствовать характерному feature size; если применить его к структурам другого масштаба, можно усилить шум вместо сигнала.

OverlayOutlines

OverlayOutlines рисует границы объектов поверх изображения. Это один из лучших QC-выходов: человек быстро видит merge/split и смещение контуров. Если overlay сохраняется через SaveImages, не используйте его потом для intensity measurements — это уже визуализированное изображение с добавленными цветными пикселями.

Ошибки интерпретации, которые не исправляются настройками

Даже идеальная маска не гарантирует правильную биологическую метрику. IntegratedIntensity зависит от площади, texture — от разрешения, neighbor count — от плотности и края поля, ratio — от двух источников ошибки. Перед выбором measurement сформулируйте, какая величина отражает гипотезу и какие confounders на неё влияют.

Автоматизация усиливает как правильный алгоритм, так и систематическую ошибку. Ручной оператор может заметить странный кадр и остановиться; batch pipeline обработает его так же, как остальные. Поэтому QC и sampling — не опция, а часть аналитического дизайна.

CellProfiler не знает, что «клетка погибла», «ядро митотическое» или «структура артефакт», если это не выражено в измеримых признаках или модели. Не превращайте техническое имя object set в биологическую истину. Nuclei — это то, что pipeline определил как Nuclei по заданным правилам.

Частые вопросы

Нужно ли программировать для CellProfiler?

Для большинства стандартных pipeline нет. Модули добавляются и настраиваются через GUI. Код понадобится при создании собственного plugin, headless automation вокруг программы или нестандартном downstream анализе.

Можно ли анализировать не клетки?

Да. «Object» — общий термин. Это могут быть ядра, колонии, пятна, органеллы, части ткани, черви или другие сегментируемые структуры. Ограничение задаётся не названием, а тем, насколько выбранный алгоритм соответствует изображению.

Можно ли использовать готовую сегментацию?

Да. Label images можно загрузить как Objects либо преобразовать через ConvertImageToObjects. Это позволяет использовать CellProfiler как измерительный слой после внешнего сегментатора.

Поддерживается ли 3D?

Часть модулей поддерживает volumetric data, но не все. IdentifyPrimaryObjects ориентирован на 2D; для объёмных объектов используется Watershed и другие 3D-capable модули. Перед созданием pipeline проверяйте таблицу Supports 3D в справке каждого шага.

Почему результаты на двух компьютерах отличаются?

Сначала сравните версию CellProfiler, pipeline, plugins, input files и metadata. Различие версии может менять зависимости и алгоритмические детали. Также проверьте, не подставляются ли разные изображения из-за путей или фильтрации.

Можно ли остановить и продолжить анализ?

В File предусмотрены Stop Analysis и механизмы возобновления для частично завершённых запусков в соответствующих форматах output. Однако для надёжной воспроизводимости большого эксперимента проще делить данные на явные batches и вести отдельные логи.

Как понять, какой параметр менять первым?

Идите от причины к следствию: сначала правильный вход и intensity range, затем background/illumination, затем threshold, затем declumping, затем post-filter. Если начать с последнего FilterObjects, можно скрыть проблему segmentation, но не решить её.

Пороговая сегментация: как читать расширенные параметры

В Threshold и advanced settings IdentifyPrimaryObjects есть несколько параметров, которые легко воспринимать как независимые «ползунки», хотя они образуют систему. Threshold strategy определяет, один порог применяется ко всему изображению или вычисляются локальные значения. Thresholding method определяет сам алгоритм оценки разделения foreground/background. Threshold correction factor затем умножает вычисленный порог, а Lower and upper bounds ограничивают допустимый диапазон. Поэтому изменение correction factor после жёстких bounds может вообще не дать ожидаемого эффекта: итоговое значение упрётся в границу.

Two-class и Three-class Otsu отвечают на вопрос, сколько статистических классов интенсивности выделять. В трёхклассовом варианте промежуточный класс можно присоединить к foreground или background. Это удобно, когда есть фон, слабый сигнал и яркий сигнал, но выбор должен соответствовать тому, что именно считается объектом. Для слабой мембранной окраски промежуточный класс может содержать реальную биологию; для загрязнённого фона — наоборот, нежелательные пиксели.

Log transform before thresholding меняет распределение интенсивностей до оценки порога. Он может помочь, когда динамический диапазон очень широк и яркие области доминируют над основной массой пикселей. Но это не нейтральный способ «улучшить» картинку: порог после логарифма соответствует другой статистической модели. Если вы включили опцию, фиксируйте её как часть метода и проверяйте, не растёт ли число слабых false positive.

Threshold smoothing scale подавляет мелкие флуктуации перед оценкой порога. Слишком маленькое сглаживание оставляет шум, слишком большое размывает тонкие структуры. Важно отличать его от smoothing, используемого для declumping: один параметр влияет на foreground mask, другой — на поиск центров и разделение объектов. Настраивайте их раздельно и оценивайте промежуточные панели display window.

Гистология и UnmixColors

CellProfiler применяется не только к флуоресценции. Для brightfield-гистологии с несколькими красителями полезен UnmixColors, который разделяет цветное изображение на каналы по оптической плотности красителей. После разделения, например, ядерный компонент можно использовать для сегментации, а DAB-подобный канал — для измерения интенсивности или площади положительно окрашенных областей.

Такой pipeline отличается от обычного RGB-разделения. Простое ColorToGray или извлечение синего канала не моделирует смешение красителей. UnmixColors работает с заданными stain vectors, поэтому качество зависит от соответствия векторов реальной окраске и сканеру. Если цветовой баланс между партиями заметно меняется, проверьте стабильность decomposition на контрольных препаратах.

После color unmixing можно использовать Threshold для выделения положительно окрашенной ткани, MeasureImageAreaOccupied для доли площади и MeasureObjectIntensity для интенсивности внутри сегментированных клеточных компартментов. Важно решить, требуется ли per-cell результат или image/tissue-level площадь: это разные аналитические задачи и требуют разной сегментации.

Image-level измерения и контроль всего поля

Не все признаки должны быть per-object. MeasureImageIntensity оценивает интенсивность по всему изображению или внутри заданной области, MeasureImageAreaOccupied — долю или площадь занятых объектов/бинарного foreground, MeasureImageQuality — характеристики пригодности кадра. Такие показатели полезны для QC и для задач, где отдельная клетка не является единицей анализа.

Например, в wound-healing assay можно анализировать площадь свободного пространства или занятой клетками области без попытки идеально разделить каждую клетку. В плотной культуре это часто стабильнее индивидуальной сегментации. Аналогично, если биологический endpoint — общая площадь DAB-положительного сигнала в ткани, искусственная per-cell segmentation может добавить ненужную ошибку.

Выбор уровня измерения должен предшествовать pipeline. Если эксперимент рандомизирован по well, но статистическая единица — well, миллионы per-cell rows не превращают клетки в независимые биологические репликаты. CellProfiler умеет извлечь per-cell данные, но корректная агрегация и статистическая модель остаются задачей исследователя.

Организация файлов для переносимого проекта

Хорошая структура каталогов уменьшает количество специальных правил. Практичный вариант — отдельная папка raw, отдельная output и стабильная схема имени, например Plate_Well_Site_Channel.tif. Условия Treatment или Genotype лучше хранить в таблице metadata, если они меняются независимо от файлов. Тогда переименование биологического условия не требует переименовывать тысячи изображений.

Не включайте в raw результаты предыдущего анализа. Если SaveImages пишет corrected TIFF рядом с входами, при следующем открытии Images они могут снова попасть в file list и создать рекурсивный набор. Фильтр по суффиксу частично спасает, но отдельные directories надёжнее.

При передаче проекта на другой компьютер относительная структура удобнее абсолютных путей. Pipeline должен опираться на имена каналов и metadata, а не на буквальный путь C:Users… конкретного автора. Перед публикацией или передачей коллеге откройте .cppipe в новом чистом проекте, добавьте копию тестовых изображений из другого пути и убедитесь, что image sets собираются корректно.

Как документировать параметры для статьи или лабораторного протокола

Фразы «сегментация выполнена в CellProfiler» недостаточно. Минимально стоит указать версию программы, канал для сегментации, тип объектов, диапазон Typical diameter, стратегию и метод threshold, correction factor, способ declumping, критерии исключения объектов на границе и ключевые preprocessing steps. Для secondary objects укажите primary seeds и метод определения границы.

Для измерений перечислите конкретные категории: AreaShape, MeanIntensity, IntegratedIntensity, Texture scale и т. п. Если использовалась illumination correction, укажите способ расчёта функции и применение Divide/Subtract. Если pipeline включает внешнюю модель, зафиксируйте её имя, версию и параметры.

Сам .cppipe лучше хранить как дополнительный материал. Он снимает неоднозначность, но не заменяет текстовое описание: читатель должен понимать аналитическую логику без разбора десятков строк pipeline. Контрольные overlays помогают показать, что техническое определение объекта соответствует заявленному биологическому объекту.

Проверка переносимости между партиями эксперимента

Pipeline, настроенный на одном дне съёмки, не обязательно переносится на следующий. Фокус, экспозиция, яркость лампы, возраст красителя и плотность клеток меняют distribution пикселей. Перед объединением партий прогоните одинаковый контроль и сравните image-level statistics, count и segmentation overlays.

Если требуется менять threshold correction factor для каждой партии, это сигнал о batch effect. Иногда такое разделение обосновано и может быть формализовано через Groups или отдельные pipeline, но лучше сначала выяснить, можно ли устранить причину: нормализовать acquisition, использовать illumination correction или выбрать более устойчивый adaptive threshold.

Нельзя скрывать различия, нормируя каждую экспериментальную группу отдельно так, что биологический эффект исчезает или создаётся. Техническая нормализация должна опираться на controls и заранее определённые правила. CellProfiler предоставляет measurements, но не определяет статистически корректный способ объединения batches.

Что означает «автоматический анализ» в CellProfiler

Автоматизация начинается после того, как pipeline настроен и проверен. Программа не угадывает биологически правильные объекты по одному нажатию Analyze Images. Пользователь задаёт каналы, размеры, пороги, методы и критерии. Затем эти решения применяются одинаково ко всей серии, что и создаёт воспроизводимость.

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

Автоматический batch особенно ценен, когда ручное выделение невозможно по масштабу. Но чем больше объём данных, тем важнее пилотная валидация и QC. Ошибка в одном параметре, умноженная на миллион клеток, создаёт очень убедительную, но неверную таблицу.

Минимальный набор артефактов хорошего проекта

  • Исходные изображения или документированное место их хранения без перезаписи.
  • Экспортированный .cppipe с понятными именами промежуточных images и objects.
  • .cpproj для конкретного запуска, если важно сохранить file list и состояние проекта.
  • Таблица metadata и описание ключей, по которым она соединяется с изображениями.
  • Несколько representative overlays и masks для визуального QC.
  • CSV или база с measurements и запись версии CellProfiler.
  • Отдельный текст с критериями исключения кадров и объектов.

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

Итог

CellProfiler наиболее ценен там, где анализ должен быть повторяемым, объектным и массовым. Программа превращает микроскопические снимки в структуру «изображения → объекты → measurements», сохраняя настройки в pipeline и позволяя отделить интерактивную разработку в Test Mode от массового Analyze Images. Главные точки качества — корректное сопоставление каналов, устойчивый threshold и declumping, осмысленные measurements, metadata и QC.

Начинать лучше с минимального pipeline и нескольких разнообразных image sets. Когда сегментация стабильна, добавляйте вторичные объекты, отношения, texture, экспорт и batch processing. Такой порядок уменьшает число скрытых зависимостей и позволяет понять, на каком шаге появляется ошибка. В результате CellProfiler становится не набором фильтров, а формализованным протоколом количественного анализа изображений.

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

0 0 голоса
Рейтинг статьи

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные