Как получить координаты белых точек на черном фоне

Немного предыстории:

Я строю арт-инсталляцию AR, и мне нужно отследить человека, который двигается по комнате.

Для этого я построил головной убор, который имеет несколько инфракрасных источников света (с рассеивателями) и камеру (веб-камера USB) с оптическим фильтром для удаления большинства / всего видимого света с изображения, а также несколько настроек к изображению, которое в основном оставляет меня с белыми точками на черном фоне.

Настроить веб-камеру таким образом, чтобы охватить границы комнаты, было довольно легко, но я не уверен, что нужно делать, а затем обрабатывать черно-белое изображение, чтобы получить координаты x,y каждой точки.

Пример вывода изображения: (Это макет, так как в этот момент у меня его нет, а также имейте в виду, что данные будут получены из видео) введите описание изображения здесь

Инструменты, которые я использую

  • NodeJS для обработки
  • Веб-камера Logitech для захвата изображения
  • Google Cardboard для визуальных эффектов
  • Инфракрасные светодиоды в шариках из пенопласта для приятного рассеянного света

Есть идеи?

3 ответа

Решение

Я могу придумать три способа сделать это с ImageMagick, который имеет node bindings и устанавливается в большинстве дистрибутивов Linux и доступен для OSX и Windows.

Во-первых, просто введите в командной строке:

identify -precision 5 -define identify:locate=maximum -define identify:limit=3 image.png
Channel maximum locations:
Gray: 65535 (1) 146,164 147,164 148,164

и это показывает, что три самых ярких пикселя имеют ширину 146 пикселей от верхнего левого угла и 164 пикселя от верхнего левого угла, а два рядом с ним - справа.

В качестве альтернативы, если вас интересует область и / или центр тяжести точки, вы можете выполнить анализ связанных компонентов с помощью ImageMagick, который выглядит следующим образом:

convert image.png                               \
    -colorspace gray -threshold 10%             \
    -define connected-components:verbose=true   \
    -connected-components 8 output.png

Objects (id: bounding-box centroid area mean-color):
0: 818x502+0+0 408.6,250.5 410539 srgb(0,0,0)
1: 11x11+143+164 148.0,169.0 97 srgb(255,255,255)

Это показывает вам (в последней строке вывода), что белый шарик имеет размер 11 x 11 пикселей и расположен на 143 пикселях поперек изображения от левого края и на 164 пикселя вниз от верха. Его центр тяжести - 148 169, площадь - 97 пикселей, цвет белый.

Первый найденный объект (от второй до последней строки вывода) - это все изображение, и вы можете не учитывать его, так как его цвет черный, т. Е. Rgb(0,0,0).

Я тоже могу немного объяснить параметры... Я преобразую в оттенки серого, потому что Coonected Component Analysis традиционно ищет белые объекты на черном фоне в черно-белом изображении. Затем я порог, чтобы получить чистый белый и чистый черный - вам может понадобиться медианный фильтр здесь в вашей реальной системе, чтобы избавиться от шума -median 3, например. verbose=true означает, что команда должна напечатать список всех больших двоичных объектов и 8 означает, что пиксели, которые соединены с 8 элементами, являются частями одного и того же большого двоичного объекта, то есть пиксель, касающийся другого в его углу NE, SE, SW или NW, считается частью того же самого большого двоичного объекта - если установить его на 4 пиксели должны быть непосредственно рядом или выше / ниже друг друга, чтобы считаться соседями.

Если вы хотите " вставить " область, которую он нашел, вы можете сделать это следующим образом:

convert image.png -stroke red -fill none -strokewidth 2 -draw "rectangle 143,164 154,175" output.png

Третий метод медленнее, и он включает в себя преобразование изображения в текст, а затем поиск слова "белый". Так. давайте начнем с простого и просто преобразуем изображение в текст следующим образом:

convert image.png -threshold 50% txt:
# ImageMagick pixel enumeration: 818,502,255,srgb
0,0: (0,0,0)  #000000  black
1,0: (0,0,0)  #000000  black
2,0: (0,0,0)  #000000  black
3,0: (0,0,0)  #000000  black
...
... 410,000 lines later
...
813,501: (0,0,0)  #000000  black
814,501: (0,0,0)  #000000  black
815,501: (0,0,0)  #000000  black
816,501: (0,0,0)  #000000  black
817,501: (0,0,0)  #000000  black

Теперь давайте уточним это и посмотрим только на белые пиксели (в Windows вы бы использовали FINDSTR скорее, чем grep):

convert image.png -threshold 50% txt: | grep white
146,164: (255,255,255)  #FFFFFF  white
147,164: (255,255,255)  #FFFFFF  white
148,164: (255,255,255)  #FFFFFF  white
149,164: (255,255,255)  #FFFFFF  white
150,164: (255,255,255)  #FFFFFF  white
145,165: (255,255,255)  #FFFFFF  white
146,165: (255,255,255)  #FFFFFF  white
147,165: (255,255,255)  #FFFFFF  white
148,165: (255,255,255)  #FFFFFF  white
149,165: (255,255,255)  #FFFFFF  white
150,165: (255,255,255)  #FFFFFF  white
151,165: (255,255,255)  #FFFFFF  white
144,166: (255,255,255)  #FFFFFF  white
145,166: (255,255,255)  #FFFFFF  white
146,166: (255,255,255)  #FFFFFF  white
147,166: (255,255,255)  #FFFFFF  white
148,166: (255,255,255)  #FFFFFF  white
149,166: (255,255,255)  #FFFFFF  white
150,166: (255,255,255)  #FFFFFF  white
151,166: (255,255,255)  #FFFFFF  white
152,166: (255,255,255)  #FFFFFF  white
143,167: (255,255,255)  #FFFFFF  white
144,167: (255,255,255)  #FFFFFF  white
145,167: (255,255,255)  #FFFFFF  white
146,167: (255,255,255)  #FFFFFF  white
147,167: (255,255,255)  #FFFFFF  white
148,167: (255,255,255)  #FFFFFF  white
149,167: (255,255,255)  #FFFFFF  white
150,167: (255,255,255)  #FFFFFF  white
151,167: (255,255,255)  #FFFFFF  white
152,167: (255,255,255)  #FFFFFF  white
153,167: (255,255,255)  #FFFFFF  white
143,168: (255,255,255)  #FFFFFF  white
144,168: (255,255,255)  #FFFFFF  white
145,168: (255,255,255)  #FFFFFF  white
146,168: (255,255,255)  #FFFFFF  white
147,168: (255,255,255)  #FFFFFF  white
148,168: (255,255,255)  #FFFFFF  white
149,168: (255,255,255)  #FFFFFF  white
150,168: (255,255,255)  #FFFFFF  white
151,168: (255,255,255)  #FFFFFF  white
152,168: (255,255,255)  #FFFFFF  white
153,168: (255,255,255)  #FFFFFF  white
143,169: (255,255,255)  #FFFFFF  white
144,169: (255,255,255)  #FFFFFF  white
145,169: (255,255,255)  #FFFFFF  white
146,169: (255,255,255)  #FFFFFF  white
147,169: (255,255,255)  #FFFFFF  white
148,169: (255,255,255)  #FFFFFF  white
149,169: (255,255,255)  #FFFFFF  white
150,169: (255,255,255)  #FFFFFF  white
151,169: (255,255,255)  #FFFFFF  white
152,169: (255,255,255)  #FFFFFF  white
153,169: (255,255,255)  #FFFFFF  white
143,170: (255,255,255)  #FFFFFF  white
144,170: (255,255,255)  #FFFFFF  white
145,170: (255,255,255)  #FFFFFF  white
146,170: (255,255,255)  #FFFFFF  white
147,170: (255,255,255)  #FFFFFF  white
148,170: (255,255,255)  #FFFFFF  white
149,170: (255,255,255)  #FFFFFF  white
150,170: (255,255,255)  #FFFFFF  white
151,170: (255,255,255)  #FFFFFF  white
152,170: (255,255,255)  #FFFFFF  white
153,170: (255,255,255)  #FFFFFF  white
143,171: (255,255,255)  #FFFFFF  white
144,171: (255,255,255)  #FFFFFF  white
145,171: (255,255,255)  #FFFFFF  white
146,171: (255,255,255)  #FFFFFF  white
147,171: (255,255,255)  #FFFFFF  white
148,171: (255,255,255)  #FFFFFF  white
149,171: (255,255,255)  #FFFFFF  white
150,171: (255,255,255)  #FFFFFF  white
151,171: (255,255,255)  #FFFFFF  white
152,171: (255,255,255)  #FFFFFF  white
153,171: (255,255,255)  #FFFFFF  white
144,172: (255,255,255)  #FFFFFF  white
145,172: (255,255,255)  #FFFFFF  white
146,172: (255,255,255)  #FFFFFF  white
147,172: (255,255,255)  #FFFFFF  white
148,172: (255,255,255)  #FFFFFF  white
149,172: (255,255,255)  #FFFFFF  white
150,172: (255,255,255)  #FFFFFF  white
151,172: (255,255,255)  #FFFFFF  white
152,172: (255,255,255)  #FFFFFF  white
145,173: (255,255,255)  #FFFFFF  white
146,173: (255,255,255)  #FFFFFF  white
147,173: (255,255,255)  #FFFFFF  white
148,173: (255,255,255)  #FFFFFF  white
149,173: (255,255,255)  #FFFFFF  white
150,173: (255,255,255)  #FFFFFF  white
151,173: (255,255,255)  #FFFFFF  white
146,174: (255,255,255)  #FFFFFF  white
147,174: (255,255,255)  #FFFFFF  white
148,174: (255,255,255)  #FFFFFF  white
149,174: (255,255,255)  #FFFFFF  white
150,174: (255,255,255)  #FFFFFF  white

Что касается node версия, я действительно не очень хорош в node но я могу указать вам мой ответ здесь, который делает другой процесс ImageMagick через node и надеемся, что вы сможете это адаптировать, если вы попробуете вышеизложенное в командной строке и обнаружите, что оно работает для вас достаточно хорошо, и вы хотите использовать ImageMagick.

Многие (большинство?) Библиотеки обработки изображений (например, OpenCV) имеют модуль извлечения подключенных компонентов. Учитывая бинарное изображение, как в вашем примере, вы получите список всех связанных областей изображения. Вы можете рассчитать их центр тяжести, чтобы получить центр ваших точек.

Одним из способов было бы использовать " преобразование Хафа". Простое преобразование в основном преобразует изображение в другую систему координат, где вы можете "легко" обнаружить круглые формы.

Я нашел nodejs-пример в другом вопросе. Я не уверен, что это сработало для них: hough transform - javascript - node.js

Вы также можете пройтись по каждому пикселю изображения и проверить, является ли он белым или нет, а если он белый, найти всех его белых соседей и удалить их. Вычислите их средние координаты xy и вуаля, у вас есть координаты вашей точки. Это, вероятно, хорошо работает, если у вас не слишком много шума.

Другие вопросы по тегам