Простое распознавание объектов - PullRequest
6 голосов
/ 19 сентября 2009

=== решаемые ===

Спасибо за ваши предложения и комментарии. Работая над алгоритмом flood_fill, приведенным в книге Beginning Python Visualization (Глава 9 - Обработка изображений), я реализовал то, что хотел. Я могу подсчитать объекты, получить прямоугольники для каждого объекта (следовательно, высоту и ширину) и, наконец, построить NumPy-массивы или матрицы для каждого из них.

Хотя это не оптимизированный подход, он делает то, что я хочу. Используемый мной исходный код (lab2.py) и файл png (lab2-частицы.png) помещены в http://code.google.com/p/ccnworks/source/browse/#svn/trunk/AtSc450.

Вам нужно установить NumPy и PIL и matplotlib, чтобы увидеть гистограмму. Ядро кода находится внутри функции objfind, где происходит основное действие поиска рекурсивного объекта.

Еще одно обновление:

SciPy's ndimage.label () тоже делает то, что я хочу.

Приветствия к David-Warde Farley и Zachary Pincus из списков рассылки NumPy и SciPy за то, что они направили мне это в глаза:)

=============

Здравствуйте,

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

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

Как я мог легко решить эту проблему? (Желательно с использованием Python)

Спасибо.

ПРИМЕЧАНИЕ. В своем вопросе я имею в виду каждый конкретный связанный пиксель как объект или объект. Мое намерение извлечь их и создать представления массива NumPy, как показано ниже. (Здесь я использую левый верхний объект; если пиксель существует, используйте 1, если не используете 0. Форма этого объекта - 3 на 3, что соответствует высоте 3 пикселя на 3 пикселя. Это проекции реальных ледяных частиц на двухмерную область при условии, что они имеют сферическую форму, эквивалентный радиус равен (высота + ширина) / 2, а затем будут получены некоторые масштабирования - от пикселей до фактических размеров и объема)

import numpy as np

np.array([[1,1,1], [1,1,1], [0,0,1]])

array([[1, 1, 1],
       [1, 1, 1],
       [0, 0, 1]])

Вот часть изображения, которую я собираюсь использовать.

снимок экрана http://img43.imageshack.us/img43/2327/particles.png

Ответы [ 5 ]

5 голосов
/ 19 сентября 2009
  1. Сканирование каждого квадрата (например, сверху слева, слева направо, сверху вниз)

  2. Когда вы нажмете синий квадрат, то:

    а. Запишите этот квадрат как местоположение нового объекта

    б. Найдите все остальные смежные синие квадраты (например, посмотрев на соседей этого квадрата, соседей этих соседей и т. Д.) И отметьте их как часть одного и того же объекта

  3. Продолжить сканирование

  4. Когда вы найдете еще один синий квадрат, проверьте, является ли он частью известного объекта, прежде чем переходить к шагу 2; в качестве альтернативы на шаге 2b сотрите любой квадрат после того, как вы связали его с объектом

3 голосов
/ 20 сентября 2009

Раньше я делал такой анализ на микроснимках и в конечном итоге помещал все, что мне было нужно, в пакет обработки и анализа изображений, написанный на C, управляемый через Tcl. (Он работал только с 512 x 512 изображениями, что объясняет, почему 512 возникает так часто. Были изображения с выделенными пикселями разных размеров, но большая часть работы была сделана с 8-битными пикселями, что объясняет, почему существует такой бизнес 0xff и максимальное значение 254 на изображении.)

Вкратце, 'zz' в начале команд Tcl отправляет остаток строки в синтаксический анализатор пакета, который вызывает соответствующую подпрограмму C с заданными аргументами. Сразу после zz находится аргумент, который указывает на ввод и вывод команды. (Может быть несколько входов, но только один выход.) «R» обозначает 512 x 512 x 8-битное изображение. Третье слово - это имя команды, которую нужно вызвать; «графики» размечают изображение, как описано в тексте ниже. Итак, «zz rr graphs» означает «Вызов парсера ZZ; введите r изображение в команду графиков и верните r изображение. ' Остальная часть командной строки Tcl указывает, какие из предварительно выделенных изображений использовать. (Изображение «g» является областью интереса, т. Е. Представляющей интерес областью; почти все операции ZZ выполняются под контролем ROI.) Таким образом, «r1 r1 g8» означает «Использовать r1 в качестве входных данных, использовать r1 в качестве выходных данных ( то есть разметить само входное изображение) и выполнить операцию, где соответствующий пиксель на изображении g8 --- то есть r8, используемый в качестве ROI ---, равен> 0.

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

Пример 6. Подсчет признаков.

Задача

Подсчет является распространенной задачей. Подсчитанные элементы называются «признаками», и обычно необходимо тщательно подготовить изображения, чтобы однозначно соответствовать признакам с вещами, которые являются реальными объектами, подлежащими подсчету. Здесь, однако, мы игнорируем подготовку изображения и вместо этого рассмотрим механизм подсчета. Первое упражнение по подсчету состоит в том, чтобы выяснить, сколько объектов находится на изображениях в каталоге ./cells?

подход

Во-первых, давайте определим «особенность». Элемент - это самая большая группа «установленных» (ненулевых) пикселей, все из которых могут быть достигнуты путем перемещения от одного установленного пикселя к другому по маршрутам север-юг-восток-запад (вверх-вниз-вправо влево), начиная с из данного набора пикселей. Команда zz, которая обнаруживает и отмечает такие особенности на изображении, называется «zz rr graphs R: src R: dest G: ROI», так называемый математический термин для такой функции - «graph». Если установлены все пиксели на изображении, то на изображении присутствует только один график, но он содержит 262144 пикселя (512 * 512). Если пиксели установлены и очищены (равны нулю) в шахматном порядке, тогда будет 131072 (512 * 512/2) графиков, но каждый будет содержать только один пиксель. Вкратце, «zz rr graphs» начинается в верхнем левом углу изображения и сканирует каждый следующая строка слева направо, пока не будет найден установленный пиксель, а затем найдены все установленные пиксели, прикрепленные к нему через север, юг, восток или запад («4-соединены»). Затем все пиксели в этом графике устанавливаются в 1 (0x01). После нахождения и маркировки графика 1 он снова начинает сканирование в пикселе после того, где он впервые обнаружил график 1, на этот раз игнорируя любые пиксели, которые уже принадлежат графику. Первые 254 графика, которые он найдет, будут отмечены уникальным образом; однако все графики, найденные после этого, будут отмечены значением 255 (0xff) и так нельзя отличитьредактировать друг от друга. Ключом к возможности точного подсчета любого числа графиков является поэтапная обработка каждого изображения, то есть поиск числа графиков на изображении и, если это число больше 254, стирание только что найденных 254 графиков, повторение обрабатывать до 254 или менее графов. Язык Tcl предоставляет средства для настройки управления этой операцией.

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

zz ur to $inDir/$img r1
zz rr graphs r1 r1 g8

Затем мы обнуляем некоторые переменные для отслеживания количества, а затем используем команду «ra max», чтобы узнать, обнаружено ли более 254 графиков.

set nGraphs [ zz ra max r1 a1 g1 ]

Если nGraphs равен 255, то к итогу должны быть добавлены 254 точно подсчитанных графика, графики с 1 по 254 должны быть стерты, а счет повторен столько раз, сколько требуется для уменьшения числа нижеприведенных графиков. 255.

while {$nGraphs == 255} {
  incr sumGraphs 254
  zz rbr lt r1 155 r1 g1 0 255 
  set sumGraphs 0
  zz rr graphs r1 r1 g8
  set nGraphs [ zz ra max r1 a1 g8 ]
}

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

incr sumGraphs $nGraphs

После цикла обработки распечатайте общее количество функций, найденных в серии.

puts “Total number of features in $inDir \
images $beginImg through $endImg is $sumGraphs.”

После цикла обработки распечатайте общее количество функций, найденных в серии.

3 голосов
/ 19 сентября 2009

Глядя на предоставленное вами изображение, все, что вам нужно сделать, это применить простой алгоритм увеличения региона .

Если бы я использовал MATLAB, я бы использовал функции bwlabel / bwboundaries . Я полагаю, что где-то в Numpy есть эквивалентная функция, или используйте OpenCV с оболочками Python, как предложено @ kwatford

2 голосов
/ 20 сентября 2009

Анализ подключенных компонентов может быть то, что вы ищете.

2 голосов
/ 19 сентября 2009

OpenCV имеет интерфейс Python, который может оказаться полезным.

...