Я сейчас занимаюсь обработкой изображений в Python через PIL (Python Image Library). Моя главная цель - подсчитать количество цветных клеток на изображении иммуногистохимии. Я знаю, что есть соответствующие программы, библиотеки, функции и учебники об этом, и я проверил почти все из них. Моя главная цель - как можно больше писать код с нуля вручную. Поэтому я стараюсь избегать использования множества внешних библиотек и функций. Я написал большую часть программы. Итак, вот что происходит шаг за шагом:
Программа берет в файл изображения:
И обрабатывает его для красных клеток (в основном, это отключает значения RGB ниже определенного порога для красных):
И создает его булеву карту (вставит ее часть, поскольку она большая), которая в основном просто помещает 1, где бы он ни встречался, с красным пикселем на обработанном втором изображении выше.
22222222222222222222222222222222222222222
20000000111111110000000000000000000000002
20000000111111110000000000000000000000002
20000000111111110000000000000000000000002
20000000011111100000000000000000001100002
20000000001111100000000000000000011111002
20000000000110000000000000000000011111002
20000000000000000000000000000000111111002
20000000000000000000000000000000111111102
20000000000000000000000000000001111111102
20000000000000000000000000000001111111102
20000000000000000000000000000000111111002
20000000000000000000000000000000010000002
20000000000000000000000000000000000000002
22222222222222222222222222222222222222222
Я намеренно сгенерировал эту похожую на кадр вещь на границах с двумя единицами, чтобы помочь мне подсчитать количество групп единиц на этой булевой карте.
У меня вопрос к вам, ребята, почему я могу эффективно подсчитать количество ячеек (групп 1) в такой логической карте? Я нашел http://en.wikipedia.org/wiki/Connected-component_labeling, которые выглядят очень похожими и похожими, но, насколько я вижу, это на уровне пикселей. Мой на логическом уровне. Просто 1 и 0.
Большое спасибо.
Ответы:
Что-то вроде подхода грубой силы, но сделанного путем инвертирования задачи для индексации по коллекциям пикселей для поиска областей, вместо растеризации по массиву.
Печать:
источник
Scipy
, которая, вероятно, тоже быстрее ^^ 'Но в любом случае, вероятно, хорошее упражнение, и оно показывает, как это сделать в целом. Я буду голосовать тогда.Вы можете использовать
ndimage.label
, что является хорошим способом сделать это. Он возвращает новый массив, в котором каждая функция имеет уникальное значение и количество объектов. Вы также можете указать элемент подключения.источник
Вот алгоритм O (общее количество пикселей + количество пикселей в ячейке). Мы просто сканируем изображение на наличие пикселей ячейки, а когда находим один, заполняем ячейку, чтобы стереть ее.
Реализация в Common Lisp, но вы сможете перевести его на Python тривиально.
источник
Больше расширенного комментария, чем ответа:
Как намекнул @interjay, в двоичном изображении, то есть в том, в котором присутствуют только 2 цвета, пиксели принимают значение 1 или 0. Это может быть или не быть правдой в используемом вами формате представления изображения, но это правда в «концептуальном» представлении вашего имиджа; не позволяйте деталям реализации сбить вас с толку в этом вопросе. Одной из таких деталей реализации является использование вами 2s вокруг границы изображения - совершенно разумный способ определения мертвой зоны вокруг изображения, но не качественно влияющий на двоичность изображения.
Что касается проверки пикселей N, NE, NW и W: это связано со связностью пикселей при формировании компонента. Каждый пиксель (за исключением особых случаев на границе) имеет 8 соседей (N, S, E, W, NE, NW, SE, SW), но какие из них являются кандидатами для включения в один и тот же компонент? Иногда компоненты, которые встречаются только в углах (NE, NW, SE, SW), не рассматриваются как связанные, иногда они есть.
Вы должны решить, что подходит для вашей заявки. Я предлагаю вам отработать вручную несколько операций последовательного алгоритма, проверяя разных соседей для каждого пикселя, чтобы понять, что происходит.
источник