OpenCV находит субъективные контуры, как человеческий глаз - PullRequest
0 голосов
/ 21 ноября 2018

Когда люди видят маркеры, предлагающие форму формы, они сразу же воспринимают саму форму, как в https://en.wikipedia.org/wiki/Illusory_contours. Я пытаюсь сделать нечто подобное в OpenCV, чтобы обнаружить форму руки вглубина изображения с очень сильным шумом.В этом вопросе предположим, что определение цвета кожи не работает (на самом деле это лучшее, чего я достиг за последнее время, но оно не является устойчивым при изменении условий освещения, теней или цветов кожи. Также используются различные формы бумаги (плоские и цветные)на столе, сбивающие с толку основанные на цвете подходы. Вот почему я пытаюсь использовать вместо этого камеру глубины).

Вот пример изображения живого материала, который уже предварительно обработан для лучшей контрастности и судален градиент фона: Hand with heavy background noise

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

Вот результат с примененным обнаружением кромки.Проблема здесь в том, что черная фигура внутри руки больше, чем фактическая рука, что приводит к превышению размера обнаруженной руки.Кроме того, линии не связаны, и я не могу определить контуры.Attempt with Canny

Обновление: Комбинирование Canny и морфологического замыкания (эллипс 4x4 px) делает возможным обнаружение контура с помощью следующихрезультат.По-прежнему слишком шумно. Canny with morphing

Обновление 2: Результат может быть слегка улучшенрисуя этот контур в пустой маске, сохраните его в буфере и повторно определите еще один контур при объединении трех буферизованных изображений.Линия, объединяющая буферизованные изображения, имеет вид hand_img = np.array(np.minimum(255, np.multiply.reduce(self.buf)), np.uint8), который затем снова трансформируется (закрывается) и, наконец, обнаруживается контур.Результаты немного менее ужасны, чем на картинке выше, но вместо этого запаздывают.

В качестве альтернативы я попытался использовать существующий CNN (https://github.com/victordibia/handtracking) для определения приблизительного положения центра руки (этошаг работает), а затем затопить оттуда. Для обнаружения контуров результат помещается в фильтр OTSU, а затем получается самый большой контур, что приводит к следующему рисунку (игнорируются черные прямоугольники слева). Проблема заключается в том, что некоторые изшум также затоплен, и результаты посредственны: Attempt with flooding

Наконец, я попробовал средства для удаления фона, такие как MOG2 или GMG. Они смущены огромным количеством быстро движущихсяШум. Также они обрезают кончики пальцев (что крайне важно для этого проекта). Наконец, они не видят достаточно деталей в руке (8 бит плюс дальнейшее уменьшение цвета с помощью equalizeHist дают очень плохое разрешение в оттенках серого) для надежного обнаружениямаленькие движения.

Смешно, как просто человеку увидеть экзct Точная форма руки на первом изображении и насколько невероятно трудно для компьютера нарисовать форму.

Какой метод рекомендовался бы для точной сегментации руки?

1 Ответ

0 голосов
/ 22 ноября 2018

После двух дней отчаянного тестирования решение было ОЧЕНЬ тщательно применить пороговое значение к хорошо обработанному изображению.

Вот шаги:

  1. Удалите столько шума, сколькоты возможно можешь.В моем случае шумоподавление было сделано с помощью Intel pyrealsense2 (я использую глубинную камеру Intel RealSense, и алгоритмы были написаны для этого семейства камер, поэтому они работают очень хорошо).Я использовал rs.temporal_filter() и сразу после rs.hole_filling_filter() на каждом кадре.
  2. Захват самого первого кадра.Помимо определения точного расстояния до таблицы (для последующего определения порога), этот шаг также сохраняет неподвижное изображение, размытое ядром 100x100 пикселей.Поскольку камера никогда не устанавливается идеально, а слегка наклоняется, на снимке появляется уродливый градиент серого, делающий операции невозможными.Это неподвижное изображение затем вычитается из каждого последующего кадра, устраняя градиент. Кстати: этот шаг удаления градиента уже включен в снимки экрана, показанные в приведенном выше вопросе
  3. Теперь изображение практически не содержит шумов. Не используйте equalizeHist. Это не просто регулярно увеличивает общий контраст, но вместо этого слишком сильно сопереживает остающемуся шуму.Это была моя главная ошибка, которую я сделал почти во всех экспериментах.Вместо этого примените порог (двоичный файл с фиксированной границей) напрямую.Граница очень тонкая, установка значения 104 вместо 205. Это очень важно.
  4. Инвертируйте цвета (если вы не взяли BINARY_INV на предыдущем шаге), примените контуры, выберите самый большой и напишите егона маску

Вуаля!

...