Перейти к содержимому
Compvision.ru
Smorodov

Поиск точки от лазерной указки

Recommended Posts

Как скорейшая реализция чего-то полезного, например управление Вашим новосконструированным роботом с субноутбуком вместо мозгов, при помощи лазерной указки подойдет такая программка.

LaserProject.png

Разберем подробнее, что же делает наша программа?

Сначала, естественно, захватывает изображение с камеры, так как это делалось в начальном примере.

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

cvThreshold( frame_red, frame_red, 250, 255, CV_THRESH_BINARY );

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

cvRectangle(frame_red, cvPoint(0,0), cvPoint(frame_red->width-1,frame_red->height-1),CV_RGB(0,0,0));

void cvMoments (IplImage* image, CvMoments* moments, int isBinary=0);

Архив проекта здесь:LaserPointer.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
А каков при этом сам алгоритм поиска точки?

В этом случае все предельно просто, после бинаризации остается лишь пятно от указки, оно ярче всего остального. А дальше алгоритм который вписывает набор точек в эллипс, эта часть есть в переведенной части руководства (нахождение осей и их наклон). Наклон тут не нужен, а центр можно найти через расчет моментов инерции этого пятна.

См. начиная со стр.12 этого документа: CV_Руководство.pdf

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я вот могу предложить некоторый алгоритм поиска подобной точки (непосредственно поиска центра).

Строим решётку по всей плоскости. Расстояния между точками должны быть такими, меньше которого точка у нас не поместилась бы.. Таким образом мы быстро натыкаемся на нашу точку (определяем например по порогу). После того как мы определили любую точку нашего лазера - в разные стороны запускаемся попиксельно (проверяя где пятно==цвет ещё существует). После мы получаем минимум по Х, по У и их максимумы. Делим пополам - получаем центр.

Интересно, в OpenCV алгоритм оптимальнее? :)

В качестве развития идеи, в алгоритме можно двигаться не попиксельно, а тоже перепрыгивая через некоторое расстояние. А как хватнули лишнего - так назад на один шаг и попиксельно смотрим где там границу потеряли.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Я вот могу предложить некоторый алгоритм поиска подобной точки (непосредственно поиска центра).

Строим решётку по всей плоскости. Расстояния между точками должны быть такими, меньше которого точка у нас не поместилась бы.. Таким образом мы быстро натыкаемся на нашу точку (определяем например по порогу). После того как мы определили любую точку нашего лазера - в разные стороны запускаемся попиксельно (проверяя где пятно==цвет ещё существует). После мы получаем минимум по Х, по У и их максимумы. Делим пополам - получаем центр.

Интересно, в OpenCV алгоритм оптимальнее? :)

В качестве развития идеи, в алгоритме можно двигаться не попиксельно, а тоже перепрыгивая через некоторое расстояние. А как хватнули лишнего - так назад на один шаг и попиксельно смотрим где там границу потеряли.

В OpenCV нет этой функции, это моя реализация, причем достаточно прямолинейная :)

Конечно лучше искать решетом, а потом методом дихотомии или попиксельным сканированием (вопрос оптимизации) находить границы и центр.

Может так получиться (при определенном диапазоне размеров изображения), что найти координаты ненулевых точек в сплошных блоках памяти будет быстрее чем извлекать отдельные точки, особенно принадлежащие вертикальным линиям.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А ещё сходу придумать можно такое:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Думаю стоит придать актуальность данной теме.

Совсем недавно занимался выделением точки от указки. В наличии было 2 лазера - красный и зеленый.

использовал 2 способа вычитание фона: вычитание другого канала и вычитание размытого канала. Алгоритм работает нормально, но только при темной картинке.

diffr = cvCreateImage( cvGetSize(view), IPL_DEPTH_8U, 1 );

diffg = cvCreateImage( cvGetSize(view), IPL_DEPTH_8U, 1 );

cvSplit( view, 0, diffg, diffr, 0);

//cvSmooth(diffg, diffr, CV_MEDIAN,41,41);

cvAddWeighted(diffr, 1, diffg, -1.20, 0, diffr);

cvReduce(diffr, &gy,1,CV_REDUCE_SUM); // Среднее по строкам

cvReduce(diffr, &gx,0,CV_REDUCE_SUM); // Среднее по столбцам

Зеленый лазер достаточно яркий и его отражение от стены на камере воспринимается засвеченным(значение около 255) во всех трех каналах, просто в зеленом оно раза в 2 больше по площади.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Добого времени суток.

А не проще отсканировать картинку на наличие небольшого красного (или того цвета которым светит лазер) пятна? Есле не пще то почему?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Это одна из реализаций того что Вы написали.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×